7.0 KiB
MCP SSH Server
An Anthropic Model Context Protocol (MCP) server that provides SSH access to remote systems, enabling full access to remote virtual machines in a sandbox environment.
Features
- Uses stdio for MCP communication
- Provides SSH connection to remote servers
- Enables command execution on remote systems
- Secure public key authentication
- SCP/SFTP file transfer (upload, download, directory listing, file removal, disk usage)
- Configurable via environment variables or MCP config
- Automatically terminates when the client stops polling for resources/prompts (controlled by
MCP_SSH_POLL_INTERVAL
andMCP_SSH_MISSED_POLLS_THRESHOLD
)
Installation
pip install -e .
Configuration
The SSH server can be configured using environment variables or the MCP JSON configuration:
Environment Variable | Description | Default |
---|---|---|
MCP_SSH_HOSTNAME |
SSH server hostname or IP address | None |
MCP_SSH_PORT |
SSH server port | 22 |
MCP_SSH_USERNAME |
SSH username | None |
MCP_SSH_KEY_FILENAME |
Path to SSH private key file | None |
MCP_SSH_SERVER_NAME |
Custom name for the server instance | "SSH Server" |
MCP_SSH_TOOL_PREFIX |
Prefix for tool names (e.g., 'server1_' for 'server1_ssh_connect') | "" |
MCP_SSH_POLL_INTERVAL |
Interval in seconds between client polling requests (resources/list / prompts/list ) |
60 |
MCP_SSH_MISSED_POLLS_THRESHOLD |
Number of missed polling intervals before the server auto-shuts down | 3 |
Claude Desktop MCP Configuration
Add the following to your Claude Desktop MCP configuration file:
{
"mcpssh": {
"command": "python",
"args": [
"-m",
"mcpssh"
],
"env": {
"MCP_SSH_HOSTNAME": "example.com",
"MCP_SSH_PORT": "22",
"MCP_SSH_USERNAME": "user",
"MCP_SSH_KEY_FILENAME": "/path/to/private_key"
}
}
}
Multiple SSH Server Configuration
You can configure multiple SSH servers in Claude Desktop by creating multiple entries with different names and using the MCP_SSH_SERVER_NAME
and MCP_SSH_TOOL_PREFIX
environment variables to distinguish them:
{
"mcpssh1": {
"command": "python",
"args": [
"-m",
"mcpssh"
],
"env": {
"MCP_SSH_HOSTNAME": "production.example.com",
"MCP_SSH_USERNAME": "prod-user",
"MCP_SSH_KEY_FILENAME": "~/.ssh/prod_key",
"MCP_SSH_SERVER_NAME": "Production Server",
"MCP_SSH_TOOL_PREFIX": "prod_"
}
},
"mcpssh2": {
"command": "python",
"args": [
"-m",
"mcpssh"
],
"env": {
"MCP_SSH_HOSTNAME": "dev.example.com",
"MCP_SSH_USERNAME": "dev-user",
"MCP_SSH_KEY_FILENAME": "~/.ssh/dev_key",
"MCP_SSH_SERVER_NAME": "Development Server",
"MCP_SSH_TOOL_PREFIX": "dev_"
}
}
}
With this configuration:
- Claude will have access to two separate SSH server tools
- Each server will be identified by its custom name in Claude's UI
- Each server's tools will have unique prefixes to distinguish them (e.g.,
prod_ssh_connect
vsdev_ssh_connect
)
Usage
This server implements the Anthropic MCP protocol and provides the following tools (note that when using MCP_SSH_TOOL_PREFIX
, the tool names will be prefixed with that value):
ssh_connect
: Connect to an SSH server using public key authentication (using config or explicit parameters)ssh_execute
: Execute a command on the SSH serverssh_disconnect
: Disconnect from the SSH serverscp_upload
: Upload a file to the remote server via SFTP/SCPscp_download
: Download a file from the remote server via SFTP/SCPscp_listdir
: List a remote directory via SFTPscp_remove
: Remove a remote file via SFTPscp_disk_usage
: Get remote disk usage statistics via SFTP
Example
from mcp import ClientSession, StdioServerParameters
from mcpssh.server import SSHServerMCP, FileTransferParams
# Start the server in a subprocess
server_params = StdioServerParameters(
command="python",
args=["-m", "mcpssh"],
env={
"MCP_SSH_HOSTNAME": "example.com",
"MCP_SSH_PORT": "22",
"MCP_SSH_USERNAME": "user",
"MCP_SSH_KEY_FILENAME": "/path/to/private_key"
}
)
# Use with an MCP client
with ClientSession(server_params) as client:
# Connect to SSH server
client.ssh_connect()
# Execute a command
result = client.ssh_execute(command="ls -la")
print(result["stdout"])
# Upload a file
upload_params = FileTransferParams(
local_path="/path/to/local.txt",
remote_path="/tmp/remote.txt",
max_size=1024*1024*10, # 10MB
on_conflict="RENAME" # Options: FAIL, OVERWRITE, RENAME
)
upload_result = client.scp_upload(upload_params)
print(upload_result)
# Download a file
download_params = FileTransferParams(
local_path="/tmp/downloaded.txt",
remote_path="/tmp/remote.txt",
on_conflict="OVERWRITE"
)
download_result = client.scp_download(download_params)
print(download_result)
# List a remote directory
dir_result = client.scp_listdir("/tmp")
print(dir_result)
# Remove a remote file
rm_result = client.scp_remove("/tmp/remote.txt")
print(rm_result)
# Get remote disk usage
disk_result = client.scp_disk_usage("/tmp")
print(disk_result)
# Disconnect
client.ssh_disconnect()
Direct Server Usage
from mcpssh.server import SSHServerMCP
# Initialize and run the server
server = SSHServerMCP(
hostname="example.com",
port=22,
username="user",
key_filename="/path/to/private_key",
server_name="My Custom Server", # Optional custom server name
tool_prefix="custom_" # Optional tool name prefix
)
# Run the server with stdio transport
server.run(transport="stdio")
File Transfer Parameters
File transfer tools (scp_upload
, scp_download
) use the FileTransferParams
model:
class FileTransferParams(BaseModel):
local_path: str
remote_path: str
max_size: Optional[int] = 1073741824 # bytes (default: 1GB)
on_conflict: Literal["FAIL", "OVERWRITE", "RENAME"] = "FAIL"
local_path
: Path to the local file (upload: source, download: destination)remote_path
: Path to the remote file (upload: destination, download: source)max_size
: Optional file size limit (in bytes)on_conflict
: What to do if the file exists (FAIL
,OVERWRITE
,RENAME
)
Conflict Resolution
FAIL
: Abort if the file existsOVERWRITE
: Replace the existing fileRENAME
: Add a timestamp suffix to avoid overwriting
Error Handling
- All file operations return a
success
boolean and detailed error messages if applicable. - Partial transfers are automatically cleaned up unless configured otherwise.
- Disk space and file size are checked before transfer.
Security Note
This tool provides full access to a remote system. It should only be used with virtual machines in sandbox environments where security implications are well understood.
License
MIT