TMUX

by bnomei

Not rated
GitHub

About

Lets agents create sessions, split panes, run commands, and capture output with TMUX

Details

Author
bnomei
Categories
Developer Tools, Automation

Setup

Install TMUX in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/bnomei/tmux-mcp

Follow the installation instructions in the repository README, then restart your MCP client.

tmux-mcp-rsis a Model Context Protocol (MCP) server for tmux. It lets MCP clients create sessions, shape windows and panes, run tracked commands, inspect output, manage tmux buffers, and drive interactive terminal programs through structured tools instead of brittle screen scraping.

Use it when an agent needs a real TTY, long-running commands, parallel panes, resumable terminal state, or a tmux session that a human can attach to during the same task.

[!WARNING] This server can let an MCP client run shell commands, type into panes, read terminal output, modify tmux sessions, and read or write tmux buffers. The default runtime policy is permissive. Use isolated tmux sockets and aconfig.tomlpolicy before exposing it to a client you do not fully trust.

- What the server provides
-
Requirements
-
Installation
-
Quick start
-
Client configuration
-
Configuration reference
-
Security hardening
-
MCP tool reference
-
MCP resource reference
-
Remote and socket workflows
-
Agent workflow patterns
-
Development
-
Notes and limitations
-
Source anchors

The MCP path is usually more reliable than a plain tmux skill because every operation has a named tool, typed parameters, stable IDs, and structured responses. Clients do not need to infer pane IDs from captured text or parse command output to determine whether a command has finished.

- tmux 3.0 or newer onPATH.
- Rust 1.70 or newer when building from source.
- A shell supported by the command tracker:bash,zsh, orfish.

On startup the server runstmux -V. It exits when it detects tmux 2.x because tmux 2.x uses different output formats and split flags. If the version cannot be detected, startup continues and tmux errors are reported by the affected tool calls.

brew install bnomei/tmux-mcp/tmux-mcp-rs
npx @bnomei/tmux-mcp-rs --version # or: npm install -g @bnomei/tmux-mcp-rs

The npm package is a thin wrapper: on first run it downloads the matching GitHub Release binary, verifies the.sha256, caches it, and forwards argv.

docker run --rm ghcr.io/bnomei/tmux-mcp:0.6.0 --version

The image isself-contained: it includes Alpinetmux3.x and the prebuilt musl Linux binary. Sessions runinside the container, not on your desktop tmux server.

- Default (recommended for Docker):isolated agent sandbox. Human attach usesdocker exec(see below).
- Optional (Linux only):mount a host tmux socket so the container drives a host-side server you cantmux attachto natively. Docker Desktop on macOS/Windows generally cannot reach host Unix sockets this way.
- For easy human/agent co-attach on a laptop, prefer Homebrew, cargo, or npm on the host instead of Docker.

docker run --rm -i \ --name tmux-mcp \ -v "$PWD:/workspace" \ ghcr.io/bnomei/tmux-mcp:0.6.0

Watch a session created inside the container:

docker exec -it tmux-mcp tmux attach -t workspace
# host: start an isolated tmux server tmux -S /tmp/tmux-mcp-agent.sock -f /dev/null new-session -d -s workspace # container: talk to that socket (image still needs its own tmux client) docker run --rm -i \ -v /tmp/tmux-mcp-agent.sock:/tmp/tmux-mcp-agent.sock \ --user "$(id -u):$(id -g)" \ ghcr.io/bnomei/tmux-mcp:0.6.0 \ --socket /tmp/tmux-mcp-agent.sock # host: attach as usual tmux -S /tmp/tmux-mcp-agent.sock attach -t workspace

Match container UID/GID to the socket owner when permissions fail. More detail:packaging/README.md.

Download a prebuilt archive fromGitHub Releases, extract it, and placetmux-mcp-rson yourPATH.

git clone https://github.com/bnomei/tmux-mcp.git cd tmux-mcp cargo build --release

The binary is written totarget/release/tmux-mcp-rs.

claude mcp add --transport stdio tmux -- tmux-mcp-rs
{ "mcpServers": { "tmux": { "command": "tmux-mcp-rs" } } }

In your MCP client, ask the agent to create or list tmux sessions.

Create a tmux session named workspace, list its windows and panes, then run pwd in the first pane.

The tool responses should include a session ID, window ID, pane ID, and acommandIdfor the tracked command.

Attach to the same tmux session if you want to watch or participate.

For safer multi-agent work, start with an isolated socket instead of the default tmux server:

tmux -S /tmp/tmux-mcp-agent.sock -f /dev/null new-session -d -s workspace tmux -S /tmp/tmux-mcp-agent.sock attach -t workspace

Then configure the MCP server with--socket /tmp/tmux-mcp-agent.sock,TMUX_MCP_SOCKET=/tmp/tmux-mcp-agent.sock, or a per-toolsocketoverride.

Useargswhen your MCP client accepts JSON configuration:

{ "mcpServers": { "tmux": { "command": "tmux-mcp-rs", "args": [ "--shell-type", "zsh", "--socket", "/tmp/tmux-mcp-agent.sock", "--config", "/path/to/config.toml" ] } } }
{ "mcpServers": { "tmux": { "command": "tmux-mcp-rs", "args": [ "--ssh", "user@host", "--socket", "/tmp/tmux-mcp-agent.sock" ] } } }

Every MCP tool exceptsocket-for-pathaccepts an optionalsocketparameter. If a tool omits it, the server uses the process default socket.

tmux-mcp-rsdoes not auto-load a config file. Pass one with--config /path/to/config.toml.

[shell] type = "zsh" [ssh] remote = "user@host" [security] enabled = true allow_execute_command = true allow_raw_mode = true allow_send_keys = false allow_kill = true allow_create = true allow_split = true allow_rename = true allow_move = true allow_capture = true allow_list = true allowed_sockets = ["/tmp/tmux-mcp-agent.sock"] allowed_sessions = ["workspace"] allowed_panes = ["%1"] allowed_buffer_paths = ["/srv/tmux-mcp-buffers"] [security.command_filter] mode = "allowlist" patterns = ["^cargo ", "^git ", "^rg ", "^sed "] [security.tools] mode = "deny" items = ["@raw-input"] [tracking] capture_initial_lines = 1000 capture_max_lines = 16000 completed_retention_minutes = 240 completed_max_entries = 1000 tracking_deadline_seconds = 600 [search] streaming_threshold_bytes = 262144

security.command_filterchecks each non-empty shell statement forexecute-command,send-keys(literal and non-literal),paste-text,set-buffer,append-buffer, and the decoded bytes passed tosend-hex. It splits unquoted;,|,&, and newlines, then recursively checks command substitutions, process substitutions, subshells, and brace groups. It rejects shell forms it cannot safely analyze, including ANSI-C$'...'quoting and shell-cwrappers. It does not screen special-key helpers. For a hard boundary, disable raw input tools at runtime or compile them out.

By default, policy enforcement is enabled but permissive:

- All coarseallow_*gates aretrue.
- command_filter.modeisoff.
- allowed_sockets,allowed_sessions,allowed_panes, andallowed_buffer_pathsare unset. Buffer file operations remain restricted to the default temp-directory sandbox.
- [security.tools]is deny mode with no denied items.

That default is convenient for local experimentation, but it is not a sandbox.

tmux -S /tmp/tmux-mcp-agent.sock -f /dev/null new-session -d -s workspace tmux-mcp-rs --socket /tmp/tmux-mcp-agent.sock --config config.toml
[security] allowed_sockets = ["/tmp/tmux-mcp-agent.sock"]

Whenallowed_socketsis set, calls without an explicit socket still resolve to the process default socket and must match the allowlist.

[security] allow_send_keys = false [security.tools] mode = "deny" items = ["@raw-input"]

Use this when shell input should go throughexecute-commandso command filtering and command-result tracking remain central.

Expose only read tools and tracked command execution

[security.tools] mode = "allow" items = ["@read", "execute-command"]

@readincludesget-command-result, listing tools, capture tools, buffer read/search tools, andsocket-for-path.

Override the tool surface for one process

