Skip to content

Repository files navigation

cmuxLayer

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

cmuxLayer

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.

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

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.

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

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.

About

10 public MCP tools for controlling cmux workspaces and managing Claude, Codex, Gemini, Kiro, and Cursor agents.

Topics

Resources

Contributing

Security policy

Stars

27 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages