MCP server for interacting with a REPL running inside a tmux pane
Project description
tmux-repl-mcp
An MCP server for interacting with a REPL running inside a tmux pane.
With it running, you might say something like the following to your AI:
I have a Lisp REPL running in the other pane (pane 0) of the current window we're in (window 6). Please debug the function we're writing together using that REPL.
It works with way more than just Lisp -- Python shell, Ruby irb, and Goose itself are all supported. Additional types of REPLs may be specified via environment variable.
Use it with Goose, Cursor, or any other MCP client.
But Why
I was working with my AI to interact with another tmux pane, and it could do it via CLI commands, but it doesn't know how to just get the output of the last command it run. Indeed, tmux doesn't support this directly. You have to ask it for the last e.g. 5000 lines or whatever, hoping that window has your output. But this poisons the context with too many tokens, and it has no mechanism for waiting until the command is finished. You just have to keep sleeping and checking, sleeping and checking. With this tool, I can now send commands to a running REPL and read back the output with perfect timing — no more guessing how long to sleep, no more context poisoning, no more "wait, 1000 lines wasn't enough" nonsense.
Features
| Tool | Description |
|---|---|
is_repl_ready |
Check whether the pane is showing a known REPL prompt |
get_last_command |
Read the last command and its output from the pane history |
execute_command |
Send a command, wait for the REPL to finish, return output |
Quick start
uvx tmux-repl-mcp
Goose configuration
extensions:
tmux-repl-mcp:
type: stdio
cmd: uvx
args:
- tmux-repl-mcp
enabled: true
Tools
is_repl_ready
is_repl_ready(pane="0", max_lines=50)
Returns {"kind": "<kind>"} if a known REPL prompt is detected on the last
non-empty line of the pane, or {"kind": null} if the pane is busy or shows
an unrecognised prompt.
get_last_command
get_last_command(kind, pane="0", max_lines=200)
Looks back through up to max_lines lines of the pane history for a complete
prompt→command→output→prompt block and returns:
{"last_command": "...", "output": "..."}
Both values are null when no complete block is found or the REPL is still
running.
execute_command
execute_command(command, kind, pane="0", max_lines=200, check=2.0)
- Verifies the REPL is ready and of the expected
kind. - Sends
commandto the pane viatmux send-keys. - Waits (polling every
checkseconds) until the REPL prompt reappears. - Returns
{"status": "ok", "last_command": "...", "output": "..."}.
REPL kinds
The following kinds are built-in:
| Kind | Prompt pattern |
|---|---|
python |
^>>> |
ipython |
^In \[\d+\]: |
bash |
[\$\#]\s*$ |
zsh |
[\$\#%]\s*$ |
sh |
[\$\#]\s*$ |
lisp |
^\*\s*$ / ^…>\s*$ / ^\d+\]\s*$ |
sbcl |
^\*\s*$ / ^\d+\]\s*$ |
node |
^> |
irb |
^irb\(.*\):\d+:\d+> $ |
iex |
^iex\(\d+\)> $ |
Adding custom kinds
Set the TMUX_REPL_KINDS environment variable to a JSON object:
export TMUX_REPL_KINDS='{"myrepl": "^myrepl> "}'
Entries here are merged on top of the built-in defaults, so existing kinds can also be overridden.
Development
# Install dev dependencies
uv sync --dev
# Run tests
uv run pytest -v
Goose permission tips
Because is_repl_ready and get_last_command only read tmux state, they are
safe to mark as Always Allow in Goose. Reserve Ask User for
execute_command since it writes to your REPL.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tmux_repl_mcp-0.1.0.tar.gz.
File metadata
- Download URL: tmux_repl_mcp-0.1.0.tar.gz
- Upload date:
- Size: 6.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e06e4e8af9252c58b56b1ef9869612362cc147320fb35bdd1db875e24040de9
|
|
| MD5 |
d8c5ae0b549bf855a217bd192505a0d7
|
|
| BLAKE2b-256 |
ce293f3ec24ee7b972fb89d4a197a1796d82596c7052ebfdda932a9f48e76919
|
Provenance
The following attestation bundles were made for tmux_repl_mcp-0.1.0.tar.gz:
Publisher:
pypi.yaml on djha-skin/tmux-repl-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tmux_repl_mcp-0.1.0.tar.gz -
Subject digest:
3e06e4e8af9252c58b56b1ef9869612362cc147320fb35bdd1db875e24040de9 - Sigstore transparency entry: 2145932236
- Sigstore integration time:
-
Permalink:
djha-skin/tmux-repl-mcp@cd1cefab3c4a65fd2e1f1e6d2ad9a0025b378136 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/djha-skin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yaml@cd1cefab3c4a65fd2e1f1e6d2ad9a0025b378136 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tmux_repl_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tmux_repl_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77169ee095f74b43c4405fa4ed44e2564c94081f7f530d5a6cb9a3d27e8bdeb5
|
|
| MD5 |
d3df47b545691c1c10aadb80ee8234a8
|
|
| BLAKE2b-256 |
8e32086b42061d3bdfd562981553a8b659ce78af35c7d32b20d8b02e57c71145
|
Provenance
The following attestation bundles were made for tmux_repl_mcp-0.1.0-py3-none-any.whl:
Publisher:
pypi.yaml on djha-skin/tmux-repl-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tmux_repl_mcp-0.1.0-py3-none-any.whl -
Subject digest:
77169ee095f74b43c4405fa4ed44e2564c94081f7f530d5a6cb9a3d27e8bdeb5 - Sigstore transparency entry: 2145932253
- Sigstore integration time:
-
Permalink:
djha-skin/tmux-repl-mcp@cd1cefab3c4a65fd2e1f1e6d2ad9a0025b378136 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/djha-skin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yaml@cd1cefab3c4a65fd2e1f1e6d2ad9a0025b378136 -
Trigger Event:
push
-
Statement type: