subagent-mcp
Manages detached tmux windows and panes where subagents run, including pane creation, output capture, liveness checks, and sending Ctrl-C.
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-mcpLaunch claude in ~/myapp to add user authentication"
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-mcp
An MCP server that collapses "launch a coding assistant in a tmux window" into one tool call.
Driving a TUI coding CLI from another agent is normally a ceremony: open a
window, send the command, wait for the TUI to boot, load a paste buffer, paste,
wait again, press Enter, then poll capture-pane to see what happened. Most of
that is unnecessary — both claude and opencode accept the prompt on the
command line — and the rest is bookkeeping a server should be doing for you.
launch_subagent does the whole thing and hands back a handle.
Requires tmux and at least one of claude / opencode installed (see
Finding the CLI — it does not have to be on the server
process's PATH).
Tools
launch_subagent— startclaudeoropencodein a tmux windowcheck_subagent— capture the last N lines of output from a running subagentwatch_subagent— put a running subagent on screen (or report how to attach)list_subagents— list all launched subagents and whether their panes are alivesend_to_subagent— paste a follow-up message into a live subagentstop_subagent— sendCtrl-C(or kill the tmux window)sweep_stale_subagents— delete run records for subagents whose panes are gone
launch_subagent takes prompt (or prompt_file), cwd, cli, and optional
session / window / task / model / agent / extra_args. Every launch
gets a directory under runs/ holding prompt.md, meta.json, and the
generated run.sh — so any subagent can be re-run by hand, and the prompt is
never lost to a scrollback buffer.
Handles are interchangeable: a run_id, a tmux pane id (%12), or a
session:window target all resolve to the same run.
Watching a subagent
Runs are detached by default — that is what makes fanning out cheap, but it also
means nothing appears on screen. Pass watch to launch_subagent (or call
watch_subagent on a run that is already going) to change that:
| Effect |
| Detached. The response still carries |
| Pulls your already-attached tmux client to the new window. |
| Opens a terminal emulator attached to the window. |
switch is the one to reach for if you live inside tmux; it is a no-op that
reports why when no client is attached, and it never fails a launch — the
subagent is running either way, visibility is best-effort.
--watch-default / SUBAGENT_WATCH_DEFAULT makes a mode the default for every
launch, so "always show me what it's doing" is a server setting, not something
to remember per call.
Every response also hands back:
attach_command—tmux attach -t sess:winattach_read_only— the same with-r, so watching cannot disturb the runoutput_log—<run_dir>/output.log, apipe-panetee of everything the pane printed.tail -fit to follow a run without attaching, and read it afterwards for output that has already scrolled out of the pane's scrollback. Disable with--no-pipe-logs.
terminal autodetects kitty, wezterm, ghostty, alacritty, foot,
gnome-terminal, konsole, xfce4-terminal, x-terminal-emulator, and xterm. Set
SUBAGENT_TERMINAL to a template containing {cmd} to override, e.g.
kitty -- bash -c {cmd}. It needs DISPLAY/WAYLAND_DISPLAY in the server's
environment; without one it reports that and leaves the run detached.
Finding the CLI
The subagent inherits the environment of whatever started the MCP server, which
is often a desktop launcher with a stripped PATH — so a perfectly working
opencode on your shell's PATH would die in the pane with command not found (exit 127). The server therefore resolves the CLI to an absolute path
before launching, searching PATH plus the usual per-user install roots
(~/.opencode/bin, ~/.claude/local, ~/.local/bin, ~/.bun/bin,
~/.cargo/bin, /usr/local/bin, /opt/homebrew/bin, nvm's newest node), and
exports that widened PATH inside run.sh for the CLI's own helpers.
If it still cannot find one, the launch fails immediately with the list of
directories searched, instead of leaving you a dead pane. Point it at a binary
explicitly with SUBAGENT_CLI_OPENCODE / SUBAGENT_CLI_CLAUDE.
Blocked detection
A launched CLI can sit waiting on a human instead of working — the folder-trust
prompt on a directory claude hasn't seen before, a login screen, or a
mid-run permission modal. A pane in that state still looks alive, so
launch_subagent and check_subagent both report blocked and
blocked_reason.
The detector matches verbatim CLI chrome, line by line, and skips lines that came from the submitted prompt — the TUI echoes it back, so without that a prompt like "fix the authentication bug" would report itself as blocked.
Note that --dangerously-skip-permissions does not bypass the folder-trust
prompt. Trust the directory once by hand, or expect blocked: true.
Related MCP server: mcp-tmux
Running
uv sync
# stdio (for an MCP client)
.venv/bin/subagent-mcp --stdio --runs-root ./runs
# HTTP for poking
.venv/bin/subagent-mcp --http --port 8100Options
Every flag has a matching environment variable.
Flag | Env | Default | Meaning |
|
|
| Parent dirs a subagent |
| — | off | Disable the |
|
|
| CLIs the server will invoke |
|
|
| Cap on live launched panes |
|
|
| Where per-run artefacts go |
|
|
| Keep at most this many run dirs ( |
|
|
| Delete run dirs older than this ( |
|
| default socket | Use a private tmux server |
|
|
| Default visibility: |
|
| autodetect | Terminal template for |
|
| off | Stop teeing pane output into |
— |
| autodetect | Absolute path to a CLI binary |
|
|
| HTTP transport only |
Retention runs on launch — the only operation that grows runs/. Both limits
count every run on disk, but a run whose pane is still alive is never deleted.
sweep_stale_subagents is the on-demand complement: it reaps run directories
whose panes are no longer alive (the dead records list_subagents reports as
alive: false). Pass dry_run=true to preview what would be cleared, or
session="atlas" to scope it to one tmux session. Live subagents are never
touched.
Client registration
"subagent": {
"command": [
"/path/to/subagent-mcp/.venv/bin/subagent-mcp",
"--stdio",
"--runs-root", "/path/to/subagent-mcp/runs"
],
"cwd": "/path/to/subagent-mcp",
"transport": "stdio",
"description": "Launch and supervise coding-CLI subagents (claude, opencode) in detached tmux windows."
}Safety
This is intentionally an unsandboxed, permission-checks-off subagent launcher.
It runs coding agents with --dangerously-skip-permissions / --auto by
default, which means anything it launches can modify your files and run
arbitrary commands. It only belongs on a single-user trusted dev box. The
guards are mistake-catchers, not a security boundary:
--allowed-rootsrestricts wherecwdcan point.--max-concurrentlimits live launched panes.Only CLIs listed in
--cli-allowlistcan be invoked.
Pass dangerous=false per launch if you want the CLI's own permission prompts
back — check_subagent will surface the resulting modals as blocked.
Layout
src/subagent_mcp/
__main__.py CLI entrypoint (stdio | HTTP)
config.py ServerConfig
server.py FastMCP tool definitions
runners.py claude/opencode argv and wrapper generation
cli_paths.py locating CLI binaries a stripped PATH would miss
watching.py tmux client switching and terminal-emulator launching
tmuxio.py thin wrapper around the tmux binary
runs.py per-run directory bookkeeping and retentionplan.md carries the design notes and the review findings behind each phase.
Tests
uv sync --extra dev
uv run pytestTests spin a private tmux socket (-L subagent-test-*) and a fake claude /
opencode on PATH, so they do not touch your real tmux sessions.
License
MIT — see LICENSE.
Available Tools
5 toolscheck_subagentARead-only
Capture the last output from a running subagent.
| Name | Required | Description | Default |
|---|---|---|---|
| lines | No | How many lines to capture from the pane top | |
| handle | Yes | run_id, pane id, or sess:win target |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, so the safety profile is known. The description adds the constraint that only running subagents are supported and specifies 'last output,' which is useful context. There is a minor ambiguity with the schema's 'pane top' phrasing, but overall the description provides valuable behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence of nine words, communicating the essential function without any fluff or redundancy. Every word contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values are covered. The description explains the core purpose and the 'running subagent' constraint. It does not address error conditions like non-running subagents, but for a simple read-only tool, this is adequately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 100% coverage for both parameters with clear descriptions, so the description does not need to add parameter details. It adds no extra semantics beyond what the schema provides, which aligns with the baseline for well-documented schemas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'capture' and resource 'last output from a running subagent', clearly distinguishing it from siblings like list_subagents, send_to_subagent, and stop_subagent. There is no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context is clear: use this tool to retrieve recent output from an active subagent. It does not explicitly mention alternatives or when-not-to-use, but the purpose alone makes the appropriate use case evident.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
launch_subagentA
Launch a coding-CLI subagent in a detached tmux window.
| Name | Required | Description | Default |
|---|---|---|---|
| cli | No | CLI to launch: claude or opencode | claude |
| cwd | No | Working directory for the subagent | |
| task | No | Short human label for the window name | |
| agent | No | Agent argument passed to the CLI | |
| model | No | Model argument passed to the CLI | |
| prompt | No | Task prompt for the subagent | |
| window | No | tmux window name; defaults to task or prompt slug | |
| dry_run | No | Return the generated wrapper without launching | |
| session | No | tmux session name; defaults to basename(cwd) | |
| dangerous | No | Skip permission prompts (--dangerously-skip-permissions / --auto) | |
| extra_args | No | Additional CLI arguments (list preferred) | |
| prompt_file | No | Path to a prompt file (fallback if prompt not provided) | |
| prompt_mode | No | 'inline' feeds the prompt on argv; 'pointer' feeds a bootstrap read-the-file prompt | inline |
| settle_seconds | No | Seconds to wait before capturing initial output |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and openWorldHint=true, so the description adds 'detached tmux window' as extra behavioral context. However, it does not disclose important traits like the default dangerous=true (skip permission prompts) or that it generates and runs a wrapper script. It provides some value but lacks deeper behavioral nuance.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It efficiently communicates the core action and environment context, earning a top score for conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (14 parameters) and the presence of a full input schema and output schema, the one-line description provides a sufficient high-level understanding. It could be slightly more complete by noting the background execution or permission implications, but overall it is adequate for a schema-rich tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 even though the description itself does not mention any parameters. The description adds no additional meaning beyond what the parameter descriptions already provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Launch') and resource ('coding-CLI subagent') with a distinguishing detail ('detached tmux window'). It clearly differentiates from sibling tools (check, list, send, stop) by indicating creation/startup rather than inspection or messaging.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no explicit guidance on when to use this tool versus alternatives. While the name and first word imply starting a new subagent, there is no mention of use cases, prerequisites, or exclusions, and it does not reference the sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_subagentsARead-only
List launched subagents and reconcile them with live tmux pane state.
| Name | Required | Description | Default |
|---|---|---|---|
| session | No | Filter to one tmux session |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already indicates safety, and the description adds useful context by mentioning reconciliation with live tmux pane state. This goes beyond the annotation, though it doesn't detail what reconciliation entails.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that conveys the core function and key behavioral nuance without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a simple parameter set, a read-only annotation, and an output schema, the description sufficiently captures the tool's intent. The term 'reconcile' is slightly ambiguous but doesn't critical hinder understanding for a list operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage for the single 'session' parameter, so the description doesn't need to elaborate. It adds no additional parameter semantics beyond the schema, justifying the baseline score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists subagents and adds the distinctive 'reconcile them with live tmux pane state' behavior, making its purpose specific and differentiated from sibling tools like check_subagent or launch_subagent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is provided on when to use this tool versus alternatives. The description does not mention any exclusions or alternatives, leaving the user to infer usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_to_subagentADestructive
Send a follow-up message to a running subagent.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Text to type into the subagent | |
| handle | Yes | run_id, pane id, or sess:win target | |
| submit | No | Press Enter after pasting |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation destructiveHint=true already signals potential destructive outcomes, and the description does not contradict it. The description adds minimal behavioral context beyond the annotation, not detailing what happens when the message is sent or whether it interrupts the subagent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that fully conveys the tool's core purpose without unnecessary filler. It is appropriately front-loaded and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the rich schema, and the presence of an output schema, the description is mostly complete. It could include a bit more about side effects or expected outcomes, but for a low-complexity tool, this is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters are fully documented in the schema. The description itself adds no parameter details, but since the schema covers all three parameters, the baseline score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('send a follow-up message') and target ('running subagent'), using a specific verb and resource. It differentiates from siblings like launch_subagent and stop_subagent, though it could more explicitly name alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'to a running subagent' implies this tool is used after launch and before stopping, providing clear context. However, it does not explicitly state when not to use it or mention any alternatives, so guidance is implied rather than direct.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stop_subagentADestructive
Interrupt or kill a running subagent.
| Name | Required | Description | Default |
|---|---|---|---|
| handle | Yes | run_id, pane id, or sess:win target | |
| kill_window | No | Kill the tmux window instead of sending Ctrl-C |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description clarifies the two modes of operation (interrupt vs. kill-window), which adds context beyond the destructiveHint annotation. However, it does not disclose potential side effects such as cleanup of child processes or consequences of killing the tmux window. The annotation already flags destructiveness, so the description offers modest additional value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, front-loaded with the action verb and resource, and contains no redundant or extraneous words. It is an exemplar of concise and efficient communication.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the comprehensive schema, and the destructiveHint annotation, the description covers the essential purpose and safety profile. Because an output schema exists, return values are not required. A brief note about handle formats or typical use cases might add slight value, but overall it is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully documents both parameters (handle and kill_window) with descriptions and a default value, covering 100% of the parameter semantics. The description adds no additional meaning beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Interrupt or kill' and clearly identifies the resource 'a running subagent'. This unambiguously distinguishes it from sibling tools like launch_subagent, check_subagent, and list_subagents. The purpose is immediately understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for stopping running subagents but does not provide explicit guidance on when to use this tool versus alternatives. It does not mention exclusions, prerequisites, or the recommended workflow, though the schema indicates the handle is required. The context is clear but alternatives are not addressed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
check_subagent - First observed
launch_subagent - First observed
list_subagents - First observed
send_to_subagent - First observed
stop_subagent
TDQS
Scored across 5 tools
Each tool has a clearly distinct purpose: launch creates a subagent, check retrieves output, list enumerates subagents, send_to delivers messages, and stop terminates. No two tools overlap in function.
All tool names follow a consistent verb_noun pattern in snake_case, using common operational verbs (launch, check, list, send_to, stop). This creates a predictable and easy-to-navigate API.
With five tools, the set is well-scoped for subagent lifecycle management. Each tool covers a necessary operation without redundancy, making the count feel intentional and complete.
The set provides full lifecycle coverage for subagents: create (launch), read (check/list), update (send_to), and delete (stop). There are no obvious missing operations for the stated purpose.
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Real-time chat for AI agents. Claude Code, Cursor, Cline and Codex join channels over MCP.
Remote MCP server for supportsheep: run AI interviews and manage support content for your blog.
MCP server for progressive tool usage at any scale (see https://klavis.ai)
Related MCP Servers
- AlicenseAqualityCmaintenanceTerminal multiplexer MCP server for orchestrating parallel AI agents. Manages workspaces, panes, surfaces with send_input/read_screen/spawn_agent/stop_agent tools. Supports Claude Code, Codex, Gemini, Cursor CLI agents with lifecycle management, browser automation, and agent status push via Claude --channels.2026Apache 2.0
- AlicenseBqualityCmaintenanceA comprehensive MCP server for driving tmux sessions, windows, panes, sending keystrokes, and reading pane output locally or over SSH, enabling real-time collaborative pairing with AI.713MIT
- AlicenseAqualityCmaintenanceAn MCP server that gives orchestrator agents fine-grained control over interactive Claude Code sessions running inside tmux, enabling mid-session steering, interruption, and token-efficient result extraction.15MIT
- AlicenseAqualityDmaintenanceMCP server for orchestrating multiple Claude Code instances via tmux, enabling spawning, reading, sending, listing, and killing sessions.521 npm2MIT