Skip to main content
Glama

opencode-bridge-for-claude-code

Let Claude Code hand its easy and medium work to cheaper opencode agents, keep the hard work for itself, and see exactly what every opencode session is doing.

A single-file, zero-dependency MCP server (Node 18+), with an equivalent Rust implementation (7 ms start, 6 MB memory; see rust/). It gives Claude Code ten tools:

  • Delegate a task to an opencode agent (explorer, librarian, fixer, oracle, ...) with the delegation policy enforced by the tool, not left to a prompt that gets forgotten.

  • Watch every opencode session on the machine (the ones you started, the ones your subagents started, the TUI ones): which are running, which failed, what each one said and did.

  • Name sessions consistently (LANE/agent: task) so a list of forty sessions is readable.

Companion repository: opencode-config. The agent roster this bridge delegates to (explorer, librarian, deep-research, oracle, fixer, designer) and the opencode-side routing rules live there. Install it as ~/.config/opencode first. Without it only the bridge's built-in worker agent exists and most of what makes the delegation useful is missing.

Why

Delegating to a cheaper model saves tokens only if it is done with discipline: send the right kind of work, never the work where a silent mistake corrupts a result, verify what comes back, and know what is running. In practice three things go wrong:

  1. The routing mode is forgotten. A project can be "sensitive" (quality-critical: delegate only recon, docs, literature and checks) or "insensitive" (aggressive offload) or the default "blueprint" mode. Instructions in a CLAUDE.md get missed after a context reset. Here the mode is detected and enforced in the tool call, and it is also sent to Claude as MCP server instructions.

  2. Nobody can see the opencode sessions. Subagents start opencode run jobs that nobody tracks. The bridge reads the opencode service's own session store.

  3. Sessions are called "Entropy-based selection of RNA structures", "New session - 2026-..." and so on. A fixed LANE/agent: task title makes them sortable and searchable.

Related MCP server: opencode-delegate

Quick start

Requirements: Node.js >= 18, opencode v2 with its background service (tested with 2.2.7; the bridge uses the opencode api command and the /api/session routes), the opencode-config agents, and a C compiler only if you want to run the process tests.

# 1. the opencode side: agent roster and routing rules. The roster is on the v2 branch (the default branch is older)
git clone -b v2 https://github.com/Subhajit-Roy-Partho/opencode-config ~/.config/opencode     # back up an existing ~/.config/opencode first

# 2. the bridge
git clone https://github.com/Subhajit-Roy-Partho/opencode-bridge-for-claude-code ~/.claude/mcp/opencode-bridge

claude mcp add --scope user opencode-bridge \
  -e OPENCODE_BRIDGE_ROOT="$HOME/projects" \
  -e OPENCODE_BRIDGE_MODEL='provider/model#variant' \
  -- node ~/.claude/mcp/opencode-bridge/server.mjs

claude mcp get opencode-bridge      # Status: ✔ Connected

OPENCODE_BRIDGE_ROOT is the only directory tree delegated tasks may work in. Restart Claude Code once; the tools appear as mcp__opencode-bridge__opencode_*. If you use several Claude config directories (CLAUDE_CONFIG_DIR), run the claude mcp add line once per directory with CLAUDE_CONFIG_DIR=... claude mcp add ....

Prefer the Rust binary? Build it with rust/build.sh (Docker) or cargo build --release and register that binary instead of node .../server.mjs; same tools, same environment variables, same tests (rust/README.md).

Then add a short section to your CLAUDE.md so Claude prefers the bridge: see examples/claude-md-snippet.md.

The tools

Tool

Read-only

What it does

opencode_start

no

Delegate a job (async, returns a task id). Requires tier; enforces mode, agent allow-list, secret guard; titles the session.

opencode_status / opencode_result

yes

State, elapsed time, attempts, session id, and the output of a task started by this bridge. A failed task shows its kind (rate_limit, quota, context_length, ...), the message and advice. Output over 60000 characters is cut unless head / tail is given.

opencode_cancel

no

Cancel a running or retrying task started by this bridge: SIGTERM then SIGKILL to its whole process group (never touches other sessions).

opencode_list

yes

Tasks started by this bridge, with agent / tier / mode and title.

opencode_policy

yes

The active routing mode for a directory, where it was detected, the allowed agents, tier rules, verification rules, roster.

opencode_sessions

yes

All opencode sessions across projects: id, state, agent, age, tokens, directory, title. Filters: state, agent, directory, search, title_prefix, since_minutes, limit, children.

opencode_session_output

yes

