MCP SSH Server
Provides tools to execute commands, manage files, services, and packages on remote Linux servers via SSH.
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 Serverrun 'df -h' on prod-web-01"
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 Server
Remote SSH Management Server for LLM Agents
A centralized MCP (Model Context Protocol) server that enables LLM agents (Cursor AI, Claude Desktop, Codex, etc.) to securely execute commands and manage Linux servers via SSH.
Features
🔐 Secure SSH Access - Key-based authentication with automatic setup
🌐 Official MCP SDK - Streamable HTTP (modelcontextprotocol/python-sdk)
🔏 MCP OAuth (RFC 9728) - Protected resource metadata + browser login for Claude Code; same API tokens as Bearer
🔄 Real-time Streaming - Live stdout/stderr streaming via SSE
🔑 Token-based Auth - Bearer tokens with granular permissions
🛡️ Security First - Command validation, rate limiting, audit logging
📊 Multi-server Support - Manage hundreds of servers from one endpoint
🚀 Production Ready - Docker support, health checks, graceful shutdown
🛠️ CLI Management - Easy server/token management via CLI tool
Related MCP server: ssh-mcp-server
Quick Start
Using Docker (Recommended)
# Clone repository
git clone https://github.com/Maxim11111/mcp-ssh.git
cd mcp-ssh
# Copy example configs
cp config/servers.json.example config/servers.json
cp config/tokens.json.example config/tokens.json
# Copy environment configuration
cp env.example .env
# Edit .env file to customize settings (optional)
# nano .env
# Start with Docker Compose
docker-compose up -d
# Quick view servers list
docker exec -it mcp-ssh-server python -m src.cli server list
# Add your first server
docker exec -it mcp-ssh-server python -m src.cli server add
# Check status
docker-compose logs -f mcp-ssh-serverLocal Installation
# Install dependencies
pip install -r requirements.txt
# Setup configuration
mkdir -p config keys logs
cp config/servers.json.example config/servers.json
cp config/tokens.json.example config/tokens.json
# Add server
python -m src.cli server add
# Start server (factory loads env each process)
uvicorn src.server_http:create_app --factory --host 0.0.0.0 --port 8000Architecture
[Cursor / Claude Code / Codex / …]
↓
HTTPS → Streamable HTTP POST /mcp (Bearer or OAuth access token)
↓
[MCP SSH Server] → SSH Keys → [Your Linux Servers]
↓
Audit Logs + Security ValidationSet PUBLIC_BASE_URL in .env to the URL clients use (e.g. https://mcp.example.com behind TLS). The SDK publishes OAuth discovery at /.well-known/oauth-protected-resource/mcp and authorization server metadata at /.well-known/oauth-authorization-server. Browser login for MCP OAuth is at /login (paste the same API token you would put in Authorization: Bearer).
Client configuration (quick reference)
Client | Config | Notes |
Cursor |
|
|
Claude Code |
| Use HTTP transport URL ending in |
OpenAI Codex |
|
|
Google Gemini CLI |
| HTTP URL ending in |
Stdio | process env |
|
Usage Examples
With Cursor AI
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"ssh-devops": {
"url": "http://your-server:8000/mcp",
"headers": {
"Authorization": "Bearer tok_your_token_here"
}
}
}
}Then in Cursor chat:
You: Install nginx on prod-web-01
AI: Executing command on prod-web-01...
✓ nginx installed successfullyWith Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"ssh-devops": {
"url": "http://your-server:8000/mcp",
"headers": {
"Authorization": "Bearer tok_your_token_here"
}
}
}
}With Claude Code (CLI)
After the server is reachable at PUBLIC_BASE_URL (HTTPS in production):
claude mcp add --transport http ssh-devops https://your-server.example.com/mcpUse Authenticate in /mcp when prompted: open /login, paste the API token from python -m src.cli token create. The issued access token is the same string as your Bearer token.
With Google Gemini CLI
Add a streamable HTTP server (user-wide config under ~/.gemini/):
gemini mcp add devops https://your-server.example.com/mcp --transport http -s userIf you use a Bearer token instead of the browser OAuth flow, pass it when adding the server:
gemini mcp add devops https://your-server.example.com/mcp --transport http -s user \
--header "Authorization: Bearer tok_your_token_here"With MCP OAuth, add the server first, then in the interactive CLI run /mcp auth devops (browser redirect to http://localhost:7777/oauth/callback).
With OpenAI Codex (config.toml)
[mcp_servers.ssh_devops]
url = "https://your-server.example.com/mcp"
bearer_token_env_var = "MCP_SSH_TOKEN"Then export MCP_SSH_TOKEN=tok_... before running Codex.
Stdio (local)
export MCP_TOKEN=tok_your_token_here
export CONFIG_DIR=./config
python -m src.server_stdioAvailable Tools
MCP SSH Server provides these tools to agents:
execute_command - Execute shell command on a server
execute_on_multiple - Execute command on multiple servers in parallel
read_file - Read file contents
write_file - Write/update files
list_directory - List directory contents
check_service_status - Check systemd service status
install_package - Install packages (apt/yum/dnf)
list_servers - Get available servers
get_system_info - Get system information
CLI Management
Server Management
# Add server with automatic SSH key setup
python -m src.cli server add
# List all servers
python -m src.cli server list
# Test connection
python -m src.cli server test prod-web-01
# Remove server
python -m src.cli server remove prod-web-01Token Management
# Create new API token
python -m src.cli token create
# List tokens
python -m src.cli token list
# Revoke token
python -m src.cli token revoke tok_abc123Configuration
Environment Variables (.env)
The server can be configured using environment variables. Copy env.example to .env and customize:
# Copy example configuration
cp env.example .env
# Edit configuration
nano .envKey configuration options:
# Server Configuration
HOST=0.0.0.0 # Server bind address
PORT=8000 # Internal container port
EXTERNAL_PORT=8000 # External Docker host port
# Security
TOKEN_EXPIRY_HOURS=8760 # Token validity period
# Rate Limiting
RATE_LIMIT_PER_MINUTE=60 # Requests per minute
RATE_LIMIT_PER_HOUR=500 # Commands per hour
# SSH Settings
SSH_CONNECTION_TIMEOUT=30 # SSH connection timeout
SSH_COMMAND_TIMEOUT=300 # Command execution timeoutReverse Proxy Setup
For production deployments with reverse proxy (nginx-proxy-manager, traefik, etc.):
# Use proxy compose file (recommended)
docker-compose -f docker-compose.yml -f docker-compose.proxy.yml up -dservers.json
{
"servers": {
"prod-web-01": {
"host": "192.168.1.10",
"port": 22,
"user": "deploy",
"ssh_key_path": "/app/keys/prod_web_ed25519",
"tags": ["production", "web"],
"enabled": true,
"description": "Production web server"
}
},
"security": {
"allowed_commands_patterns": ["^apt ", "^systemctl ", "^docker "],
"forbidden_commands": ["rm -rf /", "mkfs"],
"rate_limit": {
"requests_per_minute": 60,
"commands_per_hour": 500
}
}
}tokens.json
{
"tokens": {
"tok_abc123...": {
"name": "cursor-admin",
"permissions": ["execute", "read", "write", "install"],
"allowed_servers": ["*"],
"rate_limit_multiplier": 1.0,
"enabled": true
}
}
}Security
Multi-layer Security
Bearer Tokens - API access control
SSH Keys - Server authentication (keys never leave server)
Command Validation - Whitelist/blacklist patterns
Rate Limiting - Per-token request limits
Audit Logging - All operations logged
Permission System - Granular access control
Best Practices
Use ED25519 SSH keys
Rotate tokens regularly
Configure allowed command patterns
Monitor audit logs
Use HTTPS in production (via nginx-proxy-manager)
Limit token permissions to minimum required
Testing
# Install dev dependencies
pip install -r requirements-dev.txt
# Run tests
pytest
# Run with coverage
pytest --cov=src --cov-report=html
# View coverage report
open htmlcov/index.htmlSee TESTING.md for detailed testing instructions.
Deployment
See DEPLOYMENT.md for production deployment guide.
Documentation
QUICKSTART.md - Quick start (RU/EN)
DEPLOYMENT.md - Production deployment guide
CURSOR_INTEGRATION.md - Cursor AI integration
DEVELOPMENT.md - Development and debugging
MCP_PROTOCOL.md - MCP protocol and tools
SECURITY.md - Security best practices
TESTING.md - Testing guide
API Endpoints
The server runs HTTP JSON-RPC on a single endpoint (see MCP_PROTOCOL.md):
MCP Protocol
GET /mcp- Server info and available transportsPOST /mcp- JSON-RPC (methods:initialize,tools/list,tools/call)GET /sse- SSE transport (legacy)
Utility
GET /health- Health check
Environment Variables
All configuration can be managed via .env file. See env.example for all available options:
# Server Configuration
HOST=0.0.0.0 # Listen host
PORT=8000 # Internal container port
EXTERNAL_PORT=8000 # External Docker host port
LOG_LEVEL=INFO # Logging level
# Directory Configuration
CONFIG_DIR=/app/config # Configuration directory
KEYS_DIR=/app/keys # SSH keys directory
LOGS_DIR=/app/logs # Logs directory
# Security Settings
TOKEN_EXPIRY_HOURS=8760 # Token validity period
# Rate Limiting
RATE_LIMIT_ENABLED=true # Enable rate limiting
RATE_LIMIT_PER_MINUTE=60 # Requests per minute
RATE_LIMIT_PER_HOUR=500 # Commands per hour
# SSH Settings
SSH_CONNECTION_TIMEOUT=30 # SSH connection timeout
SSH_COMMAND_TIMEOUT=300 # Command execution timeout
# Development Settings
DEBUG=false # Debug mode
RELOAD=false # Auto-reload on changesRequirements
Python 3.10+
Docker & Docker Compose (for containerized deployment)
SSH access to target servers
OpenSSH client
Contributing
Contributions welcome! Please:
Fork the repository
Create a feature branch
Add tests for new features
Ensure all tests pass
Submit a pull request
License
MIT License - see LICENSE file for details.
Support
GitHub Issues: Report bugs
Documentation: See *.md files in the repository root
Email: your.email@example.com
Acknowledgments
Built with FastAPI
MCP Protocol specification by Anthropic
SSH via Paramiko
SSE streaming via sse-starlette
Made with ❤️ for the LLM DevOps community
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Maxim11111/mcp-ssh'
If you have feedback or need assistance with the MCP directory API, please join our Discord server