TMUX_MCP_TOOLS=send-keys,paste-text tmux-mcp-rs TMUX_MCP_TOOLS=deny:@raw-input tmux-mcp-rs TMUX_MCP_TOOLS=allow:@read,execute-command tmux-mcp-rs

The default Cargo feature set includesinteractiveandspecial-keys.

- interactiveregisterssend-keys,send-hex, andpaste-text.
- special-keysregisterssend-cancel,send-eof,send-escape,send-enter,send-tab,send-backspace,send-up,send-down,send-left,send-right,send-page-up,send-page-down,send-home, andsend-end.

Disable those features to remove the tools from the binary:

# Filtered-only build: execute-command is the only shell-input path. cargo build --release --no-default-features --features rayon,rapidfuzz # Keep raw keystrokes but remove special-key helpers. cargo build --release --no-default-features --features rayon,rapidfuzz,interactive

execute-commandis always registered and remains subject tosecurity.command_filter.

Tool availability depends on Cargo features and runtime policy. Runtime-denied tools are removed from the advertised MCP tool list and denied when called.

Tracked command snapshots useschemaVersion: 1and currently move throughqueued,running, thencompleted,failed, ortracking_error. The schema also reservescancelled, but the current tracker does not emit it. Normal tracked commands reject embedded newlines, unquoted shell comment markers (#), and unquoted background operators (&) because those forms can bypass the tracking epilogue. SetrawMode=trueornoEnter=trueonly when you intentionally want to disable side-channel completion tracking; those records remainrunning.

show-bufferreads at most 65,536 bytes by default.search-bufferdefaults to 40 context bytes, 50 matches, and 65,536 scanned bytes per buffer; it returns byte offsets and resume cursors when results are truncated. Literal and regex search are always available. Fuzzy matching and similarity scores require therapidfuzzCargo feature, which is enabled by default.

Server, pane, window, session, and client resources reflect the server's default socket. Tracked-command resources retain the effective socket recorded by their originatingexecute-command, including per-tool socket overrides. Resources are dynamically enumerated and filtered by the current security policy.

Use--sshto run tmux commands on another machine. SSH authentication must be non-interactive, such as an agent or key-based login.

Pass SSH options before the destination:

tmux-mcp-rs --ssh "-i ~/.ssh/key user@host"

The connection string is split with shell-word rules. The destination should be the last token. The server quotes the remote tmux command before sending it to SSH, and the tmux version check applies to the remote tmux when it can be reached.

Create a dedicated tmux server on the remote host:

ssh user@host 'tmux -S /tmp/tmux-mcp-agent.sock -f /dev/null new-session -d -s workspace'

Start the local MCP server against that remote socket:

tmux-mcp-rs --ssh "user@host" --socket /tmp/tmux-mcp-agent.sock

Attach directly from a shell when needed:

ssh -t user@host 'tmux -S /tmp/tmux-mcp-agent.sock attach -t workspace'

Use--socketorTMUX_MCP_SOCKETto keep one agent on one tmux server:

tmux-mcp-rs --socket /tmp/tmux-mcp-agent.sock
TMUX_MCP_SOCKET=/tmp/tmux-mcp-agent.sock tmux-mcp-rs

Pre-create the session when you want a human-visible workspace before the MCP client starts:

tmux -S /tmp/tmux-mcp-agent.sock -f /dev/null new-session -d -s workspace TMUX_MCP_SOCKET=/tmp/tmux-mcp-agent.sock tmux-mcp-rs

The GHCR image includes tmux 3.x and defaults toself-containedsessions inside the container (docker exec … tmux attach). On Linux only, you can instead mount a host socket so the container MCP server drives a host tmux server—seeInstallation → Dockerandpackaging/README.md. Docker Desktop on macOS/Windows is not a reliable host-socket path; use a native install when you need easy local co-attach.

The integration tests cover these tmux workflows:

tmux-buffer-exploreruses tmux buffers as an external search space for large text. It is useful when an agent needs bounded search and follow-up slices instead of loading a whole buffer into context.

Run unit tests that do not require tmux:

cargo test --lib cargo test --test cli cargo test --test search
No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.