@seonggukchoi/opencode-claude-code-provider
v0.3.3
Published
OpenCode provider backed by Claude Code CLI
Maintainers
Readme
@seonggukchoi/opencode-claude-code-provider
Claude Code CLI based provider for OpenCode.
What it does
- Exposes a custom
LanguageModelV2provider namedclaude-code - Runs
claude -p --verbose --input-format text --tools "" --output-format stream-jsonas a pure LLM client - Injects OpenCode tool schemas into the Claude system prompt and converts
<tool_call>text blocks into AI SDK tool-call parts - Keeps all tool execution inside OpenCode, including OpenCode-only tools such as
todowriteandtask - Persists the Claude session id in
providerMetadata["claude-code"].sessionId - Sends prompt text over stdin so long transcript bootstrap does not hit argv size limits
Tool behavior
- Claude native tools are disabled for every request
- Claude must emit exactly one
<tool_call>{"name":"...","arguments":{...}}</tool_call>block when a tool is needed - OpenCode executes the tool and feeds the result back through its normal tool loop
Known limits
- Non-streaming generation is intentionally not supported
effortis retained for config compatibility but is not sent to the CLI yetmaxTurnsis hardcoded to1because Claude does not execute tools directly in this modeloadClaudeMdis hardcoded tofalse— CLAUDE.md loading is not supportedpermissionModeis hardcoded tobypassPermissions(--dangerously-skip-permissions)- OpenCode custom providers still need a
modelsblock in config for model discovery - OpenCode 1.3.0 currently breaks direct
file:package loading by appending@latest
Configuration examples
{
"plugin": ["@seonggukchoi/opencode-claude-code-plugin"],
"provider": {
"claude-code": {
"npm": "@seonggukchoi/opencode-claude-code-provider",
"models": {
"sonnet": { "id": "claude-sonnet-4-6" },
"opus": { "id": "claude-opus-4-6" },
"haiku": { "id": "claude-haiku-4-5" }
}
}
},
"model": "claude-code/sonnet"
}- Full config example:
packages/opencode-claude-code-provider/docs/config.example.json - Minimal config example:
packages/opencode-claude-code-provider/docs/config.minimal.example.json
OpenCode custom providers still require a models block for model discovery, so the minimal example keeps only the model ids.
For local unpublished testing, replace the package names in those examples with your local install strategy such as a tarball or registry override.
Local testing
- Build:
pnpm --filter @seonggukchoi/opencode-claude-code-provider buildpnpm --filter @seonggukchoi/opencode-claude-code-plugin build
- Smoke test:
pnpm --filter @seonggukchoi/opencode-claude-code-provider test:smoke
- Smoke script:
packages/opencode-claude-code-provider/test/smoke.mjs
- Current limitation:
- OpenCode 1.3.0 breaks direct
file:package loading by appending@latest
- OpenCode 1.3.0 breaks direct
Failure handling
- Missing CLI executable: expect a process spawn failure such as
ENOENT - Unsupported auth status command on older CLI builds: use
claude auth status || claude doctor - Invalid CLI JSONL output: the provider fails the stream with a parsing error
- Invalid
<tool_call>payloads are surfaced back as plain text instead of being executed
Release checklist
pnpm --filter @seonggukchoi/opencode-claude-code-provider testpnpm --filter @seonggukchoi/opencode-claude-code-provider buildpnpm --filter @seonggukchoi/opencode-claude-code-provider test:smoke- Verify
packages/opencode-claude-code-provider/docs/config.example.json - Verify
packages/opencode-claude-code-provider/docs/config.minimal.example.json
Internal docs
- Full config example:
packages/opencode-claude-code-provider/docs/config.example.json - Minimal config example:
packages/opencode-claude-code-provider/docs/config.minimal.example.json - Smoke test:
packages/opencode-claude-code-provider/test/smoke.mjs
