Metadata-Version: 2.4
Name: mcp-ssh-tmux
Version: 0.2.8
Summary: MCP server for persistent SSH sessions via local tmux
Project-URL: Homepage, https://github.com/devnullvoid/mcp-ssh-tmux
Project-URL: Repository, https://github.com/devnullvoid/mcp-ssh-tmux
Project-URL: Issues, https://github.com/devnullvoid/mcp-ssh-tmux/issues
Author-email: Jon Rogers <67245+devnullvoid@users.noreply.github.com>
License: MIT License
        
        Copyright (c) 2026 Jon Rogers <devnullvoid>
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: mcp,persistence,ssh,terminal,tmux
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: fastmcp
Requires-Dist: libtmux
Description-Content-Type: text/markdown

# mcp-ssh-tmux

[![PyPI version](https://badge.fury.io/py/mcp-ssh-tmux.svg)](https://badge.fury.io/py/mcp-ssh-tmux)
[![Downloads](https://pepy.tech/badge/mcp-ssh-tmux)](https://pepy.tech/project/mcp-ssh-tmux)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![GitHub stars](https://img.shields.io/github/stars/devnullvoid/mcp-ssh-tmux.svg)](https://github.com/devnullvoid/mcp-ssh-tmux/stargazers)

A high-performance, persistent Model Context Protocol (MCP) server that manages SSH sessions via a local `tmux` instance.

## Why this exists?

Traditional SSH automation runs individual commands without state tracking between executions. Other implementations rely on complex regex patterns to detect command completion. By using `tmux` as a persistent terminal multiplexer, this project eliminates that complexity entirely. The AI agent simply "looks" at the screen like a human would - the server provides visual snapshots, and the agent interprets prompts, errors, and output naturally.

## Key Features

-   **Persistence**: SSH connections stay alive in `tmux` even if the MCP server or your AI client restarts.
-   **Observability**: You can manually run `tmux attach -t mcp-ssh` to see exactly what the agent is doing in real-time.
-   **Reliability**: Uses `ssh -G` for robust config resolution (handles aliases, identity files, etc.).
-   **Safety**: Built-in command validation to prevent common dangerous operations.
-   **File Transfer**: Native tools for reading and writing remote files. Reads prefer a full-file SSH transfer and fall back to the existing PTY when needed.

## Installation

### Requirements

-   **tmux** must be installed on your system
    -   Ubuntu/Debian: `apt install tmux`
    -   macOS: `brew install tmux`
    -   Arch: `pacman -S tmux`

### Via `uv` (Recommended)

```bash
uv tool install mcp-ssh-tmux
```

### Via `pip`

```bash
pip install mcp-ssh-tmux
```

## Configuration

Add this to your `mcp.json` (e.g., in Claude Desktop, Cursor, or 1mcp):

```json
{
  "mcpServers": {
    "ssh-tmux": {
      "command": "uv",
      "args": [
        "run",
        "mcp-ssh-tmux"
      ]
    }
  }
}
```

*Note: If you installed via `uv tool install`, you can just use `mcp-ssh-tmux` as the command.*

## Tools

-   `open_session(host, username, port)`: Opens a new SSH connection in a unique tmux window.
-   `send_command(session_id, command, lines, timeout)`: Sends a command and polls for a prompt/output. Returns only the last `lines` of terminal output/scrollback. `timeout` (default 2.0s) controls how long to wait — increase for slower commands like package installs.
-   `send_keys(session_id, keys)`: Sends raw keystrokes without Enter. Use for Ctrl+C, Ctrl+D, interactive input, etc.
-   `get_snapshot(session_id, lines)`: Captures the current screen state. Returns only the last `lines` of terminal output/scrollback.
-   `read_remote_file(session_id, remote_path, fallback_lines)`: Reads a remote text file. Prefer this over `cat` via `send_command()` when you need the full file contents. `fallback_lines` controls bounded tmux-history capture if direct SSH read is unavailable.
-   `write_remote_file(session_id, remote_path, content, append)`: Writes content to a remote file.
-   `list_sessions()`: Lists all active SSH windows.
-   `cleanup_dead_sessions(max_age_seconds)`: Kills all windows where the SSH connection has closed. Optionally filters by how long the session has been dead.
-   `close_session(session_id)`: Kills the window and cleans up. **WARNING**: This terminates any running processes in the session. For long-running tasks, leave the session open and monitor with `get_snapshot()`.

## Transport Modes

By default, the server uses `stdio` for communication with MCP clients. You can switch to the modern **Streamable HTTP** transport using environment variables:

```bash
# Start server in HTTP mode on port 8080
FASTMCP_TRANSPORT=http FASTMCP_PORT=8080 mcp-ssh-tmux
```

The server will be available at `http://localhost:8080/mcp`.

## Important Notes

### Automatic Cleanup

- **Background Reaper**: The server automatically cleans up sessions that have been dead (disconnected) for more than **24 hours**.
- **Manual Cleanup**: Use `cleanup_dead_sessions()` to manually clear disconnected sessions at any time.

### Reading Files

- **Use `read_remote_file()` for file contents**: `send_command("cat ...")` and `get_snapshot()` are screen/snapshot tools, so they only return the tail of terminal output.
- **`lines` controls snapshot depth**: Increase `lines` on `send_command()` or `get_snapshot()` when you need more terminal history, but use `read_remote_file()` for actual file reads.
- **`fallback_lines` controls PTY fallback depth**: If direct SSH file read is unavailable, `read_remote_file()` inspects only the last `fallback_lines` of tmux history. Increase it when needed, but keep it bounded.
- **Best for text files**: `read_remote_file()` is intended for configs, source, logs, and similar text content.

### Session Management

- **Do not close sessions with active processes**: Closing a session terminates all running commands (builds, downloads, etc.)
- **Monitor long-running tasks**: Use `get_snapshot()` to check progress without closing the session
- **Sessions persist**: SSH connections remain alive in tmux even if the MCP server restarts
- **Manual inspection**: Run `tmux attach -t mcp-ssh` to see what's happening in real-time

## Acknowledgments

Built with [FastMCP](https://github.com/PrefectHQ/fastmcp) and [libtmux](https://github.com/tmux-python/libtmux).

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

## Star History

If you find this project useful, please consider giving it a star! ⭐

## License

MIT
