cmux setup mcp: give Claude Code and Codex outside cmux the cmux MCP server

Merged
TE
17d ago
+822-19

Ready. Independent review SHIP at 5302374152f1. Hosted verify: test (linux) passed (run 39629470203). Only reds: lint (linux) clippy on base (rows_tests.rs redundant clones, fixed by #23557) and two advisory jobs cancelled at checkout.

cmux setup mcp [claude|codex ...] [--dry-run] is the fourth task cmux setup runs (plans/cmux-next/setup-DESIGN.md). Chats cmux starts already get the cmux MCP server from acpmux. Claude Code or Codex started in a terminal or another app did not, and cmux setup list only pointed at a hand-typed claude mcp add.

What it does:

  • Adds the server through each harness's own CLI, so their config files keep one writer: claude mcp add --scope user cmux -- <this cmux> mcp serve and codex mcp add cmux -- <this cmux> mcp serve. The default is each installed harness. undo is the matching mcp remove line for what changed.
  • Is idempotent. It reads only the user-scope config (~/.claude.json or $CLAUDE_CONFIG_DIR/.claude.json, $CODEX_HOME/config.toml). An entry that already runs cmux mcp serve from a command that still runs is ok, and no CLI runs.
  • Repairs a moved app. A cmux entry whose command is gone is removed and re-added; undo restores the old entry.
  • Leaves the person's own server alone. A cmux entry that runs something else is needs_user (kind: conflict), with the mcp remove command that frees the name.
  • Respects the opt-in. cmux mcp serve answers a client outside a cmux chat only when the settings file says "mcp": {"enabled": true}. That key is not in the app's schema (agents can't set it), and the settings file has one writer. So until it is on, setup writes nothing: changes are planned and the task is needs_user (kind: setting), naming the file and the key.
  • Adds an mcp check to cmux setup status.

cmux-cua is left out on purpose: it needs the app's per-session socket token, so no user config can hold it.

Tests (tests/setup.rs, agent-driven, with fake claude and codex CLIs that write the real config files):

  • cmux_setup_mcp_an_agent_gives_claude_code_and_codex_the_cmux_server_and_undoes_it: status, the switch handed to the person with nothing written, dry run, apply, rerun (no CLI runs), the undo, a named harness that isn't installed, and bad arguments.
  • cmux_setup_mcp_replaces_a_moved_cmux_and_leaves_another_server_named_cmux.

Follow-up I noticed: cmux mcp serve's "off" message suggests cmux settings set mcp.enabled true. mcp.enabled isn't in the app's settings schema, so that command is probably refused. Making the switch one click (a Settings row) would remove the last hand edit.

Agent session: cosmic-gray

🤖 Generated with Claude Code