@gonzih/cc-agent 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # cc-agent
2
+
3
+ MCP server for spawning Claude Code agents in cloned repos. Give Claude Code the ability to **branch itself** — clone a repo and kick off a sub-agent to work on it autonomously.
4
+
5
+ ## What it does
6
+
7
+ Exposes 5 MCP tools:
8
+
9
+ | Tool | Description |
10
+ |------|-------------|
11
+ | `spawn_agent` | Clone a git repo and run Claude Code on a task inside it |
12
+ | `get_job_status` | Check status of a spawned job |
13
+ | `get_job_output` | Stream output lines from a job |
14
+ | `list_jobs` | List all jobs |
15
+ | `cancel_job` | Cancel a running job |
16
+
17
+ Claude submits a job → cc-agent clones the repo → starts Claude Code in it with the task → returns immediately with a job ID → caller polls for output.
18
+
19
+ ## Quickstart
20
+
21
+ ```bash
22
+ # Add to Claude Code MCP config
23
+ claude mcp add cc-agent -- npx @gonzih/cc-agent
24
+ ```
25
+
26
+ Set one of:
27
+ ```bash
28
+ CLAUDE_CODE_TOKEN=sk-ant-oat01-... # OAuth token
29
+ ANTHROPIC_API_KEY=sk-ant-api03-... # API key
30
+ ```
31
+
32
+ Then restart Claude Code.
33
+
34
+ ## Example usage (from within Claude Code)
35
+
36
+ ```
37
+ spawn_agent({
38
+ repo_url: "https://github.com/yourorg/yourrepo",
39
+ task: "Find all TODO comments and create a summary in TODO_SUMMARY.md",
40
+ create_branch: "agent/todo-summary"
41
+ })
42
+ // → { job_id: "abc-123", status: "started" }
43
+
44
+ get_job_output({ job_id: "abc-123" })
45
+ // → { lines: ["[cc-agent] Cloning...", "..."], done: false }
46
+ ```
47
+
48
+ ## Environment variables
49
+
50
+ | Variable | Description |
51
+ |----------|-------------|
52
+ | `CLAUDE_CODE_TOKEN` | Claude OAuth token (sk-ant-oat01-...) |
53
+ | `ANTHROPIC_API_KEY` | Anthropic API key (sk-ant-api03-...) |
54
+
55
+ Per-job token override available via `claude_token` argument on `spawn_agent`.
56
+
57
+ ## MCP config example
58
+
59
+ ```json
60
+ {
61
+ "cc-agent": {
62
+ "command": "npx",
63
+ "args": ["@gonzih/cc-agent"],
64
+ "env": {
65
+ "ANTHROPIC_API_KEY": "sk-ant-api03-..."
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ ## How it works
72
+
73
+ 1. `spawn_agent` creates a job and returns immediately
74
+ 2. In background: `git clone --depth 1 <repo>` into a temp dir
75
+ 3. Optionally checks out a branch or creates a new one
76
+ 4. Runs `claude --print --output-format stream-json --dangerously-skip-permissions "<task>"`
77
+ 5. Streams output into job record
78
+ 6. Temp dir cleaned up 10 minutes after job finishes
79
+ 7. Jobs expire after 1 hour
80
+
81
+ ## Related
82
+
83
+ - [cc-tg](https://github.com/Gonzih/cc-tg) — Claude Code Telegram bot (same author)
@@ -0,0 +1,18 @@
1
+ import type { Job, JobSummary, SpawnOptions } from "./types.js";
2
+ export declare class JobManager {
3
+ private jobs;
4
+ private kills;
5
+ private defaultToken?;
6
+ constructor(token?: string);
7
+ spawn(opts: SpawnOptions): Promise<string>;
8
+ private run;
9
+ getJob(id: string): Job | undefined;
10
+ getOutput(id: string, offset?: number): {
11
+ lines: string[];
12
+ done: boolean;
13
+ };
14
+ list(): JobSummary[];
15
+ cancel(id: string): boolean;
16
+ private cleanup;
17
+ }
18
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,GAAG,EAAa,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM3E,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,YAAY,CAAC,CAAS;gBAElB,KAAK,CAAC,EAAE,MAAM;IAMpB,KAAK,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;YAwBlC,GAAG;IA+DjB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAInC,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE;IASrE,IAAI,IAAI,UAAU,EAAE;IAepB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAiB3B,OAAO,CAAC,OAAO;CAYhB"}
package/dist/agent.js ADDED
@@ -0,0 +1,151 @@
1
+ import { execFile } from "child_process";
2
+ import { mkdtemp, rm } from "fs/promises";
3
+ import { tmpdir } from "os";
4
+ import { join } from "path";
5
+ import { promisify } from "util";
6
+ import { v4 as uuidv4 } from "uuid";
7
+ import { runClaude } from "./claude.js";
8
+ const execFileAsync = promisify(execFile);
9
+ const JOB_TTL_MS = 60 * 60 * 1000; // 1 hour — clean up old done jobs
10
+ export class JobManager {
11
+ jobs = new Map();
12
+ kills = new Map();
13
+ defaultToken;
14
+ constructor(token) {
15
+ this.defaultToken = token;
16
+ // Periodic cleanup of old finished jobs
17
+ setInterval(() => this.cleanup(), 5 * 60 * 1000).unref();
18
+ }
19
+ async spawn(opts) {
20
+ const id = uuidv4();
21
+ const job = {
22
+ id,
23
+ repoUrl: opts.repoUrl,
24
+ task: opts.task,
25
+ branch: opts.branch,
26
+ createBranch: opts.createBranch,
27
+ status: "cloning",
28
+ output: [],
29
+ startedAt: new Date(),
30
+ };
31
+ this.jobs.set(id, job);
32
+ // Run async — don't await
33
+ this.run(job, opts.claudeToken ?? this.defaultToken).catch((err) => {
34
+ job.status = "failed";
35
+ job.error = String(err);
36
+ job.finishedAt = new Date();
37
+ });
38
+ return id;
39
+ }
40
+ async run(job, token) {
41
+ let workDir;
42
+ try {
43
+ // 1. Clone
44
+ workDir = await mkdtemp(join(tmpdir(), `cc-agent-${job.id.slice(0, 8)}-`));
45
+ job.workDir = workDir;
46
+ job.output.push(`[cc-agent] Cloning ${job.repoUrl}...`);
47
+ const cloneArgs = ["clone", "--depth", "1"];
48
+ if (job.branch)
49
+ cloneArgs.push("--branch", job.branch);
50
+ cloneArgs.push(job.repoUrl, workDir);
51
+ await execFileAsync("git", cloneArgs);
52
+ job.output.push(`[cc-agent] Cloned to ${workDir}`);
53
+ // 2. Create branch if requested
54
+ if (job.createBranch) {
55
+ await execFileAsync("git", ["checkout", "-b", job.createBranch], { cwd: workDir });
56
+ job.output.push(`[cc-agent] Created branch: ${job.createBranch}`);
57
+ }
58
+ // 3. Run Claude
59
+ job.status = "running";
60
+ job.output.push(`[cc-agent] Starting Claude with task...`);
61
+ await new Promise((resolve, reject) => {
62
+ const proc = runClaude(job.task, workDir, token);
63
+ this.kills.set(job.id, () => proc.kill());
64
+ proc.on("text", (text) => {
65
+ if (text.trim())
66
+ job.output.push(text);
67
+ });
68
+ proc.on("error", (err) => {
69
+ reject(err);
70
+ });
71
+ proc.on("exit", (code) => {
72
+ job.exitCode = code ?? undefined;
73
+ this.kills.delete(job.id);
74
+ if (code === 0 || code === null) {
75
+ resolve();
76
+ }
77
+ else {
78
+ reject(new Error(`Claude exited with code ${code}`));
79
+ }
80
+ });
81
+ });
82
+ job.status = "done";
83
+ job.output.push(`[cc-agent] Done. Exit code: ${job.exitCode ?? 0}`);
84
+ }
85
+ catch (err) {
86
+ job.status = "failed";
87
+ job.error = String(err);
88
+ job.output.push(`[cc-agent] FAILED: ${job.error}`);
89
+ }
90
+ finally {
91
+ job.finishedAt = new Date();
92
+ // Clean up work dir after 10 minutes to allow output inspection
93
+ if (workDir) {
94
+ setTimeout(() => rm(workDir, { recursive: true, force: true }).catch(() => { }), 10 * 60 * 1000).unref();
95
+ }
96
+ }
97
+ }
98
+ getJob(id) {
99
+ return this.jobs.get(id);
100
+ }
101
+ getOutput(id, offset = 0) {
102
+ const job = this.jobs.get(id);
103
+ if (!job)
104
+ return { lines: [], done: true };
105
+ return {
106
+ lines: job.output.slice(offset),
107
+ done: job.status === "done" || job.status === "failed" || job.status === "cancelled",
108
+ };
109
+ }
110
+ list() {
111
+ return Array.from(this.jobs.values()).map((j) => ({
112
+ id: j.id,
113
+ status: j.status,
114
+ repoUrl: j.repoUrl,
115
+ task: j.task.slice(0, 120) + (j.task.length > 120 ? "..." : ""),
116
+ branch: j.branch,
117
+ createBranch: j.createBranch,
118
+ startedAt: j.startedAt.toISOString(),
119
+ finishedAt: j.finishedAt?.toISOString(),
120
+ exitCode: j.exitCode,
121
+ error: j.error,
122
+ }));
123
+ }
124
+ cancel(id) {
125
+ const job = this.jobs.get(id);
126
+ if (!job)
127
+ return false;
128
+ if (job.status !== "cloning" && job.status !== "running")
129
+ return false;
130
+ const kill = this.kills.get(id);
131
+ if (kill) {
132
+ kill();
133
+ this.kills.delete(id);
134
+ }
135
+ job.status = "cancelled";
136
+ job.finishedAt = new Date();
137
+ job.output.push("[cc-agent] Cancelled by user.");
138
+ return true;
139
+ }
140
+ cleanup() {
141
+ const now = Date.now();
142
+ for (const [id, job] of this.jobs) {
143
+ if ((job.status === "done" || job.status === "failed" || job.status === "cancelled") &&
144
+ job.finishedAt &&
145
+ now - job.finishedAt.getTime() > JOB_TTL_MS) {
146
+ this.jobs.delete(id);
147
+ }
148
+ }
149
+ }
150
+ }
151
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { EventEmitter } from "events";
2
+ export type MessageType = "system" | "assistant" | "user" | "result";
3
+ export interface ClaudeMessage {
4
+ type: MessageType;
5
+ session_id?: string;
6
+ payload: Record<string, unknown>;
7
+ }
8
+ export interface OneShot extends EventEmitter {
9
+ on(event: "message", listener: (msg: ClaudeMessage) => void): this;
10
+ on(event: "text", listener: (text: string) => void): this;
11
+ on(event: "error", listener: (err: Error) => void): this;
12
+ on(event: "exit", listener: (code: number | null) => void): this;
13
+ }
14
+ /**
15
+ * Run Claude Code non-interactively in a directory with a task.
16
+ * Streams JSON output, emits text chunks and structured messages.
17
+ */
18
+ export declare function runClaude(task: string, cwd: string, token?: string): OneShot & {
19
+ kill: () => void;
20
+ };
21
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;AAErE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,OAAQ,SAAQ,YAAY;IAC3C,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI,CAAC;IACnE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1D,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IACzD,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;CAClE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,IAAI,CAAA;CAAE,CAgEhC"}
package/dist/claude.js ADDED
@@ -0,0 +1,104 @@
1
+ import { existsSync } from "fs";
2
+ import { spawn } from "child_process";
3
+ import { EventEmitter } from "events";
4
+ /**
5
+ * Run Claude Code non-interactively in a directory with a task.
6
+ * Streams JSON output, emits text chunks and structured messages.
7
+ */
8
+ export function runClaude(task, cwd, token) {
9
+ const emitter = new EventEmitter();
10
+ const claudeBin = resolveClaude();
11
+ const args = [
12
+ "--print",
13
+ "--output-format", "stream-json",
14
+ "--dangerously-skip-permissions",
15
+ "--verbose",
16
+ task,
17
+ ];
18
+ const env = { ...process.env };
19
+ if (token) {
20
+ if (token.startsWith("sk-ant-api")) {
21
+ env.ANTHROPIC_API_KEY = token;
22
+ delete env.CLAUDE_CODE_OAUTH_TOKEN;
23
+ }
24
+ else {
25
+ env.CLAUDE_CODE_OAUTH_TOKEN = token;
26
+ delete env.ANTHROPIC_API_KEY;
27
+ }
28
+ }
29
+ const proc = spawn(claudeBin, args, { cwd, env, stdio: ["ignore", "pipe", "pipe"] });
30
+ let buffer = "";
31
+ proc.stdout.on("data", (chunk) => {
32
+ buffer += chunk.toString();
33
+ const lines = buffer.split("\n");
34
+ buffer = lines.pop() ?? "";
35
+ for (const line of lines) {
36
+ if (!line.trim())
37
+ continue;
38
+ try {
39
+ const raw = JSON.parse(line);
40
+ const type = raw.type;
41
+ if (!type)
42
+ continue;
43
+ const msg = { type, payload: raw };
44
+ if (raw.session_id)
45
+ msg.session_id = raw.session_id;
46
+ emitter.emit("message", msg);
47
+ const text = extractText(msg);
48
+ if (text)
49
+ emitter.emit("text", text);
50
+ }
51
+ catch {
52
+ // non-JSON noise
53
+ }
54
+ }
55
+ });
56
+ proc.stderr.on("data", (chunk) => {
57
+ // stderr goes to text as info
58
+ const s = chunk.toString().trim();
59
+ if (s)
60
+ emitter.emit("text", `[stderr] ${s}`);
61
+ });
62
+ proc.on("error", (err) => emitter.emit("error", err));
63
+ proc.on("exit", (code) => emitter.emit("exit", code));
64
+ emitter.kill = () => proc.kill();
65
+ return emitter;
66
+ }
67
+ function extractText(msg) {
68
+ if (msg.type === "result") {
69
+ return msg.payload.result ?? "";
70
+ }
71
+ const message = msg.payload.message;
72
+ if (!message)
73
+ return "";
74
+ const content = message.content;
75
+ if (typeof content === "string")
76
+ return content;
77
+ if (Array.isArray(content)) {
78
+ return content
79
+ .filter((b) => b.type === "text")
80
+ .map((b) => b.text)
81
+ .join("");
82
+ }
83
+ return "";
84
+ }
85
+ function resolveClaude() {
86
+ const dirs = (process.env.PATH ?? "").split(":");
87
+ for (const dir of dirs) {
88
+ const c = `${dir}/claude`;
89
+ if (existsSync(c))
90
+ return c;
91
+ }
92
+ const fallbacks = [
93
+ `${process.env.HOME}/.npm-global/bin/claude`,
94
+ "/opt/homebrew/bin/claude",
95
+ "/usr/local/bin/claude",
96
+ "/usr/bin/claude",
97
+ ];
98
+ for (const p of fallbacks) {
99
+ if (existsSync(p))
100
+ return p;
101
+ }
102
+ return "claude";
103
+ }
104
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * cc-agent — MCP server for spawning Claude Code agents in cloned repos
4
+ *
5
+ * Usage (stdio MCP):
6
+ * npx @gonzih/cc-agent
7
+ *
8
+ * Optional env:
9
+ * CLAUDE_CODE_TOKEN — Claude OAuth token or Anthropic API key
10
+ * ANTHROPIC_API_KEY — alternative API key
11
+ *
12
+ * MCP tools exposed:
13
+ * spawn_agent — clone a repo and run Claude on a task
14
+ * get_job_status — check job status
15
+ * get_job_output — stream job output
16
+ * list_jobs — list all jobs
17
+ * cancel_job — cancel a running job
18
+ */
19
+ export {};
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG"}
package/dist/index.js ADDED
@@ -0,0 +1,197 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * cc-agent — MCP server for spawning Claude Code agents in cloned repos
4
+ *
5
+ * Usage (stdio MCP):
6
+ * npx @gonzih/cc-agent
7
+ *
8
+ * Optional env:
9
+ * CLAUDE_CODE_TOKEN — Claude OAuth token or Anthropic API key
10
+ * ANTHROPIC_API_KEY — alternative API key
11
+ *
12
+ * MCP tools exposed:
13
+ * spawn_agent — clone a repo and run Claude on a task
14
+ * get_job_status — check job status
15
+ * get_job_output — stream job output
16
+ * list_jobs — list all jobs
17
+ * cancel_job — cancel a running job
18
+ */
19
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
20
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
21
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
22
+ import { JobManager } from "./agent.js";
23
+ const token = process.env.CLAUDE_CODE_TOKEN ??
24
+ process.env.CLAUDE_CODE_OAUTH_TOKEN ??
25
+ process.env.ANTHROPIC_API_KEY;
26
+ const manager = new JobManager(token);
27
+ const server = new Server({ name: "cc-agent", version: "0.1.0" }, { capabilities: { tools: {} } });
28
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
29
+ tools: [
30
+ {
31
+ name: "spawn_agent",
32
+ description: "Clone a git repo and run Claude Code on a task inside it. Returns a job_id immediately — the agent runs in the background.",
33
+ inputSchema: {
34
+ type: "object",
35
+ properties: {
36
+ repo_url: {
37
+ type: "string",
38
+ description: "Git repository URL to clone (https or ssh)",
39
+ },
40
+ task: {
41
+ type: "string",
42
+ description: "Task description to pass to Claude Code",
43
+ },
44
+ branch: {
45
+ type: "string",
46
+ description: "Branch to checkout after cloning (optional)",
47
+ },
48
+ create_branch: {
49
+ type: "string",
50
+ description: "New branch name to create before running the task (optional)",
51
+ },
52
+ claude_token: {
53
+ type: "string",
54
+ description: "Claude OAuth token or Anthropic API key to use for this job (optional — falls back to server env)",
55
+ },
56
+ },
57
+ required: ["repo_url", "task"],
58
+ },
59
+ },
60
+ {
61
+ name: "get_job_status",
62
+ description: "Get the current status of a spawned agent job.",
63
+ inputSchema: {
64
+ type: "object",
65
+ properties: {
66
+ job_id: { type: "string", description: "Job ID returned by spawn_agent" },
67
+ },
68
+ required: ["job_id"],
69
+ },
70
+ },
71
+ {
72
+ name: "get_job_output",
73
+ description: "Get output lines from a running or finished job. Use offset to paginate.",
74
+ inputSchema: {
75
+ type: "object",
76
+ properties: {
77
+ job_id: { type: "string", description: "Job ID returned by spawn_agent" },
78
+ offset: {
79
+ type: "number",
80
+ description: "Line offset to start from (default 0)",
81
+ },
82
+ },
83
+ required: ["job_id"],
84
+ },
85
+ },
86
+ {
87
+ name: "list_jobs",
88
+ description: "List all agent jobs (running, done, failed, cancelled).",
89
+ inputSchema: { type: "object", properties: {} },
90
+ },
91
+ {
92
+ name: "cancel_job",
93
+ description: "Cancel a running agent job.",
94
+ inputSchema: {
95
+ type: "object",
96
+ properties: {
97
+ job_id: { type: "string", description: "Job ID to cancel" },
98
+ },
99
+ required: ["job_id"],
100
+ },
101
+ },
102
+ ],
103
+ }));
104
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
105
+ const { name, arguments: args } = req.params;
106
+ const a = (args ?? {});
107
+ switch (name) {
108
+ case "spawn_agent": {
109
+ const jobId = await manager.spawn({
110
+ repoUrl: a.repo_url,
111
+ task: a.task,
112
+ branch: a.branch,
113
+ createBranch: a.create_branch,
114
+ claudeToken: a.claude_token,
115
+ });
116
+ return {
117
+ content: [
118
+ {
119
+ type: "text",
120
+ text: JSON.stringify({ job_id: jobId, status: "started", message: "Agent spawned. Use get_job_output to follow progress." }),
121
+ },
122
+ ],
123
+ };
124
+ }
125
+ case "get_job_status": {
126
+ const job = manager.getJob(a.job_id);
127
+ if (!job) {
128
+ return { content: [{ type: "text", text: JSON.stringify({ error: "Job not found" }) }] };
129
+ }
130
+ return {
131
+ content: [
132
+ {
133
+ type: "text",
134
+ text: JSON.stringify({
135
+ job_id: job.id,
136
+ status: job.status,
137
+ repo_url: job.repoUrl,
138
+ task: job.task.slice(0, 120),
139
+ branch: job.branch,
140
+ create_branch: job.createBranch,
141
+ started_at: job.startedAt.toISOString(),
142
+ finished_at: job.finishedAt?.toISOString(),
143
+ exit_code: job.exitCode,
144
+ error: job.error,
145
+ output_lines: job.output.length,
146
+ }),
147
+ },
148
+ ],
149
+ };
150
+ }
151
+ case "get_job_output": {
152
+ const offset = typeof a.offset === "number" ? a.offset : 0;
153
+ const { lines, done } = manager.getOutput(a.job_id, offset);
154
+ return {
155
+ content: [
156
+ {
157
+ type: "text",
158
+ text: JSON.stringify({
159
+ job_id: a.job_id,
160
+ offset,
161
+ lines,
162
+ next_offset: offset + lines.length,
163
+ done,
164
+ }),
165
+ },
166
+ ],
167
+ };
168
+ }
169
+ case "list_jobs": {
170
+ const jobs = manager.list();
171
+ return {
172
+ content: [
173
+ {
174
+ type: "text",
175
+ text: JSON.stringify({ jobs, total: jobs.length }),
176
+ },
177
+ ],
178
+ };
179
+ }
180
+ case "cancel_job": {
181
+ const cancelled = manager.cancel(a.job_id);
182
+ return {
183
+ content: [
184
+ {
185
+ type: "text",
186
+ text: JSON.stringify({ job_id: a.job_id, cancelled }),
187
+ },
188
+ ],
189
+ };
190
+ }
191
+ default:
192
+ throw new Error(`Unknown tool: ${name}`);
193
+ }
194
+ });
195
+ const transport = new StdioServerTransport();
196
+ await server.connect(transport);
197
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export type JobStatus = "cloning" | "running" | "done" | "failed" | "cancelled";
2
+ export interface Job {
3
+ id: string;
4
+ repoUrl: string;
5
+ task: string;
6
+ branch?: string;
7
+ createBranch?: string;
8
+ status: JobStatus;
9
+ output: string[];
10
+ exitCode?: number;
11
+ error?: string;
12
+ workDir?: string;
13
+ startedAt: Date;
14
+ finishedAt?: Date;
15
+ }
16
+ export interface SpawnOptions {
17
+ repoUrl: string;
18
+ task: string;
19
+ branch?: string;
20
+ createBranch?: string;
21
+ claudeToken?: string;
22
+ }
23
+ export interface JobSummary {
24
+ id: string;
25
+ status: JobStatus;
26
+ repoUrl: string;
27
+ task: string;
28
+ branch?: string;
29
+ createBranch?: string;
30
+ startedAt: string;
31
+ finishedAt?: string;
32
+ exitCode?: number;
33
+ error?: string;
34
+ }
35
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEhF,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,CAAC,EAAE,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@gonzih/cc-agent",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for spawning Claude Code agents in cloned repos — branch your agents",
5
+ "type": "module",
6
+ "bin": {
7
+ "cc-agent": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "start": "node dist/index.js",
12
+ "dev": "node --loader ts-node/esm src/index.ts",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "files": [
16
+ "dist/"
17
+ ],
18
+ "dependencies": {
19
+ "@modelcontextprotocol/sdk": "^1.12.0",
20
+ "uuid": "^11.0.0"
21
+ },
22
+ "devDependencies": {
23
+ "@types/node": "^22.0.0",
24
+ "@types/uuid": "^10.0.0",
25
+ "typescript": "^5.5.0"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/Gonzih/cc-agent.git"
30
+ },
31
+ "homepage": "https://github.com/Gonzih/cc-agent",
32
+ "bugs": {
33
+ "url": "https://github.com/Gonzih/cc-agent/issues"
34
+ },
35
+ "keywords": ["claude", "claude-code", "mcp", "agent", "ai", "model-context-protocol", "branching-agents"],
36
+ "license": "MIT"
37
+ }