<h1 align="center">Super Subagents for OpenCode</h1>

<h3 align="center">Spawn parallel autonomous AI agents from any MCP client.</h3>

<p align="center">
  Each agent gets its own isolated OpenCode session with full tool access (file read/write, terminal, search). Your main session stays unblocked while agents code, plan, research, and test simultaneously.
</p>

<p align="center">
  <a href="https://www.npmjs.com/package/mcp-subagents-opencode"><img src="https://img.shields.io/npm/v/mcp-subagents-opencode?style=flat-square&color=cb3837&label=npm" alt="npm"></a>
  <img src="https://img.shields.io/node/v/mcp-subagents-opencode?style=flat-square&color=339933&label=node" alt="node 18+">
  <a href="https://github.com/yigitkonur/mcp-subagents-opencode/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="license MIT"></a>
  <img src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey?style=flat-square" alt="platform">
  <img src="https://img.shields.io/badge/backend-OpenCode-purple?style=flat-square" alt="OpenCode backend">
</p>

<p align="center">
  <img src="https://img.shields.io/badge/4_tools-spawn%20%C2%B7%20message%20%C2%B7%20cancel%20%C2%B7%20answer-brightgreen?style=flat-square" alt="4 tools">
  <img src="https://img.shields.io/badge/4_roles-coder%20%C2%B7%20planner%20%C2%B7%20researcher%20%C2%B7%20tester-orange?style=flat-square" alt="4 roles">
  <img src="https://img.shields.io/badge/32_templates-16%20lang%20%2B%2016%20specialty-blue?style=flat-square" alt="32 templates">
</p>

---

## Quick Navigation

[Prerequisites](#prerequisites) &#8226; [Quick Install](#quick-install) &#8226; [How It Works](#how-it-works) &#8226; [Tools](#tool-reference) &#8226; [Templates](#agent-templates) &#8226; [Configuration](#environment-variables) &#8226; [Transport Modes](#transport-modes) &#8226; [Troubleshooting](#troubleshooting)

---

## Prerequisites

This MCP server delegates work to an [OpenCode](https://opencode.ai) headless server. Start it before spawning agents:

```bash
# Install OpenCode (if not already installed)
curl -fsSL https://opencode.ai/install | bash

# Start the headless server
opencode serve
```

Verify it's running:

```bash
curl -s -H 'Accept: application/json' http://127.0.0.1:19747/session | head -c 100
```

> OpenCode must have at least one AI provider configured (Anthropic, OpenAI, etc). The MCP server lets OpenCode pick the model internally.

---

## Quick Install

No cloning needed. Install directly from npm with a single command for your client.

### Claude Code (CLI)

```bash
claude mcp add supersubagents -- npx -y mcp-subagents-opencode
```

With a custom OpenCode URL:

```bash
claude mcp add supersubagents \
  -e OPENCODE_BASE_URL=http://127.0.0.1:19747 \
  -- npx -y mcp-subagents-opencode
```

Scoped installs:

```bash
# Project scope -- shared via .mcp.json (checked into git)
claude mcp add supersubagents --scope project -- npx -y mcp-subagents-opencode

# User scope -- available in all your projects
claude mcp add supersubagents --scope user -- npx -y mcp-subagents-opencode
```

Or point to the HTTP transport:

```bash
claude mcp add supersubagents --transport http http://127.0.0.1:51997/mcp
```

<details>
<summary>Verify / remove</summary>

```bash
claude mcp list
claude mcp get supersubagents
claude mcp remove supersubagents
```

</details>

---

### Claude Desktop

Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "supersubagents": {
      "command": "npx",
      "args": ["-y", "mcp-subagents-opencode"],
      "env": {
        "OPENCODE_BASE_URL": "http://127.0.0.1:19747"
      }
    }
  }
}
```

Restart Claude Desktop after saving.

---

### Cursor

Create `.cursor/mcp.json` in your project root (or `~/.cursor/mcp.json` for global):

```json
{
  "mcpServers": {
    "supersubagents": {
      "command": "npx",
      "args": ["-y", "mcp-subagents-opencode"],
      "env": {
        "OPENCODE_BASE_URL": "http://127.0.0.1:19747"
      }
    }
  }
}
```

Or via HTTP transport:

```json
{
  "mcpServers": {
    "supersubagents": {
      "type": "streamable-http",
      "url": "http://127.0.0.1:51997/mcp"
    }
  }
}
```

---

### VS Code + GitHub Copilot

Create `.vscode/mcp.json` in your workspace:

```json
{
  "mcpServers": {
    "supersubagents": {
      "command": "npx",
      "args": ["-y", "mcp-subagents-opencode"],
      "env": {
        "OPENCODE_BASE_URL": "http://127.0.0.1:19747"
      }
    }
  }
}
```

> Requires VS Code 1.101+ with Copilot extension.

---

### Windsurf

Edit `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "supersubagents": {
      "command": "npx",
      "args": ["-y", "mcp-subagents-opencode"],
      "env": {
        "OPENCODE_BASE_URL": "http://127.0.0.1:19747"
      }
    }
  }
}
```

Or via Settings UI: `Cmd+Shift+P` > "Open Windsurf Settings" > Advanced Settings > Cascade > MCP.

---

### OpenAI Codex CLI

Edit `~/.codex/config.toml`:

```toml
[[mcp.servers]]
name = "supersubagents"
command = "npx"
args = ["-y", "mcp-subagents-opencode"]

