Skip to content

Options reference

Every provider option, its type, its default and what it changes.

The minimum config is just the plugin entry above. Everything below is optional override that goes in a provider.claude-code block.

{
"plugin": ["@khalilgharbaoui/opencode-claude-code-plugin"],
"provider": {
"claude-code": {
"options": {
"cliPath": "claude",
"proxyTools": ["Bash", "Edit", "Write", "WebFetch", "Task"],
"skipPermissions": true,
"permissionMode": "default",
"bridgeOpencodeMcp": true,
"strictMcpConfig": false,
"idleProcessTimeoutMs": 900000
}
}
}
}
Option Type Default Description
cliPath string "claude" Path to the claude executable (a binary, not a shell command with flags). opencode’s config hook seeds this with "claude", so under opencode this default always applies; CLAUDE_CLI_PATH is only consulted when createClaudeCode() is called directly and the option is absent. Account providers wrap it with a generated script; never point it at one of those yourself.
accounts string[] – Optional. Most setups need no accounts at all: with this unset you get a single Claude Code (Default) provider on your normal ~/.claude login. Supply names only to run several Claude logins side by side; default stays implicit, so ["work", "personal"] gives you Claude Code (Default), Claude Code (Work) and Claude Code (Personal). See Multiple Claude Code accounts.
accountFailover "ask" | "off" "ask" When this account runs out of usage mid-task, show a form listing the other configured accounts and continue on the one you pick, inside the same turn. Only ever fires when more than one account is configured, so a single-account setup is unaffected. "off" keeps the plain rate-limit error. See Account failover.
cwd string see description Working directory for the spawned CLI. Resolved lazily per request, first match winning: this explicit value, then the opencode session’s own directory (so opencode serve and the web UI spawn in the right project even though one server handles many), then process.cwd() when it is a real directory, then the project directory captured at plugin init (this rescues macOS GUI launches, where process.cwd() is /), and finally process.cwd() regardless. Startup diagnostics reports which tier won. Session tier contributed by @galvani.
skipPermissions boolean true Pass --dangerously-skip-permissions to claude. It is still passed when proxyTools is set: proxied calls go through opencode’s permission system regardless, but unproxied CLI built-ins do not. The one case where the flag is dropped is permissionMode: "plan", because the CLI lets the skip flag override plan mode outright. See Plan mode.
permissionMode acceptEdits | auto | bypassPermissions | default | dontAsk | plan – Forwarded to headless claude --permission-mode. "plan" also suppresses --dangerously-skip-permissions (see the row above). Not version-gated, so check that your installed CLI accepts the value. The interactive transport does not forward it.
permissionPreset "read-only" – A named permission posture, so you set one option instead of combining five and getting one wrong. Opt-in: unset is exactly today’s behaviour. "read-only" replaces skipPermissions, permissionMode, controlRequestBehavior and controlRequestToolBehaviors, and filters the write and command tools out of proxyTools. See Read-only mode.
defaultSubagentCacheTtl string – Prompt cache TTL (5m or 1h) for plugin-discovered mode: subagent agents whose own definition states no cacheTtl. Reaches the CLI as CLAUDE_CODE_PROMPT_CACHE_TTL. Unset means the CLI keeps choosing, which is 1 hour on a subscription. An unrecognised value warns and changes nothing. See The prompt cache an agent writes.
defaultSubagentModel string – Model that plugin-discovered mode: subagent agents run on when their own definition pins nothing. The caller’s account is kept; only the model name changes. An agent’s own forceModel wins over it, and an unknown id is refused rather than spawned. Unset means no implicit override at all. See Subagents: your account, their model.
fallbackModels string[] – Ordered models to try when the one a turn would run on is refused. The default for agents that declare no fallbackModels of their own; a per-agent list replaces this one rather than extending it. Always the same account, never a different one. Only two things arm it: the CLI refusing the model (model_not_found) and a usage limit on an account with no other account to offer. Each model is tried at most once per turn and an exhausted chain surfaces the original error. Unset means no chain at all. See Fallback model chain.
proxyTools string[] ["Bash", "Edit", "Write", "WebFetch", "Task"] Claude built-in tools to route through opencode’s executor + permission UI. Opt-in extras: "Question", "Compress". See Selective tool proxy.
extraDisallowedTools string[] – Extra Claude built-ins to switch off with --disallowedTools, on top of what proxyTools implies. Claude’s names, e.g. ["NotebookEdit"]. See Closing a tool with no proxy.
proxyToolTimeoutMs Record<string, number> – Optional wall-clock backstop per proxy tool, in ms, keyed by proxy tool name (bash, task, …). A call normally ends on an event the plugin listens for (result, abort, next message, process exit, chat deletion), not on a timer; see How a proxied call ends. Defaults: 10 min flat, task / task_batch → none, question → 30 min. 0 disables a tool’s deadline; negative or non-numeric values are ignored. For bash, the call’s own input.timeout is honoured on top (max(resolved, input.timeout)). See Per-tool proxy timeouts.
planModeQuestion boolean false Route ExitPlanMode approval through opencode’s native question tool instead of a text “(yes/no)” prompt. Opt-in, and currently unreachable on the default headless transport, which is not offered an ExitPlanMode tool at all. See Plan mode.
controlRequestBehavior allow | deny allow Default response when skipPermissions: false and Claude sends a can_use_tool control request.
controlRequestToolBehaviors Record<string, "allow" | "deny"> – Per-tool override for can_use_tool. Example: { "Bash": "deny", "Read": "allow" }.
controlRequestDenyMessage string built-in message Message returned to Claude on a deny.
bridgeOpencodeMcp boolean true Auto-translate your opencode mcp block into Claude’s --mcp-config. See MCP bridge.
mcpConfig string | string[] – Extra --mcp-config paths/JSON passed alongside the bridged config.
strictMcpConfig boolean false Pass --strict-mcp-config so Claude loads only the configured servers and ignores ~/.claude/settings.json.
hotReloadMcp boolean true With MCP bridging on, compare the merged MCP config and runtime status at the start of each turn and respawn the claude process when they drifted, so a server you just enabled, disabled or finished connecting becomes visible without restarting opencode or opening a new chat. It only ever acts at a safe boundary: never during /compact, never on the interactive transport, never while a proxied call is still in the air, a turn is still running or a plan-mode approval is outstanding, and the Claude session id is preserved for --resume so the conversation continues. A log line at INFO names which servers joined and left. A server that flaps buys at most one respawn per minute per conversation (CLAUDE_CODE_MCP_HOT_RELOAD_COOLDOWN_MS). Set false to keep a cached subprocess until the chat is reset. It does not reload other provider options and does not watch the contents of files named in mcpConfig.
mcpConnectWaitMs number 3000 How long the first turn of a conversation waits for MCP servers opencode reports as still connecting before planning the claude spawn without them. Only opencode 2 can report that state (pending); opencode 1’s own status call blocks until every server has decided, so this budget is what makes the two majors behave alike. Set 0 to always plan with whatever the host says at that instant. Aborting the turn also ends the wait at once. A server slower than the budget is not lost either way: it is still bridged, and hotReloadMcp moves the conversation onto a process that has it on the next turn.
proxyOpencodeMcpTools boolean false Route opencode’s MCP-backed tools through the in-process opencode_proxy server instead of bridging them straight into Claude’s --mcp-config, so each call executes once, inside opencode, with its permission prompt and its tool row. The default changed from true to false in this release, and no behaviour changed with it: at true it used to route nothing at all, because discovery read opencode’s tool registry, which contains built-ins and plugin-declared tools and has never contained an MCP tool. Discovery now reads the model tool set opencode passes the provider, which is where MCP tools actually are, so the option works, and turning it on is the operator’s decision rather than a silent migration of traffic that the direct bridge is handling today. Two caveats before enabling it: pair it with strictMcpConfig: true, because a server also registered in Claude Code’s own config is reached directly and bypasses the proxy entirely; and a routed call runs in opencode with the calling agent’s permissions, the same trade proxyOpencodeTools makes. Servers whose tools are not found stay on the direct bridge, and a warning says so, so do not treat this as an exactly-once guarantee for write-capable tools.
proxyOpencodeTools string[] [] Forward explicitly named opencode tools through the proxy (for example, a plugin’s compress or V2 Code Mode execute). V1 uses registry ids; V2 uses the current model tool snapshot, including its real JSON Schema and agent visibility, not the registry’s empty schemas. A forwarded tool runs inside opencode with the calling agent’s permissions. A name already held by a proxy def is dropped with a warning. The read-only preset refuses execute. See Forwarding opencode’s own tools and V2 Code Mode.
stripContextReminders boolean false Remove opencode-dcp’s <dcp-system-reminder> blocks from message text when no compress tool is proxied, so an order the model cannot follow stops being re-sent with every message that carries it. Inert as soon as compress is reachable. See Trimming unsatisfiable context reminders.
webSearch "claude" | "disabled" | <tool> "claude" Routing for Claude’s built-in WebSearch. See WebSearch routing.
multiStepContinuation boolean true Append a system-prompt hint nudging Claude to chain tool calls within one turn instead of pausing between subtasks. Each opencode turn boundary requires the user to manually press “continue”, so for multi-step tasks this reduces friction. Set false to disable.
autoContinueIncompleteTurns boolean | "smart" "smart" Smartly continue incomplete Claude CLI results inside the same opencode turn. Reduces manual “continue” presses when Claude ends after reasoning/tool activity without a useful final answer. Also gates the ▌ **no reply:** note on a turn that ends with no text and no tool call. Set false to disable both.
compactionModel string "claude-haiku-4-5" Model used when opencode invokes /compact. Override per-process via the CLAUDE_CODE_COMPACTION_MODEL env var (env wins over config). See Compaction.
ignoreAnthropicApiKey boolean false Strip ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN from every spawned claude process so it authenticates with your logged-in subscription instead of pay-as-you-go API billing. The plugin warns once at startup whenever an API key is detected, regardless of this setting. See Billing.
idleProcessTimeoutMs number – Kill a retained headless Claude worker after this many idle milliseconds following a completed turn. The timer starts when a turn finishes, a new turn cancels it, a worker that is mid-turn when it fires is left alone and re-timed, and the session id is preserved for --resume. Values above Node’s maximum timer delay (2147483647) are ignored. Omit or set 0 to retain workers until LRU eviction (16 processes). Interactive transport is excluded. Contributed by @bernardofortes.
bridgeOpencodeSkills boolean false Expose your opencode skills to Claude’s native Skill tool, from every root opencode itself reads. Off by default because every bridged skill is also in the system prompt opencode forwards, so a large set is paid for twice per turn; the bundled configuration skill is staged either way. See Skill bridge. Written by @broskees.
bridgeSkipNativeSkills boolean true Leave a skill unbridged when the Claude session already loads it from $CLAUDE_CONFIG_DIR/skills, the project’s .claude/skills, or an installed plugin, so one skill does not reach the model twice. Matched by resolved path, by identical SKILL.md, or by name. false bridges everything and reinstates the duplicates. See Skills Claude already has.
logging object all defaults The plugin’s own logger, four independent fields: file (boolean, default false), dir (string, default ~/.local/share/opencode-claude-code/), mode ("silent" | "debug", default "silent") and level ("debug" | "info" | "notice" | "warn" | "error", default "info"). Goes under provider.claude-code.options like every other row here. See Logging.
turnStats boolean false Append a one-line cost / duration / cache footer to each finished turn. See Per-turn stats.
forkSessions boolean false Branch a forked opencode session off the parent’s Claude conversation with --fork-session instead of replaying its history as text. See The prompt cache an agent writes.
interactive boolean false Experimental. Drive the interactive claude TUI (subscription billing) instead of headless --print. Requires opencode running under Bun with PTY support; silently falls back to headless otherwise. The tool proxy, permissionMode and /btw are all unavailable on it, so read What it does not support before enabling. Env: CLAUDE_CODE_INTERACTIVE_TRANSPORT=1.
interactiveBypass boolean false Deprecated/no-op with interactive: Claude Code’s TUI shows a manual safety confirmation for bypassPermissions, so the plugin intentionally does not pass it.
interactiveAllowTools string[] ["Bash", "Edit", "Write", "Read", "WebFetch"] With interactive: built-in tools pre-allowed without prompting (replaces the default list). MCP server wildcards (mcp__<server>__*) are always added from the bridged config.
interactiveSystemPrompt boolean true With interactive: append this plugin’s CLI/AGENTS/continuation prompt via --append-system-prompt-file. The transport intentionally does not forward opencode’s own system prompt, because it can trigger Claude Code’s third-party-app usage gate on subscription accounts. Set false only for diagnostics.

Free and MIT-licensed. If the plugin saves you time, you can buy its maintainer a coffee.

Buy me a coffee