subagent-cockpit-mcp
Integrates with Google Antigravity as a coding subagent, enabling tasks such as drafting release notes, with accept-edits, plan, and auto modes.
Integrates with OpenAI Codex as a coding subagent, allowing the main agent to delegate implementation tasks, collect results, handle approvals, and manage sessions.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@subagent-cockpit-mcp Have the coder add rate limiting, then have the reviewer and security review the diff"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
subagent-cockpit-mcp
One MCP server, six coding agents from six vendors: OpenAI Codex, Claude Code, Grok, OpenCode, Google Antigravity and Pi.
Let the agent you already use (Claude Code, Codex CLI, Cursor, any MCP client) hand work to the other coding agents on your machine. One writes the code, the others review it, test it and draft the release notes.
Mix vendors. Each role gets the agent and model that suits it, all behind the same 17 tools.
Work in parallel.
prompt(wait: false)sends tasks to several agents at once,statusandoutputcollect the results.Keep context. Review findings go back to the session that wrote the code. Reconnect to a session by id days later.
Stay in charge. Approvals and questions come back to the main agent, and
allowlasts for one session only.No screen scraping. Every agent runs over the Agent Client Protocol (ACP).
Watch it live. A read-only page at
http://127.0.0.1:7200shows every session as it runs.
Web UI
Open http://127.0.0.1:7200 to watch the sessions: replies as they stream, tool calls with their diffs, plans, approvals and questions, plus a protocol log of every raw ACP message.
Read-only. The page watches and never acts. Approvals and answers still go through the tools.
Starts and stops by itself. The first MCP server that finds the port free starts it, and every server on the machine reports to the same page. It exits about 10 seconds after the last server goes away.
Memory only. Nothing is written to disk. A web UI started again shows the sessions that are still open, not the old messages.
Port.
"webui": { "port": 7200 }in the config, orSUBAGENT_COCKPIT_WEBUI_PORT, which wins.0turns it off. When another program holds the port, the server says so on stderr and runs without the web UI.Privacy. The page shows the ACP messages as sent, prompts and
argsincluded. It listens on 127.0.0.1 only, but other users of the same machine can open it.Font. The conversation tab is monospace. Install Sarasa Mono SC (or Noto Sans Mono CJK SC) and Chinese lines up with Latin text at exactly two columns per character; without it Chinese falls back to the system font.
Related MCP server: subturn
Quick start
Install Node.js 22+ and the agents you want, and log in to each. The server never downloads them.
Agent
Version
Install
OpenAI Codex
0.160.1+
brew install --cask codexornpm i -g @openai/codexAnthropic Claude Code
2.1.292+
brew install --cask claude-codeor the official installerxAI Grok Build
1.0.46+
brew install --cask grok-buildOpenCode
2.0.30+
brew install opencode(the 1.xopencode-aion npm is not supported)Google Antigravity
1.4.2+
brew install --cask antigravity-cli, then runagyonce to sign inEarendil Pi
1.4.0+
brew install pi-coding-agentornpm i -g @earendil-works/pi-coding-agent(Node 22.19+), then runpiand/login, or give it a provider key inenvAdd the server to your MCP client:
claude mcp add subagent-cockpit -- npx -y subagent-cockpit-mcpClaude Code asks before each MCP tool call. To let it drive the subagents without asking, allow the whole server in
~/.claude/settings.jsonor the project's.claude/settings.json:{ "permissions": { "allow": ["mcp__subagent-cockpit"] } }Codex CLI (
~/.codex/config.toml):[mcp_servers.subagent-cockpit] command = "npx" args = ["-y", "subagent-cockpit-mcp"] tool_timeout_sec = 1800 # default 60, longer means fewer status checks default_tools_approval_mode = "approve" # needed for `codex exec`Cursor (
.cursor/mcp.jsonor~/.cursor/mcp.json):{ "mcpServers": { "subagent-cockpit": { "command": "npx", "args": ["-y", "subagent-cockpit-mcp"] } } }Give each agent a role in
~/.subagent-cockpit/config.json(created on first start):"subagents": { "coder": { "adapter": "codex", "role": "You implement changes in this repository." }, "reviewer": { "adapter": "claude", "mode": "plan", "role": "You review diffs. Report findings, do not edit files." }, "security": { "adapter": "grok", "role": "You look for security issues in diffs. Do not edit files." }, "tester": { "adapter": "opencode", "role": "You run the test suite and report failures." }, "docs": { "adapter": "antigravity", "model": "gemini-3.8-flash", "role": "You draft release notes as text. Do not edit files." }, "unit": { "adapter": "pi", "model": "anthropic/claude-sonnet-5-5", "role": "You write unit tests for new code." } }Ask your main agent:
Use subagent-cockpit. Have the coder add rate limiting to the API and the unit subagent write tests for it. Have the reviewer and the security subagent review the diff, and send their findings back to the coder until both pass. Then have the tester run npm test, ask the docs subagent for release notes, and report.
Supported agents
Agent | Connected through | Approvals | Questions |
|
Codex | bundled | yes | in | archives |
Claude Code | bundled | yes |
| deletes the transcript |
Grok Build | grok's own ACP | yes | plain text only | deletes the session files |
OpenCode | opencode's own ACP | yes |
| deletes the session |
Antigravity | bundled bridge over | denied by agy, see notes | skipped by agy | not supported |
Pi | bundled bridge over | never asked, see notes | not asked | deletes the session file |
Verified with codex 0.162.1, claude 2.1.292, grok 1.0.46, opencode 2.0.30, agy 1.4.3 and pi 1.4.0. There is no upper version bound. A release that breaks the protocol fails with AGENT_ERROR until the server is updated. This is the ACP rewrite of subagent-cli.
Tools
Group | Tools |
Prompt |
|
Approvals |
|
Questions |
|
Snapshot |
|
Sessions |
|
Config |
|
prompt, approve, allow, reject and answer wait as long as the turn takes and return done with the output, approval_needed or question_needed. Pass wait: false to return right away. The server never times out a turn. If your client gives up first, the turn keeps running, and status and output pick it up.
open with reuse: true takes an idle session of this server with the same cwd and subagent, else reconnects the latest closed one on disk. If that one cannot be reconnected, you get a new session and a reuse_skipped note, and the broken one is not picked again.
snapshot returns the conversation exactly as the Web UI shows it: prompts, replies, thinking, tool calls with their input, output and diffs, plans, approvals, questions and agent-specific messages, one item each, plus every session's state and pending notifications. Narrow it down when you only need part of it:
{ "session": "codex_019a…", "types": ["tool"], "last": 5 }
{ "session": "codex_019a…", "exclude_types": ["thought", "raw"] }
{ "since": 1287, "server_id": "f3c1…" }types keeps and exclude_types drops item kinds (prompt, message, thought, tool, plan, turn and the rest), last takes the last few, and since with the seq and server_id of the previous call returns only what changed. reset: true means start over from the items returned.
A UI client that polls passes simplify: true. Tool calls then come with their title, status and paths only, and each session without its slash commands. It fetches the rest of one item when the person opens it:
{ "simplify": true, "since": 1287, "server_id": "f3c1…" }
{ "session": "codex_019a…", "id": "tool:call_2" }The second line is the item call. An item that is no longer kept fails with ITEM_NOT_FOUND.
Configuration
~/.subagent-cockpit/config.json is created on first start with one entry per agent. An entry using every field:
{
"idle": { "timeout": 0 },
"webui": { "port": 7200 },
"subagents": {
"reviewer": {
"adapter": "claude",
"description": "Reviews diffs",
"role": "You review diffs. Report findings, do not edit files.",
"model": "opus",
"reasoning_effort": "high",
"mode": "plan",
"path": "/opt/homebrew/bin/claude",
"args": ["--add-dir", "/data"],
"env": { "CLAUDE_CONFIG_DIR": "/path/to/claude-config", "ANTHROPIC_API_KEY": "${ANTHROPIC_API_KEY}" }
}
}
}A subagents object you write replaces the default entries as a whole. idle.timeout closes sessions idle that many seconds. The default 0 never closes them, since the server and its agents exit with your MCP client anyway. A session closed this way comes back by itself on the next prompt or set_config, settings included; status meanwhile reports it CLOSED. webui.port is the Web UI port, 0 for none. SUBAGENT_COCKPIT_HOME moves the whole ~/.subagent-cockpit directory.
The Web UI and snapshot keep the latest 5000 ACP messages per session, and show any message over 1 MB (1048576 bytes) as a truncation marker. Each has its own setting, in bytes and counts:
{
"webui": { "port": 7200, "truncate_message_size": 1048576, "max_message_count": 5000 },
"snapshot": { "truncate_message_size": 1048576, "max_message_count": 5000 }
}Conversation items go with the messages behind them. The Web UI keeps the max_message_count of the server that started it.
Field | Meaning |
|
|
| Shown by the |
| Role prompt sent to every new session |
| Initial settings for new sessions (Claude and OpenCode call the effort |
| The agent program. Empty means look it up in |
| Extra command-line args and environment. |
| Settings shared by several subagents, see below |
Agent |
|
|
Codex |
| ignored |
Claude Code |
| passed to claude, e.g. |
Grok | not supported | between |
OpenCode |
| after |
Antigravity |
| on the |
Pi | not supported | on the |
Clients started from a desktop app may hand the server a PATH without /opt/homebrew/bin. Set path then.
Profiles
A profile holds settings that several subagents share. A subagent names it in profile and overrides what it needs:
"profiles": {
"gateway": { "env": { "ANTHROPIC_BASE_URL": "https://example.com", "ANTHROPIC_AUTH_TOKEN": "${GATEWAY_TOKEN}" } }
},
"subagents": {
"claude": { "adapter": "claude", "profile": "gateway" },
"claude-fast": { "adapter": "claude", "profile": "gateway", "model": "haiku" }
}Plain fields come from the subagent when set, else from the profile. env merges by name and args by --flag, with the subagent winning. A profile cannot name another profile, and a missing one fails with PROFILE_NOT_FOUND.
Credentials and gateways
The server never logs in and never stores credentials. Each agent uses its own login unless the subagent env says otherwise. On AUTH_REQUIRED, log in with the agent's CLI or fix env.
Claude Code:
ANTHROPIC_API_KEY, orANTHROPIC_BASE_URLwithANTHROPIC_AUTH_TOKEN.CLAUDE_CONFIG_DIRgives a subagent its own config directory.Codex: a custom provider goes in the
config.tomlof a separateCODEX_HOME, with its key inenv, e.g.{ "CODEX_HOME": "/path/to/codex-home", "OPENAI_API_KEY": "${MY_KEY}" }.DEFAULT_AUTH_REQUESTmakes codex-acp log in by itself and save the key inCODEX_HOME/auth.json.Grok: a custom endpoint goes in the
config.tomlof a separateGROK_HOME, withXAI_API_KEYinenv.OpenCode: point
OPENCODE_CONFIGat a config whoseproviders.openai.settingssetsbaseURLandapiKey({env:VAR}). Add"transport": "http"if the gateway has no WebSocket.Antigravity: signs in only from its own terminal UI. For a second account, set
HOMEinenvand runHOME=/path/to/home agyonce.Pi:
/loginsaves toauth.jsonunderPI_CODING_AGENT_DIR(default~/.pi/agent). A gateway goes inmodels.jsonin the same directory (baseUrl,apiand anapiKeysuch as${MY_KEY}), with the key inenv. SetPI_CODING_AGENT_DIRinenvto give a subagent its own config.
What the agents read from your machine
The server passes settings through and never isolates them.
Claude Code and Grok read your Claude Code settings (including
permissions.defaultMode), plugins and hooks. Isolate Claude Code withCLAUDE_CONFIG_DIR, and Grok with anotherHOMEplus an explicitGROK_HOME.OpenCode reads your Claude Code skills and
CLAUDE.md.OPENCODE_DISABLE_CLAUDE_CODE=1turns that off.Antigravity reads
~/.gemini/antigravity-cli/settings.json(includingpermissions.allow) underHOME.Pi loads skills (also from
~/.agents/skills/and.agents/skills/), extensions, MCP servers,AGENTS.mdandCLAUDE.md.--no-skills,--no-extensions,--no-mcpand--no-context-filesinargsturn them off.
Notes
Questions. A question arrives as
question_neededwith the agent's own form inrequested_schema. Field names differ per agent, so read them from the schema and reply withanswer({ session, question_id, content: { question_0: "Red" } }). Approvals go first when both wait.Approvals. An agent's own "don't ask again" option is usually saved for good, so
allownever picks it. It allows the call once and keeps a rule in the server until the session closes. To have the agent remember it anyway,approvewith that option: Codexaccept_execpolicy_amendment, Claude Codeallow-with-updates, Grokalways-allow, OpenCodealways.Deleting.
deleteremoves the server's session directory and the agent's own session. An open Claude Code session is closed first, which takes a few seconds. agy cannot delete a conversation, so it stays under~/.gemini/antigravity-cli/.Antigravity.
agy -pis headless and never asks. A tool that needs a permission is denied, reading a file outside the session'scwdincluded, and the output ends with a note such asagy denied in headless mode: ReadFile. Either allow the action inpermissions.allowof~/.gemini/antigravity-cli/settings.json, in agy's own form such asread_file(<path>), or let that subagent skip agy's checks:"docs": { "adapter": "antigravity", "args": ["--dangerously-skip-permissions"] }Pi. pi never asks for approval, so every tool it has runs straight away,
bash,editandwriteincluded. Limit the tools inargs, e.g.["--tools", "read,grep,find,ls"]for a read-only subagent.Client timeouts. Codex CLI times out tool calls after 60 seconds unless
tool_timeout_secis set. Claude Code aborts a call after 30 minutes without progress, and the server sends progress every 60 seconds, so long turns survive.
Development
npm install
npm run build && npm run lint && npm test
npm run test:e2e:codex # also :claude, :grok, :opencode, :antigravity, :pi, :concurrent
npm run check:deps # bundled ACP adapters == verified versionsThe diagram is hand-written SVG, assets/overview-light.svg and assets/overview-dark.svg. Keep the two in sync. Product names and logos belong to their owners.
License
Apache-2.0
Available Tools
17 toolsallowA
Allow and stop asking for similar calls in this session only. Uses the agent's session-scoped option when it offers one; otherwise this server allows once and answers matching requests itself until the session closes. Never writes a persistent agent rule. Blocks until the turn is done, needs an approval or asks a question; the server sets no time limit. If your client times out, the turn keeps running and the connection stays: call status for the state and output for the reply instead of sending the task again. Returns "approval_needed" with an approval to answer via approve / allow / reject, or "question_needed" with a question to answer via answer.
Inputs: session (required), approval_id (required), wait. Returns: output, status, outcome, turn_id, +2 more
answerA
Answer a question the agent asked (question_needed). requested_schema is the agent's own form, passed on as sent: with action "accept" (the default), give content as an object whose keys and values follow it. "decline" refuses to answer, "cancel" dismisses the question. Blocks until the turn is done, needs an approval or asks a question; the server sets no time limit. If your client times out, the turn keeps running and the connection stays: call status for the state and output for the reply instead of sending the task again. Returns "approval_needed" with an approval to answer via approve / allow / reject, or "question_needed" with a question to answer via answer.
Inputs: session (required), question_id (required), wait, action, +1 more. Returns: output, status, outcome, turn_id, +2 more
approveA
Allow this one tool call (allow_once), or pick option_id explicitly. Blocks until the turn is done, needs an approval or asks a question; the server sets no time limit. If your client times out, the turn keeps running and the connection stays: call status for the state and output for the reply instead of sending the task again. Returns "approval_needed" with an approval to answer via approve / allow / reject, or "question_needed" with a question to answer via answer.
Inputs: session (required), approval_id (required), wait, option_id. Returns: output, status, outcome, turn_id, +2 more
cancelA
Cancel the current turn. Returns "cancelling" until the agent confirms, or "done" when already idle.
Inputs: session (required). Returns: status
closeA
Close a session, or all sessions of this server when session is omitted. Session history is kept.
Inputs: session. Returns: closed
deleteC
Delete a session and its native agent session (deleted / archived / unsupported).
Inputs: session (required). Returns: native, session
itemA
One conversation item in full, by the id snapshot gave it: a tool call with its input, output and diffs, or any other item. For UI clients that poll snapshot with simplify and show details on demand.
Inputs: id (required), session (required). Returns: item
openA
Open a session: reconnect when session is given; with reuse, take this server's idle session with the same cwd and subagent, else reconnect the latest closed one on disk; otherwise create one. A reuse that cannot reconnect creates a new session and says why in reuse_skipped. Reconnecting puts back the config the session last had (the subagent config, or later set_config changes). Returns once the session is set up (role prompt included), with the session id and the full config_options. It takes no task: send tasks with prompt.
Inputs: cwd (required), subagent (required), role, reuse, +1 more. Returns: output, reused, status, outcome, +6 more
outputC
Final reply of the most recent turn.
Inputs: session (required). Returns: output, turn_id
progressA
The agent's latest execution feedback: its plan, context usage, session title and slash commands. Not needed to run a task; call it only when you want to know. Cheap, never blocks.
Inputs: session (required). Returns: plan, title, usage, commands
promptA
Send a task to an IDLE session. In ASKING or QUESTIONING it returns the pending approval or question instead. A session closed for idleness is reopened first. Blocks until the turn is done, needs an approval or asks a question; the server sets no time limit. If your client times out, the turn keeps running and the connection stays: call status for the state and output for the reply instead of sending the task again. Returns "approval_needed" with an approval to answer via approve / allow / reject, or "question_needed" with a question to answer via answer.
Inputs: text (required), session (required), wait. Returns: output, status, outcome, turn_id, +2 more
rejectA
Reject this tool call (reject_once). Codex and Claude Code continue the turn; Grok and OpenCode end it as cancelled. Blocks until the turn is done, needs an approval or asks a question; the server sets no time limit. If your client times out, the turn keeps running and the connection stays: call status for the state and output for the reply instead of sending the task again. Returns "approval_needed" with an approval to answer via approve / allow / reject, or "question_needed" with a question to answer via answer.
Inputs: session (required), approval_id (required), wait. Returns: output, status, outcome, turn_id, +2 more
sessionsA
List sessions on disk, most recent first, with state, title, last_prompt and last_at. Use it to find a session id after an interrupted open.
Inputs: cwd, status. Returns: sessions
set_configA
Change a session config option (model, reasoning_effort, mode, ...). Returns the full config_options. Unknown ids or values fail with the available choices. A session closed for idleness is reopened first.
Inputs: value (required), session (required), config_id (required). Returns: config_options
snapshotA
Full conversation of open sessions, the same as the webui shows: prompts, replies, thinking, tool calls with their input, output and diffs, plans, approvals, questions and agent-specific messages, plus each session's state and pending notifications. It can be large: pass session, and use last, types or exclude_types to keep it small. Pass back server_id and seq as since to get only what changed. ack is for UI clients that relay notifications. UI clients that poll: pass simplify to leave out tool call details (input, output, content) and session commands, and get one item in full with item.
Inputs: ack, last, since, types, +4 more. Returns: seq, reset, sessions, server_id
statusA
Session state, cancelling flag, current config values, pending approvals and questions, and whether a blocking call is waiting. Cheap to call repeatedly; the config choices are in open, set_config and snapshot. A session closed for idleness reports CLOSED with its last values.
Inputs: session (required). Returns: cwd, state, config, session, +5 more
subagentsB
List configured subagents.
Inputs: no named parameters. Returns: subagents
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 17 tools
Most tools target clearly distinct lifecycle or interaction steps: open/close/delete sessions, prompt, approvals, questions, status, output, and snapshot. Two minor overlaps remain: approve vs allow both permit calls (differing only in one-time vs session scope), and item is essentially a detail view of snapshot. The descriptions do enough to separate them, but an agent could occasionally hesitate.
Names are consistently lowercase snake_case, with only set_config using a multiword form and the rest single tokens. The set mixes action verbs (open, prompt, approve, cancel) with resource/state nouns (subagents, sessions, status, output, snapshot, item), but the style is uniform and readable. It is not a strict verb_noun convention, though it is internally consistent.
Seventeen tools is slightly heavy but reasonable for a session cockpit covering lifecycle, prompts, approvals, questions, config, and conversation inspection. A few tools (progress, item) are optional or UI-polling helpers and could be consolidated, but each has a plausible role. This sits at the low end of the heavy range rather than being overstuffed.
The surface covers the main session lifecycle: list subagents/sessions, open, prompt, approve/allow/reject, answer questions, configure, cancel, inspect status/output/progress, snapshot conversation, and delete. Gaps are minor, such as no tool for defining or editing subagents and no session search/rename operation. Agents can work around these for the core cockpit purpose.
Maintenance
Related MCP Connectors
MCP gateway and cloud hosting for MCP servers, agents and apps like RAG, managed from your agent.
Remote MCP storefront for agent routing, verification, web extraction and x402-paid tools.
Start and manage Reason cloud coding agents, projects and sessions from any MCP client.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables coding agents to discover, message, poll, cancel, and register remote A2A agents via MCP, with an optional read-only local activity dashboard.5MIT
- AlicenseNot gradedqualityBmaintenanceEnables any MCP client to launch and manage subagent sessions in installed coding agents like Codex, Claude Code, Grok, and OpenCode, using your existing logins and chosen models.13 npmMIT
- AlicenseBqualityBmaintenanceEnables any MCP host to delegate work to multiple coding-agent CLIs such as Codex, Claude Code, and Antigravity as subagents, preserving native sessions and supporting team-based supervision and agent-to-agent messaging.179 npmApache 2.0
- AlicenseBqualityBmaintenanceEnables a host coding agent to launch and coordinate real subagent sessions in other agent CLIs and accounts, sharing existing MCP servers, skills, plugins, and instructions. Supports two-way messaging, automatic account failover, and mixed-CLI delegation while leaving credentials with the vendor CLIs.813Apache 2.0