opencode-executor-mcp
by sohryuu101
README.md
# opencode-executor-mcp
MCP server exposing an `ask_opencode` tool that delegates a prompt to an
[OpenCode](https://opencode.ai) agent session. Lets a Claude Code
orchestrator hand off executor-role / bulk work to a cheaper backend
instead of spawning another Claude subagent.
Not tied to any specific provider: by default it uses OpenCode's own
bundled Zen free models (only needs `opencode auth login`, no company
gateway required). If you have a company/paid gateway configured in
OpenCode, pass it explicitly per-call.
```
Claude Code (orchestrator)
-> MCP tool call: ask_opencode(prompt, provider?, model?, sessionId?)
-> this server
-> opencode serve (localhost:4096) REST API
-> whichever provider is selected (default: OpenCode Zen free tier)
```
## Prerequisites
- Node.js 18+ (global `fetch` required)
- [OpenCode CLI](https://opencode.ai) installed
- `opencode auth login` run once (sets up the bundled Zen free-tier
credentials used as the default)
- Optional: any additional provider configured in OpenCode (company
gateway, other API key, etc.) if you want to target something other than
the default free models
## Setup
1. Install dependencies:
```
npm install
```
2. Authenticate OpenCode's default (Zen) provider, if you haven't:
```
opencode auth login
```
3. Start the OpenCode server (must stay running while you use the tool):
```
opencode serve --port 4096
```
4. Verify at least one provider is live:
```
curl -s http://127.0.0.1:4096/config/providers | jq
```
You should see a provider with id `opencode` (the bundled Zen models).
Any additional provider you've configured will show up alongside it.
5. Register this server with Claude Code. Add to `~/.claude.json` under
`mcpServers` (see `docs/claude-code-integration.md` for the exact block):
```json
"opencode-executor": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/to/opencode-mcp/index.js"]
}
```
6. Restart Claude Code. The `ask_opencode` and `list_opencode_models` tools
are now available.
## Usage
```
list_opencode_models()
# -> [{ providerID: "opencode", modelID: "big-pickle", name: "Big Pickle", bundled: true }, ...]
ask_opencode({ prompt: "summarize this log file" })
# uses the default bundled Zen model
ask_opencode({ prompt: "...", provider: "my-provider", model: "some-model-id" })
# targets a specific configured provider instead
```
Omit `sessionId` for a fresh one-off session (no memory of prior calls).
Pass the `sessionId` returned by a previous `ask_opencode` call to continue
that same conversation — OpenCode retains the history, so the model sees
prior turns. This is still call-and-response driven by Claude Code calling
the tool each turn; OpenCode never initiates on its own.
Calls can be issued concurrently (fan-out / swarm) since each session is
independent unless you deliberately reuse a `sessionId`; see
`docs/architecture.md`.
## Configuration
| Env var | Default | Purpose |
|---|---|---|
| `OPENCODE_URL` | `http://127.0.0.1:4096` | Base URL of the running `opencode serve` instance |
| `OPENCODE_PROVIDER` / `OPENCODE_MODEL` | unset | Pin a default provider/model for every call that doesn't specify one, instead of auto-picking the bundled Zen provider |
## Troubleshooting
See `docs/troubleshooting.md`.
## Docs
- [`docs/architecture.md`](docs/architecture.md) — how the pieces fit together, why this shape
- [`docs/claude-code-integration.md`](docs/claude-code-integration.md) — wiring into Claude Code's `mcpServers` config
- [`docs/troubleshooting.md`](docs/troubleshooting.md) — common failures and fixes
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues