Architecture
cmux exposes two interfaces for external integrations:- CLI: Shell commands like
cmux notify,cmux new-workspace,cmux send - Socket API: JSON-RPC protocol over a Unix domain socket at
/tmp/cmux.sock
Using the CLI
Thecmux CLI binary is bundled with the app at /Applications/cmux.app/Contents/MacOS/cmux.
Environment variables
cmux sets these variables in every terminal session:CMUX_WORKSPACE_ID: Current workspace ID (e.g.,workspace:1)CMUX_SURFACE_ID: Current surface/tab ID (e.g.,surface:2)CMUX_SOCKET_PATH: Path to the control socket (default:/tmp/cmux.sock)
Common CLI patterns
Example: Simple agent hook
Here’s a minimal agent integration that sends a notification when a task completes:~/bin/agent-notify
Using the socket API
The socket API uses a JSON-RPC-like protocol. Each request is a JSON object sent over a Unix socket, followed by a newline.Connection
Connect to the socket
Open a connection to
/tmp/cmux.sock (or the path in $CMUX_SOCKET_PATH).The socket is owned by your user and only accepts connections from the same user for security.
Request format
id: Any unique string (used to match requests to responses)method: API method name (see below)params: Method-specific parameters (optional)
Response format
Success:Available methods
Workspace methods
Workspace methods
workspace.list- List all workspacesworkspace.create- Create a new workspace (params:cwd)workspace.select- Select a workspace (params:workspace_id)workspace.close- Close a workspace (params:workspace_id)workspace.rename- Rename a workspace (params:workspace_id,title)workspace.current- Get current workspace ID
Surface methods
Surface methods
surface.list- List surfaces in a workspace (params:workspace_id)surface.create- Create a new surface/tab (params:workspace_id, optionaltype,url)surface.focus- Focus a surface (params:workspace_id,surface_id)surface.close- Close a surface (params:workspace_id,surface_id)surface.send_text- Send text to a surface (params:workspace_id,surface_id,text)surface.send_key- Send key to a surface (params:workspace_id,surface_id,key)surface.read_text- Read terminal text (params:workspace_id,surface_id, optionallines,scrollback)
Pane methods
Pane methods
pane.list- List panes in a workspace (params:workspace_id)pane.create- Create a new pane (params:workspace_id,direction)pane.focus- Focus a pane (params:workspace_id,pane_id)
Window methods
Window methods
window.list- List all windowswindow.current- Get current window IDwindow.focus- Focus a window (params:window_id)
System methods
System methods
system.capabilities- Get API capabilitiessystem.identify- Get current context (workspace, surface, pane)
Example: Python integration
Here’s a Python class for interacting with the cmux socket:~/lib/cmux_client.py
Building an agent integration
Here’s a complete example of integrating a custom AI agent with cmux:Best practices
Use environment variables
Always read
CMUX_WORKSPACE_ID and CMUX_SURFACE_ID to target the correct workspace instead of hardcoding IDs.Handle missing socket gracefully
Check if cmux is running before sending commands. Fail gracefully if the socket doesn’t exist.
Sanitize notification content
Strip newlines and control characters from notification text to avoid breaking the protocol.
Use refs instead of UUIDs
Workspace/surface refs like
workspace:1 are more stable and human-readable than UUIDs.Security considerations
- The socket at
/tmp/cmux.sockis owned by your user and only accepts connections from the same UID - cmux verifies socket ownership before connecting to prevent fake-socket attacks
- No authentication is required for local socket connections (assumes filesystem permissions provide sufficient security)
- If you need stricter access control, you can enable password-protected socket access (see
--passwordflag in the CLI docs)
Troubleshooting
Socket not found
Socket not found
Ensure cmux is running:If the app isn’t running, launch it and wait for the socket to appear.
Permission denied
Permission denied
Check socket ownership:The socket must be owned by your user. If it’s owned by another user, quit cmux and restart it.
JSON parse errors
JSON parse errors
Ensure your JSON is valid and terminated with a newline:Use a JSON linter if you’re constructing requests manually.
Command not found
Command not found
Add cmux to your PATH:Add this to your shell config (
~/.zshrc or ~/.bashrc) to persist it.Further reading
- CLI Reference - Complete CLI command reference
- Socket API - JSON-RPC protocol documentation
- Claude Code integration - Example of a full hook-based integration