@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 +83 -0
- package/dist/agent.d.ts +18 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +151 -0
- package/dist/agent.js.map +1 -0
- package/dist/claude.d.ts +21 -0
- package/dist/claude.d.ts.map +1 -0
- package/dist/claude.js +104 -0
- package/dist/claude.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +197 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +37 -0
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)
|
package/dist/agent.d.ts
ADDED
|
@@ -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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"}
|
package/dist/claude.d.ts
ADDED
|
@@ -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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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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"}
|
package/dist/types.d.ts
ADDED
|
@@ -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 @@
|
|
|
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
|
+
}
|