[mcp.servers.env]
OPENCODE_BASE_URL = "http://127.0.0.1:19747"
```

Or via command:

```bash
codex mcp add --transport stdio supersubagents -- npx -y mcp-subagents-opencode
```

---

### Any MCP Client (HTTP mode)

Start the server in HTTP mode, then point your client to the URL:

```bash
npx -y mcp-subagents-opencode
# Set MCP_TRANSPORT=http to use HTTP instead of stdio:
MCP_TRANSPORT=http npx -y mcp-subagents-opencode
# → Listening on http://127.0.0.1:51997/mcp
```

Then configure your client to connect to `http://127.0.0.1:51997/mcp`.

---

## How It Works

```
You (main session):  "Spawn three agents: refactor auth, write tests, research pagination"

  brave-tiger-42:    Refactoring auth module...          [running]
  calm-falcon-17:    Writing API integration tests...    [running]
  swift-panda-88:    Researching pagination patterns...  [running]

You:                 Continue working on other things -- or spawn more agents.
```

Each agent runs as an isolated OpenCode headless session. When it finishes, results appear in MCP resources and output files. Task IDs are human-readable (`brave-tiger-42`, `calm-falcon-17`) for easy tracking.

### Architecture

```
MCP Client (Claude Code, Cursor, VS Code, Windsurf, Codex, etc.)
    |
    v
mcp-subagents-opencode (this server -- via npx or self-hosted)
    |
    v
OpenCode Headless Server (HTTP API on :19747)
    |
    v
AI Provider (Anthropic, OpenAI, etc. -- configured in OpenCode)
```

---

## Tool Reference

4 MCP tools for agent orchestration:

| Tool | Purpose |
|---|---|
| **`spawn_agent`** | Create a new autonomous agent with role, prompt, and context files |
| **`send_message`** | Follow up on an existing task ("now add tests", or just "continue") |
| **`cancel_task`** | Cancel one task, multiple tasks, or clear all |
| **`answer_question`** | Respond when an agent asks a clarifying question |

### `spawn_agent`

| Parameter | Type | Required | Description |
|---|---|---|---|
| `role` | `coder` `planner` `tester` `researcher` | Yes | Agent specialization |
| `prompt` | string | Yes | Complete self-contained instructions |
| `context_files` | `[{path, description}]` | Coder/tester: yes | Files to inject into context (max 20) |
| `specialization` | string | No | Language/framework overlay (e.g. `typescript`, `react`, `playwright`) |
| `model` | string | No | `claude-sonnet-4.5` (default), `claude-haiku-4.5`, or `claude-opus-4.6` |
| `cwd` | string | No | Working directory (absolute path) |
| `timeout` | number | No | Max duration in ms (default: 1,800,000 = 30 min) |
| `depends_on` | string[] | No | Task IDs that must complete first |
| `labels` | string[] | No | Labels for grouping/filtering (max 10) |

```json
{
  "role": "coder",
  "prompt": "Refactor /src/auth.ts to use JWT refresh tokens. Read the file first, then implement...",
  "context_files": [{"path": "/src/auth.ts", "description": "Current auth implementation"}],
  "specialization": "typescript",
  "labels": ["backend", "auth"]
}
```

### `send_message`

| Parameter | Type | Required | Description |
|---|---|---|---|
| `task_id` | string | Yes | Task ID to continue |
| `message` | string | No | Follow-up instruction (default: `"continue"`) |

```json
{"task_id": "brave-tiger-42", "message": "Now add unit tests for the changes you made"}
```

### `cancel_task`

```json
{"task_id": "brave-tiger-42"}
{"task_id": ["brave-tiger-42", "calm-falcon-17"]}
{"task_id": "all", "clear": true, "confirm": true}
```

### `answer_question`

```json
{"task_id": "brave-tiger-42", "answer": "2"}
{"task_id": "brave-tiger-42", "answer": "CUSTOM: Use TypeScript instead"}
```

---

## MCP Resources

Live status monitoring without polling:

| Resource URI | Content |
|---|---|
| `system:///status` | OpenCode connection, task counts by status, pending questions |
| `task:///all` | All tasks with IDs, statuses, labels, session IDs, timestamps |
| `task:///{id}` | Single task detail: progress, output tail, error info, model, CWD |

Resources support subscriptions (`resources/subscribe`) for real-time change notifications.

### Output Files

Every task streams its execution log to `{cwd}/.super-agents/{task-id}.output`:

```bash
tail -f .super-agents/brave-tiger-42.output    # Follow live
tail -20 .super-agents/brave-tiger-42.output   # Last 20 lines
```

---

## Agent Templates

Templates provide specialized system prompts. Your prompt is wrapped with role-specific instructions.

| Role | Template | Behavior |
|---|---|---|
| `coder` | `super-coder` | "Think 10 times, write once." Searches codebase before changes. Verifies after. |
| `planner` | `super-planner` | "Plan with evidence." Explores first, designs atomic tasks. Always uses opus. |
| `researcher` | `super-researcher` | "Find truth, not confirmation." Multi-angle investigation. |
| `tester` | `super-tester` | "Test like a user." E2E first, then integration, then unit. |

### Specialization Overlays

Add a `specialization` to get language/framework-specific instructions layered on top:

**Coder:** `typescript` `python` `react` `nextjs` `vue` `go` `rust` `java` `kotlin` `swift` `ruby` `csharp` `tauri` `supabase` `supastarter` `triggerdev`

**Planner:** `feature` `bugfix` `migration` `refactor` `architecture`

**Tester:** `playwright` `rest` `graphql` `suite`

**Researcher:** `security` `library` `performance`

```json
{"role": "coder", "specialization": "react", "prompt": "Build a dashboard component..."}
```

---

## Models

| Model | Usage |
|---|---|
| `claude-sonnet-4.5` | **Default.** Best balance of speed and capability. |
| `claude-haiku-4.5` | Fast, simple tasks. Quick iterations. |
| `claude-opus-4.6` | Complex reasoning. Set `ENABLE_OPUS=true` to show in tool descriptions. Always available via alias. |

> `planner` role always uses `claude-opus-4.6` regardless of the `model` parameter.

---

## Task Dependencies

Chain tasks with `depends_on`. Dependent tasks wait in `waiting` status until all dependencies complete.

```
spawn_agent(role: "planner")  --> plan-tiger-42         [running]
spawn_agent(role: "coder",
  depends_on: ["plan-tiger-42"])  --> code-falcon-17    [waiting]
spawn_agent(role: "tester",
  depends_on: ["code-falcon-17"]) --> test-panda-88     [waiting]

plan-tiger-42 completes   --> code-falcon-17 auto-starts
code-falcon-17 completes  --> test-panda-88 auto-starts
```

Circular dependencies are detected and rejected at spawn time.

---

## Task Lifecycle

```
pending --> running --> completed
                   --> failed
                   --> cancelled
                   --> timed_out
                   --> rate_limited --> (auto-retry) --> pending --> running

pending --> waiting (dependencies) --> pending --> running
```

---

## Environment Variables

| Variable | Default | Description |
|---|---|---|
| `OPENCODE_BASE_URL` | `http://127.0.0.1:19747` | OpenCode headless server URL |
| `OPENCODE_SERVER_USERNAME` | -- | Basic auth username (if OpenCode requires it) |
| `OPENCODE_SERVER_PASSWORD` | -- | Basic auth password |
| `ENABLE_OPUS` | `false` | Show `claude-opus-4.6` in tool descriptions |
| `MCP_TRANSPORT` | `stdio` | Transport mode: `stdio` or `http` |
| `MCP_PORT` | `51997` | HTTP transport port (when `MCP_TRANSPORT=http`) |
| `MCP_TASK_TIMEOUT_MS` | `1800000` (30 min) | Default task timeout |
| `MCP_TASK_TIMEOUT_MAX_MS` | `3600000` (1 hr) | Maximum allowed timeout |
| `MCP_TASK_STALL_WARN_MS` | `300000` (5 min) | No-output warning threshold |
| `DEBUG_NOTIFICATIONS` | `false` | Log MCP notification errors to stderr |

---

## Transport Modes

| Mode | Best For | How to Start |
|---|---|---|
| **STDIO** (default) | Claude Code, Claude Desktop, Cursor, VS Code | `npx -y mcp-subagents-opencode` |
| **HTTP Streamable** | Self-hosted, Docker, multi-client, LAN sharing | `MCP_TRANSPORT=http npx -y mcp-subagents-opencode` |

