cmuxlayer
cmuxLayer is an MCP server that controls cmux terminal workspaces and orchestrates CLI coding agents (Claude Code, Codex, Gemini, Cursor, Kiro) through exactly 10 public tools.
Spawn or resume agents (
spawn_agent): launch a managed agent or plain terminal, optionally in a git worktree, with repo, role, model, effort, prompt, placement, and cost cap; resume a captured agent by ID on a fresh surface.Send work to agents (
send_to): deliver text, commands, or keystrokes to an agent by ID or to a raw surface (agent/surface/command/keymodes), with delivery receipts and safety gates at pickers/menus.Read terminal output (
read_screen): capture a screen, scrollback, or raw text, with auto-parsed agent metadata (status, model, tokens, context %) for Claude Code, Codex, Gemini, and Cursor.Track agents (
list_agents): list live-derived agents with filters by repo, model, state, parent, blocked-on-prompt, or explicit IDs; summary or full detail.Wait for completion (
wait_for): block on one or many agents reaching a target state (ready/working/idle/done/error) or on a delivery ID, plus file-marker/content watches and report-path done markers.Inspect topology (
list_surfaces): list workspaces, panes, and surfaces, with optional screen previews and raw cmux fields.Arrange surfaces (
update_surface): move or rename a terminal surface.Close things safely (
close_surface): close a surface, managed agent, or workspace, with live-agent guards andforceoverride.Escalate blockers (
report_to_parent): raise a short blocker to a managed agent's registry parent with durable delivery and fallback routing.Diagnose the control path (
control_health): report socket, binary, process, job-control, and cmux FD diagnostics (terse or full).Supporting behavior: all 10 tools carry MCP ToolAnnotations for client safety policy, results are lean by default (
verbose:truefor full detail), and servers can run a smaller resident palette viaCMUXLAYER_DEFAULT_PALETTEwithexpand_paletteto register the rest.
cmuxLayer
cmuxLayer exposes a 10-tool public MCP surface for controlling cmux terminal workspaces and managing CLI agents.
Quick start
brew install etanhey/layers/cmuxlayer # stable, pinned release
brew install --HEAD etanhey/layers/cmuxlayer # or: dogfood the latest mainThis installs the cmuxlayer command plus cmuxlayer-app-server and
cmuxlayer-proxy. cmux must be running.
For fleet wiring, versions, dogfooding, and the CMUX_SOCKET_PATH pin, see
docs/guides/releases-and-brew.md.
Then set up this machine:
cmuxlayer initThe wizard selects spawnable repositories, per-repo launchers or direct CLI
launches, and approval behavior. It writes ~/.config/cmuxlayer/env.sh and, in
launcher mode, a launcher registry. cmuxlayer reads both at startup, including
when an MCP client starts it from a GUI. The wizard asks before replacing a file
and creates a backup first.
For scripted installs, pass --yes with --repo <name>=<path>. cmuxlayer does
not assume a fixed repository layout. See
docs/guides/fresh-install.md for the walkthrough and
docs/guides/registry-optional-spawn.md for how each
lane behaves.
Related MCP server: hyperpanes-mcp
Raise the open-files limit for agent CLIs
Agent CLIs open many files, while macOS login shells can start with a low soft
open-files limit. If you use repoGolem launchers, put this POSIX shell snippet
in a global.prelaunch entry so it runs before each agent CLI. You can also
put it in your shell rc file. It raises a low soft limit up to the hard limit,
capped at 65536, and never lowers an existing soft limit.
cmux_nf_s=$(ulimit -Sn); cmux_nf_h=$(ulimit -Hn); [ "$cmux_nf_s" = unlimited ] || [ "$cmux_nf_s" -ge 65536 ] || { [ "$cmux_nf_h" = unlimited ] && cmux_nf_h=65536; [ "$cmux_nf_h" -gt 65536 ] && cmux_nf_h=65536; ulimit -Sn "$cmux_nf_h"; }Add to your MCP config:
Codex CLI / T3 Code
T3 Code inherits MCP servers from the Codex CLI config file at ~/.codex/config.toml (or $CODEX_HOME/config.toml).
[mcp_servers.cmuxlayer]
command = "cmuxlayer"
env_vars = ["CMUX_SURFACE_ID", "CMUX_WORKSPACE_ID", "CMUX_TAB_ID", "CMUX_SOCKET_CAPABILITY", "CMUX_SOCKET_PATH"]env_vars forwards the pane's existing values into Codex's MCP process. Do not paste a capability value into this file.
Claude Code, Cursor, VS Code, Claude Desktop
{
"mcpServers": {
"cmuxlayer": {
"command": "cmuxlayer"
}
}
}To keep only a per-session resident subset of tools, set
CMUXLAYER_DEFAULT_PALETTE to comma-separated bare tool names, for example
list_surfaces,spawn_agent,send_to. The server also exposes expand_palette,
which registers the rest of the 10 public tools for the rest of that MCP
session.
When unset or blank, the signed 10-tool thin-core default applies. When set, the
environment value overrides that default for the session. Unknown names are
warned and ignored while valid names still load.
cmuxlayer never answers a prompt chooser on an agent's behalf. It detects the
chooser, marks the agent blocked_on_prompt, and escalates without sending a
key.
CMUXLAYER_FILE_DELIVERY_TICKETS=1 opts into public delivery-failure auto-filing with allowlisted bodies; full evidence stays in local tickets by default.
Config locations: Codex CLI / T3 Code
~/.codex/config.toml(or$CODEX_HOME/config.toml) | Claude Code.mcp.jsonorclaude mcp add cmuxlayer -s user -- cmuxlayer| Cursor.cursor/mcp.json| VS Code.vscode/mcp.json| Claude Desktop — see MCP docs for platform-specific paths
Drive panes through the MCP, not the raw cmux CLI
Use cmuxlayer's MCP tools for pane operations. Calling the raw cmux CLI yourself bypasses stable-UUID guards, draft ownership, delivery receipts, tailer reaping, and placement. After a cmux restart, reconnect cmuxlayer before any pane operation: run /mcp reconnect cmuxlayer in Claude Code, restart Codex CLI or T3 Code, or use MCP: List Servers → Restart Server in VS Code. Use the equivalent MCP reconnect control in other clients.
Bare terminal creation through the production server requires an available observer. The handler checks the creation observer and any returned surface UUID before and after runtime initialization, at temporary focus and cleanup boundaries, and through its restoration lease. If those checks detect lost identity, cmuxlayer refuses stale refs and skips unsafe cleanup; the original initialization error remains visible. These handler checks do not provide atomic ownership across a connector's internal awaits, self-healing retries, or an in-flight RPC. Unsupported runtime metadata still permits temporary focus when ownership is stable. Explicit focus:false keeps initialization in the background, and a user focus change prevents restoration.
What you can do
Tell your AI agent things like:
"Run my test suite in the pane to the right"
"Spawn a Claude Code agent in a new pane to refactor auth.ts"
"Read the screen of surface:2 and tell me if the build passed"
"Wait for all agents to finish, then read their output"
By default cmuxLayer registers exactly 10 tools, and all 10 are callable through MCP; there are no hidden internal tool definitions. read_screen parses agent metadata (status, model, tokens, context %) for Claude Code, Codex, Gemini, and Cursor.
Agent routing workflow
For managed agents, use the agent-first path: list_agents to find the target, send_to to deliver work by agent_id, then wait_for when you need completion. send_to also preserves the registry-independent escape hatch: use mode:"surface", mode:"command", or mode:"key" with a raw surface ref for shells, launch/resume commands, and stuck-pane recovery.
Busy Codex messages use Return to steer at the next tool boundary. Pass codex_busy_mode:"queue" to send_to only for deliberate Tab delivery after the turn. steer_pending and queued both mean delivered:false; use wait_for({delivery_id}) for confirmation. After 10 minutes, unresolved pending deliveries raise needs_attention and a parent alert without interruption or replay. Set CMUXLAYER_DELIVERY_ATTENTION_MS to a positive integer in milliseconds to change that threshold.
See Agent Routing and Handling Workflow for the full operator playbook, including stuck surface recovery and safe /mcp menu reconnects.
MCP tools (10 registered and callable)
All public tools include ToolAnnotations that clients can use in safety policy.
Public MCP surface — spawn_agent report_to_parent send_to read_screen list_agents wait_for control_health close_surface update_surface list_surfaces
Tool | What it does |
| Spawn or resume; default receipt: |
| Raise a short blocker to the managed agent's registry parent |
| Send by agent ID or raw surface using |
| Read terminal output with parsed agent status |
| All agents, with optional filters |
| Wait for one |
| Report socket, binary, process, and job-control diagnostics |
| Close one surface, managed agent, or workspace, with live-agent guards |
| Move or rename a surface; explicitly adopt an existing managed session with pinned evidence |
| List all surfaces across workspaces |
update_surface with action: "adopt_session" supports Claude and Codex after a restart, including
retained old bindings. Legacy rows require a known registry role and exact-session hook/process proof;
missing authority and placement use the same role aliases as spawn, and process cwd supplies missing
launch cwd. Legacy recovery records surface_provenance: "session_registration" and a one-line audit.
The old UUID must be absent and the new UUID uniquely live; titles never grant recovery authority.
Adoption requires the current stable surface and workspace UUIDs,
managed_agent_id, the same recorded session_id, expected_agent_version, an observer_transition
with explicit historical_owner_id and current_owner_id, and an absolute binding_evidence_path
plus its binding_evidence_sha256. The selected historical witness must establish the original
binding and explicit authority. Fresh complete topology, exact hook registration, qualified PID,
and direct process cwd must agree; ambiguous or competing known claimants refuse adoption.
Authority and coordination fields remain those of the original managed record. Adoption sends no
input and moves no panes; normal layout reconciliation follows separately. An interrupted write
returns pending_verify; an unchanged exact repeat revalidates binding, process, observer and routing
before completing persistence. A lifecycle-invalidated binding requires a fresh explicitly versioned
request. A public
action: "move" alone does not write a placement override or recover managed session identity.
control_health reports cmux_fds for detected cmux.app processes and warns when open descriptors reach 4096; set CMUXLAYER_CMUX_FD_WARN to a positive integer to change that threshold.
These 10 are the whole surface by default: setting CMUXLAYER_DEFAULT_PALETTE restricts the initially registered tools to the ones it names and adds expand_palette, which registers the rest on demand.
Supported agents
CLI | Command | Auto-detected |
Claude Code |
| status, model, tokens, context % |
Codex |
| status, model, context % |
Gemini CLI |
| status, model, tokens, context % |
Cursor |
| status, model, tokens, context % |
Kiro CLI |
| spawn and lifecycle only; no Kiro-specific screen parser |
read_screen auto-detects agent type and parses metadata from terminal output.
For launch and resume forms, input limits, and the ready/working/done markers per
CLI, see the CLI reference.
Architecture
AI Agent ─── MCP ───> cmuxLayer ─── Unix socket ───> cmux
├── Agent engine (spawn → monitor → teardown)
├── Screen parser (Claude Code, Codex, Gemini, Cursor)
├── Mode policy (autonomous vs manual)
├── State manager + event log
├── Metacomm READ — harness JSONL (real tokens/context/model)
└── Metacomm WRITE — per-agent inbox file + Monitor dispatchThe socket client connects to cmux through a persistent Unix socket instead of starting a cmux CLI subprocess per call. It reconnects after a disconnect and falls back to the CLI subprocess when the socket is unavailable.
Troubleshooting
cmux is not running cmuxLayer requires a running cmux instance. Install it first, then start a cmux session before using cmuxLayer.
Tools not appearing in Codex CLI or T3 Code
Restart the client after adding cmuxlayer to ~/.codex/config.toml. If you use a custom Codex home, verify $CODEX_HOME/config.toml contains the same mcp_servers.cmuxlayer entry.
Tools not appearing in Claude Code
Restart Claude Code after adding the MCP config. Run claude mcp list to verify cmuxlayer is connected.
Socket connection failed
cmuxLayer auto-discovers the cmux socket (macOS: ~/Library/Application Support/cmux/cmux.sock). Override with CMUX_SOCKET_PATH if needed.
"Cannot resolve a working directory for repo ..."
cmuxLayer could not find that checkout. Run cmuxlayer init to register it, or
set CMUXLAYER_REPO_HOME to the colon-separated directories holding your
repositories. The error lists every path it searched.
Testing
bun run test # vitest; 4452 tests collected by `vitest list`
bun run typecheck # Type checkingGit hooks
Enable project hooks to run the regression gate automatically on git push:
git config core.hooksPath .githooksThis enables .githooks/pre-push, which runs scripts/run_tests.sh and blocks pushes on regression failures.
Development
bun install
bun run dev # Run with tsx (hot reload)
bun run build # Compile TypeScript
bun run start # Run compiled outputContributing
See CONTRIBUTING.md for development setup and PR guidelines.
License
Apache 2.0 — see LICENSE.
Part of the Golems AI agent ecosystem. cmuxlayer.etanheyman.com | Built by @EtanHey.
Available Tools
10 toolsclose_surfaceADestructive
Close one surface, managed agent, or workspace with live-agent guards. scope="agent" stops the agent AND closes its pane, and reports the two halves separately (agent_stopped, surface_closed) so a pane that survives is never reported as closed. The pane close obeys the same live-agent guard as scope="surface": without force:true a still-live agent keeps its pane, and the receipt says so.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | Close even when the backing agent is still live (not done/error). This never bypasses stable surface identity checks. Without force, a live agent's surface is protected and the response returns the current pane contents instead of closing. | |
| scope | No | surface | |
| surface | No | Target surface ref | |
| agent_id | No | Managed agent ID | |
| workspace | No | Target workspace ref |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| pane | No | |
| force | No | |
| scope | No | |
| state | No | |
| agents | No | |
| refused | No | |
| removed | No | |
| surface | No | |
| agent_id | No | |
| surfaces | No | |
| workspace | No | |
| live_agents | No | |
| retry_count | Yes | |
| collapse_pane | No | |
| caller_workspace | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey destructiveness, and the description adds meaningful context: scope='agent' stops the agent, closes its pane, reports the two results separately, and the pane close is guarded exactly like scope='surface'. It does not, however, disclose what closing a workspace does to contained surfaces or agents, which is a notable gap for a destructive tool.
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?
Three sentences with no filler. The core purpose is front-loaded, and each subsequent sentence adds a distinct behavioral edge case or guard rule that an agent needs to invoke the tool correctly.
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?
Surface and agent scopes are well covered, including guard behavior and partial-failure reporting, and the output schema covers return shape. The workspace scope is only named without explaining whether closing cascades to contained surfaces/agents or how the live-agent guard applies, which is important for a destructive 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?
Schema coverage is 80%, so most parameters are already documented. The description adds real value by explaining the otherwise-undocumented scope enum, the force/guard interaction, and the split agent_stopped/surface_closed reporting.
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 opening sentence states a specific verb ('Close') and explicit object types ('surface, managed agent, or workspace') plus the operative guard. This is unambiguous and easily distinguished from sibling tools like list_surfaces, update_surface, and spawn_agent.
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 gives clear conditional usage for scope='agent' versus scope='surface' and explains when force:true is or isn't needed. It does not explicitly name alternatives or say 'use this instead of X', but no sibling performs closing, so the intended use is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
control_healthARead-onlyIdempotent
Report terse control-path health by default; pass detail=full for diagnostics.
| Name | Required | Description | Default |
|---|---|---|---|
| detail | No | terse |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| health | No | |
| retry_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so safety is covered. The description adds the mode distinction (terse vs full) but doesn't elaborate on exact behavior or response shape; output schema accounts for that.
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?
One sentence with zero wasted words; default behavior is front-loaded, alternative follows.
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 only one optional param, output schema present, and annotations covering safety, the description is adequately complete. No missing prerequisites or side effects.
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 has 0% description coverage, so the description must compensate. It explains that detail=full is for diagnostics, which gives semantic meaning to the enum value, but doesn't explain what 'terse' vs 'full' includes. Still, for a single parameter, it partially fills the gap.
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?
States a specific verb ('Report') and resource ('control-path health'), with explicit default and alternative modes. Distinct from siblings that handle waiting, surfaces, agents, and 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?
Provides clear context for using the default terse mode and when to request full diagnostics. Doesn't name alternative tools, but the context is specific enough that an agent can infer when a health check is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_agentsA
List live-derived agents, including registry-persisted prompt blockage and pause state; filter to blocked agents or children with mine/parent_agent_id. Default summary returns flat addressable scalars and hides close tombstones and failed spawns whose surfaces are absent; request a terminal state or detail=full to include them. Full detail also includes provenance, health diagnostics, the registry record, and up to 20 unresolved or attention delivery receipts.
| Name | Required | Description | Default |
|---|---|---|---|
| mine | No | Return direct children of the calling agent | |
| repo | No | Filter by repository | |
| model | No | Filter by model | |
| state | No | Filter by state | |
| detail | No | summary (default): flat addressable scalar rows. full: provenance, health diagnostics, the full registry record, and up to 20 unresolved or attention delivery receipts. | summary |
| agent_ids | No | Return only these agent IDs | |
| max_age_ms | No | Maximum acceptable snapshot age in milliseconds (0-5000); topology changes always invalidate the snapshot | |
| parent_agent_id | No | Return direct children of this agent | |
| blocked_on_prompt | No | Return only agents whose registry records show a live prompt blocker |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| count | No | |
| agents | No | |
| derived_at | No | |
| retry_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses important non-obvious behavior beyond the annotations: default summary hides close tombstones and failed spawns, and full detail adds provenance, health diagnostics, the registry record, and up to 20 receipts. Annotations are all false and provide no safety profile, so this carries most of the burden; side effects and auth are not mentioned, but nothing indicates they are needed for this list operation.
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 three dense, front-loaded sentences, each earning its place: what is listed, how filtering works, and what full detail includes. There is no filler or redundant restatement of schema fields.
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?
For a tool with 9 optional parameters and an output schema, the description covers the non-obvious semantics—live-derived state, hidden tombstones/failed spawns, detail levels, and receipt counts—while the schema covers parameter mechanics. The definition is complete enough for an agent to select and invoke this tool correctly.
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 schema already documents every parameter; the description adds value by connecting mine/parent_agent_id to child filtering, blocked_on_prompt to live prompt blockers, and by explaining how state/detail interact with hidden items. This goes beyond simple schema repetition.
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?
Description opens with a specific verb and resource: 'List live-derived agents' and immediately adds distinguishing scope such as registry-persisted prompt blockage, pause state, and child/blocked filtering. This makes it clearly distinct from sibling tools like list_surfaces or spawn_agent.
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 gives clear retrieval guidance: default summary hides tombstones and failed spawns, while requesting a terminal state or detail=full includes them. It does not explicitly name alternative tools or state when not to use this tool, but the context for correct invocation is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_surfacesARead-onlyIdempotent
List workspace, pane, and surface topology. Condensed by default; verbose=true adds raw cmux fields.
| Name | Required | Description | Default |
|---|---|---|---|
| verbose | No | Return all raw cmux fields instead of the condensed default. This materially increases token usage and is rarely needed; use it only when a specific raw field is required. | |
| workspace | No | Filter by workspace ref | |
| preview_lines | No | Number of preview lines | |
| include_screen_preview | No | Include screen content preview |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| surfaces | No | |
| workspaces | No | |
| retry_count | Yes | |
| column_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds behavioral context by noting the condensed default and that verbose=true adds raw cmux fields, which is meaningful beyond the annotations.
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?
Two tight sentences with the core purpose front-loaded and no filler. Every word earns its place.
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?
For a read-only topology listing tool with a complete input schema, rich annotations, and an output schema, the description is nearly sufficient. It could be improved by explicitly routing the agent to this tool versus its siblings, but nothing critical is missing for invocation.
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. The description reinforces the verbose behavior but does not add substantial meaning beyond what the schema already provides for the other parameters.
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 ('List') with a clear resource ('workspace, pane, and surface topology'). This distinguishes it from siblings like list_agents, read_screen, and the surface mutation tools.
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 the tool is for inspecting surface topology but does not explicitly state when to choose it over alternatives like read_screen or list_agents. It does give useful guidance on the verbose flag, but not on tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_screenARead-onlyIdempotent
Read a terminal screen and parsed harness status. Use raw=true for full text or parsed_only=true for monitoring.
| Name | Required | Description | Default |
|---|---|---|---|
| raw | No | If true, include the full untrimmed terminal content (separators, status-bar art, all lines). Default false returns a compact de-chromed screen_preview instead. | |
| lines | No | Number of lines to read | |
| surface | No | Target surface ref | |
| workspace | No | Target workspace ref | |
| scrollback | No | Include scrollback buffer | |
| surface_id | No | Alias for `surface`, as emitted by list_agents/spawn_agent. | |
| parsed_only | No | If true, return only parsed fields (omit screen content). Best for agent monitoring. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| parsed | No | |
| surface | No | |
| retry_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: the tool returns two kinds of content (terminal text and parsed harness status), and the mode selects which one the caller gets, which matters for how an agent consumes the result.
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?
Two short sentences, zero filler. The purpose is front-loaded first, followed immediately by the only mode-selection guidance an agent needs. Every word earns its place.
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?
For a read-only tool with full schema coverage on all 7 parameters, an output schema, and safety annotations covering the behavioral risk, the description is nearly complete. The only minor gap is that it does not describe the shape of the 'parsed harness status' fields, but the output schema presumably covers that, so nothing critical is missing.
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 schema already fully documents all 7 parameters. The description's mention of raw=true and parsed_only=true merely restates the schema's own detailed explanations ('full untrimmed terminal content' vs 'return only parsed fields') without adding new semantic value, matching the baseline of 3.
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 names a specific verb and resource ('Read a terminal screen and parsed harness status'), and the dual-output mention (raw text vs parsed status) distinguishes it from sibling reads like list_surfaces or list_agents. It is clear, though it does not explicitly name any sibling it is not.
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 line 'Use raw=true for full text or parsed_only=true for monitoring' gives explicit context for choosing between the two output modes. However, it provides no when-not-to-use guidance or comparison against sibling tools such as wait_for or list_agents, leaving tool-selection mostly to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
report_to_parentA
Raise a short blocker to this managed agent's registry parent. cmuxlayer chooses the parent; callers cannot address arbitrary agents. The blocker is durably appended to the parent's inbox and its pointer is actively delivered. If that wake fails, cmuxlayer alerts the nearest reachable ancestor and returns fallback provenance. A root agent has no parent and receives an error. Workers with collab_path must append there to reach their own parent lead; this tool refuses that upward route.
| Name | Required | Description | Default |
|---|---|---|---|
| blocker | Yes | Short blocker pointer, capped at 500 characters; put detailed evidence in a report file |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| route | No | |
| durable | No | |
| delivery | No | |
| error_code | No | |
| delivery_id | No | |
| retry_count | Yes | |
| child_agent_id | No | |
| parent_agent_id | No | |
| notified_agent_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish non-read-only and non-destructive behavior, and the description adds durable append to the parent's inbox, active delivery of the pointer, fallback alert to the nearest reachable ancestor with fallback provenance, and refusal for collab_path workers. These behavioral details go well beyond the schema and annotations.
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 dense paragraph, but every sentence carries distinct information—purpose, parent selection, persistence, fallback, root edge case, and collab_path exclusion. It is front-loaded with the action and then details constraints in a logical order.
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 one parameter fully documented in the schema, an output schema present, and annotations covering safety, the description supplies the behavioral details needed to call the tool correctly, including fallback behavior and error cases. No critical operational information is missing.
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 coverage is 100%, so the baseline is 3, but the description reinforces that the blocker is a short pointer and adds delivery semantics ('durably appended', 'actively delivered'). This adds meaningful context beyond the schema's own description.
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 states a specific verb and resource: 'Raise a short blocker to this managed agent's registry parent.' It also clarifies scope by saying cmuxlayer chooses the parent and callers cannot address arbitrary agents, which distinguishes it from arbitrary messaging siblings like send_to.
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 explicit context: root agents receive an error, and workers with collab_path must append there to reach their parent lead because 'this tool refuses that upward route.' It clearly implies this is for parent-directed blockers, but it does not explicitly name alternatives such as send_to, so some routing inference remains.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_toA
Send text or a key through the shared delivery engine. send_to submits new messages. Key-Return supports pickers, menus, permission prompts, and recovery of this caller's exact typed draft on the same agent/session once the displayed unambiguous reset time passes or new harness output confirms recovery; the old refusal may stay visible. Exact /usage, /usage-credits or /rate-limit-options navigation is also guarded. Read the pane and receipt first; never retype or repeat accepted input. Every receipt includes caller_agent_id (null when unknown). Workers with collab_path cannot address their own parent or ancestor leads in any mode; append to that collab file instead. Unknown callers remain allowed. Lead-originated and engine-internal pushes remain allowed. Targets may be one agent, structured agent targeting, or a raw surface in surface/command/key mode; for shell commands use mode:command. Text success requires a verified submit or new matching queue proof. Otherwise ok=false with submit_unverified retains pending verification and ownership for retries without retyping. Verified text success returns only ok, target identity, delivery_id, delivery_state, submitted, caller_agent_id, and queued_behind_turn when applicable. Key success returns its key verification fields. Pass verbose=true for full diagnostics; failures always retain them.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | agent | |
| text | No | Max 2-3 short lines. Longer payloads BREAK the receiving pane — write the payload to a file and send one line: `Read and follow <path>`. Text to send. Capped at 500 inline UTF-8 bytes by default. | |
| target | No | ||
| surface | No | ||
| verbose | No | Return the full legacy success receipt, including transport and timing diagnostics. Failures always keep full detail. | |
| agent_id | No | ||
| targeting | No | ||
| workspace | No | ||
| allow_busy | No | Deprecated no-op. Safety gates still refuse text at a picker/menu or permission prompt; use mode=key to drive those deliberately. | |
| background | No | ||
| chunk_size | No | ||
| press_enter | No | Press enter after sending text | |
| rename_to_task | No | ||
| codex_busy_mode | No | Busy Codex defaults to Return steering at the next tool call; queue opts into Tab after-turn delivery. Neither pending state is delivered. | |
| boot_prompt_path | No | ||
| allow_long_inline | No | Bypass the inline length and multi-paragraph safety guards for a deliberate raw send. Large allowed sends keep the existing chunked delivery behavior. | |
| boot_prompt_timeout_ms | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| key | No | |
| model | No | |
| title | No | |
| typed | No | |
| health | No | |
| screen | No | |
| status | No | |
| command | No | |
| surface | No | |
| accepted | No | |
| agent_id | No | |
| delivery | No | |
| receipts | No | |
| terminal | No | |
| delivered | No | |
| agent_type | No | |
| delivery_id | No | |
| done_marker | No | |
| report_path | No | |
| retry_count | No | |
| rpc_methods | No | |
| duplicate_of | No | |
| contract_path | No | |
| delivery_state | No | |
| registry_state | No | |
| state_conflict | No | |
| needs_attention | No | |
| submit_evidence | No | |
| submit_verified | No | |
| attention_reason | No | |
| submit_attempted | No | |
| boot_prompt_bytes | No | |
| submit_dispatched | No | |
| boot_prompt_receipt | No | |
| boot_prompt_warning | No | |
| boot_prompt_delivered | No | |
| coordination_footer_note | No | |
| coordination_footer_bytes | No | |
| boot_prompt_submit_verified | No | |
| coordination_footer_delivered | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations give only the safety profile, and the description adds substantial context beyond it: permission gating (supervised callers barred from their own parent/ancestor leads, must append to the collab file), success criteria (verified submit or new queue proof), ok=false/submit_unverified retention of ownership without retyping, and guaranteed caller_agent_id in every receipt. The detail is genuinely useful, though some of it (verbose, allow_busy) duplicates the schema.
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 core action is correctly front-loaded in the first two sentences, and most clauses carry substantive content. However the remainder is a dense run-on block of semicolon-joined caveats with no structure, making it hard for an agent to extract the operative rules (e.g. the 'old refusal may stay visible' aside) at a glance.
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 an output schema exists and annotations cover safety, the description does explain the pieces an agent needs: modes, target shapes, permission bars, and partial-failure/retry semantics. Remaining gaps are secondary parameter explanations and the interaction among target, agent_id, and targeting, which are not disentangled.
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 coverage is only 35% across 17 parameters, so the description carries real burden. It partially compensates by explaining the targeting space ('one agent, structured agent targeting, or a raw surface in surface/command/key mode') and mode semantics, but roughly ten parameters (chunk_size, press_enter, background, rename_to_task, boot_prompt_path, boot_prompt_timeout_ms, allow_long_inline, workspace, etc.) get no mention in either place.
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 opening two sentences state a specific verb and resource (send text or a key, submit new messages) and identify the four operational modes, so the agent knows this is the delivery tool. It is weaker on sibling differentiation: report_to_parent and spawn_agent are never named, and the only routing advice is mode-internal ('for shell commands use mode:command').
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?
There is real conditional guidance ('Read the pane and receipt first; never retype or repeat accepted input', mode=key for pickers/menus, mode:command for shell), but it is scattered rather than framed as when-to-use-this-vs-alternatives. No sibling tool is named as the alternative for any case, so the agent must infer routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
spawn_agentA
Spawn a managed agent or terminal, or resume a captured agent on a fresh surface preserving its ID. Resume: {resume_agent_id:"..."}. Omit new-spawn fields: repo, cli, model, effort, cwd, prompt, boot_prompt_path, worktree, mcp_profile, role, placement, authority, collab_path, parent_agent_id, max_cost_per_agent; these cause INVALID_RESUME_SPEC. Optional resume controls such as force, workspace, focus, report_path and verbose remain supported. Resume restores session context; it does not resend a task. For a new task, check current readiness, then use send_to separately. ok:true/state:started means lifecycle started, not ready or task delivered. At a chooser or permission prompt, inspect the current frame with read_screen before acting; never blindly send Return or assume success. pending_verify leaves delivery unverified; follow wait_for guidance in warning when present; do not resend blindly. Placement is deterministic; boot_prompt_timeout_ms also bounds pane placement. Default successes have at most six fields: ok, agent_id, surface_id, state (spawn outcome), delivered (boot prompt), and optional warning. Use verbose:true for contract_path, report_path, done_marker, transport, worktree, and diagnostics; report_path and done_marker are also in the issued contract file. Failures always keep full detail.
| Name | Required | Description | Default |
|---|---|---|---|
| cli | No | New spawn only; omit on resume. CLI tool to launch | |
| cwd | No | Initial working directory for type=terminal | |
| repo | No | New spawn only; omit on resume. Repository name (e.g. 'brainlayer', 'golems') | |
| role | No | Agent job function: implementor, reviewer, or gatherer. Lead callers may omit it to spawn an implementor with worker authority on the right by default; explicit roles and axes still apply. Legacy orchestrator/worker aliases remain accepted. Other Claude callers require an explicit role. | |
| type | No | Spawn an AI agent or a plain terminal | agent |
| focus | No | Leave focus on the created tab instead of restoring the exact origin after initialization. Resume and bare terminals: false forbids focus and fails closed if background initialization is unavailable; omitted may temporarily focus to initialize, then restore the origin. Fresh managed agents retain legacy initialization focus. | |
| force | No | With resume_agent_id only: override missing or inconclusive proof that the old session is not running (no recorded pid, an unproven pid, an unreadable topology or process table) after the caller deliberately verifies the old agent is gone. Does not bypass session or terminal-state requirements. | |
| model | No | OPTIONAL — leave UNSET so the launcher pins the top-tier model. For cli:'codex', an explicit model is checked against Codex's runtime model list before any worktree or surface is created, then passed through to the launcher. Never pass 'opus' for claude — the top Claude model is already the default. | |
| title | No | The caller-supplied agent pane title is applied verbatim (for example `cmuxlayer-WORKER · run1 name-the-tabs`); when omitted or blank, the existing agent-id/surface fallback is retained. Managed identity comes from the agent registry, not this display title (#479/#492). | |
| effort | No | Required for codex new agent spawns: low, medium, high, xhigh, max, ultra. Choose deliberately: medium for well-specified lanes, high for security/open-ended; xhigh and above cost more. Omit on resume (the session keeps its effort) and for other CLIs (effort is invalid). | |
| prompt | No | Max 2-3 short lines. Longer payloads BREAK the receiving pane — write the payload to a file and send one line: `Read and follow <path>`. New spawn only; omit on resume and send a new task separately with send_to after checking readiness. Inline task prompt to send after the agent is ready. Capped at 500 inline UTF-8 bytes by default; use boot_prompt_path for larger prompts. Mutually exclusive with boot_prompt_path. | |
| verbose | No | Return the full success receipt, including contract_path, report_path, done_marker, transport, worktree, and diagnostics; defaults to at most six fields. Failures always keep full detail. | |
| version | No | SpawnSpec schema version | |
| worktree | No | When set, create or reuse a git worktree before launch. Pass a string such as "tool-usage" as the worktree name, true for a generated name, or an object with name, path, branch, base, create, and reuse. When repoGolem registers the repo with an absolute path, that path is the repo root; otherwise the root is resolved from CMUXLAYER_REPO_HOME, the running checkout, or ~/Gits. true uses <registered-root>/.worktrees/<generated-name> (legacy ~/Gits/<repo>.wt read-fallback until ~2026-09). If a later spawn step fails before a recoverable surface exists, a newly created worktree and branch are rolled back. | |
| authority | No | Authority axis, independent from job function and placement | |
| force_new | No | When true, suppress same repo/workspace/role duplicate-lane warnings. Default false so collab leads see reusable existing agents before spawning another lane. | |
| placement | No | Physical placement axis: left or right. It must agree with authority (lead=left, worker=right). Legacy orchestrator/worker aliases remain accepted. | |
| workspace | No | Target workspace ref. Omit to use the caller/current workspace; pass only when intentionally spawning in a different workspace. | |
| collab_path | No | Lead coordination file; workers inherit their parent lead collab_path unless explicitly supplied. | |
| mcp_profile | No | MCP profile hint for worktree launches. Defaults to inherit. Use sterile/skill_eval or include/exclude lists for narrower evals. | |
| report_path | No | Optional ABSOLUTE override for the engine-issued report path. Omit in almost all cases: the engine issues ~/.cmux/agents/<agent_id>/report.md and verifies closure against it. Pass a distinct FILE path per child (never a directory) to place a report somewhere you already watch. report_path, done_marker, contract_path, coordination_footer_delivered and coordination_footer_note are verbose:true-only fields; the default warning contains any required relay instruction with its exact issued paths or marker. For resume_agent_id calls, coordination_footer_note is folded into warning: the pointer was deliberately not re-delivered, so relay only if the restored session lost its original context. For new spawns, when contract_path is present and folded pointer submission was queued or unverified, warning includes the pointer. Inspect the pane, then relay with send_to({agent_id, text:"Read and follow <contract_path>", press_enter:true}); do not use raw cmux send/send-key. When contract_path is absent, inline mode is active or the contract file could not be written, so warning tells YOU to relay report_path and done_marker. | |
| halt_escalation | No | Notify the nearest live ancestor when this agent remains awaiting input, idle without done evidence, or wedged past its dwell threshold. Set false for deliberate debugging lanes. | |
| parent_agent_id | No | ID of the parent agent for hierarchical spawning. Normally inferred from the managed caller surface; pass explicitly only when no managed caller supplies the hierarchy. Parent must exist. | |
| resume_agent_id | No | THE way to revive an agent: resume this captured session on a fresh surface, keeping its public agent ID and re-issuing its coordination contract. cmuxlayer never revives a pane by itself (#492) -- a pane you close stays closed -- so a lead that wants an agent back asks here, by id. Refused with a reason when the session transcript is not on disk, rather than opening an empty pane. Use {resume_agent_id:"..."}; omit all new-spawn fields listed in the tool description. Optional resume controls remain supported. Check current readiness before sending a new task separately with send_to; no task is automatically resent. | |
| boot_prompt_path | No | New spawn only; omit on resume. Optional readable prompt-file path. Checked before spawning; multiline or over-cap files are submitted as one `Read and follow <path>` pointer and one final return after readiness. Mutually exclusive with prompt. | |
| allow_long_inline | No | Bypass the inline prompt length cap for a deliberate raw boot-prompt send. Prefer boot_prompt_path for large prompts. | |
| max_cost_per_agent | No | Maximum cost cap in USD for this agent | |
| auto_archive_on_done | No | Deprecated compatibility flag. TASK_DONE updates agent state only; cmuxlayer does not auto-close panes. | |
| boot_prompt_timeout_ms | No | Optional timeout override in milliseconds for pane placement, initial shell readiness, agent launch readiness, and the boot prompt. When omitted, each phase keeps its established default (45s placement, 10s shell, 15s launch, 60s boot prompt). |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| cwd | No | |
| role | No | |
| type | No | |
| state | No | |
| title | No | |
| version | No | |
| warning | No | |
| agent_id | No | |
| delivered | No | |
| surface_id | No | |
| cwd_receipt | No | |
| done_marker | No | |
| next_action | No | |
| report_path | No | |
| retry_count | No | |
| spawn_state | No | |
| workspace_id | No | |
| contract_path | No | |
| delivered_chars | No | |
| parent_agent_id | No | |
| boot_prompt_bytes | No | |
| boot_prompt_receipt | No | |
| update_menu_skipped | No | |
| boot_prompt_delivered | No | |
| update_menu_text_hash | No | |
| coordination_footer_note | No | |
| coordination_footer_bytes | No | |
| boot_prompt_submit_verified | No | |
| coordination_footer_delivered | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the mutation profile (readOnlyHint=false, destructiveHint=false, idempotentHint=false), and the description adds substantial behavioral context: ok/state:started is lifecycle-only, pending_verify means unverified delivery, verbose expands the receipt, failures keep full detail. However, much of this repeats or elaborates on schema-provided information (verbose, report_path, force) rather than disclosing unannotated traits such as permissions or rate limits, so it sits slightly above baseline rather than at the top.
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 critical resume instruction is front-loaded, but the body is a dense run-on of overlapping clauses (INVALID_RESUME_SPEC, ok/state semantics, chooser handling, pending_verify, placement, default fields, verbose) with some repetition about omitting new-spawn fields. Given 29 parameters the length is defensible, but structure could be tighter.
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?
For a 29-parameter mutation tool with an output schema present, the description covers mode selection, the resume field contract, receipt shape, failure behavior, and readiness gating, leaving nothing an agent needs in order to invoke it correctly unstated.
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%, and the required parameters are all extensively documented in the schema itself. The description adds real routing value by enumerating the new-spawn-only fields that must be omitted on resume and confirming which resume controls (force, workspace, focus, report_path, verbose) remain valid, but most per-parameter meaning is already in the schema. Baseline 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 opening sentence states a specific verb (spawn/resume) and resource (managed agent or terminal) and explicitly splits the two modes: new spawn vs. resume-preserving-ID. It distinguishes itself from siblings by naming the resume path and contrasting it with sending a task via send_to.
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?
It gives explicit when-to-do-what: omit new-spawn fields on resume or get INVALID_RESUME_SPEC, use send_to separately for a new task, inspect with read_screen at a chooser or permission prompt, and follow wait_for guidance on pending_verify. Alternatives are named rather than implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_surfaceB
Move or rename a surface, or adopt_session to rebind an existing managed Claude or Codex identity after a restart using pinned historical evidence and fresh process/topology proof. Adoption changes no pane or input; layout reconciliation follows separately.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | ||
| pane | No | ||
| role | No | ||
| after | No | ||
| focus | No | ||
| index | No | ||
| model | No | ||
| title | No | ||
| action | Yes | ||
| before | No | ||
| surface | Yes | ||
| authority | No | ||
| placement | No | ||
| workspace | No | ||
| launch_cwd | No | ||
| session_id | No | ||
| collab_path | No | ||
| parent_agent_id | No | ||
| preserve_prefix | No | ||
| managed_agent_id | No | ||
| observer_transition | No | ||
| binding_evidence_path | No | ||
| expected_agent_version | No | ||
| binding_evidence_sha256 | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| pane | No | |
| title | No | |
| action | No | |
| surface | No | |
| workspace | No | |
| retry_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (not read-only, not destructive, not idempotent), so the bar is lower. The description still adds non-obvious behavior: adoption rebinds an identity without touching pane or input, requires pinned historical evidence plus fresh process/topology proof, and defers layout reconciliation to a separate step.
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?
Two dense but front-loaded sentences with essentially no filler; the primary actions lead and the adoption nuances follow. It is appropriately sized given the tool's complexity, though the second sentence's phrasing is slightly convoluted.
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 need no explanation, and the adopt_session path is reasonably described. But for a 24-parameter tool with zero schema descriptions and three enum actions, the move/rename paths and most parameter semantics are unexplained, leaving real gaps.
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 0% across 24 parameters, so the description must carry the burden and does not. It hints at the evidence/observer concepts (binding evidence, historical owner) but never explains surface, pane, index, before/after, preserve_prefix, workspace, or the observer_transition object, leaving most inputs opaque.
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 names three concrete actions (move, rename, adopt_session) against the 'surface' resource, so the agent knows what operation family it is entering. It is distinguishable from siblings like close_surface and list_surfaces by the mutate/rebind framing, though it never explicitly contrasts with them.
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?
It gives a real usage condition for adopt_session ('after a restart ... using pinned historical evidence and fresh process/topology proof') and notes that layout reconciliation happens separately. However, move and rename receive no when-to-use guidance, and there are no exclusions or sibling routing hints.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wait_forB
Block until one agent_id or every agent in ids reaches a target registry state and return health. Defaults to waiting for completion (done).
| Name | Required | Description | Default |
|---|---|---|---|
| ids | No | Agent IDs to wait for together | |
| mine | No | Wait for every direct child of the calling agent | |
| watch | No | Declared WatchSpec alternative to agent_id/ids | |
| agent_id | No | Single agent ID from spawn_agent | |
| condition | No | Alias for target_state | |
| timeout_ms | No | Timeout in milliseconds (default: 5 minutes) | |
| delivery_id | No | Wait for a send_to delivery_id to reach a terminal outcome | |
| done_marker | No | Final-line marker for report_path | |
| report_path | No | With done_marker and agent_id: file-backed done. Matches when this ABSOLUTE file's final non-empty line equals done_marker, the same report contract spawn_agent issues. After symlinks resolve it must be a regular file (max 1 MiB) under ~/.cmux/agents/<agent_id>/ or ~/.cmux/live-harness/, else refused. An agent in error never matches. | |
| target_state | No | State to wait for |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| typed | No | |
| watch | No | |
| results | No | |
| agent_id | No | |
| delivery | No | |
| terminal | No | |
| delivered | No | |
| timed_out | No | |
| delivery_id | No | |
| retry_count | Yes | |
| rpc_methods | No | |
| duplicate_of | No | |
| delivery_state | No | |
| needs_attention | No | |
| submit_evidence | No | |
| submit_verified | No | |
| attention_reason | No | |
| submit_attempted | No | |
| submit_dispatched | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description usefully discloses blocking semantics and that health is returned, which the annotations (readOnlyHint=false, idempotentHint=false) do not convey. It omits what happens on timeout, whether a timeout is an error or a normal return, and that the input is a set of mutually exclusive modes. No contradiction with the annotations.
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?
Two tight sentences, front-loaded with the blocking verb and scope, with no filler. Every sentence earns its place.
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?
For a 10-parameter tool with a nested WatchSpec and multiple mutually exclusive wait modes, the description accounts for only the agent-state mode. A caller cannot learn from it that file-marker watches, delivery-outcome waits, or file-backed done markers exist, so it is materially incomplete even though an output schema exists.
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 10 parameters are already documented in the schema and the baseline is 3. The description echoes agent_id/ids/target_state but adds no meaning beyond the schema, and says nothing about the nested watch object or the delivery_id/report_path alternatives.
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?
States a specific verb ('Block until') and resource (an agent_id or every agent in ids reaching a target registry state) plus the default target of 'done'. However, it only describes one of the several wait modes the schema exposes (watch, delivery_id, report_path), so it under-describes the tool's actual scope.
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 only usage information is the implicit default ('Defaults to waiting for completion'), which is already carried by the target_state default in the schema. It never says when to prefer this over sibling approaches such as list_agents or read_screen, nor when not to use it.
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.
4 tool updates
v0.4.106- Changed
send_to4 fields changed- added
Input schema / properties / codex_busy_modeAdded value: +{ + "description": "Busy Codex defaults to Return steering at the next tool call; queue opts into Tab after-turn delivery. Neither pending state is delivered.", + "enum": [ + "steer", + "queue" + ], + "type": "string" +} - changed
Output schema / properties / delivery / enumPrevious value: -[ - "submitted", - "typed", - "queued", - "queued_followup", - "rescued", - "failed", - "pending_verify", - "failed_confirmed", - "stalled_queue" -]New value: +[ + "submitted", + "typed", + "queued", + "steer_pending", + "queued_followup", + "rescued", + "failed", + "pending_verify", + "failed_confirmed", + "stalled_queue" +] - changed
Output schema / properties / delivery_state / enumPrevious value: -[ - "submitted", - "typed", - "queued", - "queued_followup", - "rescued", - "failed", - "pending_verify", - "failed_confirmed", - "stalled_queue" -]New value: +[ + "submitted", + "typed", + "queued", + "steer_pending", + "queued_followup", + "rescued", + "failed", + "pending_verify", + "failed_confirmed", + "stalled_queue" +] - changed
Output schema / requiredPrevious value: -[ - "ok", - "retry_count" -]New value: +[ + "ok" +]
- Changed
spawn_agent18 fields changed- changed
Input schema / properties / boot_prompt_path / descriptionPrevious value: -"Optional readable prompt-file path. Checked before spawning; multiline or over-cap files are submitted as one `Read and follow <path>` pointer and one final return after readiness. Mutually exclusive with prompt."New value: +"New spawn only; omit on resume. Optional readable prompt-file path. Checked before spawning; multiline or over-cap files are submitted as one `Read and follow <path>` pointer and one final return after readiness. Mutually exclusive with prompt." - changed
Input schema / properties / cli / descriptionPrevious value: -"CLI tool to launch"New value: +"New spawn only; omit on resume. CLI tool to launch" - removed
Input schema / properties / focus / defaultRemoved value: -false - changed
Input schema / properties / focus / descriptionPrevious value: -"Leave focus on the created agent tab instead of restoring the exact origin after initialization."New value: +"Leave focus on the created tab instead of restoring the exact origin after initialization. Resume and bare terminals: false forbids focus and fails closed if background initialization is unavailable; omitted may temporarily focus to initialize, then restore the origin. Fresh managed agents retain legacy initialization focus." - changed
Input schema / properties / prompt / descriptionPrevious value: -"Max 2-3 short lines. Longer payloads BREAK the receiving pane — write the payload to a file and send one line: `Read and follow <path>`. Inline task prompt to send after the agent is ready. Capped at 500 inline UTF-8 bytes by default; use boot_prompt_path for larger prompts. Mutually exclusive with boot_prompt_path."New value: +"Max 2-3 short lines. Longer payloads BREAK the receiving pane — write the payload to a file and send one line: `Read and follow <path>`. New spawn only; omit on resume and send a new task separately with send_to after checking readiness. Inline task prompt to send after the agent is ready. Capped at 500 inline UTF-8 bytes by default; use boot_prompt_path for larger prompts. Mutually exclusive with boot_prompt_path." - changed
Input schema / properties / repo / descriptionPrevious value: -"Repository name (e.g. 'brainlayer', 'golems')"New value: +"New spawn only; omit on resume. Repository name (e.g. 'brainlayer', 'golems')" - changed
Input schema / properties / report_path / descriptionPrevious value: -"Optional ABSOLUTE override for the engine-issued report path. Omit in almost all cases: the engine issues ~/.cmux/agents/<agent_id>/report.md, returns it here, and verifies closure against it. Pass a distinct FILE path per child (never a directory) to place a report somewhere you already watch. Check coordination_footer_delivered. For resume_agent_id calls, false means the pointer was deliberately not re-delivered: follow coordination_footer_note and relay only if the restored session lost its original context. For new spawns, if false and contract_path is present, folded pointer submission was queued or unverified. Inspect the pane, then relay with send_to({agent_id, text:\"Read and follow <contract_path>\", press_enter:true}); do not use raw cmux send/send-key. If false and contract_path is absent, inline mode is active or the contract file could not be written, so YOU must relay report_path and done_marker."New value: +"Optional ABSOLUTE override for the engine-issued report path. Omit in almost all cases: the engine issues ~/.cmux/agents/<agent_id>/report.md and verifies closure against it. Pass a distinct FILE path per child (never a directory) to place a report somewhere you already watch. report_path, done_marker, contract_path, coordination_footer_delivered and coordination_footer_note are verbose:true-only fields; the default warning contains any required relay instruction with its exact issued paths or marker. For resume_agent_id calls, coordination_footer_note is folded into warning: the pointer was deliberately not re-delivered, so relay only if the restored session lost its original context. For new spawns, when contract_path is present and folded pointer submission was queued or unverified, warning includes the pointer. Inspect the pane, then relay with send_to({agent_id, text:\"Read and follow <contract_path>\", press_enter:true}); do not use raw cmux send/send-key. When contract_path is absent, inline mode is active or the contract file could not be written, so warning tells YOU to relay report_path and done_marker." - changed
Input schema / properties / resume_agent_id / descriptionPrevious value: -"THE way to revive an agent: resume this captured session on a fresh surface, keeping its public agent ID and re-issuing its coordination contract. cmuxlayer never revives a pane by itself (#492) -- a pane you close stays closed -- so a lead that wants an agent back asks here, by id. Refused with a reason when the session transcript is not on disk, rather than opening an empty pane. Mutually exclusive with new-spawn fields."New value: +"THE way to revive an agent: resume this captured session on a fresh surface, keeping its public agent ID and re-issuing its coordination contract. cmuxlayer never revives a pane by itself (#492) -- a pane you close stays closed -- so a lead that wants an agent back asks here, by id. Refused with a reason when the session transcript is not on disk, rather than opening an empty pane. Use {resume_agent_id:\"...\"}; omit all new-spawn fields listed in the tool description. Optional resume controls remain supported. Check current readiness before sending a new task separately with send_to; no task is automatically resent." - changed
Input schema / properties / role / descriptionPrevious value: -"Agent job function: implementor, reviewer, or gatherer. Legacy orchestrator/worker aliases remain accepted for compatibility. Claude requires this field explicitly."New value: +"Agent job function: implementor, reviewer, or gatherer. Lead callers may omit it to spawn an implementor with worker authority on the right by default; explicit roles and axes still apply. Legacy orchestrator/worker aliases remain accepted. Other Claude callers require an explicit role." - changed
Input schema / properties / verbose / descriptionPrevious value: -"Return the full legacy spawn response instead of the lean default."New value: +"Return the full success receipt, including contract_path, report_path, done_marker, transport, worktree, and diagnostics; defaults to at most six fields. Failures always keep full detail." - changed
Output schema / properties / agent_id / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / cwd_receipt / properties / delivery / enumPrevious value: -[ - "submitted", - "typed", - "queued", - "queued_followup", - "rescued", - "failed", - "pending_verify", - "failed_confirmed", - "stalled_queue" -]New value: +[ + "submitted", + "typed", + "queued", + "steer_pending", + "queued_followup", + "rescued", + "failed", + "pending_verify", + "failed_confirmed", + "stalled_queue" +] - changed
Output schema / properties / cwd_receipt / properties / delivery_state / enumPrevious value: -[ - "submitted", - "typed", - "queued", - "queued_followup", - "rescued", - "failed", - "pending_verify", - "failed_confirmed", - "stalled_queue" -]New value: +[ + "submitted", + "typed", + "queued", + "steer_pending", + "queued_followup", + "rescued", + "failed", + "pending_verify", + "failed_confirmed", + "stalled_queue" +] - added
Output schema / properties / deliveredAdded value: +{ + "type": "boolean" +} - changed
Output schema / properties / spawn_state / enumPrevious value: -[ - "started", - "boot_unsubmitted" -]New value: +[ + "started", + "boot_unsubmitted", + "pending_verify" +] - added
Output schema / properties / stateAdded value: +{ + "type": "string" +} - added
Output schema / properties / warningAdded value: +{ + "type": "string" +} - changed
Output schema / requiredPrevious value: -[ - "ok", - "retry_count" -]New value: +[ + "ok" +]
- Changed
update_surface16 fields changed- changed
Input schema / properties / action / enumPrevious value: -[ - "move", - "rename" -]New value: +[ + "move", + "rename", + "adopt_session" +] - added
Input schema / properties / authorityAdded value: +{ + "not": {} +} - added
Input schema / properties / binding_evidence_pathAdded value: +{ + "type": "string" +} - added
Input schema / properties / binding_evidence_sha256Added value: +{ + "pattern": "^[a-f0-9]{64}$", + "type": "string" +} - added
Input schema / properties / collab_pathAdded value: +{ + "not": {} +} - added
Input schema / properties / cwdAdded value: +{ + "not": {} +} - added
Input schema / properties / expected_agent_versionAdded value: +{ + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / launch_cwdAdded value: +{ + "not": {} +} - added
Input schema / properties / managed_agent_idAdded value: +{ + "minLength": 1, + "type": "string" +} - added
Input schema / properties / modelAdded value: +{ + "not": {} +} - added
Input schema / properties / observer_transitionAdded value: +{ + "additionalProperties": false, + "properties": { + "current_owner_id": { + "minLength": 1, + "type": "string" + }, + "historical_owner_id": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "historical_owner_id", + "current_owner_id" + ], + "type": "object" +} - added
Input schema / properties / parent_agent_idAdded value: +{ + "not": {} +} - added
Input schema / properties / placementAdded value: +{ + "not": {} +} - added
Input schema / properties / roleAdded value: +{ + "not": {} +} - added
Input schema / properties / session_idAdded value: +{ + "minLength": 1, + "type": "string" +} - changed
Output schema / properties / action / enumPrevious value: -[ - "move", - "rename" -]New value: +[ + "move", + "rename", + "adopt_session" +]
- Changed
wait_for2 fields changed- changed
Output schema / properties / delivery / enumPrevious value: -[ - "submitted", - "typed", - "queued", - "queued_followup", - "rescued", - "failed", - "pending_verify", - "failed_confirmed", - "stalled_queue" -]New value: +[ + "submitted", + "typed", + "queued", + "steer_pending", + "queued_followup", + "rescued", + "failed", + "pending_verify", + "failed_confirmed", + "stalled_queue" +] - changed
Output schema / properties / delivery_state / enumPrevious value: -[ - "submitted", - "typed", - "queued", - "queued_followup", - "rescued", - "failed", - "pending_verify", - "failed_confirmed", - "stalled_queue" -]New value: +[ + "submitted", + "typed", + "queued", + "steer_pending", + "queued_followup", + "rescued", + "failed", + "pending_verify", + "failed_confirmed", + "stalled_queue" +]
1 tool update
v0.4.92- Changed
spawn_agent4 fields changed- changed
Input schema / properties / effort / descriptionPrevious value: -"Codex reasoning effort, passed to the repoGolem launcher. CHOOSE THIS DELIBERATELY PER MISSION — it is a cost decision, not a default to inherit. The installed launcher currently accepts: low, medium, high, xhigh, max, ultra. spawn_agent rejects other values before creating a worktree or surface. The live launcher defaults to HIGH when omitted (~/.config/ralphtools/golem-dispatch.zsh). Per /agent-routing, MEDIUM is the settled floor for well-specified implementation lanes — use it unless the task genuinely needs more; xhigh and above burn budget fast and are rarely warranted for a lane with a clear brief."New value: +"Required for codex new agent spawns: low, medium, high, xhigh, max, ultra. Choose deliberately: medium for well-specified lanes, high for security/open-ended; xhigh and above cost more. Omit on resume (the session keeps its effort) and for other CLIs (effort is invalid)." - changed
Input schema / properties / effort / enumPrevious value: -[ - "low", - "medium", - "high", - "xhigh", - "max", - "ultra" -]New value: +[ + "low", + "medium", + "high", + "xhigh", + "max", + "ultra", + "" +] - changed
Input schema / properties / force / descriptionPrevious value: -"With resume_agent_id only: override inconclusive recorded-process liveness after the caller deliberately verifies the old agent is gone. Does not bypass session or terminal-state requirements."New value: +"With resume_agent_id only: override missing or inconclusive proof that the old session is not running (no recorded pid, an unproven pid, an unreadable topology or process table) after the caller deliberately verifies the old agent is gone. Does not bypass session or terminal-state requirements." - changed
Input schema / properties / report_path / descriptionPrevious value: -"Optional ABSOLUTE override for the engine-issued report path. Omit in almost all cases: the engine issues ~/.cmux/agents/<agent_id>/report.md, returns it here, and verifies closure against it. Pass a distinct FILE path per child (never a directory) to place a report somewhere you already watch. Check coordination_footer_delivered. For resume_agent_id calls, false means the pointer was deliberately not re-delivered: follow coordination_footer_note and relay only if the restored session lost its original context. For new spawns, if false and contract_path is present, folded pointer submission was queued or unverified, so YOU must relay contract_path, report_path, and done_marker. If false and contract_path is absent, inline mode is active or the contract file could not be written, so YOU must relay report_path and done_marker."New value: +"Optional ABSOLUTE override for the engine-issued report path. Omit in almost all cases: the engine issues ~/.cmux/agents/<agent_id>/report.md, returns it here, and verifies closure against it. Pass a distinct FILE path per child (never a directory) to place a report somewhere you already watch. Check coordination_footer_delivered. For resume_agent_id calls, false means the pointer was deliberately not re-delivered: follow coordination_footer_note and relay only if the restored session lost its original context. For new spawns, if false and contract_path is present, folded pointer submission was queued or unverified. Inspect the pane, then relay with send_to({agent_id, text:\"Read and follow <contract_path>\", press_enter:true}); do not use raw cmux send/send-key. If false and contract_path is absent, inline mode is active or the contract file could not be written, so YOU must relay report_path and done_marker."
1 tool update
v0.4.89- Changed
wait_for1 field changed- changed
Input schema / properties / report_path / descriptionPrevious value: -"With done_marker and agent_id: file-backed done. Matches when this ABSOLUTE file's final non-empty line equals done_marker, the same report contract spawn_agent issues. After symlinks resolve it must sit under ~/.cmux/ or ~/.cmux/agents/<agent_id>/, else refused."New value: +"With done_marker and agent_id: file-backed done. Matches when this ABSOLUTE file's final non-empty line equals done_marker, the same report contract spawn_agent issues. After symlinks resolve it must be a regular file (max 1 MiB) under ~/.cmux/agents/<agent_id>/ or ~/.cmux/live-harness/, else refused. An agent in error never matches."
24 tool updates
v0.4.88- Removed
browser_surface - Changed
close_surface5 fields changed- added
Input schema / properties / agent_idAdded value: +{ + "description": "Managed agent ID", + "type": "string" +} - added
Input schema / properties / forceAdded value: +{ + "default": false, + "description": "Close even when the backing agent is still live (not done/error). This never bypasses stable surface identity checks. Without force, a live agent's surface is protected and the response returns the current pane contents instead of closing.", + "type": "boolean" +} - added
Input schema / properties / scopeAdded value: +{ + "default": "surface", + "enum": [ + "surface", + "agent", + "workspace" + ], + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "surface" -] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "agent_id": { + "type": "string" + }, + "agents": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "caller_workspace": { + "type": "boolean" + }, + "collapse_pane": { + "type": "boolean" + }, + "force": { + "type": "boolean" + }, + "live_agents": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "ok": { + "type": "boolean" + }, + "pane": { + "type": "string" + }, + "refused": { + "type": "boolean" + }, + "removed": { + "additionalProperties": {}, + "type": "object" + }, + "retry_count": { + "minimum": 0, + "type": "integer" + }, + "scope": { + "enum": [ + "surface", + "agent", + "workspace" + ], + "type": "string" + }, + "state": { + "type": "string" + }, + "surface": { + "type": "string" + }, + "surfaces": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "workspace": { + "type": "string" + } + }, + "required": [ + "ok", + "retry_count" + ], + "type": "object" +}
- Added
control_health - Removed
get_agent_state - Removed
interact - Removed
kill - Changed
list_agents7 fields changed- added
Input schema / properties / agent_idsAdded value: +{ + "description": "Return only these agent IDs", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / blocked_on_promptAdded value: +{ + "description": "Return only agents whose registry records show a live prompt blocker", + "type": "boolean" +} - added
Input schema / properties / detailAdded value: +{ + "default": "summary", + "description": "summary (default): flat addressable scalar rows. full: provenance, health diagnostics, the full registry record, and up to 20 unresolved or attention delivery receipts.", + "enum": [ + "summary", + "full" + ], + "type": "string" +} - added
Input schema / properties / max_age_msAdded value: +{ + "description": "Maximum acceptable snapshot age in milliseconds (0-5000); topology changes always invalidate the snapshot", + "maximum": 5000, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / mineAdded value: +{ + "default": false, + "description": "Return direct children of the calling agent", + "type": "boolean" +} - added
Input schema / properties / parent_agent_idAdded value: +{ + "description": "Return direct children of this agent", + "type": "string" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "agents": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "count": { + "minimum": 0, + "type": "integer" + }, + "derived_at": { + "type": "number" + }, + "ok": { + "type": "boolean" + }, + "retry_count": { + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "ok", + "retry_count" + ], + "type": "object" +}
- Changed
list_surfaces2 fields changed- added
Input schema / properties / verboseAdded value: +{ + "default": false, + "description": "Return all raw cmux fields instead of the condensed default. This materially increases token usage and is rarely needed; use it only when a specific raw field is required.", + "type": "boolean" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "column_count": { + "minimum": 0, + "type": "integer" + }, + "ok": { + "type": "boolean" + }, + "retry_count": { + "minimum": 0, + "type": "integer" + }, + "surfaces": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "workspaces": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "ok", + "retry_count" + ], + "type": "object" +}
- Removed
new_split - Removed
read_agent_output - Changed
read_screen5 fields changed- added
Input schema / properties / parsed_onlyAdded value: +{ + "default": false, + "description": "If true, return only parsed fields (omit screen content). Best for agent monitoring.", + "type": "boolean" +} - added
Input schema / properties / rawAdded value: +{ + "default": false, + "description": "If true, include the full untrimmed terminal content (separators, status-bar art, all lines). Default false returns a compact de-chromed screen_preview instead.", + "type": "boolean" +} - added
Input schema / properties / surface_idAdded value: +{ + "description": "Alias for `surface`, as emitted by list_agents/spawn_agent.", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "surface" -] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "ok": { + "type": "boolean" + }, + "parsed": { + "additionalProperties": {}, + "type": "object" + }, + "retry_count": { + "minimum": 0, + "type": "integer" + }, + "surface": { + "type": "string" + } + }, + "required": [ + "ok", + "retry_count" + ], + "type": "object" +}
- Removed
rename_tab - Added
report_to_parent - Removed
send_input - Removed
send_key - Added
send_to - Removed
send_to_agent - Removed
set_progress - Removed
set_status - Changed
spawn_agent29 fields changed- added
Input schema / properties / allow_long_inlineAdded value: +{ + "default": false, + "description": "Bypass the inline prompt length cap for a deliberate raw boot-prompt send. Prefer boot_prompt_path for large prompts.", + "type": "boolean" +} - added
Input schema / properties / authorityAdded value: +{ + "description": "Authority axis, independent from job function and placement", + "enum": [ + "lead", + "worker" + ], + "type": "string" +} - added
Input schema / properties / auto_archive_on_doneAdded value: +{ + "default": false, + "description": "Deprecated compatibility flag. TASK_DONE updates agent state only; cmuxlayer does not auto-close panes.", + "type": "boolean" +} - added
Input schema / properties / boot_prompt_pathAdded value: +{ + "description": "Optional readable prompt-file path. Checked before spawning; multiline or over-cap files are submitted as one `Read and follow <path>` pointer and one final return after readiness. Mutually exclusive with prompt.", + "type": [ + "string", + "null" + ] +} - added
Input schema / properties / boot_prompt_timeout_msAdded value: +{ + "description": "Optional timeout override in milliseconds for pane placement, initial shell readiness, agent launch readiness, and the boot prompt. When omitted, each phase keeps its established default (45s placement, 10s shell, 15s launch, 60s boot prompt).", + "exclusiveMinimum": 0, + "type": "integer" +} - added
Input schema / properties / collab_pathAdded value: +{ + "description": "Lead coordination file; workers inherit their parent lead collab_path unless explicitly supplied.", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / cwdAdded value: +{ + "description": "Initial working directory for type=terminal", + "type": "string" +} - added
Input schema / properties / effortAdded value: +{ + "description": "Codex reasoning effort, passed to the repoGolem launcher. CHOOSE THIS DELIBERATELY PER MISSION — it is a cost decision, not a default to inherit. The installed launcher currently accepts: low, medium, high, xhigh, max, ultra. spawn_agent rejects other values before creating a worktree or surface. The live launcher defaults to HIGH when omitted (~/.config/ralphtools/golem-dispatch.zsh). Per /agent-routing, MEDIUM is the settled floor for well-specified implementation lanes — use it unless the task genuinely needs more; xhigh and above burn budget fast and are rarely warranted for a lane with a clear brief.", + "enum": [ + "low", + "medium", + "high", + "xhigh", + "max", + "ultra" + ], + "type": "string" +} - added
Input schema / properties / focusAdded value: +{ + "default": false, + "description": "Leave focus on the created agent tab instead of restoring the exact origin after initialization.", + "type": "boolean" +} - added
Input schema / properties / forceAdded value: +{ + "default": false, + "description": "With resume_agent_id only: override inconclusive recorded-process liveness after the caller deliberately verifies the old agent is gone. Does not bypass session or terminal-state requirements.", + "type": "boolean" +} - added
Input schema / properties / force_newAdded value: +{ + "default": false, + "description": "When true, suppress same repo/workspace/role duplicate-lane warnings. Default false so collab leads see reusable existing agents before spawning another lane.", + "type": "boolean" +} - added
Input schema / properties / halt_escalationAdded value: +{ + "default": true, + "description": "Notify the nearest live ancestor when this agent remains awaiting input, idle without done evidence, or wedged past its dwell threshold. Set false for deliberate debugging lanes.", + "type": "boolean" +} - added
Input schema / properties / max_cost_per_agentAdded value: +{ + "description": "Maximum cost cap in USD for this agent", + "type": "number" +} - added
Input schema / properties / mcp_profileAdded value: +{ + "anyOf": [ + { + "enum": [ + "inherit", + "sterile", + "skill_eval" + ], + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "include": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + } + ], + "description": "MCP profile hint for worktree launches. Defaults to inherit. Use sterile/skill_eval or include/exclude lists for narrower evals." +} - changed
Input schema / properties / model / descriptionPrevious value: -"Model name (e.g. 'sonnet', 'codex', 'opus')"New value: +"OPTIONAL — leave UNSET so the launcher pins the top-tier model. For cli:'codex', an explicit model is checked against Codex's runtime model list before any worktree or surface is created, then passed through to the launcher. Never pass 'opus' for claude — the top Claude model is already the default." - added
Input schema / properties / parent_agent_idAdded value: +{ + "description": "ID of the parent agent for hierarchical spawning. Normally inferred from the managed caller surface; pass explicitly only when no managed caller supplies the hierarchy. Parent must exist.", + "type": "string" +} - added
Input schema / properties / placementAdded value: +{ + "description": "Physical placement axis: left or right. It must agree with authority (lead=left, worker=right). Legacy orchestrator/worker aliases remain accepted.", + "enum": [ + "left", + "right", + "orchestrator", + "worker" + ], + "type": "string" +} - changed
Input schema / properties / prompt / descriptionPrevious value: -"Task prompt to send after agent is ready"New value: +"Max 2-3 short lines. Longer payloads BREAK the receiving pane — write the payload to a file and send one line: `Read and follow <path>`. Inline task prompt to send after the agent is ready. Capped at 500 inline UTF-8 bytes by default; use boot_prompt_path for larger prompts. Mutually exclusive with boot_prompt_path." - added
Input schema / properties / report_pathAdded value: +{ + "description": "Optional ABSOLUTE override for the engine-issued report path. Omit in almost all cases: the engine issues ~/.cmux/agents/<agent_id>/report.md, returns it here, and verifies closure against it. Pass a distinct FILE path per child (never a directory) to place a report somewhere you already watch. Check coordination_footer_delivered. For resume_agent_id calls, false means the pointer was deliberately not re-delivered: follow coordination_footer_note and relay only if the restored session lost its original context. For new spawns, if false and contract_path is present, folded pointer submission was queued or unverified, so YOU must relay contract_path, report_path, and done_marker. If false and contract_path is absent, inline mode is active or the contract file could not be written, so YOU must relay report_path and done_marker.", + "type": "string" +} - added
Input schema / properties / resume_agent_idAdded value: +{ + "description": "THE way to revive an agent: resume this captured session on a fresh surface, keeping its public agent ID and re-issuing its coordination contract. cmuxlayer never revives a pane by itself (#492) -- a pane you close stays closed -- so a lead that wants an agent back asks here, by id. Refused with a reason when the session transcript is not on disk, rather than opening an empty pane. Mutually exclusive with new-spawn fields.", + "type": "string" +} - added
Input schema / properties / roleAdded value: +{ + "description": "Agent job function: implementor, reviewer, or gatherer. Legacy orchestrator/worker aliases remain accepted for compatibility. Claude requires this field explicitly.", + "enum": [ + "orchestrator", + "worker", + "implementor", + "reviewer", + "gatherer" + ], + "type": "string" +} - added
Input schema / properties / titleAdded value: +{ + "description": "The caller-supplied agent pane title is applied verbatim (for example `cmuxlayer-WORKER · run1 name-the-tabs`); when omitted or blank, the existing agent-id/surface fallback is retained. Managed identity comes from the agent registry, not this display title (#479/#492).", + "type": "string" +} - added
Input schema / properties / typeAdded value: +{ + "default": "agent", + "description": "Spawn an AI agent or a plain terminal", + "enum": [ + "agent", + "terminal" + ], + "type": "string" +} - added
Input schema / properties / verboseAdded value: +{ + "default": false, + "description": "Return the full legacy spawn response instead of the lean default.", + "type": "boolean" +} - added
Input schema / properties / versionAdded value: +{ + "const": 1, + "default": 1, + "description": "SpawnSpec schema version", + "type": "number" +} - changed
Input schema / properties / workspace / descriptionPrevious value: -"Target workspace ref"New value: +"Target workspace ref. Omit to use the caller/current workspace; pass only when intentionally spawning in a different workspace." - added
Input schema / properties / worktreeAdded value: +{ + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "base": { + "type": "string" + }, + "branch": { + "type": "string" + }, + "create": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "reuse": { + "type": "boolean" + } + }, + "type": "object" + } + ], + "description": "When set, create or reuse a git worktree before launch. Pass a string such as \"tool-usage\" as the worktree name, true for a generated name, or an object with name, path, branch, base, create, and reuse. When repoGolem registers the repo with an absolute path, that path is the repo root; otherwise the root is resolved from CMUXLAYER_REPO_HOME, the running checkout, or ~/Gits. true uses <registered-root>/.worktrees/<generated-name> (legacy ~/Gits/<repo>.wt read-fallback until ~2026-09). If a later spawn step fails before a recoverable surface exists, a newly created worktree and branch are rolled back." +} - removed
Input schema / requiredRemoved value: -[ - "repo", - "model", - "cli", - "prompt" -] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "agent_id": { + "type": "string" + }, + "boot_prompt_bytes": { + "minimum": 0, + "type": "integer" + }, + "boot_prompt_delivered": { + "type": "boolean" + }, + "boot_prompt_receipt": { + "$ref": "#/properties/cwd_receipt" + }, + "boot_prompt_submit_verified": { + "type": [ + "boolean", + "null" + ] + }, + "contract_path": { + "type": "string" + }, + "coordination_footer_bytes": { + "minimum": 0, + "type": "integer" + }, + "coordination_footer_delivered": { + "type": "boolean" + }, + "coordination_footer_note": { + "type": "string" + }, + "cwd": { + "type": [ + "string", + "null" + ] + }, + "cwd_receipt": { + "additionalProperties": true, + "properties": { + "attention_reason": { + "type": "string" + }, + "bytes": { + "minimum": 0, + "type": "integer" + }, + "delivered": { + "type": "boolean" + }, + "delivery": { + "enum": [ + "submitted", + "typed", + "queued", + "queued_followup", + "rescued", + "failed", + "pending_verify", + "failed_confirmed", + "stalled_queue" + ], + "type": "string" + }, + "delivery_id": { + "type": "string" + }, + "delivery_state": { + "enum": [ + "submitted", + "typed", + "queued", + "queued_followup", + "rescued", + "failed", + "pending_verify", + "failed_confirmed", + "stalled_queue" + ], + "type": "string" + }, + "duplicate_of": { + "type": "string" + }, + "needs_attention": { + "type": "boolean" + }, + "prompt_bytes": { + "minimum": 0, + "type": "integer" + }, + "prompt_sha256": { + "type": "string" + }, + "prompt_warning": { + "type": [ + "string", + "null" + ] + }, + "rpc_methods": { + "items": { + "enum": [ + "surface.send_text", + "surface.send_key" + ], + "type": "string" + }, + "type": "array" + }, + "submit_attempted": { + "type": "boolean" + }, + "submit_dispatched": { + "type": "boolean" + }, + "submit_evidence": { + "anyOf": [ + { + "enum": [ + "token_delta", + "transcript_echo", + "cleared_composer", + "status_only" + ], + "type": "string" + }, + { + "type": "null" + } + ] + }, + "submit_verified": { + "type": [ + "boolean", + "null" + ] + }, + "terminal": { + "type": "boolean" + }, + "typed": { + "type": "boolean" + } + }, + "type": "object" + }, + "delivered_chars": { + "minimum": 0, + "type": "integer" + }, + "done_marker": { + "type": "string" + }, + "next_action": { + "type": "string" + }, + "ok": { + "type": "boolean" + }, + "parent_agent_id": { + "type": [ + "string", + "null" + ] + }, + "report_path": { + "type": "string" + }, + "retry_count": { + "minimum": 0, + "type": "integer" + }, + "role": { + "type": "string" + }, + "spawn_state": { + "enum": [ + "started", + "boot_unsubmitted" + ], + "type": "string" + }, + "surface_id": { + "type": "string" + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "agent", + "terminal" + ], + "type": "string" + }, + "update_menu_skipped": { + "type": "boolean" + }, + "update_menu_text_hash": { + "type": "string" + }, + "version": { + "const": 1, + "type": "number" + }, + "workspace_id": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "ok", + "retry_count" + ], + "type": "object" +}
- Removed
stop_agent - Added
update_surface - Changed
wait_for10 fields changed- changed
Input schema / properties / agent_id / descriptionPrevious value: -"Agent ID from spawn_agent"New value: +"Single agent ID from spawn_agent" - added
Input schema / properties / conditionAdded value: +{ + "description": "Alias for target_state", + "enum": [ + "ready", + "working", + "idle", + "done", + "error" + ], + "type": "string" +} - added
Input schema / properties / delivery_idAdded value: +{ + "description": "Wait for a send_to delivery_id to reach a terminal outcome", + "type": "string" +} - added
Input schema / properties / done_markerAdded value: +{ + "description": "Final-line marker for report_path", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / idsAdded value: +{ + "description": "Agent IDs to wait for together", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / mineAdded value: +{ + "default": false, + "description": "Wait for every direct child of the calling agent", + "type": "boolean" +} - added
Input schema / properties / report_pathAdded value: +{ + "description": "With done_marker and agent_id: file-backed done. Matches when this ABSOLUTE file's final non-empty line equals done_marker, the same report contract spawn_agent issues. After symlinks resolve it must sit under ~/.cmux/ or ~/.cmux/agents/<agent_id>/, else refused.", + "type": "string" +} - added
Input schema / properties / watchAdded value: +{ + "additionalProperties": false, + "description": "Declared WatchSpec alternative to agent_id/ids", + "properties": { + "change": { + "const": "content", + "description": "Persistent file-content change watch; mutually exclusive with predicate and marker", + "type": "string" + }, + "deadline": { + "description": "Absolute Unix deadline in milliseconds", + "exclusiveMinimum": 0, + "type": "integer" + }, + "marker": { + "description": "Literal file marker; mutually exclusive with predicate and change", + "minLength": 1, + "type": "string" + }, + "notify": { + "description": "Opt in to the configured external notification transport", + "type": "boolean" + }, + "owner": { + "description": "Agent/seat notified by the watch", + "minLength": 1, + "type": "string" + }, + "predicate": { + "description": "Agent screen-state predicate: thinking, working, idle, done, error; mutually exclusive with marker and change", + "enum": [ + "thinking", + "working", + "idle", + "done", + "error" + ], + "type": "string" + }, + "target": { + "description": "Absolute file path or public agent_id", + "minLength": 1, + "type": "string" + }, + "watermark": { + "description": "Prior marker count; defaults to count observed at arm time", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "owner", + "target", + "deadline" + ], + "type": "object" +} - removed
Input schema / requiredRemoved value: -[ - "agent_id", - "target_state" -] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "agent_id": { + "type": "string" + }, + "attention_reason": { + "type": "string" + }, + "delivered": { + "type": "boolean" + }, + "delivery": { + "enum": [ + "submitted", + "typed", + "queued", + "queued_followup", + "rescued", + "failed", + "pending_verify", + "failed_confirmed", + "stalled_queue" + ], + "type": "string" + }, + "delivery_id": { + "type": "string" + }, + "delivery_state": { + "enum": [ + "submitted", + "typed", + "queued", + "queued_followup", + "rescued", + "failed", + "pending_verify", + "failed_confirmed", + "stalled_queue" + ], + "type": "string" + }, + "duplicate_of": { + "type": "string" + }, + "needs_attention": { + "type": "boolean" + }, + "ok": { + "type": "boolean" + }, + "results": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "retry_count": { + "minimum": 0, + "type": "integer" + }, + "rpc_methods": { + "items": { + "enum": [ + "surface.send_text", + "surface.send_key" + ], + "type": "string" + }, + "type": "array" + }, + "submit_attempted": { + "type": "boolean" + }, + "submit_dispatched": { + "type": "boolean" + }, + "submit_evidence": { + "anyOf": [ + { + "enum": [ + "token_delta", + "transcript_echo", + "cleared_composer", + "status_only" + ], + "type": "string" + }, + { + "type": "null" + } + ] + }, + "submit_verified": { + "type": [ + "boolean", + "null" + ] + }, + "terminal": { + "type": "boolean" + }, + "timed_out": { + "type": "boolean" + }, + "typed": { + "type": "boolean" + }, + "watch": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "ok", + "retry_count" + ], + "type": "object" +}
- Removed
wait_for_all
20 tool updates
v0.1.0- First observed
browser_surface - First observed
close_surface - First observed
get_agent_state - First observed
interact - First observed
kill - First observed
list_agents - First observed
list_surfaces - First observed
new_split - First observed
read_agent_output - First observed
read_screen - First observed
rename_tab - First observed
send_input - First observed
send_key - First observed
send_to_agent - First observed
set_progress - First observed
set_status - First observed
spawn_agent - First observed
stop_agent - First observed
wait_for - First observed
wait_for_all
TDQS
Scored across 10 tools
Each tool has a reasonably distinct purpose: spawn, send, list, close, read, wait, health, report. There is mild overlap between list_agents and list_surfaces (agents live on surfaces) and among the surface-touching tools (spawn_agent, update_surface, close_surface), but descriptions clarify the boundaries.
Nearly all names are snake_case with a verb_noun or verb_prep pattern (control_health, spawn_agent, list_agents, update_surface, close_surface, list_surfaces, read_screen). Minor deviations are the prepositional forms send_to, wait_for, and report_to_parent, which are still readable and consistent in style.
Ten tools is well within the ideal range and each covers a distinct facet of agent/surface orchestration. No redundant or filler tools appear; the set feels tightly scoped to the domain.
The surface covers the full lifecycle: spawn/resume, list, send, read, wait, update/adopt, close, report, and health. Coverage is strong, with only minor gaps such as no dedicated agent-state update beyond update_surface's adoption path.
Maintenance
Related MCP Connectors
Real-time chat for AI agents. Claude Code, Cursor, Cline and Codex join channels over MCP.
Remote MCP server exposing your Node Command fleet (files, shell, processes, browser) to AI hosts.
Real-time chat hub for AI agents — Claude Code, Cursor, Cline, Codex over MCP or REST.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceTerminal MCP server for AI coding agents with persistent PTY sessions, ring-buffer incremental reads, headless xterm screen capture, multi-agent orchestration, and a real-time web dashboard.14 npm28MIT
- AlicenseAqualityCmaintenanceMCP server for hyperpanes terminal workspace app, enabling AI agents to compose and launch workspace layouts, inspect and drive terminal panes, stream output, and orchestrate agent hierarchies.471MIT
- AlicenseAqualityBmaintenanceMCP server to control Onda terminal from AI agents, providing tools for splitting panes, running commands, managing tabs and workspaces, and orchestrating multi-agent workflows across multiple windows.395 npmMIT
- AlicenseAqualityCmaintenanceMCP server that launches and supervises coding-CLI subagents (claude, opencode) in detached tmux windows, collapsing the ceremony of starting a TUI coding assistant into a single tool call.5MIT