claude-octopus 1.0.0 → 1.0.1

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,255 @@
1
+ # Claude Octopus
2
+
3
+ One brain, many arms.
4
+
5
+ An MCP server that wraps the [Claude Agent SDK](https://docs.anthropic.com/en/docs/claude-code/sdk), letting you run multiple specialized Claude Code agents — each with its own model, tools, system prompt, and personality — from any MCP client.
6
+
7
+ ## Why
8
+
9
+ Claude Code is powerful. But one instance does everything the same way. Sometimes you want a **strict code reviewer** that only reads files. A **test writer** that defaults to TDD. A **cheap quick helper** on Haiku. A **deep thinker** on Opus.
10
+
11
+ Claude Octopus lets you spin up as many of these as you need. Same binary, different configurations. Each one shows up as a separate tool in your MCP client.
12
+
13
+ ## Prerequisites
14
+
15
+ - **Node.js** >= 18
16
+ - **Claude Code** — the [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) is bundled as a dependency, but it spawns Claude Code under the hood, so you need a working `claude` CLI installation
17
+ - **Anthropic API key** (`ANTHROPIC_API_KEY` env var) or an active Claude Code OAuth session
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ npm install claude-octopus
23
+ ```
24
+
25
+ Or skip the install entirely — use `npx` directly in your `.mcp.json` (see Quick Start below).
26
+
27
+ ## Quick Start
28
+
29
+ Add to your `.mcp.json`:
30
+
31
+ ```json
32
+ {
33
+ "mcpServers": {
34
+ "claude": {
35
+ "command": "npx",
36
+ "args": ["claude-octopus"],
37
+ "env": {
38
+ "CLAUDE_PERMISSION_MODE": "bypassPermissions"
39
+ }
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ This gives you two tools: `claude_code` and `claude_code_reply`. That's it — you have Claude Code as a tool.
46
+
47
+ ## Multiple Agents
48
+
49
+ The real power is running several instances with different configurations:
50
+
51
+ ```json
52
+ {
53
+ "mcpServers": {
54
+ "code-reviewer": {
55
+ "command": "npx",
56
+ "args": ["claude-octopus"],
57
+ "env": {
58
+ "CLAUDE_TOOL_NAME": "code_reviewer",
59
+ "CLAUDE_SERVER_NAME": "code-reviewer",
60
+ "CLAUDE_DESCRIPTION": "Strict code reviewer. Finds bugs and security issues. Read-only.",
61
+ "CLAUDE_MODEL": "opus",
62
+ "CLAUDE_ALLOWED_TOOLS": "Read,Grep,Glob",
63
+ "CLAUDE_APPEND_PROMPT": "You are a strict code reviewer. Report real bugs, not style preferences.",
64
+ "CLAUDE_EFFORT": "high"
65
+ }
66
+ },
67
+ "test-writer": {
68
+ "command": "npx",
69
+ "args": ["claude-octopus"],
70
+ "env": {
71
+ "CLAUDE_TOOL_NAME": "test_writer",
72
+ "CLAUDE_SERVER_NAME": "test-writer",
73
+ "CLAUDE_DESCRIPTION": "Writes thorough tests with edge case coverage.",
74
+ "CLAUDE_MODEL": "sonnet",
75
+ "CLAUDE_APPEND_PROMPT": "Write tests first. Cover edge cases. TDD."
76
+ }
77
+ },
78
+ "quick-qa": {
79
+ "command": "npx",
80
+ "args": ["claude-octopus"],
81
+ "env": {
82
+ "CLAUDE_TOOL_NAME": "quick_qa",
83
+ "CLAUDE_SERVER_NAME": "quick-qa",
84
+ "CLAUDE_DESCRIPTION": "Fast answers to quick coding questions.",
85
+ "CLAUDE_MODEL": "haiku",
86
+ "CLAUDE_MAX_BUDGET_USD": "0.02",
87
+ "CLAUDE_EFFORT": "low"
88
+ }
89
+ }
90
+ }
91
+ }
92
+ ```
93
+
94
+ Your MCP client now sees three distinct tools — `code_reviewer`, `test_writer`, `quick_qa` — each purpose-built.
95
+
96
+ ## Agent Factory
97
+
98
+ Don't want to write configs by hand? Add a factory instance:
99
+
100
+ ```json
101
+ {
102
+ "mcpServers": {
103
+ "agent-factory": {
104
+ "command": "npx",
105
+ "args": ["claude-octopus"],
106
+ "env": {
107
+ "CLAUDE_FACTORY_ONLY": "true",
108
+ "CLAUDE_SERVER_NAME": "agent-factory"
109
+ }
110
+ }
111
+ }
112
+ }
113
+ ```
114
+
115
+ This exposes a single `create_claude_code_mcp` tool — an interactive wizard. Tell it what you want ("a strict code reviewer that only reads files") and it generates the `.mcp.json` entry for you, listing all available options you can customize.
116
+
117
+ In factory-only mode, no query tools are registered — just the wizard. This keeps routing clean: the factory creates agents, the agents do work.
118
+
119
+ ## Tools
120
+
121
+ Each non-factory instance exposes:
122
+
123
+ | Tool | Purpose |
124
+ |------|---------|
125
+ | `<name>` | Send a task to the agent, get a response + `session_id` |
126
+ | `<name>_reply` | Continue a previous conversation by `session_id` |
127
+
128
+ Per-invocation parameters (override server defaults):
129
+
130
+ | Parameter | Description |
131
+ |-----------|-------------|
132
+ | `prompt` | The task or question (required) |
133
+ | `cwd` | Working directory override |
134
+ | `model` | Model override |
135
+ | `allowedTools` | Tool whitelist (intersects with server default) |
136
+ | `disallowedTools` | Tool blacklist (unions with server default) |
137
+ | `maxTurns` | Max conversation turns |
138
+ | `maxBudgetUsd` | Max spend in USD |
139
+ | `systemPrompt` | Additional prompt (appended to server default) |
140
+
141
+ ## Configuration
142
+
143
+ All configuration is via environment variables in `.mcp.json`. Every env var is optional.
144
+
145
+ ### Identity
146
+
147
+ | Env Var | Description | Default |
148
+ |---------|-------------|---------|
149
+ | `CLAUDE_TOOL_NAME` | Tool name prefix (`<name>` and `<name>_reply`) | `claude_code` |
150
+ | `CLAUDE_DESCRIPTION` | Tool description shown to the host AI | generic |
151
+ | `CLAUDE_SERVER_NAME` | MCP server name in protocol handshake | `claude-octopus` |
152
+ | `CLAUDE_FACTORY_ONLY` | Only expose the factory wizard tool | `false` |
153
+
154
+ ### Agent
155
+
156
+ | Env Var | Description | Default |
157
+ |---------|-------------|---------|
158
+ | `CLAUDE_MODEL` | Model (`sonnet`, `opus`, `haiku`, or full ID) | SDK default |
159
+ | `CLAUDE_CWD` | Working directory | `process.cwd()` |
160
+ | `CLAUDE_PERMISSION_MODE` | `default`, `acceptEdits`, `bypassPermissions`, `plan` | `default` |
161
+ | `CLAUDE_ALLOWED_TOOLS` | Comma-separated tool whitelist | all |
162
+ | `CLAUDE_DISALLOWED_TOOLS` | Comma-separated tool blacklist | none |
163
+ | `CLAUDE_MAX_TURNS` | Max conversation turns | unlimited |
164
+ | `CLAUDE_MAX_BUDGET_USD` | Max spend per invocation | unlimited |
165
+ | `CLAUDE_EFFORT` | `low`, `medium`, `high`, `max` | SDK default |
166
+
167
+ ### Prompts
168
+
169
+ | Env Var | Description |
170
+ |---------|-------------|
171
+ | `CLAUDE_SYSTEM_PROMPT` | Replaces the default Claude Code system prompt |
172
+ | `CLAUDE_APPEND_PROMPT` | Appended to the default prompt (usually what you want) |
173
+
174
+ ### Advanced
175
+
176
+ | Env Var | Description |
177
+ |---------|-------------|
178
+ | `CLAUDE_ADDITIONAL_DIRS` | Extra directories to grant access (comma-separated) |
179
+ | `CLAUDE_PLUGINS` | Local plugin paths (comma-separated) |
180
+ | `CLAUDE_MCP_SERVERS` | MCP servers for the inner agent (JSON) |
181
+ | `CLAUDE_PERSIST_SESSION` | `true`/`false` — enable session resume (default: `true`) |
182
+ | `CLAUDE_SETTING_SOURCES` | Settings to load: `user`, `project`, `local` |
183
+ | `CLAUDE_SETTINGS` | Path to settings JSON or inline JSON |
184
+ | `CLAUDE_BETAS` | Beta features (comma-separated) |
185
+
186
+ ### Authentication
187
+
188
+ | Env Var | Description | Default |
189
+ |---------|-------------|---------|
190
+ | `ANTHROPIC_API_KEY` | Anthropic API key for this agent | inherited from parent |
191
+ | `CLAUDE_CODE_OAUTH_TOKEN` | Claude Code OAuth token for this agent | inherited from parent |
192
+
193
+ Leave both unset to inherit auth from the parent process. Set one per agent to use a different account or billing source.
194
+
195
+ Lists accept JSON arrays when values contain commas: `["path,with,comma", "/normal"]`
196
+
197
+ ## Security
198
+
199
+ - **Permission mode defaults to `default`** — tool executions prompt for approval unless you explicitly set `bypassPermissions`.
200
+ - **`cwd` overrides are confined** — per-invocation `cwd` must be a descendant of the server-level base directory. Traversal attempts are silently ignored.
201
+ - **Tool restrictions narrow, never widen** — per-invocation `allowedTools` intersects with the server whitelist (can only remove tools, not add). `disallowedTools` unions (can only block more).
202
+ - **`_reply` tool respects persistence** — not registered when `CLAUDE_PERSIST_SESSION=false`.
203
+
204
+ ## Architecture
205
+
206
+ ```
207
+ ┌─────────────────────────────────┐
208
+ │ MCP Client │
209
+ │ (Claude Desktop, Cursor, etc.) │
210
+ │ │
211
+ │ Sees: code_reviewer, │
212
+ │ test_writer, quick_qa │
213
+ └──────────┬──────────────────────┘
214
+ │ JSON-RPC / stdio
215
+ ┌──────────▼──────────────────────┐
216
+ │ Claude Octopus (per instance) │
217
+ │ │
218
+ │ Env: CLAUDE_MODEL=opus │
219
+ │ CLAUDE_ALLOWED_TOOLS=... │
220
+ │ CLAUDE_APPEND_PROMPT=... │
221
+ │ │
222
+ │ Calls: Agent SDK query() │
223
+ └──────────┬──────────────────────┘
224
+ │ in-process
225
+ ┌──────────▼──────────────────────┐
226
+ │ Claude Agent SDK │
227
+ │ Runs autonomously: reads files,│
228
+ │ writes code, runs commands │
229
+ │ Returns result + session_id │
230
+ └─────────────────────────────────┘
231
+ ```
232
+
233
+ ## How It Compares
234
+
235
+ | Feature | [`claude mcp serve`](https://code.claude.com/docs/en/mcp) | [claude-code-mcp](https://github.com/steipete/claude-code-mcp) | **Claude Octopus** |
236
+ |---------|--------------------|--------------------------|--------------------|
237
+ | Approach | Built-in | CLI wrapping | Agent SDK |
238
+ | Exposes | 16 raw tools | 1 prompt tool | 1 prompt + reply |
239
+ | Multi-instance | No | No | Yes |
240
+ | Per-instance config | No | No | Yes (18 env vars) |
241
+ | Factory wizard | No | No | Yes |
242
+ | Session continuity | No | No | Yes |
243
+
244
+ ## Development
245
+
246
+ ```bash
247
+ pnpm install
248
+ pnpm build # compile TypeScript
249
+ pnpm test # run tests (vitest)
250
+ pnpm test:coverage # 100% coverage
251
+ ```
252
+
253
+ ## License
254
+
255
+ [ISC](https://github.com/xiaolai/claude-octopus/blob/main/LICENSE) - Xiaolai Li
package/dist/constants.js CHANGED
@@ -111,4 +111,18 @@ export const OPTION_CATALOG = [
111
111
  hint: "Enable beta capabilities (comma-separated)",
112
112
  example: '"context-1m-2025-08-07" for 1M context window',
113
113
  },
114
+ {
115
+ key: "apiKey",
116
+ envVar: "ANTHROPIC_API_KEY",
117
+ label: "API key",
118
+ hint: "Anthropic API key for this agent (overrides inherited auth)",
119
+ example: '"sk-ant-api03-..." — leave unset to inherit from parent',
120
+ },
121
+ {
122
+ key: "oauthToken",
123
+ envVar: "CLAUDE_CODE_OAUTH_TOKEN",
124
+ label: "OAuth token",
125
+ hint: "Claude Code OAuth token for this agent (overrides inherited auth)",
126
+ example: '"sk-ant-oat01-..." — leave unset to inherit from parent',
127
+ },
114
128
  ];
package/dist/index.js CHANGED
File without changes
@@ -55,6 +55,8 @@ export function registerFactoryTool(server, serverEntry) {
55
55
  settingSources: z.array(z.string()).optional(),
56
56
  mcpServers: z.record(z.string(), z.unknown()).optional(),
57
57
  betas: z.array(z.string()).optional(),
58
+ apiKey: z.string().optional().describe("Anthropic API key for this agent (leave unset to inherit)"),
59
+ oauthToken: z.string().optional().describe("Claude Code OAuth token for this agent (leave unset to inherit)"),
58
60
  }),
59
61
  }, async (params) => {
60
62
  const { description, name: nameParam, toolName: toolNameParam } = params;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-octopus",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "One brain, many arms — spawn multiple specialized Claude Code agents as MCP servers",
5
5
  "type": "module",
6
6
  "bin": {
package/src/constants.ts CHANGED
@@ -113,4 +113,18 @@ export const OPTION_CATALOG: OptionCatalogEntry[] = [
113
113
  hint: "Enable beta capabilities (comma-separated)",
114
114
  example: '"context-1m-2025-08-07" for 1M context window',
115
115
  },
116
+ {
117
+ key: "apiKey",
118
+ envVar: "ANTHROPIC_API_KEY",
119
+ label: "API key",
120
+ hint: "Anthropic API key for this agent (overrides inherited auth)",
121
+ example: '"sk-ant-api03-..." — leave unset to inherit from parent',
122
+ },
123
+ {
124
+ key: "oauthToken",
125
+ envVar: "CLAUDE_CODE_OAUTH_TOKEN",
126
+ label: "OAuth token",
127
+ hint: "Claude Code OAuth token for this agent (overrides inherited auth)",
128
+ example: '"sk-ant-oat01-..." — leave unset to inherit from parent',
129
+ },
116
130
  ];
@@ -68,6 +68,8 @@ export function registerFactoryTool(
68
68
  settingSources: z.array(z.string()).optional(),
69
69
  mcpServers: z.record(z.string(), z.unknown()).optional(),
70
70
  betas: z.array(z.string()).optional(),
71
+ apiKey: z.string().optional().describe("Anthropic API key for this agent (leave unset to inherit)"),
72
+ oauthToken: z.string().optional().describe("Claude Code OAuth token for this agent (leave unset to inherit)"),
71
73
  }),
72
74
  }, async (params) => {
73
75
  const { description, name: nameParam, toolName: toolNameParam } = params;