Skip to main content

MCP SSH Multi - Multi-server SSH access through MCP

Project description

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 and reconnection
  • 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

Installation

Using uv (recommended)

uv tool install mcp-ssh-multi

Using pip

pip install mcp-ssh-multi

Using uvx (one-shot)

uvx --from mcp-ssh-multi ssh-mcp

From source

git clone https://github.com/gilberth/mcp-ssh-multi.git
cd mcp-ssh-multi
uv sync

Configuration

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 .env
Variable Default Description
SSH_SERVERS_FILE ssh_servers.yaml Path to servers config
SSH_TIMEOUT 30 Default command timeout (seconds)
LOG_LEVEL INFO Logging level
MCP_PORT 8086 HTTP server port
MCP_SECRET_PATH /mcp HTTP endpoint path

Usage

stdio mode (local MCP clients)

ssh-mcp

Or with uvx:

uvx --from mcp-ssh-multi ssh-mcp

HTTP mode (web/remote MCP clients)

ssh-mcp-web

The 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
ssh_list_servers List all configured servers with connection status
ssh_disconnect Disconnect from a specific server

Command Execution

Tool Description
ssh_execute Execute a shell command on a remote server

File Operations

Tool Description
ssh_upload Upload a local file to a remote server
ssh_download Download a file from a remote server
ssh_file_exists Check if a file/directory exists on a server
ssh_list_dir List contents of a remote directory
ssh_read_file Read a text file from a remote server
ssh_write_file Write content to a file on a remote server

System Monitoring

Tool Description
ssh_tail_log Tail a log file on a remote server
ssh_process_list List running processes (optionally filtered)

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
  • uv and cloudflared installed 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.deb

2. 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"
EOF

3. 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.com

4. 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
EOF

5. 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
EOF

cloudflared service:

cloudflared service install

Enable and start both:

systemctl daemon-reload
systemctl enable --now mcp-ssh-multi
systemctl enable --now cloudflared

6. 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 cloudflared

Environment Variables

Variable Default Description
SSH_SERVERS_FILE ssh_servers.yaml Path to servers config
SSH_TIMEOUT 30 Default command timeout (seconds)
LOG_LEVEL INFO Logging level
MCP_PORT 8086 HTTP server port
MCP_SECRET_PATH /mcp 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/ -v

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_ssh_multi-0.1.1.tar.gz (24.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_ssh_multi-0.1.1-py3-none-any.whl (24.8 kB view details)

Uploaded Python 3

File details

Details for the file mcp_ssh_multi-0.1.1.tar.gz.

File metadata

  • Download URL: mcp_ssh_multi-0.1.1.tar.gz
  • Upload date:
  • Size: 24.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.4

File hashes

Hashes for mcp_ssh_multi-0.1.1.tar.gz
Algorithm Hash digest
SHA256 2dad1ffeef36857902e783b25c4f3c282b68f4ab7728a66920ba1832274f4ab2
MD5 f94f7be666486271f96f293c3f8868ab
BLAKE2b-256 bfb4fd00900f292fa6189ac5069537d278d2c3d42d29ee13b387adfb83319134

See more details on using hashes here.

File details

Details for the file mcp_ssh_multi-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for mcp_ssh_multi-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0d1f3e33ead311e44b7fd64d32e7f188fb7c976d33373ae72059d8b951e0f718
MD5 2fa55201fb7382f300275060d8746acd
BLAKE2b-256 c4a4f78d16aa907a8316e94ba180ccef0b49a6284cabda8d4551f870851ca1b1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page