loading…
Search for a command to run...
loading…
Model Context Protocol server that lets LLMs collaboratively drive tmux
Model Context Protocol server that lets LLMs collaboratively drive tmux
Remote-first tmux co-pilot for humans + LLMs.
CI License: AGPL-3.0 Node Dependabot npm MCP Registry
mcp-tmux is a Model Context Protocol server for people who learned the hard way that large language models are extremely confident about terminals they cannot actually see. It lets an LLM operate inside tmux with real, inspectable state instead of vibes, screenshots, or remembered lies. The server anchors the model to concrete reality: SSH-aware session discovery and bootstrapping, authoritative window and pane topology, and pull-based state snapshots so context is fetched when needed rather than hallucinated continuously. It can spawn or reattach to remote tmux sessions via your SSH config, inject keystrokes into the correct pane on purpose, read scrollback with full historical context, manage windows and splits deterministically, and enforce defaults so the model doesn’t calmly execute commands in a pane that stopped existing five minutes ago.
You need this if you want an LLM to assist in real terminals without pretending the terminal is a chat log. This is for pairing with an AI on live systems, debugging multi-pane chaos, automating the boring parts while you handle the judgment calls, or letting a model help without giving it omnipotent shell access and hoping nothing exciting happens. mcp-tmux exists to replace guesswork with state, narration with observation, and “I think you’re in the left pane” with provable fact.
Disclaimer: reasonable engineering effort has been applied to reduce the probability of reality-ending command execution. Guardrails exist. So do sharp edges. If something catastrophic happens, it will almost certainly be because a human approved it, ignored context, or decided this was a good idea at the time. Logs are kept. History remembers. Responsibility remains firmly biological.
npm install
npm run build
MCP_TMUX_HOST=my-ssh-alias MCP_TMUX_SESSION=collab npx @k8ika0s/mcp-tmux
tmux_open_session → tmux_default_context → tmux_list_windows / tmux_list_panes → tmux_send_keys → tmux_capture_pane
tmux_state.confirm=true; defaults keep the model from mis-targeting panes.tmux_state snapshot that includes recent scrollback.| Pillar | What it covers |
|---|---|
| Remote orchestration | tmux_open_session, SSH-aware tmux spawn/attach, PATH/tmux-bin overrides, host profiles |
| Grounded control | tmux_state, tmux_capture_pane, tmux_list_*, default targets, pane/window labels |
| Collaboration | tmux_new_window, tmux_split_pane, sync panes, layout capture/restore, layout profiles |
| Safety | confirm=true on destructive calls, logging + audit logs, defaults to avoid mis-targeting |
| Automation | tmux_multi_run, tail/pattern/watch tasks, fan-out capture/tail/pattern modes |
TMUX_BIN=/path/to/tmux). For remote flows, tmux must be installed on the remote host.host parameter is the ssh config Host).npm install
npm run build
MCP_TMUX_HOST=my-ssh-alias MCP_TMUX_SESSION=collab npx @k8ika0s/mcp-tmux # optional defaults
# Version check
mcp-tmux --version
During development you can use hot reload:
npm run dev
Add to your MCP client config (example for Claude Desktop/CLI style):
{
"servers": {
"tmux": {
"command": "npx",
"args": ["@k8ika0s/mcp-tmux"],
"env": {
"MCP_TMUX_HOST": "my-ssh-alias", // optional default host
"MCP_TMUX_SESSION": "collab" // optional default session
}
}
}
}
SSH quality-of-life: consider enabling ControlMaster/ControlPersist in your ssh config for faster repeated ssh -T <host> tmux ... invocations.
tmux_open_session: Ensure a remote tmux session exists (create if missing) given host (ssh alias) and session, and set them as defaults.tmux_default_context: Shows detected default session and a quick session listing.tmux_state: Snapshot sessions, windows, panes, and capture of the active/default pane.tmux_set_default / tmux_get_default: Persist or view default host/session/window/pane.tmux_capture_layout / tmux_restore_layout: Save and re-apply window layouts.tmux_tail_pane: Poll a pane repeatedly to follow output without reissuing commands.tmux_tail_task: Task-based tail with polling over time (client polls task results).tmux_select_window / tmux_select_pane: Change focus targets explicitly.tmux_set_sync_panes: Toggle synchronize-panes for a window.tmux_save_layout_profile / tmux_apply_layout_profile: Persist and re-apply layout profiles by name.tmux_readonly_state: Snapshot sessions/windows/panes/capture without touching defaults.tmux_batch_capture: Capture multiple panes in parallel for faster context gathering.tmux_run_batch: Run multiple commands in one call in the same pane (uses && by default, or ;/newline via joinWith for heredocs), auto-clean the prompt (bash/zsh: Ctrl+C then Ctrl+U) before writes by default (cleanPrompt=true), and auto-captures output with paging (starts ~20 lines, grows if needed).tmux_send_keys: Send keys (supports <SPACE>, <ENTER>, <TAB>, <ESC> tokens; empty + enter=true sends Enter).tmux_health: Quick health check (tmux reachable, session listing, host profile info).tmux_context_history: Pull recent scrollback (pane or session) and extract recent commands.tmux_quickstart: Return a concise playbook/do-don’t block for the LLM.tmux_multi_run: Fan-out send + capture/tail/pattern to multiple hosts/panes.tmux_state_resource (URI tmux://state/default) returns the current default snapshot on read.~/.config/mcp-tmux/logs/{host}/{session}/YYYY-MM-DD.log (override with MCP_TMUX_LOG_DIR).tmux_set_audit_logging to log commands and outputs verbosely (may grow large).tmux_list_sessions: Enumerate sessions with window/attach counts.tmux_list_windows: List windows (optionally scoped to a session).tmux_list_panes: List panes (optionally scoped to a target).tmux_capture_pane: Read scrollback from a pane (defaults to last ~200 lines).tmux_send_keys: Send keystrokes to a pane, optionally with Enter.tmux_new_session: Create a detached session to collaborate in.tmux_new_window: Create a window inside a session.tmux_split_pane: Split a pane horizontally/vertically, optionally with a command.tmux_kill_session, tmux_kill_window, tmux_kill_pane: Tear down targets (require confirm=true).tmux_rename_session, tmux_rename_window: Rename targets.tmux_command: Raw access to any tmux command/flags for advanced cases.Targets accept standard tmux notation: session, session:window, session:window.pane, or pane/window IDs. Most tools also accept an optional host (ssh alias) and will fall back to MCP_TMUX_HOST or whatever tmux_open_session last set.
~/.ssh/config as Host my-ssh-alias).tmux_open_session with host: "my-ssh-alias" and session: "collab". It will create the remote tmux session if needed and set it as default.tmux_default_context to verify layout (uses the default host/session).tmux_send_keys and read it with tmux_capture_pane.ssh -t my-ssh-alias tmux attach -t collab to collaborate in real time.tmux_state to see sessions/windows/panes and the recent scrollback.{"name":"tmux_open_session","arguments":{"host":"my-ssh-alias","session":"collab","command":"cd /srv && bash"}}
{"name":"tmux_state","arguments":{"captureLines":200}}
{"name":"tmux_run_batch","arguments":{
"target":"collab:0.0",
"steps":[{"command":"ls -lah"}],
"cleanPrompt":true,
"failFast":true
}}
{"name":"tmux_tail_pane","arguments":{"target":"collab:0.0","lines":200,"iterations":3,"intervalMs":1000}}
{"name":"tmux_tail_task","arguments":{"target":"collab:0.0","lines":200,"iterations":5,"intervalMs":1500}}
{"name":"tmux_multi_run","arguments":{
"targets":[
{"host":"web-1","target":"ops:0.0"},
{"host":"web-2","target":"ops:0.0"}
],
"keys":"ls -lah /var/log && tail -n 50 app.log",
"mode":"send_capture",
"capture":true,
"captureLines":200,
"delayMs":500
}}
"mode":"tail" with tailIterations/tailIntervalMs."mode":"pattern" with pattern/patternFlags.{"name":"tmux_context_history","arguments":{"session":"collab","lines":800,"allPanes":true}}
{"name":"tmux_run_batch","arguments":{
"target":"collab:0.0",
"steps":[
{"command":"git status"},
{"command":"npm test","enter":true}
],
"cleanPrompt":true,
"failFast":true
}}
cleanPrompt (default true) sends Ctrl+C then Ctrl+U (bash/zsh) before the first write to clear stray input.failFast=true joins commands with && (single Enter); set failFast=false to send each step separately (Enter per step).{"name":"tmux_quickstart","arguments":{}}
{"name":"tmux_select_window","arguments":{"target":"collab:0"}}
{"name":"tmux_select_pane","arguments":{"target":"collab:0.1"}}
{"name":"tmux_set_sync_panes","arguments":{"target":"collab:0","on":true}}
{"name":"tmux_capture_layout","arguments":{"session":"collab"}}
{"name":"tmux_restore_layout","arguments":{"target":"collab:0","layout":"your-layout-string"}}
{"name":"tmux_save_layout_profile","arguments":{"session":"collab","name":"logs"}}
{"name":"tmux_apply_layout_profile","arguments":{"name":"logs"}}
{"name":"tmux_health","arguments":{"host":"my-ssh-alias"}}
{"name":"tmux_split_pane","arguments":{"target":"collab:0.0","orientation":"horizontal","command":"htop"}}
{"name":"tmux_kill_window","arguments":{"host":"my-ssh-alias","target":"collab:1","confirm":true}}
{"name":"tmux_set_default","arguments":{"host":"my-ssh-alias","session":"collab","window":"collab:0","pane":"collab:0.0"}}
{"name":"tmux_get_default","arguments":{}}
Use Supergateway and (optionally) ngrok to expose the MCP stdio server to ChatGPT (Atlas tools):
npm i -g @k8ika0s/mcp-tmux
mcp-tmux --version # verify version
supergateway serve --listen 0.0.0.0:3001 --command "mcp-tmux" --env "MCP_TMUX_HOST=my-ssh-alias" --env "MCP_TMUX_SESSION=collab"
ngrok http 3001
Copy the https tunnel URL. 4) In ChatGPT (Atlas) tools, add a Custom MCP server pointing to your Supergateway URL (ngrok tunnel or local if supported). Example config snippet:
{
"servers": {
"tmux": {
"url": "https://your-ngrok-subdomain.ngrok.io",
"capabilities": ["tools", "resources"]
}
}
}
Use readonly tools (tmux_readonly_state, tmux_batch_capture, tmux_list_*, tmux_capture_pane) for information gathering; use confirm flags for destructive actions.
MCP_TMUX_SESSION: Prefer this session when no explicit target is provided.MCP_TMUX_HOST: Preferred ssh host alias when no explicit host is provided.TMUX_BIN: Path to the tmux binary (defaults to tmux).MCP_TMUX_TIMEOUT_MS: Timeout in ms for tmux/ssh invocations (default 15000).tmux_set_default or tmux_select_pane; tools like tmux_capture_pane, tmux_send_keys, and tail/pattern tasks fall back to the default pane when target is omitted./opt/homebrew/bin:/usr/local/bin:/usr/bin when invoking tmux (local or remote) so Homebrew installs are found.MCP_TMUX_HOSTS_FILE can point to a JSON file like:{
"hashimac": { "pathAdd": ["/opt/homebrew/bin"], "tmuxBin": "/opt/homebrew/bin/tmux", "defaultSession": "ka0s" }
}
~/.config/mcp-tmux/layouts.json by default via tmux_save_layout_profile/tmux_apply_layout_profile.~/.config/mcp-tmux/logs (override with MCP_TMUX_LOG_DIR), organized by host/session with daily log files.Safety spotlight: destructive tools need
confirm=true, and defaults help you avoid targeting the wrong pane. Keep logs on; review captures before acting.
tmux_send_keys will happily run destructive commands—ask for confirmation before altering state or killing sessions/windows.tmux/kill-*, destructive tmux_command) require confirm=true.tmux_command runs whatever you pass through to tmux; double-check args before using it.tmux_capture_pane to read output after sending keys.tmux_open_session → tmux_default_context → tmux_list_windows/tmux_list_panes → tmux_send_keys → tmux_capture_pane.tmux_set_default and re-ground with tmux_state.tmux_command.tmux_server_info (reports package name, version, repository link, and log directory).CI workflow) runs npm run build.npm audit --audit-level=high) runs in CI.Release (manual) builds, packs, and can publish. Inputs: publish, tag, version, bump. When publish=true, it publishes to npmjs (requires NPM_TOKEN), attempts GitHub Packages only if the package name is scoped to @k8ika0s/... (warns/skip otherwise), and creates a git tag plus GitHub Release with the tarball.mcp-tmux CLI entrypoint, MCP stdio server.npm test (vitest) covers helper path composition.npm run buildmake install — install dependenciesmake build — compile to dist/make test — run tests (vitest)make dev — hot-reload dev modemake start — run compiled servermake clean — remove dist/AGPL-3.0-only
Выполни в терминале:
claude mcp add tmux --env MCP_TMUX_HOST="" --env MCP_TMUX_SESSION="" -- npx -y @k8ika0s/mcp-tmuxДа, Tmux MCP бесплатный — установка в один клик через Unyly без оплаты.
Да, требуются переменные окружения: MCP_TMUX_HOST, MCP_TMUX_SESSION. Unyly подставит их в конфиг при установке.
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Открой Tmux на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
pro-tip
Поставил Tmux? Скажи Claude: «запомни почему я установил Tmux и что хочу попробовать» — попадёт в твой Vault.
как это работает →CSA PROJECT - FZCO © 2026 IFZA Business Park, DDP, Premises Number 31174 - 001
Безопасность
Низкий рискАвтоматическая эвристика по публичным данным — не гарантия безопасности.