cmuxLayer exposes a 10-tool public MCP surface for controlling cmux terminal workspaces and managing CLI agents.
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.
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.
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
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.
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.
See Agent Routing and Handling Workflow for the full operator playbook, including stuck surface recovery and safe /mcp menu reconnects.
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 a CLI agent and return an agent_id for routing |
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 one terminal surface |
list_surfaces |
List all surfaces across workspaces |
These 10 are the whole surface: setting CMUXLAYER_DEFAULT_PALETTE adds expand_palette and no other tool is registered.
| 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.
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.
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.
bun run test # vitest; 4452 tests collected by `vitest list`
bun run typecheck # Type checkingEnable 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.
bun install
bun run dev # Run with tsx (hot reload)
bun run build # Compile TypeScript
bun run start # Run compiled outputSee CONTRIBUTING.md for development setup and PR guidelines.
Apache 2.0 — see LICENSE.
Part of the Golems AI agent ecosystem. cmuxlayer.etanheyman.com | Built by @EtanHey.