opencode-claude is the OpenCode plugin for running Claude models — Fable, Opus, Sonnet, and Haiku — from a Claude Pro/Max subscription, with effort variants, tools, attachments, and auto-compact.
Use Claude from OpenCode and OpenChamber without an Anthropic API key. The plugin runs the official Anthropic Agent SDK plus the local claude CLI and proxies an OpenAI-compatible /v1/chat/completions surface into OpenCode. Claude Code owns authentication; the plugin never reads, copies, refreshes, or sends your credentials itself.
Built on Anthropic's official Agent SDK and Claude Code authentication flow. Designed for local, user-operated Claude Code usage.
No OAuth tokens are extracted, copied, stored, injected, or sent by this plugin. All authentication and model access are performed internally by the official Claude Code runtime. The plugin does not call Anthropic inference endpoints directly and does not impersonate Anthropic API clients.
Sibling plugins: @openchamber/opencode-cursor and @openchamber/opencode-commandcode.
The OpenCode/OpenChamber sign-in action launches claude auth login --claudeai and relays it: the CLI's own sign-in page opens from the host, and the code Claude shows is pasted back into the host, not a separate terminal. The official CLI performs the OAuth exchange and stores its own credentials. The plugin stores no credentials or connection markers in OpenCode; every inference request, including title and summary generation, runs through the Agent SDK.
Aliases fable / opus / sonnet / haiku plus pinned ids. Native OpenCode variants low → max map to Claude --effort and adaptive thinking.
OpenCode tools bridge as in-process MCP. Calls park and resume instead of deadlocking or inventing output. Streaming, MCP, and sticky Claude session IDs keep follow-ups on the same Agent SDK turn.
Images and PDFs from OpenCode reach Claude (data URLs and remote URLs). Long sessions auto-compact like Claude Code. When a Claude session cannot be resumed, the prior conversation is serialized into the prompt so Claude does not start blind.
Subscription limit state is tracked with its reset time. GET /v1/rate-limit answers when limits return; doomed turns fail fast with 429 and Retry-After.
claude-code is not a built-in OpenCode provider. Install the plugin first, or opencode auth login --provider claude-code fails with Unknown provider "claude-code".
npm install -g @openchamber/opencode-claudeOr with OpenCode:
# global (recommended)
opencode plugin @openchamber/opencode-claude -g
# or project-local (writes .opencode/opencode.json)
opencode plugin @openchamber/opencode-claudeAdd (or merge) this into ~/.config/opencode/opencode.json:
claude auth login
opencode auth login --provider claude-code
# pick "Sign in with Claude Code CLI"opencode run "Summarise this repository in five bullets." --model claude-code/sonnetIn the TUI, pick provider claude-code, choose a model, and set the effort variant (low / medium / high / xhigh / max) when you want deeper thinking.
git clone https://github.com/openchamber/opencode-claude.git
cd opencode-claude
bun install && bun run build
opencode plugin file://$PWD| Step | What happens |
|---|---|
| Sign in with Claude Code CLI | Shown when the CLI is installed: launches the official CLI login and opens the sign-in page the CLI asked for |
| Install Claude Code CLI and sign in | Shown only when the CLI is missing: runs the official installer (npm i -g @anthropic-ai/claude-code, official install script as fallback), then continues with the sign-in relay |
| Paste the code from the Claude page | Goes straight to the CLI's stdin; the CLI does the token exchange and owns the result |
claude auth login --claudeai |
Terminal alternative, always called out in the instructions — also the offered fallback when the CLI is missing (with the install command alongside) |
| Successful verification | Completes without writing to OpenCode's auth store |
| Access expires | Claude Code refreshes its own credentials |
Signing in is either the link and its code or the terminal command — the sign-in page the CLI asks for is the only URL the plugin ever hands to the host.
The plugin does not implement OAuth, inspect Claude credential files, inject tokens, or call Anthropic inference endpoints directly.
OpenCode
└─ /v1/chat/completions
└─ Bun.serve proxy (ephemeral port; configured by the plugin)
└─ Claude Agent SDK query()
└─ claude CLI (subscription OAuth)
| Layer | Responsibility |
|---|---|
| Plugin hooks | Provider config, model catalog, effort headers |
| Proxy | OpenAI ↔ Agent SDK protocol, tool parking, compact, rate-limit gate |
| CLI | Subscription credentials and the Claude Code harness |
Model catalog: aliases fable / opus / sonnet / haiku plus pinned ids. Effort selection is encoded in x-opencode-claude-effort so the proxy passes the exact effort (and adaptive thinking) into the Agent SDK.
The proxy records Agent SDK rate_limit_event telemetry and hard session-limit errors (including the parsed reset time) to ~/.local/share/opencode-claude/rate-limit.json.
GET /v1/rate-limit→{ limited, status, rateLimitType, utilization, resetsAt, resetsAtISO, resetInSeconds, message, updatedAt }— poll this for a "limits reset in …" countdown.utilizationis only present when the latest SDK event reported it — it is never carried over from an earlier limit window.GET /healthincludes a compactrateLimitsummary.- While a confirmed hard limit is active, new turns return HTTP 429 with
Retry-After+x-claude-rate-limit-resetheaders and anerror.type = "rate_limit_error"body. The block lifts automatically at reset time; the next turn resumes the same Claude session. OPENCODE_CLAUDE_RATE_LIMIT_FAST_FAIL=0disables the 429 gate (turns are attempted and error normally).
- OpenCode
- Claude Code CLI — on
PATHor installed via the provider's install action (npm is used, or the official install script); the plugin also checks~/.local/binand the npm global bin for a CLI the server PATH cannot see - Claude plan supported by Claude Code
- Bun (plugin runtime) · Node.js ≥ 18
bun install
bun run build
bun run testDebug logging: OPENCODE_CLAUDE_DEBUG=1.
Optional knobs:
OPENCODE_CLAUDE_PROXY_PORT— optional pinned proxy port (default: ephemeral / OS-assigned; live URL is published to OpenCode via plugin config)OPENCODE_CLAUDE_CWD— working directory passed to the Agent SDKOPENCODE_CLAUDE_RATE_LIMIT_FAST_FAIL—0disables the 429 rate-limit gateOPENCODE_CLAUDE_RATE_LIMIT_STORE— override the rate-limit store path (tests)OPENCODE_CLAUDE_HISTORY_MAX_CHARS— budget for transferred conversation history when a Claude session cannot be resumed (default400000; newest messages are kept,0disables transfer)
| Symptom | Fix |
|---|---|
Unknown provider claude-code |
Install @openchamber/opencode-claude and restart OpenCode |
| Claude Code missing from provider list | Confirm plugin includes @openchamber/opencode-claude and restart OpenCode |
| Authentication error | Run claude auth login, verify claude auth status --json, then restart OpenCode |
| 429 / rate-limit | Poll GET /v1/rate-limit or wait until resetsAt; the next turn resumes the same session |
| Tools hang or invent output | Update to the latest plugin — park/resume MCP bridging is required |
| Attachments ignored | Use a current build; image/PDF parts are converted to Claude blocks |
Publish via GitHub Actions → Actions → Release → Run workflow:
| Input | Purpose |
|---|---|
version |
Explicit semver (0.6.0). Empty → use bump |
bump |
minor (default) / patch / major |
dry_run |
Skip npm publish; create a draft GitHub release |
Requires repo secrets: NPM_TOKEN, optional DISCORD_WEBHOOK_URL.
Local pin refresh after a release:
./scripts/update-plugin.sh --dry-run
./scripts/update-plugin.shIssues and pull requests belong in this repository: openchamber/opencode-claude.
bun install
bun run build
bun run testThis plugin started as community work around Claude Code in OpenCode. Special thanks to:
- OpenCode for the plugin API
- OpenChamber for the workspace that runs this plugin in production
- Anthropic for the Claude Agent SDK and Claude Code CLI
- Contributors who shaped OAuth, the proxy, tools, and compact
{ "$schema": "https://opencode.ai/config.json", "plugin": ["@openchamber/opencode-claude"], "provider": { "claude-code": { "name": "Claude Code" } } }