> **STDIO caveat:** STDIO transport closes when the MCP client disconnects. Tasks that are still running continue in the OpenCode server, but MCP notifications can't be delivered until the client reconnects. Output files are always written regardless of transport.

### HTTP Transport

```bash
MCP_TRANSPORT=http npx -y mcp-subagents-opencode
# Listening on http://127.0.0.1:51997/mcp
```

Custom port:

```bash
MCP_TRANSPORT=http MCP_PORT=8080 npx -y mcp-subagents-opencode
```

Endpoints:
- `POST /mcp` -- MCP Streamable HTTP (session management)
- `GET /health` -- Health check (JSON)

---

## Development

```bash
git clone https://github.com/yigitkonur/mcp-subagents-opencode.git
cd mcp-subagents-opencode

npm install
npm run build    # TypeScript compile + copy MDX templates

# Watch mode
npm run dev

# Run
npm start
```

### Project Structure

```
src/
  index.ts                          # Bootstrap, transport setup
  models.ts                         # Model definitions and resolution
  types.ts                          # Core type definitions
  tools/
    spawn-agent.ts                  # spawn_agent tool
    send-message.ts                 # send_message tool
    cancel-task.ts                  # cancel_task tool
    answer-question.ts              # answer_question tool
    shared-spawn.ts                 # Shared spawn logic
  services/
    opencode-client.ts              # OpenCode HTTP API client
    opencode-spawner.ts             # Session creation and message dispatch
    task-manager.ts                 # Task lifecycle, persistence, output files
    retry-queue.ts                  # Exponential backoff retry (5m->2h, 6 retries)
    question-registry.ts            # Pending question tracking
    client-context.ts               # MCP client roots and CWD
    task-persistence.ts             # JSON persistence to ~/.super-agents/
    output-file.ts                  # Output file writer
  server/
    register-tools.ts               # MCP tool handler registration
    register-tasks.ts               # MCP task primitive handlers
    register-resources.ts           # MCP resource handlers
    register-notifications.ts       # Change notification wiring
    register-retry-execution.ts     # Retry and execution callbacks
  templates/
    index.ts                        # Template loader
    super-coder.mdx                 # 4 base role templates
    overlays/                       # 28 specialization overlays
      coder-typescript.mdx
      planner-feature.mdx
      tester-playwright.mdx
      researcher-security.mdx
      ...
  config/
    timeouts.ts                     # Timeout constants
  utils/
    format.ts                       # Output formatting
    sanitize.ts                     # Input validation
    task-id.ts                      # Human-readable ID generator
```

---

## Troubleshooting

<details>
<summary><strong>Tasks fail with "OpenCode server not available"</strong></summary>

The OpenCode headless server must be running before spawning agents.

```bash
# Start OpenCode
opencode serve

# Verify
curl -s -H 'Accept: application/json' http://127.0.0.1:19747/session | head -c 100
```

Make sure `OPENCODE_BASE_URL` matches the port OpenCode is running on.

</details>

<details>
<summary><strong>Tasks spawn but results never appear (STDIO mode)</strong></summary>

STDIO transport closes when the MCP client disconnects. The task continues running in OpenCode, but MCP can't deliver notifications.

**Solutions:**
1. Check the output file directly: `tail -f .super-agents/{task-id}.output`
2. Use HTTP transport for persistent sessions: `MCP_TRANSPORT=http`
3. Reconnect and read the resource: `task:///{task-id}`

</details>

<details>
<summary><strong>Empty or no response from agents</strong></summary>

- Verify OpenCode has a configured AI provider (Anthropic API key, etc.)
- Check the OpenCode server logs for errors
- Try a simple test: `curl -X POST http://127.0.0.1:19747/session` to verify session creation works

</details>

<details>
<summary><strong>Agent produces poor results</strong></summary>

- Agents run in isolation -- your prompt is their **ONLY** context. Include all file paths, background, and success criteria.
- For coders: provide at least 1000 characters with OBJECTIVE, FILES, CRITERIA, CONSTRAINTS, PATTERNS.
- Attach `context_files` with `.md` plans or specifications.
- Use `specialization` to activate language-specific templates (e.g., `typescript`, `react`).

</details>

<details>
<summary><strong>How to check running tasks</strong></summary>

```bash
# Via output files
ls -la .super-agents/*.output
tail -f .super-agents/brave-tiger-42.output
```

Or read MCP resources: `system:///status`, `task:///all`, `task:///{id}`

</details>

---

<p align="center">
  <strong>MIT License</strong> &mdash; <a href="https://github.com/yigitkonur">Yigit Konur</a>
</p>
