Skip to main content
Glama

cmuxLayer

cmuxLayer exposes a 10-tool public MCP surface for controlling cmux terminal workspaces and managing CLI agents.

install License MCP Tools Tests

Quick start

brew install etanhey/layers/cmuxlayer       # stable, pinned release
brew install --HEAD etanhey/layers/cmuxlayer # or: dogfood the latest main

This 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 init

The 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.json or claude 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_agent

Spawn or resume; default receipt: ok, agent_id, surface_id, state, delivered, optional warning (at most six fields). Use verbose:true for contract and diagnostics; failures keep full detail

report_to_parent

Raise a short blocker to the managed agent's registry parent

send_to

Send by agent ID or raw surface using mode:"agent"|"surface"|"command"|"key"

read_screen

Read terminal output with parsed agent status

list_agents

All agents, with optional filters

wait_for

Wait for one agent_id or several ids (defaults to done)

control_health

Report socket, binary, process, and job-control diagnostics

close_surface

Close one surface, managed agent, or workspace, with live-agent guards

update_surface

Move or rename a surface; explicitly adopt an existing managed session with pinned evidence

list_surfaces

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

claude

status, model, tokens, context %

Codex

codex

status, model, context %

Gemini CLI

gemini

status, model, tokens, context %

Cursor

cursor agent

status, model, tokens, context %

Kiro CLI

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 dispatch

The 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 checking

Git hooks

Enable project hooks to run the regression gate automatically on git push:

git config core.hooksPath .githooks

This 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 output

Contributing

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 tools
close_surfaceA
Destructive

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.

Inputs: force, scope, surface, agent_id, +1 more. Returns: ok, pane, force, scope, +12 more

control_healthA
Read-onlyIdempotent

Report terse control-path health by default; pass detail=full for diagnostics.

Inputs: detail. Returns: ok, health, retry_count

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.

Inputs: mine, repo, model, state, +5 more. Returns: ok, count, agents, derived_at, +1 more

list_surfacesA
Read-onlyIdempotent

List workspace, pane, and surface topology. Condensed by default; verbose=true adds raw cmux fields.

Inputs: verbose, workspace, preview_lines, include_screen_preview. Returns: ok, surfaces, workspaces, retry_count, +1 more

read_screenA
Read-onlyIdempotent

Read a terminal screen and parsed harness status. Use raw=true for full text or parsed_only=true for monitoring.

Inputs: raw, lines, surface, workspace, +3 more. Returns: ok, parsed, surface, retry_count

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.

Inputs: blocker (required). Returns: ok, route, durable, delivery, +6 more

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.

Inputs: mode, text, target, surface, +13 more. Returns: ok, key, model, title, +37 more

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.

Inputs: cli, cwd, repo, role, +25 more. Returns: ok, cwd, role, type, +26 more

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.

Inputs: action (required), surface (required), cwd, pane, +20 more. Returns: ok, pane, title, action, +3 more

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).

Inputs: ids, mine, watch, agent_id, +6 more. Returns: ok, typed, watch, results, +16 more

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 10 tools

    Disambiguation4/5

    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.

    Naming Consistency4/5

    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.

    Tool Count5/5

    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.

    Completeness4/5

    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

    ActivityActive
    ResponsivenessMostly unanswered

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Terminal 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.
      38 npm
      28
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      MCP 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.
      50
      1
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      MCP 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.
      39
      16 npm
      MIT