ssh-mcp-server

kunwarmahen/ssh-mcp-server

3.2

If you are the rightful owner of ssh-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

A secure Model Context Protocol (MCP) server that enables remote SSH command execution with strict read-only enforcement.

Tools
5
Resources
0
Prompts
0

SSH Read-Only MCP Server

A secure Model Context Protocol (MCP) server that enables remote SSH command execution with strict read-only enforcement. Perfect for safely delegating SSH access to Claude while preventing accidental or malicious write operations.

Features

Read-Only Command Enforcement – Only allows safe, read-only commands
SSH Connection Pooling – Support multiple simultaneous connections
Command Validation – Blocks dangerous patterns and write operations
Multicast Discovery – Auto-announces on network for easy discovery
Flexible Transport – Stdio, HTTP, or Streamable-HTTP modes
Comprehensive Logging – Full audit trail in ssh_mcp.log
Environment Configuration – Fully configurable via .env

Installation

Prerequisites

  • Python 3.8+
  • uv package manager

Setup

# Clone or create project directory
mkdir ssh-mcp-server
cd ssh-mcp-server

# Initialize uv project (if needed)
uv init

# Install dependencies
uv pip install fastmcp paramiko python-dotenv

Or use pyproject.toml:

[project]
name = "ssh-mcp-server"
version = "0.1.0"
dependencies = [
    "fastmcp>=0.1.0",
    "paramiko>=3.0.0",
    "python-dotenv>=1.0.0",
]

Then install:

uv sync

Configuration

Create a .env file in the project root:

# Transport mode: stdio (default), http, or streamable-http
MCP_TRANSPORT=stdio

# Server identification
MCP_SERVER_NAME=SSH Read-Only MCP Server

# HTTP mode settings (if using http/streamable-http)
MCP_HOST=0.0.0.0
MCP_PORT=3000

# Multicast discovery
MCP_ENABLE_BROADCAST=true
MCP_BROADCAST_INTERVAL=30

Environment Variables

VariableDefaultDescription
MCP_TRANSPORTstdioCommunication transport: stdio, http, or streamable-http
MCP_SERVER_NAMESSH Read-Only MCP ServerDisplay name for the server
MCP_HOST0.0.0.0Bind address for HTTP mode
MCP_PORT3000Port for HTTP mode
MCP_ENABLE_BROADCASTtrueEnable multicast discovery announcements
MCP_BROADCAST_INTERVAL30Seconds between broadcast announcements

Usage

Start the Server

Stdio mode (default):

uv run ssh_readonly_fastmcp_mcast.py

HTTP mode with multicast discovery:

MCP_TRANSPORT=http MCP_PORT=3000 uv run ssh_readonly_fastmcp_mcast.py

HTTP mode without broadcasting:

MCP_ENABLE_BROADCAST=false MCP_TRANSPORT=http MCP_PORT=3000 uv run ssh_readonly_fastmcp_mcast.py

Available Tools

1. ssh_connect

Establish an SSH connection to a remote machine.

Parameters:

  • host (required) – Remote host IP or hostname
  • username (required) – SSH username
  • port (optional, default: 22) – SSH port
  • key_filename (optional) – Path to private key file (recommended)
  • password (optional) – SSH password (fallback)

Example:

Connect to 192.168.1.100 as user 'admin' with private key
host: 192.168.1.100
username: admin
key_filename: /home/user/.ssh/id_rsa
2. ssh_execute

Execute a read-only command on the connected remote machine.

Parameters:

  • host (required) – Remote host (must be connected first)
  • username (required) – SSH username
  • command (required) – Read-only command to execute
  • port (optional, default: 22) – SSH port

Example:

Run 'ls -la /home' on connected server
host: 192.168.1.100
username: admin
command: ls -la /home
3. ssh_disconnect

Close an SSH connection.

Parameters:

  • host (required) – Remote host
  • username (required) – SSH username
  • port (optional, default: 22) – SSH port
4. ssh_list_connections

View all active SSH connections.

Parameters: None

5. ssh_get_allowed_commands

Retrieve the list of allowed read-only commands.

Parameters: None

Allowed Commands

