// coordinator bridge
v0.5.1 release / repo / compatibility / tool api
A coordinator bridge. Your harness delegates, OpenCode works.
OpenCode MCP Bridge is a coordinator MCP bridge, not OpenCode itself. A host harness (Codex, Claude Code, Cursor, VS Code, Gemini CLI, OpenHands, Pi/Hermes, or ChatGPT connectors) calls the bridge over Streamable HTTP, and the bridge runs OpenCode worker agents against an OpenCode server you control. Bring your own server, your own bridge deployment, and your own token. The maintainer's homeserver is not a public shared worker service.
- Safe endpoint
- /worker-mcp x8, never exec_run
- Full endpoint
- /mcp x19, exec_run opt-in only
- OpenCode server
- you run it, 127.0.0.1:4096
01 // What this is
A bridge. Nothing more.
What it is
A coordinator MCP server over Streamable HTTP. Your host harness delegates implementation to OpenCode workers through the safe /worker-mcp endpoint: exactly eight worker tools (worker_catalog, worker_run, worker_wait, worker_status, worker_verify, worker_cleanup, worker_decide, worker_resume). The full /mcp endpoint carries 19 tools for legacy clients, with exec_run listed but fail-closed unless the operator sets ENABLE_EXEC_RUN=true.
What it is not
Not OpenCode itself. Not a model provider. Not a hosted coding environment, and not a shared OpenCode instance for everyone. You connect the bridge to your own OpenCode server. The maintainer's homeserver is not a public shared worker service. Full legacy /mcp is private administration only, never the public recommendation.
What you run
An OpenCode server you control (your own machine or private host) plus your own bridge deployment and token. The bridge defaults to http://127.0.0.1:4096 and talks to it over HTTP. Configure your own endpoint https://<your-domain>/worker-mcp and keep the token in the environment, never in a file or chat log.
02 // Your OpenCode server
Point the bridge at a server you control.
This section is the OpenCode worker service, not an MCP client. Start OpenCode with opencode serve. Default host is 127.0.0.1, default port is 4096. MCP clients connect to the bridge; the bridge talks to this server. Pick the setup that matches where the server lives.
> A. Same machine
Bridge and OpenCode on the same box. Safest default.
opencode serve --hostname 127.0.0.1 --port 4096> B. Private remote host
Server on a box you reach over the network. Set a password, put it behind HTTPS and a firewall, then point the bridge at it with OPENCODE_BASE_URL. Never expose it unauthenticated.
OPENCODE_SERVER_PASSWORD=... opencode serve --hostname 0.0.0.0 --port 4096> C. Existing deployment
Already run OpenCode somewhere? Point the bridge at it with OPENCODE_BASE_URL. Placeholder address, replace it:
OPENCODE_BASE_URL=https://opencode.example.com03 // Coordination loop
Four stations. One direction. No loops left open.
01
HOST
Your harness plans the work and keeps the brief.
02
DISPATCH
Bridge spawns an isolated OpenCode session.
03
WORKER
Worker executes in its own worktree.
04
VERIFY
Host checks the diff, then cleans up.
$ session transcript
worker_catalog -> worker_run -> worker_wait/worker_status -> worker_verify -> worker_cleanup # approval-gated runs pause at worker_decide, then worker_resume
04 // Eight-tool surface // v0.5.1
Small enough to hold in your head.
The host keeps the plan. The worker keeps the worktree. Safe /worker-mcp serves exactly eight worker tools and never exposes exec_run. Full /mcp serves 19 tools (the same eight plus eleven legacy session/model/diff tools) for legacy clients; exec_run stays listed but fail-closed unless the operator explicitly sets ENABLE_EXEC_RUN=true.
worker_run is async and returns a taskID at once. Then wait bounded server-side with worker_wait (default 30s, clamped 1-120s, returns on change or with timed_out=true plus a next_action hint), or take single snapshots with worker_status. Approval gates pause before any OpenCode call: worker_decide approves or rejects, worker_resume starts an approved run exactly once. Default runs still start immediately.
Default worker model is free Muse Spark 1.3 (opencode/muse-spark-1.3-contributor-free). Paid OpenCode Go Muse Spark 1.3 (opencode-go/muse-spark-1.3-contributor) is an explicit fallback only: requested per task, never auto-selected. Full signatures live in the tool API docs.
TOOL_01
worker_catalog
List models before spending anything. Free default first, paid fallback explicit only.
TOOL_02
worker_run
Dispatch one isolated session with a tight brief. Async, returns a taskID at once.
TOOL_03
worker_wait
Bounded server-side wait. Returns on change or at timeout_s (default 30, clamped 1-120).
TOOL_04
worker_status
Immediate snapshot fallback. One read, no waiting.
TOOL_05
worker_verify
Evidence gate. Read-only git bundle plus state before anything is accepted.
TOOL_06
worker_cleanup
Abort or delete the session. Every session ends closed.
TOOL_07
worker_decide
New in v0.4.0: approve or reject a paused approval-gated run. No side effects until approved.
TOOL_08
worker_resume
New in v0.4.0: start an approved run exactly once with the same inputs.
That is the whole safe API.
Learn it once, script it forever.
05 // Release history // v0.5.1 latest
v0.5.1 is current. Observability, redacted logs, aligned pins.
v0.5.1 2026-09-16 — the bridge stays a coordinator MCP server for an OpenCode server you own. You bring your own server, your own bridge deployment, and your own credentials. It adds liveness, readiness, and metrics endpoints, plus centralized log redaction for bearer tokens, API keys, and OpenCode credentials. Codex and Claude plugin pins align to v0.5.1, and the docs now describe the worker operating model and the ordered free-to-paid model fallback. The deployed worker surface keeps worker_wait and the approval worker_decide / worker_resume tools, with no exec_run on /worker-mcp. Verification: 442 tests passed (8 live tests skipped by their environment gate); Ruff, formatting, whitespace, and plugin-manifest checks passed. See the v0.5.1 release notes.
> Older releases
v0.4.3 2026-09-14 — Version coherence, no runtime change
- All authoritative version sources track 0.4.3: pyproject.toml, server.json, Codex, Claude, and OpenHands plugin.json files, Claude marketplace.json, Codex marketplace ref v0.4.3, fallback version, CHANGELOG, docs pins.
- Guarded by tests/test_release_coherence.py.
- Safe /worker-mcp with exactly 8 worker tools; full /mcp with 19 tools and opt-in exec_run.
v0.4.2 2026-09-14 — CI caps, Codex approvals, empty-taskID guard
- CI 20-minute caps plus least-privilege permissions.
- Codex bundle declares worker_decide and worker_resume approvals; 8-tool safe set pinned.
- worker_status rejects empty taskID before backend I/O.
v0.4.1 2026-09-14 — Stable unknown for missing sessions
- Backend-missing session returns unknown status (task_not_found, retryable=false) instead of an MCP error.
- Transport and auth failures still raise; wait and verify inherit the snapshot.
v0.4.0 2026-09-14 — Approval, resume, eight tools
- worker_decide and worker_resume join; /worker-mcp serves exactly 8 tools, /mcp serves 19 with exec_run fail-closed.
- Bounded worker_wait (default 30s, clamped 1-120s) with timed_out and next_action contracts.
- Native OpenHands package plus compatibility and adoption docs; opt-in live conformance gate.
v0.3.0 2026-09-14 — Bounded worker_wait, six tools
- New worker_wait: bounded server-side wait on /worker-mcp (6 tools) and /mcp (17 tools).
- Stable additive task contracts: state, timed_out, retryable, next_action, error_code, evidence.
- Deterministic MCP conformance tests plus worker_wait-first harness docs.
v0.2.0 2026-09-04 — Worker API, plugins, hardening
- Worker API: worker_run, worker_status, worker_catalog, worker_verify, worker_cleanup (5 tools on /worker-mcp).
- Codex and Claude plugin packaging, bundled MCP configs, worker playbook skills.
- Auth rotation, task locking, directory authorization, CI and Docker hardening.
Full per-version entries live in the repo CHANGELOG.md. The harness matrix and first-call contract live in docs/compatibility.md, backed by network-free adoption checks in CI.
06 // Harness setup
Bring your own endpoint. Keep the token in the environment.
Every snippet below uses your own bridge URL https://<your-domain>/worker-mcp. Replace it with your deployment. Every caller needs their own bearer token; nothing here grants access and no token is shown. Start with:
export OPENCODE_MCP_URL="https://<your-domain>/worker-mcp"
export OPENCODE_MCP_BEARER_TOKEN="<paste-token-here>"Compatibility is protocol-level: MCP over Streamable HTTP with an Authorization: Bearer header. Config key names differ per product, so confirm them in the official client docs before pasting. Full steps live in the README and client setup guide. First-call proof (tools/list, then worker_catalog) is in docs/compatibility.md.
> Codex CLIdocs-only, unverified end-to-end
Syntax from the official Codex docs. Reads the token from the environment at request time; register per machine with your own URL.
codex mcp add opencode --url "$OPENCODE_MCP_URL" --bearer-token-env-var OPENCODE_MCP_BEARER_TOKEN> Codex plugindocs-only, unverified end-to-end
opencode-worker 0.5.1 via the repo marketplace. The bundled URL is a placeholder; register your own transport above after install.
codex plugin marketplace add ManuOtel/opencode-mcp-bridge --ref v0.5.1codex plugin add opencode-worker --marketplace opencode-mcp-bridge> Claude Codedocs-only, unverified end-to-end
opencode-worker 0.5.1 plugin path first, native MCP as fallback. Two commands, in order:
claude plugin marketplace add ManuOtel/opencode-mcp-bridgeclaude plugin install opencode-worker@opencode-mcp-bridge> Claude Code native MCP - fallback
Single quotes keep ${OPENCODE_MCP_BEARER_TOKEN} as a reference so the raw secret never lands in local config:
claude mcp add --transport http --header 'Authorization: Bearer ${OPENCODE_MCP_BEARER_TOKEN}' opencode "$OPENCODE_MCP_URL"> ChatGPT custom MCP / connectorsdocs-only, unverified, auth boundary
Manual setup, not verified end-to-end. Turn Developer Mode on, create a remote MCP connector in URL mode with your own https://<your-domain>/worker-mcp, then scan tools and call worker_catalog. Official docs list OAuth, no-auth, and mixed-auth paths, not a static Bearer header, so confirm the auth method there first. Needs an eligible plan and workspace and may need admin approval; availability depends on your account, not on this bridge.
> Cursordocs-only, unverified end-to-end
MCP client, not the worker service. Add to your project's .cursor/mcp.json with your own URL; the token stays in OPENCODE_MCP_BEARER_TOKEN.
{
"mcpServers": {
"opencode-bridge": {
"url": "https://<your-domain>/worker-mcp",
"headers": {
"Authorization": "Bearer ${OPENCODE_MCP_BEARER_TOKEN}"
}
}
}
}> VS Codedocs-only, unverified end-to-end
MCP client, not the worker service. Uses servers (not mcpServers) with type: http; secrets via inputs, never hardcoded. Confirm key names in the VS Code docs for your version.
{
"servers": {
"opencode-bridge": {
"type": "http",
"url": "https://<your-domain>/worker-mcp",
"headers": {
"Authorization": "Bearer ${input:opencode-bridge-token}"
}
}
},
"inputs": [
{
"type": "promptString",
"id": "opencode-bridge-token",
"description": "Bearer token for your own bridge (MCP_BEARER_TOKEN)",
"password": true
}
]
}> Gemini CLIdocs-only, unverified end-to-end
Manual setup from the official Gemini CLI docs. Uses httpUrl (not url) in ~/.gemini/settings.json.
{
"mcpServers": {
"opencode-bridge": {
"httpUrl": "https://<your-domain>/worker-mcp",
"headers": {
"Authorization": "Bearer ${OPENCODE_MCP_BEARER_TOKEN}"
}
}
}
}> OpenHandsdocs-only, unverified, auth boundary
Manual setup, not verified end-to-end. CLI Bearer path below; the TOML settings path documents shttp_servers with url plus api_key, not a generic Authorization header, so confirm the auth field for your OpenHands build. Native package (plugins/openhands/) ships the skill and placeholder config; structural checks only.
openhands mcp add opencode-bridge --transport http --header "Authorization: Bearer $OPENCODE_MCP_BEARER_TOKEN" "https://<your-domain>/worker-mcp"> Pi / Hermesdocs-only, unverified end-to-end
Manual setup from the official adapter docs. Pi uses the pi-mcp-adapter with a shared config file; Hermes uses YAML mcp_servers with an explicit tool include list. No one-click plugin is claimed.
{
"mcpServers": {
"opencode-bridge": {
"url": "https://<your-domain>/worker-mcp",
"auth": "bearer",
"bearerTokenEnv": "OPENCODE_MCP_BEARER_TOKEN",
"includeTools": ["worker_catalog", "worker_run", "worker_wait", "worker_status", "worker_verify", "worker_cleanup"],
"lifecycle": "lazy"
}
}
}mcp_servers:
opencode-bridge:
url: "https://<your-domain>/worker-mcp"
headers:
Authorization: "Bearer ${OPENCODE_MCP_BEARER_TOKEN}"
tools:
include: [worker_catalog, worker_run, worker_wait, worker_status, worker_verify, worker_cleanup]
resources: false
prompts: false> First call (your own bridge)
Expect exactly eight worker tools on /worker-mcp, never exec_run. Prints counts and tool names only, never the token.
curl -fsS -X POST "$OPENCODE_MCP_URL" -H 'Content-Type: application/json' -H "Authorization: Bearer $OPENCODE_MCP_BEARER_TOKEN" -H 'Accept: application/json, text/event-stream' -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'07 // Security / operations
Isolated by default. Verified on purpose.
Static bearer on /worker-mcp
Every call carries your own static bearer token. No token, no dispatch. You configure and rotate it. There is no OAuth or one-click auth; bearer-only, no OAuth claims.
Least privilege by endpoint
Use /worker-mcp for everything new: eight worker tools, no shell. /mcp is legacy only; exec_run stays fail-closed unless you explicitly enable it where a shell is intended.
Explicit verify
Nothing merges on good intentions. The host calls worker_verify, inspects the exact diff, and runs tests and lint with its own tools before accepting anything.
No open servers
A remote OpenCode server stays behind HTTPS, auth, and a firewall. Localhost stays on 127.0.0.1 unless you know why it should not.
Deployment, rotation, and rollback steps live in the operations docs.
08 // Registry
Listed. Self-host for anything real.
No official registry approval is claimed: no MCP Registry approval, no vendor approval, no OAuth flow, no hosting. A listing points at the repo and docs; it never grants access and never supplies a token. The repo and README are the source of truth. Publication checklist: docs/registry.md.
MCP Registry
Metadata lives as
server.jsonin the repo (io.github.ManuOtel/opencode-mcp-bridge). Not submitted or approved by this change.Smithery
Static bearer auth, no OAuth login flow. URL publishing is a dashboard/CLI flow with the token supplied out of band.
Glama
Until a listing is confirmed, the repo and README are the source of truth.
// open source