A secure MCP (Model Context Protocol) server that enables AI assistants to execute commands on remote servers via SSH. Cross-platform support for Windows, macOS, and Linux.
- Secure SSH execution - Execute commands on remote servers with encrypted config storage
- Multiple transport protocols - Support for both stdio and HTTP/WebSocket protocols
- Connection management - Persistent connections with pooling and health checks
- Cross-platform - Works from any OS to any SSH-enabled server
- Security-first - Command validation, audit logging, and access controls
- Easy integration - Works with Claude Desktop, Cursor, VS Code, web apps, and other MCP clients
git clone <repository-url>
cd ssh-command-executor-mcp
uv sync # or: pip install -r requirements.txt
Requirements: Python 3.10+
Stdio Transport (for MCP clients like Claude Desktop):
# Using uv (recommended)
uv run -- python run_server.py
# Or using Python directly
python run_server.py
HTTP Transport (for web applications and direct API access):
# Start HTTP server on localhost:8000
python run_http_server.py
# Or with custom host/port
SSH_MCP_HTTP_HOST=0.0.0.0 SSH_MCP_HTTP_PORT=9000 python run_http_server.py
Add to your config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:
%APPDATA%/Claude/claude_desktop_config.json
{
"mcpServers": {
"ssh-command-executor": {
"command": "uv",
"args": ["run", "--", "python", "/path/to/ssh-command-executor-mcp/run_server.py"]
}
}
}
Replace /path/to/ssh-command-executor-mcp
with the actual absolute path to your project directory.
For Cursor, VS Code, or other MCP-compatible tools, configure them to run:
# Using uv (recommended)
uv run -- python /path/to/ssh-command-executor-mcp/run_server.py
# Or using Python directly
python /path/to/ssh-command-executor-mcp/run_server.py
Replace /path/to/ssh-command-executor-mcp
with the actual absolute path to your project directory.
HTTP REST API:
# Start the HTTP server
python run_http_server.py
# Available endpoints:
# GET /health - Health check
# GET /tools - List available tools
# POST /tools/{name} - Execute a tool
# GET /prompts - List available prompts
# POST /prompts/{name} - Execute a prompt
WebSocket (Real-time):
const ws = new WebSocket('ws://localhost:8000/ws');
// Execute a tool
ws.send(JSON.stringify({
type: 'tool_call',
tool: 'ssh_execute',
arguments: {
host: '192.168.1.100',
username: 'admin',
command: 'df -h'
}
}));
// Handle response
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
console.log('Result:', response.result);
};
Configure a server:
{
"name": "ssh_configure",
"arguments": {
"name": "production",
"host": "prod-server.com",
"username": "deploy",
"key_path": "~/.ssh/deploy_key"
}
}
Execute commands:
{
"name": "ssh_run",
"arguments": {
"command": "systemctl status nginx"
}
}
{
"name": "ssh_execute",
"arguments": {
"host": "192.168.1.100",
"username": "admin",
"command": "df -h",
"key_path": "/path/to/key"
}
}
Tool | Description | Stdio | HTTP | WebSocket |
---|---|---|---|---|
ssh_configure |
Configure server connection details for reuse | ✅ | ✅ | ✅ |
ssh_run |
Execute commands on pre-configured servers | ✅ | ✅ | ✅ |
ssh_execute |
Execute commands with full connection details | ✅ | ✅ | ✅ |
ssh_test_connection |
Test SSH connectivity | ✅ | ✅ | ✅ |
ssh_list_servers |
List configured servers | ✅ | ✅ | ✅ |
Resource | Description | Content Type |
---|---|---|
ssh://servers |
List all configured SSH servers | 📋 Server Inventory |
ssh://history |
Recent SSH command execution history | 📈 Command History |
ssh://servers/{name}/status |
Real-time status of specific server | 📊 Server Status |
ssh://config/security |
Current security configuration | 🔒 Security Settings |
ssh://troubleshooting |
SSH troubleshooting guide | 📚 Help Documentation |
Execute a command:
curl -X POST http://localhost:8000/tools/ssh_execute \
-H "Content-Type: application/json" \
-d '{
"arguments": {
"host": "192.168.1.100",
"username": "admin",
"command": "df -h",
"key_path": "/path/to/key"
}
}'
Test connection:
curl -X POST http://localhost:8000/tools/ssh_test_connection \
-H "Content-Type: application/json" \
-d '{
"arguments": {
"host": "server.example.com",
"username": "user"
}
}'
View server inventory:
# Via HTTP
curl http://localhost:8000/resources/ssh://servers
# MCP clients can access: ssh://servers
Check command history:
# Via HTTP
curl http://localhost:8000/resources/ssh://history
# MCP clients can access: ssh://history
Get server status:
# Via HTTP
curl http://localhost:8000/resources/ssh://servers/production/status
# MCP clients can access: ssh://servers/production/status
- 🔐 Encrypted Storage - Server configs encrypted with Fernet (AES-128)
- 🛡️ Access Controls - Host/user validation, SSH key verification
- 🚨 Command Security - Injection prevention, dangerous command blocking
- 📋 Audit Logging - Complete operation trail with timestamps
# Environment variables for enhanced security
export SSH_MCP_ALLOWED_HOSTS="prod.com,staging.com"
export SSH_MCP_BLOCKED_COMMANDS="rm -rf,shutdown,reboot"
export SSH_MCP_AUDIT_LOG=true
# Transport configuration
export SSH_MCP_TRANSPORT=stdio # or 'http'
export SSH_MCP_HTTP_HOST=0.0.0.0 # HTTP server host
export SSH_MCP_HTTP_PORT=8000 # HTTP server port
├── src/
│ ├── server.py # Main MCP server
│ ├── transport.py # Transport layer (stdio/HTTP/WebSocket)
│ ├── ssh_tool.py # SSH execution logic
│ ├── config.py # Configuration management
│ ├── security.py # Security controls
│ └── audit.py # Audit logging
├── tests/ # Test suite
├── scripts/dev.py # Development utilities
├── run_server.py # Stdio transport runner
├── run_http_server.py # HTTP transport runner
└── requirements.txt # Dependencies
# Install dependencies
uv sync
# Run tests
uv run pytest
# Format code
uv run black src/ tests/
uv run isort src/ tests/
# Type checking
uv run mypy src/
Once integrated, ask your AI assistant:
- "Execute
df -h
on my production server to check disk space" - "Test SSH connection to staging server"
- "Run system updates on my Ubuntu servers"
- "Deploy my application using the deployment script"
Use the REST API or WebSocket for web applications:
# Check server health
curl http://localhost:8000/health
# List available tools
curl http://localhost:8000/tools
# Execute SSH command
curl -X POST http://localhost:8000/tools/ssh_execute \
-H "Content-Type: application/json" \
-d '{"arguments": {"host": "server.com", "username": "user", "command": "uptime"}}'
- Use SSH keys instead of passwords
- Configure allowed hosts to restrict access
- Use service accounts with minimal permissions
- Enable audit logging for monitoring
- Keep dependencies updated for security
MIT License - see LICENSE file for details.