tmux-python / tmux-python/libtmux-mcp
run_command: tmux completion wrapper breaks over SSH panes (error connecting to socket)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 13
- Forks
- 0
- Avg merge
- 13h 52m
- Merged PRs (30d)
- 4
Description
Description
run_command wraps each authored command with a completion-sync wrapper (see
src/libtmux_mcp/tools/pane_tools/io.py, the status_cmd / signal_cmd
construction):
(
<command>
); s=$?; tmux set-option -p -t <pane_id> @s_<id> "$s"; tmux wait-for -S r_<id>
The tmux set-option and tmux wait-for -S fragments execute inside the
pane's shell. When the pane's shell is an active SSH session, that shell
lives on a remote host that has no tmux server (or a different socket), so both
calls fail in the pane with:
error connecting to /tmp/tmux-1001/default (No such file or directory)
error connecting to /tmp/tmux-1001/default (No such file or directory)
(the socket path carries the remote user's uid).
Steps to reproduce
- In a tmux pane, run
ssh user@remote-hostand log in. - Have the agent call
run_commandin that pane (e.g.git status). - Observe the two
error connecting to .../defaultlines printed in the pane.
Actual behavior
- The user's command still runs and its output is visible, so it looks like it
"works". - But the
wait-forchannel is never signalled, so the server-side wait runs to
theLIBTMUX_MCP_WAIT_MAX_SECONDSceiling and the call reports a
timeout-based result. - The
@s_<id>pane option is never set, so no exit status can be read back. - The error lines are printed into the pane a human may be watching.
Expected behavior
One or both:
- Document the limitation —
gotchas.md,troubleshooting.md, and/or the
run_commandtool description:run_commandassumes the pane's shell can
reach the same tmux server the MCP talks to. In SSH panes, compose
send_keys+ a shell-level completion marker +wait_for_text+
capture_paneinstead. - Detect it — e.g. check
pane_current_command(orpane_in_mode) before
wrapping: when the pane isssh, either skip the wrapper and warn in the
result, or fail loudly with a hint, rather than sending a wrapper that is
guaranteed to emit errors on the remote.
Workaround that works (shell marker, no tmux in the payload)
send_keys(pane_id, "git status; echo __MCP_DONE_$?__", enter=True, literal=True)
wait_for_text(pane_id, patterns=["__MCP_DONE_"], timeout=120)
capture_pane(pane_id)
The marker is pure shell and runs on the remote — no tmux call, so no error
lines; the exit code is read from the __MCP_DONE_<n> line in the capture.
Environment
- libtmux-mcp
0.1.0a22(FastMCP 4.0.3) - tmux 3.4 on WSL2 Ubuntu (local); remote host is a plain Ubuntu 24.04 box
- MCP server addresses the local tmux server; the affected pane is a shell that
has logged in over SSH
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/libtmux_mcp/tools/pane_tools/io.py at the status_cmd and signal_cmd construction, then reproduce run_command in an SSH-backed pane. Review the existing run_command description and documentation files named in the issue. Done means the chosen behavior is documented or detected clearly, without remote tmux errors or timeout-based completion results.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100