Labsco
bnomei logo

TMUX

36

from bnomei

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

🔥🔥🔥🔥✓ VerifiedFreeAdvanced setup

tmux-mcp-rs

Crates.io Downloads

A Model Context Protocol (MCP) server for tmux, written in Rust. It lets AI assistants create sessions, split panes, run commands, and capture output.

  • The agent runs this MCP server to create and manage its own tmux session (often on an isolated socket).
  • The user/developer can attach to the same session to watch or participate in real time.
  • Bonus: it also works with human-created sessions, including remote setups over SSH.

Requires tmux 3.x installed and available on PATH. The server checks the version on startup and refuses to run against tmux 2.x, whose output formats and split flags differ. CI runs integration tests against the tmux version provided by ubuntu-latest; development is on 3.6.

[!WARNING] Using this MCP allows the agent to escape the sandbox and its security limitations. Here be dragons!

Why MCP (Not Just A Skill)

You can automate tmux with a plain-text skill, but the MCP tools are more reliable and cheaper to run:

  • Structured inputs and structured outputs reduce ambiguity, which improves agent quality.
  • Tool responses return stable IDs (session/window/pane/command), which avoids fragile name matching.
  • execute-command + get-command-result yields attributable output and exit codes without screen scraping.
  • Structured results are compact, so the agent spends fewer tokens than repeatedly capturing and parsing panes.
  • The MCP server can enforce policy (tool gating, allow/deny patterns, scoped sockets/sessions/panes).

Tools

Core Utilities

  • socket-for-path - Derive a deterministic tmux socket path for a project directory

Session Management

  • list-sessions - List all tmux sessions
  • find-session - Find a session by name pattern
  • create-session - Create a new session
  • kill-session - Kill a session
  • get-current-session - Get the current/attached session
  • rename-session - Rename a session

Window Management

  • list-windows - List windows in a session
  • create-window - Create a new window
  • kill-window - Kill a window
  • rename-window - Rename a window
  • move-window - Move a window to another position/session
  • select-window - Select/focus a window
  • select-layout - Apply a window layout (tiled/even/main-*)
  • set-synchronize-panes - Toggle synchronize-panes for a window

Pane Management

  • list-panes - List panes in a window
  • split-pane - Split a pane horizontally or vertically
  • kill-pane - Kill a pane (closing the last pane also closes its window)
  • rename-pane - Set pane title
  • capture-pane - Capture pane content (state/logs; not for routine command output)
  • select-pane - Select/focus a pane
  • resize-pane - Resize a pane by direction or size
  • zoom-pane - Toggle pane zoom
  • join-pane - Join a source pane into a target pane's window
  • break-pane - Break a pane into a new window
  • swap-pane - Swap two panes

Command Execution

  • execute-command - Execute a command in a pane (preferred for non-interactive)
  • get-command-result - Get the result of an executed command (preferred output path)

Client Management

  • list-clients - List tmux clients
  • detach-client - Detach a tmux client

Buffer Management

  • list-buffers - List tmux paste buffers
  • show-buffer - Show buffer contents (supports offset/max bytes; defaults to 64KB)
  • save-buffer - Save buffer contents to a file (writes to the server filesystem; governed by allow_capture and [security.tools])
  • delete-buffer - Delete a buffer

Additional Buffer Tools

  • set-buffer - Create or replace a buffer with UTF-8 content
  • load-buffer - Load buffer contents from a file (reads from the server filesystem; governed by allow_capture and [security.tools])
  • append-buffer - Append UTF-8 content to an existing buffer
  • rename-buffer - Emulate rename by copying then deleting
  • search-buffer - Structured search over one or more buffers (literal/regex + metadata)
  • subsearch-buffer - Anchor-scoped follow-up search with structured metadata

Key Sending

  • send-keys - Send keys to a pane (interactive only). Use literal=true for exact text and enter=true to submit in one call
  • paste-text - Paste multi-line UTF-8 text via bracketed paste (paste-buffer -p); embedded newlines stay literal (no per-line submit) when the receiving program supports bracketed paste
  • send-hex - Send raw bytes as whitespace-separated hex tokens (e.g. CSI-u 1b 5b 31 33 3b 32 75 = Shift+Enter) for escape sequences key names cannot express
  • send-cancel - Send Ctrl+C
  • send-eof - Send Ctrl+D (EOF)
  • send-escape - Send Escape key
  • send-enter - Send Enter key (interactive prompts)
  • send-tab - Send Tab key
  • send-backspace - Send Backspace key
  • send-up - Send Up arrow
  • send-down - Send Down arrow
  • send-left - Send Left arrow
  • send-right - Send Right arrow
  • send-page-up - Send Page Up
  • send-page-down - Send Page Down
  • send-home - Send Home key
  • send-end - Send End key

Resources

The server exposes the following MCP resources:

URIDescription
tmux://server/infoDefault socket and SSH context for routing tool calls
tmux://pane/{paneId}Content of a specific pane (last 200 lines)
tmux://pane/{paneId}/infoMetadata for a specific pane
tmux://pane/{paneId}/tail/{lines}Tail N lines from a pane
tmux://pane/{paneId}/tail/{lines}/ansiTail N lines with ANSI colors
tmux://window/{windowId}/infoMetadata for a window
tmux://session/{sessionId}/treeSession + windows + panes snapshot
tmux://clientsList tmux clients
tmux://command/{commandId}/resultStatus and output of a tracked command

Resources are dynamically enumerated - the server lists available panes, windows, sessions, clients, and active commands.

Skills

  • tmux-via-mcp - Use the tmux MCP tools to create sessions, shape layouts, run tracked commands, and automate interactive terminals when a real TTY or parallel panes are required.
  • tmux-buffer-explorer - Explore large tmux buffers via search and bounded slices. Use when buffer data is too large to load at once or needs incremental inspection.

Probing and Refining with tmux-buffer-explorer

The additonal buffer tools extend tmux’s native buffers for the probe‑and‑refine workflow described in the paper from Alex L. Zhang, Tim Kraska and Omar Khattab Recursive Language Models, while keeping all state inside tmux buffers and thus in RAM. They’re general-purpose building blocks used by the coordinating Skill at skills/tmux-buffer-explorer/SKILL.md.

The tmux buffer search is not intended to replace ripgrep or similar search approaches. rg is a high-performance, one-shot search tool optimized for humans who already know what they are looking for. This skill targets a different problem: enabling LLM agents to explore large contexts incrementally.

Search here is a navigation primitive, not an end result. It provides:

  • structured results with stable offsets and match IDs
  • bounded, zoom-able reads for follow-up inspection
  • deterministic behavior across multiple reasoning steps

This aligns with the Recursive Language Models approach: treat context as an external environment to explore, not a blob to ingest. Performance is more than enough for buffer-scale text, and the dominant cost is agent reasoning, not scanning.

Examples: Old Man and the Sea (113 KB = too big for LLM context)

  • Q: Use the tmux buffer to search the tests/fixtures/old-man-and-the-sea.txt for baseball near dimago.
  • Q: Where does the old man talk about why he admires DiMaggio, and what reason does he give?
  • Q: Where does the old man reflect on his loneliness at sea, and how does that reflection change later in the story?
  • Q: Find the passage where the lions are mentioned most vividly and summarize what they symbolize.

Q: Locate the moment where the old man’s confidence shifts into doubt during the fight with the fish.

A: In tmux buffer oldman around byte offset ~56320 (mid‑fight, when his left hand cramps), he asserts he can handle the line with his right arm alone, then immediately says he doesn’t know what the fish will do and starts questioning the fish’s plan and his own. That’s the confidence‑to‑doubt shift.

Remote SSH (optional)

Use --ssh to control a tmux server on another machine. Make sure SSH authentication is non-interactive (e.g. agent or keys).

tmux-mcp-rs --ssh "user@host"

For extra SSH options, put them before the host (e.g. --ssh "-i ~/.ssh/key user@host") or use ~/.ssh/config. The destination should be the last token in the --ssh string.

The connection string is split with shell-word rules (quotes honored); an unbalanced quote is rejected at startup. On the remote, the server runs ssh <args> <quoted tmux command>, and the tmux version check applies to the remote tmux when it can be reached. SSH parsing and remote command quoting are unit-tested; end-to-end remote behavior is verified manually, not in CI (no remote host in the test environment).

Remote + isolated (SSH + socket)

Create a dedicated tmux server on the remote host, then point the MCP server at that socket:

# On the remote host (once):
ssh user@host 'tmux -S /tmp/ai-agent.sock -f /dev/null new-session -d -s workspace'

# Locally:
tmux-mcp-rs --ssh "user@host" --socket /tmp/ai-agent.sock

Socket isolation (optional)

Use --socket or TMUX_MCP_SOCKET to point the MCP server at a specific tmux server socket.

# Connect to a specific socket id
tmux-mcp-rs --socket /tmp/tmux-mcp-<agent-id>.sock

# Or via environment variable
TMUX_MCP_SOCKET=/tmp/tmux-mcp-<agent-id>.sock tmux-mcp-rs

If you want to pre-create an isolated tmux server for the agent:

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

Workflow Patterns (CLI Agents)

These patterns mirror how CLI agents like Codex can structure tmux work. Each core flow is backed by an integration test in tests/integration.rs (run with TMUX_MCP_INTEGRATION=1).

  • ID-first targeting: Use window/pane IDs for operations when names collide. Tools: list-windows/list-panes, rename-window. Test: test_workflow_id_first_targeting.
  • Task-per-session layout: Create a session per task, add windows for build/test/docs, and split panes for runners/logs. Tools: create-session, create-window, split-pane, rename-pane, list-windows, list-panes. Test: test_workflow_task_per_session_layout.
  • Stateful shell context: Set environment/state in a pane and reuse it across commands. Tools: send-keys, capture-pane. Test: test_workflow_stateful_shell_context.
  • Continuous output pane: Run a long command and poll capture-pane to summarize progress without losing terminal state. Tools: send-keys, capture-pane. Test: test_workflow_continuous_output_capture.
  • Interactive prompt automation: Drive a blocking prompt (or simple TUI) by sending responses via keys, then capture the result. Tools: send-keys, capture-pane. Test: test_workflow_interactive_prompt.
  • Interactive interrupts: Cancel long-running commands and end stdin streams with EOF. Tools: send-cancel, send-eof, capture-pane. Test: test_workflow_interactive_interrupts.
  • Synchronized panes broadcast: Fan out a command to multiple panes at once using synchronize-panes. Tools: set-synchronize-panes, send-keys, capture-pane. Test: test_workflow_synchronized_panes_broadcast.
  • Buffer handoff + probe: Stash output in buffers, inspect it, save to disk, and delete when done. Tools: list-buffers, show-buffer, save-buffer, delete-buffer. Test: test_workflow_buffer_roundtrip (core flow).
  • Pane rearrangements: Swap/break/join panes and apply layouts while preserving pane identities. Tools: split-pane, select-layout, swap-pane, break-pane, join-pane, list-panes, list-windows. Test: test_workflow_pane_rearrangements.
  • Metadata + zoom: Rename session/window/pane and inspect pane/window metadata; toggle zoom and resize. Tools: rename-session, rename-window, rename-pane, zoom-pane, resize-pane. Resources: tmux://pane/{paneId}/info, tmux://window/{windowId}/info. Test: test_workflow_metadata_and_zoom.
  • Audit-ready context bundle: Pair tracked command output with raw pane capture for traceability. Tools: execute-command, get-command-result, capture-pane. Test: test_workflow_audit_context_bundle.
  • Agent orchestration: Run parallel commands across windows/panes with log monitoring. Tools: create-window, split-pane, execute-command, send-keys, capture-pane. Test: test_workflow_agent_orchestration.

Development

Running Tests

Unit tests (no tmux required):

cargo test --lib

Integration tests (requires tmux installed):

# Install tmux if needed
# macOS: brew install tmux
# Ubuntu: sudo apt-get install tmux

# Run integration tests (uses isolated tmux server)
TMUX_MCP_INTEGRATION=1 cargo test --test integration

Integration tests create an isolated tmux server using a temp socket, so they won't affect your running tmux sessions.

Security defaults (why nothing is denied)

By default, the security policy is permissive to avoid breaking agent workflows:

  • security.enabled = true, but all allow_* flags are true
  • security.tools.mode = "deny" with no items (no tool filtering)
  • command_filter.mode = "off" (no allow/deny patterns)
  • allowed_sockets/sessions/panes are unset (no scoping)

Denylist behavior: when command_filter.mode = "denylist", any regex in security.command_filter.patterns that matches a command string will block that command. This applies to execute-command, non-literal send-keys, and paste-text; multi-line inputs are checked one non-empty line at a time so anchored patterns such as ^rm still apply after embedded newlines. For send-hex, decoded bytes are screened by the same command filter on a best-effort basis: erase/kill line-editing control bytes are rejected outright, but raw bytes can still encode actions a string-matching regex cannot fully anticipate, so do not rely on the denylist as a hard boundary for raw input. Literal send-keys is gated by allow_send_keys only; its content is not screened. Scope raw input tools with allowed_panes/allowed_sessions, or disable allow_send_keys.

When allowed_sockets is configured, it is enforced against the effective socket for every tool and resource request: an explicit tool socket wins, otherwise TMUX_MCP_SOCKET/--socket is used, and otherwise tmux's default socket path is checked. Include the default socket path in allowed_sockets only if default-server access is intended; otherwise set --socket or TMUX_MCP_SOCKET to an allowed isolated socket.

Command results are socket-bound: when a command is executed, the resolved socket is recorded and get-command-result must use the same socket (explicitly or via defaults), or it will be denied.

To harden a deployment, configure [security.tools], add command deny/allow patterns, or restrict sockets/sessions/panes explicitly. The older allow_* flags still work as coarse group gates, but [security.tools] is the preferred surface because it removes disabled tools from list-tools. For the strongest guarantee that shell input cannot bypass the command_filter, compile without the raw input tools (see Hardened build).