LabscoMCP early access ↗
bnomeiMCP SERVER

Tmux Rust MCP Server

Give an agent a real terminal: named tmux sessions, windows and panes, tracked commands with IDs and exit codes, and a session you can attach to yourself while it works.

by bnomei ↗Editors, Terminals & Local Dev EnvironmentCommunity

LABSCO SUMMARY

The policy file is the part to read before you connect a client you don't fully trust.

Out of the box every allow_* gate is true, the command filter is off, and no socket, session or pane allowlist is set — convenient locally, but that is not a sandbox. The practical hardening is an isolated socket plus a config.toml that sets allowed_sockets and denies the @raw-input group, so shell input has to go through execute-command where the regex command filter and tracking apply; TMUX_MCP_TOOLS=deny:@raw-input does the same for one process without a file.

What it is

An MCP server for tmux, written in Rust. Every tmux operation is a named tool with typed parameters and stable IDs, so a client never has to infer a pane ID from captured text or guess whether a command has finished. Long-running work runs as a tracked command that returns a commandId and a resource URI; completion arrives through a private tmux exit buffer and wait-for signal rather than scraped scrollback. Because the session is a normal tmux session, a human can attach to it mid-task.

What you get

  • Sessions, windows and panes created, renamed, split, resized, zoomed, joined, broken out and killed — create-session, create-window, split-pane, rename-session, rename-window, rename-pane, select-layout, resize-pane, zoom-pane, join-pane, break-pane, swap-pane, kill-session, kill-window, kill-pane
  • Shell commands run with tracking: a command ID, a status of queued, running, completed, failed or tracking_error, and the output between markers — execute-command, get-command-result
  • Live pane text for progress checks, plus listings of sessions, windows, panes and clients — capture-pane, list-sessions, find-session, list-windows, list-panes, list-clients, get-current-session
  • Tmux buffers used as an external search space: read a slice, search literal or regex with byte offsets and resume cursors, then write or file the result — list-buffers, show-buffer, search-buffer, subsearch-buffer, set-buffer, append-buffer, save-buffer, load-buffer, delete-buffer, rename-buffer
  • Raw keystrokes for prompts, REPLs, pagers and TUIs, including the special keys — send-keys, paste-text, send-hex, send-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, send-end
  • A deterministic per-project socket path, and read-only resources for server info, pane tails, window and session trees and tracked command results — socket-for-path, tmux://server/info, tmux://pane/{paneId}/tail/{lines}, tmux://session/{sessionId}/tree, tmux://command/{commandId}/result

Requirements

Tmux 3.0 or newer on PATH, and a shell the command tracker supports — bash, zsh or fish. The server runs tmux -V on startup and exits if it finds tmux 2.x, whose output formats and split flags differ. Install with cargo install tmux-mcp-rs, brew install bnomei/tmux-mcp/tmux-mcp-rs, npx @bnomei/tmux-mcp-rs, or the container image ghcr.io/bnomei/tmux-mcp:0.6.0; building from source needs Rust 1.70 or newer. It speaks stdio. --socket or TMUX_MCP_SOCKET pins it to one tmux server, --ssh routes tmux commands to a remote host over a non-interactive SSH login, and --config loads a TOML policy file — nothing is auto-loaded.

Setup effort

One command — cargo install tmux-mcp-rs