Content
# sshmcp
A stateful SSH MCP server for Claude Code. Gives Claude persistent shell sessions over SSH — commands preserve working directory, environment variables, and state across calls.
## Features
- **Stateful sessions**: tmux-backed shells that persist cwd, env, shell state
- **Multiple sessions**: connect to multiple hosts simultaneously, switch between them
- **File operations**: upload, download, and write files via SFTP
- **Output management**: automatic truncation with head/tail preservation
- **Background processes**: supports `&` for long-running commands
## Install
```bash
pip install -e .
```
## Claude Code config
Add to `~/.claude/claude_desktop_config.json` or your MCP settings:
```json
{
"mcpServers": {
"ssh": {
"command": "sshmcp",
"args": []
}
}
}
```
## Tools
| Tool | Description |
|------|-------------|
| `ssh_connect` | Connect to a host via SSH (password, key, or agent) |
| `ssh_exec` | Run a command in the persistent shell |
| `ssh_read_output` | Read recent terminal output |
| `ssh_upload` | Upload a local file via SFTP |
| `ssh_download` | Download a remote file via SFTP |
| `ssh_write_file` | Write content to a remote file |
| `ssh_list_sessions` | List all active sessions |
| `ssh_switch_session` | Switch active session |
| `ssh_close` | Close a session |
## Usage
Once configured, Claude can:
```
ssh_connect(host="myserver.com", username="user", key_path="~/.ssh/id_ed25519")
ssh_exec(command="cd /opt/app && cat config.yaml")
ssh_exec(command="grep -r 'ERROR' /var/log/app/") # still in /opt/app context
ssh_upload(local_path="./exploit.py", remote_path="/tmp/exploit.py")
```