Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

libtmux-mcp

A Model Context Protocol server for tmux, built on libtmux.

Python Version PyPI Version License

[!WARNING] Pre-alpha. APIs may change. Contributions and feedback welcome.

Give your AI agent hands inside the terminal — create sessions, run commands, read output, orchestrate panes.

Tools

Module Tools
Server list_servers, list_sessions, create_session, kill_server, get_server_info
Batch call_readonly_tools_batch, call_mutating_tools_batch, call_destructive_tools_batch
Session list_windows, get_session_info, create_window, rename_session, select_window, kill_session
Window list_panes, get_window_info, split_window, rename_window, select_layout, resize_window, move_window, kill_window
Pane run_command, send_keys, send_keys_batch, paste_text, capture_pane, capture_since, snapshot_pane, search_panes, find_pane_by_position, get_pane_info, wait_for_text, wait_for_content_change, wait_for_channel, signal_channel, display_message, select_pane, swap_pane, resize_pane, set_pane_title, clear_pane, pipe_pane, enter_copy_mode, exit_copy_mode, respawn_pane, kill_pane
Options show_option, set_option
Environment show_environment, set_environment
Buffers load_buffer, paste_buffer, show_buffer, delete_buffer
Hooks show_hooks, show_hook

Quickstart

Requirements: Python 3.10+, tmux on $PATH.

Install and run:

uvx libtmux-mcp

Claude Code

claude mcp add tmux -- uvx libtmux-mcp

Codex CLI

codex mcp add tmux -- uvx libtmux-mcp

Gemini CLI

gemini mcp add tmux uvx -- libtmux-mcp

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "tmux": {
      "command": "uvx",
      "args": ["libtmux-mcp"]
    }
  }
}

More clients and JSON config: client setup docs

What it feels like

You: Create a session called "api" and run pytest tests/api/ -x in it.

Agent: Created session api with window tests. Running pytest now. Here's the output — 14 passed, 2 failed. The failures are in test_auth.py::test_token_refresh and test_auth.py::test_expired_session. Want me to open those files?

The agent manages tmux directly. No copy-pasting terminal output. No switching windows to check on long-running processes.

When the server earns its keep

For a single tmux send-keys, the server doesn't. It earns its keep the moment the agent has to wait, inspect, or avoid damaging the terminal it is using — pytest finishing, a dev server printing its port, a deploy log settling. The difference then is not more access to tmux, but a better place to put the control loop.

The server-side moves are:

Running. run_command sends an authored shell command, waits for deterministic completion, and returns exit status plus tail-preserved output as one typed value. The command and its completion signal reach the shell as one space-prefixed event, so best-effort history suppression keeps agent-generated input out of shell history by default. The alternative — hand-rolled send-keys plus wait-for plus a pane capture — leaves every typed command, signal included, in shell history.

Driving. send_keys_batch sends several ordered raw-input operations for TUIs and persistent shell interaction. It is deliberately not a workflow DSL; command completion stays in run_command, and repeated observation stays in capture_since.

Waiting. wait_for_text and wait_for_content_change block inside the server until a condition fires for output the agent does not author. The alternative is the model polling capture-pane in a loop, paying both context tokens and round-trip latency for every turn.

Reading. snapshot_pane returns content, cursor, copy-mode state, and scroll offset as one typed value. The alternative is several tmux invocations stitched together with regex.

Observing. capture_since returns a cursor with the current pane content, then returns only newly written or rewritten rows on follow-up calls. The alternative is re-sending the same scrollback to the model on every check.

Guarding. The server detects the agent's own pane across sockets and declines self-destructive operations — kill_session on itself fails loudly instead of silently terminating the host environment the agent is running in. LIBTMUX_SAFETY (readonly, mutating, destructive) hides whole tiers from the client's tool list before any prompt is built.

Documentation

Full docs, guides, and tool reference: libtmux-mcp.git-pull.com

Development

Clone and install:

git clone https://github.com/tmux-python/libtmux-mcp.git
cd libtmux-mcp
uv sync --dev

Run the server locally:

uv run libtmux-mcp

Run tests:

uv run pytest

Related projects

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

libtmux_mcp-0.1.0a18.tar.gz (668.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

libtmux_mcp-0.1.0a18-py3-none-any.whl (117.9 kB view details)

Uploaded Python 3

File details

Details for the file libtmux_mcp-0.1.0a18.tar.gz.

File metadata

  • Download URL: libtmux_mcp-0.1.0a18.tar.gz
  • Upload date:
  • Size: 668.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for libtmux_mcp-0.1.0a18.tar.gz
Algorithm Hash digest
SHA256 0bd9168c6b0b478cd322d529954da0aad1f4ba24715524127f506376a90828cb
MD5 9877772cd158a8a3bee0f17caac9dfb7
BLAKE2b-256 68198667d1f80b2dc81bdb920c848f21681d389b0d5451010fa572f57d45debb

See more details on using hashes here.

Provenance

The following attestation bundles were made for libtmux_mcp-0.1.0a18.tar.gz:

Publisher: tests.yml on tmux-python/libtmux-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file libtmux_mcp-0.1.0a18-py3-none-any.whl.

File metadata

  • Download URL: libtmux_mcp-0.1.0a18-py3-none-any.whl
  • Upload date:
  • Size: 117.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for libtmux_mcp-0.1.0a18-py3-none-any.whl
Algorithm Hash digest
SHA256 fd1f6e08b219b60155b6814caedb0cde8494351d98b4d54e00901072025d9414
MD5 39f88e714bb8649352f07e72d04b39ad
BLAKE2b-256 f870e5983258d10b6809b3382a747cfd2ded6665c7e9edddbc70c7c9bdb5d573

See more details on using hashes here.

Provenance

The following attestation bundles were made for libtmux_mcp-0.1.0a18-py3-none-any.whl:

Publisher: tests.yml on tmux-python/libtmux-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page