The server permits the following read-only operations:

  • File operations: cat, ls, file, head, tail, find, locate
  • System info: ps, top, df, du, free, uname, hostname, uptime
  • Network: netstat, ss, ifconfig, ip, curl, wget, dig, nslookup, ping, traceroute
  • Process management: lsof, systemctl, service
  • Text processing: grep, awk, sed, wc
  • And many more read-only utilities

Blocked operations: rm, mv, cp, chmod, chown, mkdir, touch, kill, shutdown, reboot, sudo, and any write/modify commands.

Multicast Discovery

When running in HTTP mode with broadcasting enabled, the server announces itself on the multicast group:

  • Address: 239.255.255.250
  • Port: 5353
  • Interval: Configurable (default: 30 seconds)

Discovery announcement includes:

  • Server UUID
  • Server name
  • Local IP and port
  • Transport type
  • Protocol version

Logging

All activity is logged to ssh_mcp.log:

2025-10-17 10:30:45,123 [INFO] ssh_mcp - Starting MCP server with transport=http
2025-10-17 10:30:46,456 [INFO] ssh_mcp - Starting multicast broadcaster on 239.255.255.250:5353
2025-10-17 10:30:47,789 [INFO] ssh_mcp - Successfully connected to admin@192.168.1.100:22

Security Considerations

🔒 Read-Only Enforcement:

  • Only whitelisted commands are allowed
  • Dangerous patterns (pipes, redirects, subshells) are blocked
  • Write operations are prevented at the command level

⏱️ Timeouts:

  • 30-second execution timeout per command
  • Prevents hanging commands from blocking the server

🔐 Authentication:

  • SSH key authentication recommended over passwords
  • Passwords stored in memory only, never persisted

📋 Audit Trail:

  • All connections and commands are logged
  • Review ssh_mcp.log for security audits

Troubleshooting

Connection Refused

Error: Connection failed: [Errno 111] Connection refused
  • Verify the remote host is reachable: ping <host>
  • Check SSH is running on the remote machine
  • Verify port number (default 22)

Authentication Failed

Error: Connection failed: Authentication failed
  • Verify username is correct
  • For key auth: check key file path and permissions (chmod 600)
  • For password auth: verify credentials
  • Ensure SSH public key is authorized on remote (~/.ssh/authorized_keys)

Command Not Allowed

Error: Command not allowed for security reasons
  • The command contains a blocked pattern or is not in the allowed list
  • Use ssh_get_allowed_commands to see permitted commands
  • For write operations, use SSH directly instead

Broadcast Not Working

  • Verify MCP_ENABLE_BROADCAST=true
  • Check network supports multicast (most corporate networks block it)
  • Verify firewall allows UDP on port 5353
  • Check ssh_mcp.log for broadcast errors

Development

Running in Debug Mode

DEBUG=true uv run ssh_readonly_fastmcp_mcast.py

Testing

# Test connection
uv run -c "from ssh_readonly_fastmcp_mcast import is_command_safe; print(is_command_safe('ls -la'))"

# Should print: True

# Test blocked command
uv run -c "from ssh_readonly_fastmcp_mcast import is_command_safe; print(is_command_safe('rm -rf /'))"

# Should print: False

Project Structure

ssh-mcp-server/
├── ssh_readonly_fastmcp_mcast.py    # Main server implementation
├── .env                        # Configuration file
├── .env.example               # Configuration template
├── ssh_mcp.log                # Server logs (auto-generated)
├── pyproject.toml             # Project metadata
└── README.md                  # This file

API Response Format

All tools return consistent JSON responses:

Success:

{
  "status": "success",
  "host": "192.168.1.100",
  "command": "ls -la /home",
  "exit_code": 0,
  "output": "total 24\ndrwxr-xr-x 3 root root 4096...",
  "error": null
}

Error:

{
  "status": "error",
  "message": "Command not allowed for security reasons",
  "reason": "Only read-only commands are permitted"
}

License

MIT

Contributing

Contributions welcome! Please ensure:

  • All changes maintain read-only enforcement
  • Code is logged appropriately
  • Tests pass for security validations

Support

For issues or questions:

  1. Check ssh_mcp.log for error details
  2. Review the Troubleshooting section
  3. Verify environment configuration
  4. Check network connectivity to remote hosts