mcp-ssh-multi
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-ssh-multiCheck uptime on proxmox server."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-ssh-multi
MCP server for managing multiple SSH servers through AI assistants. Provides 11 tools for remote command execution, file operations, and system monitoring.
Features
Multi-server management — Configure and manage multiple SSH servers from a single YAML file
Connection pooling — Automatic connection reuse with per-server locks and retry on stale connections
11 MCP tools — Execute commands, transfer files, read/write files, tail logs, list processes
Two transports — stdio (for local MCP clients) and streamable-http (for web/remote)
Cloudflare Tunnel compatible — Deploy behind a tunnel for remote access
MCP tool annotations — Hints for destructive, read-only, idempotent, and open-world operations
MCP resources —
ssh://serversresource for listing configured serversPagination — Directory listings support
limit/offsetfor large directoriesInput validation — Path and filter sanitization to prevent command injection
Structured errors — Consistent error responses with codes, messages, and suggestions
Installation
Using uv (recommended)
uv tool install mcp-ssh-multiUsing pip
pip install mcp-ssh-multiUsing uvx (one-shot)
uvx --from mcp-ssh-multi ssh-mcpFrom source
git clone https://github.com/gilberth/mcp-ssh-multi.git
cd mcp-ssh-multi
uv syncConfiguration
1. SSH Servers (ssh_servers.yaml)
Create a ssh_servers.yaml file with your server definitions:
servers:
proxmox:
host: 192.168.1.100
port: 22
username: root
key_file: ~/.ssh/id_rsa
description: "Proxmox VE hypervisor"
truenas:
host: 192.168.1.101
port: 22
username: root
password: "my-password" # or use key_file
description: "TrueNAS storage server"2. Environment Variables (.env)
Copy .env.example to .env and customize:
cp .env.example .envVariable | Default | Description |
|
| Path to servers config |
|
| Default command timeout (seconds) |
|
| Logging level |
|
| HTTP server port |
|
| HTTP endpoint path |
Usage
stdio mode (local MCP clients)
ssh-mcpOr with uvx:
uvx --from mcp-ssh-multi ssh-mcpHTTP mode (web/remote MCP clients)
ssh-mcp-webThe server will listen on http://0.0.0.0:8086/mcp by default.
MCP Client Configuration
Add to your MCP client config (e.g., Claude Desktop):
{
"mcpServers": {
"ssh": {
"command": "uvx",
"args": ["--from", "mcp-ssh-multi", "ssh-mcp"],
"env": {
"SSH_SERVERS_FILE": "/path/to/ssh_servers.yaml"
}
}
}
}For HTTP mode:
{
"mcpServers": {
"ssh": {
"url": "http://localhost:8086/mcp"
}
}
}Tool Reference
Connection Management
Tool | Description |
| List all configured servers with connection status |
| Disconnect from a specific server |
Command Execution
Tool | Description |
| Execute a shell command on a remote server |
File Operations
Tool | Description |
| Upload a local file to a remote server |
| Download a file from a remote server |
| Check if a file/directory exists on a server |
| List contents of a remote directory (supports pagination with |
| Read a text file from a remote server |
| Write content to a file on a remote server |
System Monitoring
Tool | Description |
| Tail a log file on a remote server |
| List running processes (optionally filtered) |
MCP Resources
The server exposes the following MCP resources:
Resource URI | Description |
| List of all configured SSH servers with connection status |
Changelog
v0.2.0
Per-server connection locks — Replaced global lock with per-server async locks for better concurrency
Connection retry — Automatic single retry on stale/lost SSH connections
MCP tool annotations — Added
destructiveHint,readOnlyHint,idempotentHint,openWorldHintto all toolsMCP resource — Added
ssh://serversresource endpointDirectory pagination —
ssh_list_dirnow supportslimitandoffsetparametersInput validation — Path sanitization for
ssh_tail_logand filter validation forssh_process_listStructured errors — Consistent error format with
ErrorCodeenum across all toolsDynamic versioning — Version sourced from
importlib.metadatainstead of hardcoded stringsTest suite — Added tests for pagination, retry logic, input validation, and version consistency
v0.1.1
Initial public release with 11 SSH tools, stdio and HTTP transports
Production Deployment (LXC + Cloudflare Tunnel)
Full deployment guide for running mcp-ssh-multi as a systemd service behind a Cloudflare Tunnel on a Proxmox LXC container.
Prerequisites
A Proxmox LXC container (Debian 12/13)
A Cloudflare account with a domain
uvandcloudflaredinstalled on the LXC
1. Install dependencies
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install cloudflared
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb \
-o cloudflared.deb && dpkg -i cloudflared.deb2. Create SSH servers config
mkdir -p /ssh-mcp
cat > /ssh-mcp/ssh_servers.yaml << 'EOF'
servers:
my-server:
host: 192.168.1.100
port: 22
username: root
password: "my-password" # or use key_file
description: "My server"
EOF3. Create the Cloudflare Tunnel
# Login to Cloudflare (opens browser)
cloudflared tunnel login
# Create the named tunnel
cloudflared tunnel create ssh-mcp
# Route DNS to your domain
cloudflared tunnel route dns ssh-mcp ssh-mcp.yourdomain.com4. Configure the tunnel
The tunnel create command outputs the tunnel UUID (e.g. 2687c640-38df-40f9-...) and creates a credentials file at /root/.cloudflared/<TUNNEL-ID>.json. If you need to find it later, run cloudflared tunnel list.
# Replace <TUNNEL-ID> with the UUID from "cloudflared tunnel create" output
cat > /root/.cloudflared/config.yml << 'EOF'
tunnel: <TUNNEL-ID>
credentials-file: /root/.cloudflared/<TUNNEL-ID>.json
ingress:
- hostname: ssh-mcp.yourdomain.com
service: http://localhost:8086
- service: http_status:404
EOF5. Create systemd services
mcp-ssh-multi service:
cat > /etc/systemd/system/mcp-ssh-multi.service << 'EOF'
[Unit]
Description=MCP SSH Multi Server
After=network.target
[Service]
Type=simple
Environment=SSH_SERVERS_FILE=/ssh-mcp/ssh_servers.yaml
Environment=MCP_SECRET_PATH=/your-secret-path
ExecStart=/root/.local/bin/uvx --from mcp-ssh-multi@latest ssh-mcp-web
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOFcloudflared service:
cloudflared service installEnable and start both:
systemctl daemon-reload
systemctl enable --now mcp-ssh-multi
systemctl enable --now cloudflared6. Verify
# Check services
systemctl status mcp-ssh-multi
systemctl status cloudflared
# Test the endpoint
curl -s -X POST "https://ssh-mcp.yourdomain.com/your-secret-path" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'7. Configure your MCP client
{
"mcpServers": {
"ssh": {
"type": "remote",
"url": "https://ssh-mcp.yourdomain.com/your-secret-path"
}
}
}Service management
# View logs
journalctl -u mcp-ssh-multi -f
journalctl -u cloudflared -f
# Restart services
systemctl restart mcp-ssh-multi
systemctl restart cloudflaredEnvironment Variables
Variable | Default | Description |
|
| Path to servers config |
|
| Default command timeout (seconds) |
|
| Logging level |
|
| HTTP server port |
|
| HTTP endpoint path (use a secret value) |
Development
# Install with dev dependencies
uv sync --group dev
# Run linting
uv run ruff check src/ tests/ --fix
uv run ruff format src/ tests/
# Run type checking
uv run mypy src/
# Run tests
uv run pytest tests/ -vLicense
MIT
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/gilberth/mcp-ssh-multi'
If you have feedback or need assistance with the MCP directory API, please join our Discord server