You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A transparent proxy that lets you use your **Claude Max subscription**with [OpenCode](https://opencode.ai) — with full multi-model agent delegation.
7
+
A transparent proxy that allows a Claude Max subscription to be used with [OpenCode](https://opencode.ai), preserving multi-model agent routing.
8
8
9
-
## The Idea
9
+
OpenCode targets the Anthropic API, while Claude Max provides access to Claude via the [Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk). The proxy forwards tool calls from Claude Max to OpenCode so agent routing works correctly.
10
10
11
-
OpenCode speaks the Anthropic API. Claude Max gives you unlimited Claude through the [Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk). This proxy bridges the two — but the interesting part isn't the bridging, it's **how tool execution and agent delegation work**.
11
+
Tool execution is handled within the Agent SDK, which is responsible for running tools, coordinating sub-agents, and streaming responses. Because the SDK only has access to Claude models, any tool calls or delegated tasks are executed within that scope. In configurations such as [oh-my-opencode](https://github.com/code-yeongyu/oh-my-opencode), where agents may be assigned to OpenaI, Gemini, or other providers, those assignments are not preserved at execution time, and all work is effectively routed through Claude.
12
12
13
-
Most proxy approaches try to handle everything internally: the SDK runs tools, manages subagents, and streams back a finished result. The problem? The SDK only knows about Claude models. If you're using [oh-my-opencode](https://github.com/code-yeongyu/oh-my-opencode) with agents routed to GPT-5.4, Gemini, or other providers, the SDK can't reach them. Your carefully configured multi-model agent setup gets flattened to "everything runs on Claude."
13
+
We avoid that limitation by forwarding tool calls instead of executing them. When a `tool_use` event is emitted, the proxy intercepts it, halts the current turn, and sends the raw payload back to OpenCode. OpenCode executes the tool, including any agent routing, and returns the result as a `tool_result`. The proxy then resumes the SDK session.
14
14
15
-
This proxy takes a different approach: **passthrough delegation**. Instead of handling tools internally, the proxy intercepts every tool call *before the SDK executes it*, stops the turn, and forwards the raw `tool_use` back to OpenCode. OpenCode handles execution — including routing `Task` calls through its own agent system with full model routing. The result comes back as a standard `tool_result`, the proxy resumes the SDK session, and Claude continues.
16
-
17
-
The effect: Claude thinks it's calling tools normally. OpenCode thinks it's talking to the Anthropic API. But behind the scenes, your oracle agent runs on GPT-5.4, your explore agent runs on Gemini, and the main session runs on Claude Max — exactly as configured.
15
+
From Claude’s perspective, tool usage proceeds normally. From OpenCode’s perspective, it is interacting with the Anthropic API. Execution remains distributed according to the configured agents, allowing different models to handle different roles without being constrained by the SDK.
18
16
19
17
```
20
18
┌──────────┐ ┌───────────────┐ ┌──────────────┐
21
-
│ │ 1. Request │ │ SDK Auth │ │
19
+
│ │ │ │ │ │
22
20
│ OpenCode │ ─────────────► │ Proxy │ ───────────► │ Claude Max │
The key insight is the Claude Agent SDK's `PreToolUse` hook — an officially supported callback that fires before any tool executes. Combined with `maxTurns: 1`, it gives us precise control over the execution boundary:
46
+
The Claude Agent SDK exposes a `PreToolUse` hook that fires before any tool executes. Combined with `maxTurns: 1`, it gives us precise control over the execution boundary without monkey-patching or stream rewriting.
46
47
47
48
1.**Claude generates a response** with `tool_use` blocks (Read a file, delegate to an agent, run a command)
48
-
2.**The PreToolUse hook fires** for each tool call — we capture the tool name, input, and ID, then return `decision: "block"` to prevent SDK-internal execution
49
+
2.**The PreToolUse hook fires** for each tool call - we capture the tool name, input, and ID, then return `decision: "block"` to prevent SDK-internal execution
49
50
3.**The SDK stops** (blocked tool + maxTurns:1 = turn complete) and we have the full tool_use payload
50
51
4.**The proxy returns it to OpenCode** as a standard Anthropic API response with `stop_reason: "tool_use"`
51
52
5.**OpenCode handles everything** — file reads, shell commands, and crucially, `Task` delegation through its own agent system with full model routing
52
53
6.**OpenCode sends `tool_result` back**, the proxy resumes the SDK session, and Claude continues
53
54
54
-
No monkey-patching. No forked SDKs. No fragile stream rewriting. Just a hook and a turn limit.
55
-
56
55
## Quick Start
57
56
58
57
### Prerequisites
59
58
60
-
1.**Claude Max subscription** — [Subscribe here](https://claude.ai/settings/subscription)
59
+
1.**Claude Max subscription** — [Subscribe here](https://claude.ai/settings/billing)
61
60
2.**Claude CLI** authenticated: `npm install -g @anthropic-ai/claude-code && claude login`
62
61
63
62
### Option A: npm Install
@@ -172,13 +171,13 @@ bun run proxy
172
171
173
172
Tools execute inside the proxy via MCP. Subagents run on Claude via the SDK's native agent system. Simpler setup, but all agents use Claude regardless of oh-my-opencode config.
174
173
175
-
|| Passthrough | Internal |
176
-
|---|---|---|
177
-
| Tool execution | OpenCode | Proxy (MCP) |
178
-
| Agent delegation | OpenCode → multi-model | SDK → Claude only |
179
-
| oh-my-opencode models | ✅ Respected | ❌ All Claude |
180
-
| Agent system prompts | ✅ Full | ⚠️ Description only |
@@ -236,68 +240,58 @@ Sessions are cached for 24 hours. When using per-terminal proxies (`oc.sh`), the
236
240
>
237
241
> We are monitoring the upstream Bun issue for a fix.
238
242
239
-
## Model Mapping
240
-
241
-
| OpenCode Model | Claude SDK |
242
-
|----------------|------------|
243
-
|`anthropic/claude-opus-*`| opus |
244
-
|`anthropic/claude-sonnet-*`| sonnet (default) |
245
-
|`anthropic/claude-haiku-*`| haiku |
246
-
247
-
## Disclaimer
248
-
249
-
This project is an **unofficial wrapper** around Anthropic's publicly available [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk). It is not affiliated with, endorsed by, or supported by Anthropic.
250
-
251
-
**Use at your own risk.** The authors make no claims regarding compliance with Anthropic's Terms of Service. It is your responsibility to review and comply with [Anthropic's Terms of Service](https://www.anthropic.com/terms) and any applicable usage policies. Terms may change at any time.
252
-
253
-
This project calls `query()` from Anthropic's public npm package using your own authenticated account. No API keys are intercepted, no authentication is bypassed, and no proprietary systems are reverse-engineered.
254
-
255
243
## FAQ
256
244
257
245
<details>
258
246
<summary><strong>Why passthrough mode instead of handling tools internally?</strong></summary>
259
247
260
-
Internal tool execution means the SDK handles everything — but the SDK only speaks Claude. If your agents are configured for GPT-5.4 or Gemini via oh-my-opencode, that routing gets lost. Passthrough mode preserves the full OpenCode agent pipeline, including multi-model routing, full system prompts, and agent lifecycle management.
248
+
If the Agent SDK executes tools directly, everything runs through Claude. Any agent routing defined in OpenCode is bypassed. Passthrough mode just sends the tool calls to OpenCode to run.
249
+
261
250
</details>
262
251
263
252
<details>
264
253
<summary><strong>Does this work without oh-my-opencode?</strong></summary>
265
254
266
-
Yes. Both modes work with native OpenCode (build + plan agents) and with any custom agents defined in your `opencode.json`. oh-my-opencode just adds more agents and model routing — the proxy handles whatever OpenCode sends.
255
+
Yes. Both modes work with native OpenCode (build + plan agents) and with any custom agents defined in your `opencode.json`. oh-my-opencode just adds more agents and model routing. The proxy handles whatever OpenCode sends.
256
+
267
257
</details>
268
258
269
259
<details>
270
-
<summary><strong>Why do I need ANTHROPIC_API_KEY=dummy?</strong></summary>
260
+
<summary><strong>Why do I need `ANTHROPIC_API_KEY=dummy`?</strong></summary>
271
261
272
262
OpenCode requires an API key to be set, but the proxy never uses it. Authentication is handled by your `claude login` session through the Agent SDK.
263
+
273
264
</details>
274
265
275
266
<details>
276
267
<summary><strong>What about rate limits?</strong></summary>
277
268
278
269
Your Claude Max subscription has its own usage limits. The proxy doesn't add any additional limits. Concurrent requests are supported.
270
+
279
271
</details>
280
272
281
273
<details>
282
274
<summary><strong>Is my data sent anywhere else?</strong></summary>
283
275
284
276
No. The proxy runs locally. Requests go directly to Claude through the official SDK. In passthrough mode, tool execution happens in OpenCode on your machine.
277
+
285
278
</details>
286
279
287
280
<details>
288
281
<summary><strong>Why does internal mode use MCP tools?</strong></summary>
289
282
290
283
The Claude Agent SDK uses different parameter names for tools than OpenCode (e.g., `file_path` vs `filePath`). Internal mode provides its own MCP tools with SDK-compatible parameter names. Passthrough mode doesn't need this since OpenCode handles tool execution directly.
284
+
291
285
</details>
292
286
293
287
## Troubleshooting
294
288
295
-
| Problem | Solution |
296
-
|---------|----------|
297
-
| "Authentication failed" | Run `claude login` to authenticate |
298
-
| "Connection refused" | Make sure the proxy is running: `bun run proxy`|
299
-
| "Port 3456 is already in use" |`kill $(lsof -ti :3456)` or use `CLAUDE_PROXY_PORT=4567`|
300
-
| Title generation fails | Set `"small_model": "anthropic/claude-haiku-4-5"` in your OpenCode config |
├── logger.ts # Structured logging with AsyncLocalStorage context
370
355
├── plugin/
371
-
│ └── claude-max-headers.ts # OpenCode plugin for session header injection
372
-
└── __tests__/ # 106 tests across 13 files
373
-
├── helpers.ts
374
-
├── integration.test.ts
375
-
├── proxy-agent-definitions.test.ts
376
-
├── proxy-agent-fuzzy-match.test.ts
377
-
├── proxy-error-handling.test.ts
378
-
├── proxy-mcp-filtering.test.ts
379
-
├── proxy-passthrough-concept.test.ts
380
-
├── proxy-pretooluse-hook.test.ts
381
-
├── proxy-session-resume.test.ts
382
-
├── proxy-streaming-message.test.ts
383
-
├── proxy-subagent-support.test.ts
384
-
├── proxy-tool-forwarding.test.ts
385
-
├── proxy-transparent-tools.test.ts
386
-
└── proxy-working-directory.test.ts
356
+
└── claude-max-headers.ts # OpenCode plugin for session header injection
387
357
```
388
358
359
+
## Disclaimer
360
+
361
+
This project is an **unofficial wrapper** around Anthropic's publicly available [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk). It is not affiliated with, endorsed by, or supported by Anthropic.
362
+
363
+
**Use at your own risk.** The authors make no claims regarding compliance with Anthropic's Terms of Service. It is your responsibility to review and comply with [Anthropic's Terms of Service](https://www.anthropic.com/legal/consumer-terms) and [Authorized Usage Policy](https://www.anthropic.com/legal/aup). Terms may change at any time.
364
+
365
+
This project calls `query()` from Anthropic's public npm package using your own authenticated account. No API keys are intercepted, no authentication is bypassed, and no proprietary systems are reverse-engineered.
0 commit comments