What a session did: mode=last (final answer), tail (recent steps, default), full. Reasoning blocks are dropped; tool calls and results are clipped.

opencode_session_rename

writes a title

Set a session title (warns when it breaks the naming convention).

opencode_processes

yes

OS view of running opencode run / TUI processes with their exact --title, agent, cwd and elapsed time (includes runs that have no session in the service).

Example (illustrative; opencode_sessions state=running):

2 session(s) (state=running); scanned 100; service-active ids: 0
ses_e3188e02...  running  deep-research  <1m ago  650k/29k tok  Github/project-a  ALPHA/deep-research: collect API reference notes
ses_e31688286... running  worker         <1m ago    0/0 tok     Github/project-a  BETA/worker: rename api_key to apiKey in the loader

Example (illustrative; opencode_session_output mode=tail):

ses_e31688286...  succeeded  worker  updated <1m ago  19k/78 tok
Github/project-a  |  BETA/worker: rename api_key to apiKey in the loader
----------------------------------------
[00:09:57] agent -> worker
[00:10:02] user: Rules: do the work yourself, ... READ-ONLY / build-and-test line ... <the task>
[00:10:04] assistant: Renaming in three files.
  -> edit({"path":"src/loader.js", ...}) [completed] => ok
[00:10:36] assistant: DONE
[00:10:37] - idle (succeeded) -

States: running (no outcome yet, and recent or reported active by the service), succeeded, failed, interrupted, and stale? (no outcome but quiet for 45 minutes: crashed, killed, or a very long silent tool call). Runs started with --standalone (as the bridge does) are not in the service's own active list, so for them running comes from recency.

The delegation policy (modes and tiers)

The policy is the one in docs/POLICY.md; in short:

Tiers. Only easy and medium work is delegated: literature search, quote extraction, DOI lookups, bulk download / parse / convert / clean, table collation, boilerplate and glue scripts, functions with a given spec, unit tests, README drafts, plots from given tables, mechanical refactors, UI against a written blueprint. Hard and moderately hard work stays on Claude: experiment and protocol design, split and leakage decisions, anything touching held-out data, model and feature design, statistics and every reported number, scoring / metric / energy code, non-obvious debugging, architecture, interpretation. If a silent mistake would change a result, do not delegate; if unsure, treat the job as one tier harder. opencode_start refuses tier: "hard" and "unsure".

Modes.

Mode

Detected from

What is allowed

blueprint (default)

nothing else set

All agents. Recon/docs first, then Claude writes a Blueprint (files, signatures, edge cases, acceptance criteria, test command) for fixer / designer; optionally oracle grades the diff; Claude verifies.

sensitive (conservative)

OPENCODE_MODE / OPENCODE_BRIDGE_MODE = sensitive; <project>/.claude/sensitive; the mode argument when the user asked

explorer, librarian, deep-research, oracle; fixer / worker only with mechanical: true. designer and general are refused.

insensitive (aggressive offload)

env, <project>/.claude/insensitive, ~/.claude/insensitive, $CLAUDE_CONFIG_DIR/insensitive, or the mode argument

All agents; parallel lanes are encouraged. Hard work still stays on Claude.

Sensitive always wins when sources disagree. The project root is the nearest parent of the working directory that has a .claude or .git. Call opencode_policy (optionally with cwd) to see the result and the reason.

Also enforced. Prompts that look like they contain a secret (API keys, tokens, private keys, password=...) are refused before anything starts. Read-only agents get an explicit read-only instruction, editing agents a "run the build/test and fix until it passes" instruction, and every run is told never to commit or push. The output is always an untrusted draft: Claude is told to check files exist, rerun tests, recompute numbers, inspect git diff.

Session naming

