Skip to main content
Glama

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 — start claude or opencode in a tmux window

  • check_subagent — capture the last N lines of output from a running subagent

  • watch_subagent — put a running subagent on screen (or report how to attach)

  • list_subagents — list all launched subagents and whether their panes are alive

  • send_to_subagent — paste a follow-up message into a live subagent

  • stop_subagent — send Ctrl-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:

watch

Effect

off (default)

Detached. The response still carries attach_command.

switch

Pulls your already-attached tmux client to the new window.

terminal

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_commandtmux attach -t sess:win

  • attach_read_only — the same with -r, so watching cannot disturb the run

  • output_log<run_dir>/output.log, a pipe-pane tee of everything the pane printed. tail -f it 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 8100

Options

Every flag has a matching environment variable.

Flag

Env

Default

Meaning

--allowed-roots

SUBAGENT_ALLOWED_ROOTS

~/git,~/ATLAS-GROUP

Parent dirs a subagent cwd may live under

--any-cwd

off

Disable the cwd allowlist entirely

--cli-allowlist

SUBAGENT_CLI_ALLOWLIST

claude,opencode

CLIs the server will invoke

--max-concurrent

SUBAGENT_MAX_CONCURRENT

12

Cap on live launched panes

--runs-root

SUBAGENT_RUNS_ROOT

./runs

Where per-run artefacts go

--runs-keep-max

SUBAGENT_RUNS_KEEP_MAX

200

Keep at most this many run dirs (0 disables)

--runs-max-age-days

SUBAGENT_RUNS_MAX_AGE_DAYS

14

Delete run dirs older than this (0 disables)

--tmux-socket

SUBAGENT_TMUX_SOCKET

default socket

Use a private tmux server

--watch-default

SUBAGENT_WATCH_DEFAULT

off

Default visibility: off / switch / terminal

--terminal

SUBAGENT_TERMINAL

autodetect

Terminal template for watch=terminal, e.g. kitty -- bash -c {cmd}

--no-pipe-logs

SUBAGENT_NO_PIPE_LOGS

off

Stop teeing pane output into <run_dir>/output.log

SUBAGENT_CLI_OPENCODE / SUBAGENT_CLI_CLAUDE

autodetect

Absolute path to a CLI binary

--host / --port

SUBAGENT_HOST / SUBAGENT_PORT

127.0.0.1:8100

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-roots restricts where cwd can point.

  • --max-concurrent limits live launched panes.

  • Only CLIs listed in --cli-allowlist can 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 retention

plan.md carries the design notes and the review findings behind each phase.

Tests

uv sync --extra dev
uv run pytest

Tests 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 tools
check_subagentA
Read-only

Capture the last output from a running subagent.

ParametersJSON Schema
NameRequiredDescriptionDefault
linesNoHow many lines to capture from the pane top
handleYesrun_id, pane id, or sess:win target

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliNoCLI to launch: claude or opencodeclaude
cwdNoWorking directory for the subagent
taskNoShort human label for the window name
agentNoAgent argument passed to the CLI
modelNoModel argument passed to the CLI
promptNoTask prompt for the subagent
windowNotmux window name; defaults to task or prompt slug
dry_runNoReturn the generated wrapper without launching
sessionNotmux session name; defaults to basename(cwd)
dangerousNoSkip permission prompts (--dangerously-skip-permissions / --auto)
extra_argsNoAdditional CLI arguments (list preferred)
prompt_fileNoPath to a prompt file (fallback if prompt not provided)
prompt_modeNo'inline' feeds the prompt on argv; 'pointer' feeds a bootstrap read-the-file promptinline
settle_secondsNoSeconds to wait before capturing initial output

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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_subagentsA
Read-only

List launched subagents and reconcile them with live tmux pane state.

ParametersJSON Schema
NameRequiredDescriptionDefault
sessionNoFilter to one tmux session

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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_subagentA
Destructive

Send a follow-up message to a running subagent.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesText to type into the subagent
handleYesrun_id, pane id, or sess:win target
submitNoPress Enter after pasting

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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_subagentA
Destructive

Interrupt or kill a running subagent.

ParametersJSON Schema
NameRequiredDescriptionDefault
handleYesrun_id, pane id, or sess:win target
kill_windowNoKill the tmux window instead of sending Ctrl-C

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

  1. 5 tool updatesv0.1.0
    • First observedcheck_subagent
    • First observedlaunch_subagent
    • First observedlist_subagents
    • First observedsend_to_subagent
    • First observedstop_subagent

TDQS

A4.1/5.0

Scored across 5 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness5/5

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

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Terminal 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.
    20
    26
    Apache 2.0
  • A
    license
    B
    quality
    C
    maintenance
    A 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.
    71
    3
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    An 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.
    15
    MIT