<LANE>/<agent>: <task>: LANE in capitals (a lane or repository short name), agent = the opencode agent, task = 3-8 words. Example: DOCS/librarian: collect API notes. opencode_start sets it from lane (default: upper-cased directory name) and the first line of the prompt, or from an explicit title. For a plain opencode run pass --title; an explicit title is kept (opencode's automatic title generator backs off from custom titles). opencode_session_rename fixes old ones; opencode_sessions title_prefix="DOCS/" lists one lane. Details: docs/SESSION-NAMING.md.

Limits, errors and recovery

The bridge assumes things go wrong and says what to do about it (docs/ERRORS.md has the full tables):

  • Provider errors (rate limit, quota, context length, output limit, overload, auth, bad model or agent, network) are parsed from opencode's error events and stderr, classified, and returned with advice. Only transient errors of read-only agents that produced no output are retried automatically (backoff 20 s, 60 s); an agent that edits files is never replayed.

  • Runaway work: at most 6 tasks at once, a 120 minute timeout per task, and cancel / timeout / disconnect kill the whole process group, including the shell commands the agent started.

  • Size limits: prompts over ~100 KB are attached as a file (Linux limits one argument to 128 KiB); replies are capped at 100000 characters; output is kept up to 2 MB per task.

  • Service problems: a stopped, hung or unauthorised opencode service, or a huge reply, produces a one-line message, not a stack trace; long scans stop at a deadline and say PARTIAL.

Configuration

Variable

Meaning

OPENCODE_BRIDGE_ROOT

Directory tree delegated tasks may use as cwd (default: the server's working directory).

OPENCODE_BRIDGE_MODEL

Model for delegated runs, provider/model[#variant]. Unset = opencode's own default.

OPENCODE_BRIDGE_AGENT

Default agent when agent is omitted (blueprint / insensitive). Default worker. In sensitive mode the default is always explorer.

OPENCODE_BRIDGE_MODE, OPENCODE_MODE

Force a routing mode (blueprint / sensitive / insensitive).

CLAUDE_CONFIG_DIR

Also searched for an insensitive marker file.

OPENCODE_BRIDGE_MAX_PARALLEL

Concurrent delegated tasks, default 6 (1-64).

OPENCODE_BRIDGE_TIMEOUT_MIN

Default per-task timeout in minutes, default 120 (timeout_minutes overrides per task).

OPENCODE_BRIDGE_RETRIES, OPENCODE_BRIDGE_RETRY_DELAY_S

Automatic retries (default 2) and the first delay (default 20 s, then x3).

OPENCODE_BRIDGE_API_TIMEOUT_MS, OPENCODE_BRIDGE_SCAN_DEADLINE_MS, OPENCODE_BRIDGE_KILL_GRACE_MS

Service call timeout (45000), session-scan deadline (35000), SIGTERM to SIGKILL grace (5000).

How it works

All session reads go through opencode api GET /api/session..., which talks to the opencode background service and handles its authentication, so the bridge never touches credentials. Routes used: session.list, session.get, session.message.list, session.active, session.update (title only). Delegated runs are opencode run --standalone --agent <agent> --title <title> --auto --format json, in cwd inside the allowed root. Nothing is ever deleted or interrupted by the bridge, and opencode_cancel only kills processes it started itself. Notes on the API: docs/API-NOTES.md.

Tests

npm test                 # 190 offline tests: fake opencode, no network, no tokens
npm run test:live        # 7 live tests against your real opencode service (spends a few thousand tokens, cleans up after itself)
BRIDGE_BIN=/path/to/opencode-bridge npm test    # the same suite against the Rust binary

The offline suite covers the MCP protocol, every tool and every parameter, pagination across pages, state / stale detection, output rendering and truncation, rename, the process table (against a compiled stand-in binary named opencode), mode detection from every source and their precedence, tier and agent enforcement per mode, the secret guard, and every error path: provider errors and their classification, the retry rules, timeouts and process-group kills, the parallel limit, oversized prompts, service failures, shutdown. See docs/TESTING.md.

Limitations

  • opencode v2 only (/api/... routes). The older opencode serve HTTP API with /session is not supported.

  • The bridge runs one opencode run --standalone process per task; it does not keep a long-lived opencode server of its own. Task state is in memory: after a restart of the bridge the opencode sessions remain readable, but the tasks are no longer listed.

  • tier and mode are enforced mechanically, but whether a task is really "easy" is still Claude's judgement. The policy cannot read the task.

  • Session output can contain whatever the agent saw, including file contents. The tools are read-only but the text goes to the model.

Prior art

Other MCP servers for opencode exist, for example nosolosoft/opencode-mcp and several listed on Glama. They mostly wrap the older HTTP API with basic auth. This one targets the v2 service through opencode api, adds the policy enforcement and the naming convention, and is designed for the opencode-config agent roster.

License

MIT

Available Tools

10 tools
opencode_cancelA

Cancel a running or retrying task started by this bridge: SIGTERM, then SIGKILL, to its whole process group (never touches other sessions). A finished task is reported as such.

Inputs: id (required).

opencode_listA

List tasks started by this bridge. For ALL opencode sessions use opencode_sessions.

Inputs: no named parameters.

opencode_policyA

READ-ONLY. Show the delegation policy that opencode_start enforces: the ACTIVE routing mode for a directory and where it was detected, the agents allowed in that mode, the tier rules (what to delegate / keep), the verification rules and the roster. Call it before delegating if unsure which mode applies.

Inputs: cwd, mode.

opencode_processesA

READ-ONLY. OS-level view: running opencode run / opencode TUI processes (pid, elapsed, agent, title, working directory). Shows work that has no session in the service (e.g. --standalone runs) and processes that hang.

Inputs: no named parameters.

opencode_resultB

Output of a task started by this bridge, with the failure kind and advice when it failed (rate_limit, quota, context_length, output_limit, overloaded, auth, model, agent, invalid_request, network, timeout, spawn, exit). Large outputs are cut to the last 60000 characters unless head / tail is given.

Inputs: id (required), head, tail.

opencode_session_outputA

READ-ONLY. Read what an opencode session did. mode "last" = the final assistant answer; "tail" (default) = the last N messages condensed (assistant text, tool calls with truncated input / result; reasoning is dropped); "full" = like tail but all fetched messages. Output is cut to max_chars from the end.

Inputs: id (required), mode, messages, max_chars, +1 more.

opencode_session_renameB

Set the title of an opencode session (the only write done on other sessions). Use the convention "/: ".

Inputs: id (required), title (required).

opencode_sessionsA

READ-ONLY. List opencode sessions of the background service across all projects (newest first): id, state (running / succeeded / failed / interrupted / stale?), agent, age, tokens, directory, title. Use state=running to see what is active now; a session whose last update is older than ~45 min and has no outcome is shown as "stale?".

Inputs: agent, limit, state, search, +4 more.

opencode_startA

Delegate an EASY or MEDIUM job to an opencode agent (async; returns a task id). POLICY IS ENFORCED: tier is required and hard/unsure work is refused (it stays on Claude); the routing MODE (blueprint default | sensitive | insensitive; sensitive wins) is detected from env OPENCODE_MODE, /.claude/sensitive|insensitive, ~/.claude/insensitive, or the mode argument, and limits the agents (sensitive: explorer, librarian, deep-research, oracle, and fixer/worker only with mechanical:true). Blueprint mode: give fixer/designer a written Blueprint (files, signatures, edge cases, acceptance criteria, test command). Prompts containing secrets are refused. The session is titled "/: ". LIMITS: at most OPENCODE_BRIDGE_MAX_PARALLEL tasks at once (default 6), a per-task timeout, automatic retry (backoff) of transient provider errors for read-only agents only, prompts over ~100 KB are sent as an attached file. Verify the result yourself - it is an untrusted draft. Call opencode_policy for the full rules.

Inputs: tier (required), prompt (required), cwd, lane, +7 more.

opencode_statusB

Status of a task started by this bridge (running/done/failed), elapsed time and session id.

Inputs: id (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 10 tools

    Disambiguation4/5

    There are several 'what is running' views (opencode_list, opencode_status, opencode_sessions, opencode_processes), but the descriptions explicitly separate bridge tasks from all service sessions and from OS-level processes, so an agent can pick correctly after reading. opencode_result vs opencode_session_output is the closest remaining overlap: one reads a bridge task's output, the other an arbitrary session's, which is a minor source of misselection.

    Naming Consistency4/5

    All ten tools share the opencode_ prefix and snake_case, so the family is instantly recognizable. The only deviation is the ordering in opencode_session_rename (noun before verb) versus the verb-first style of list/start/status/result/cancel.

    Tool Count5/5

    Ten tools is well within the sweet spot and each maps to a distinct concern: delegate, inspect, retrieve, cancel, plus separate read-only introspection of policy, sessions, and processes. No filler tools and nothing obviously missing for the async-task lifecycle.

    Completeness4/5

    The async lifecycle is fully covered: start, list, status, result, cancel, plus session-level inspection, rename, and process-level diagnostics, with a policy endpoint to guard usage. Gaps are modest: there is no follow-up/continue operation to send additional instructions to an existing session, and no cleanup/prune of finished tasks.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables Claude Code and Claude Desktop to delegate coding tasks to any model available in OpenCode while Claude remains the orchestrator, planning work, reviewing diffs, and running tests. Supports synchronous and async delegation, model selection, session continuation, and permission-aware execution.
      6
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables Claude Code to delegate software-engineering tasks to OpenCode agents running in the same workspace/worktree, with the model and provider chosen per agent. Exposes tools for task delegation, persistent sessions, diffs, and agent listing so an orchestrator can research, edit, review, and test code.
      7
      130 npm
      MIT