MCP SSH Server
A centralized MCP server that enables LLM agents to securely execute commands and manage Linux servers via SSH.
README
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
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-server
Local 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 8000
Architecture
[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 Validation
Set 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 | ~/.cursor/mcp.json |
url + headers.Authorization: Bearer tok_… |
| Claude Code | claude mcp add … or project config |
Use HTTP transport URL ending in /mcp; complete Authenticate with token from cli token create, or pre-supply Bearer if the client supports it |
| OpenAI Codex | ~/.codex/config.toml or .codex/config.toml |
[mcp_servers.name] with url = "https://host/mcp" and bearer_token_env_var = "MCP_SSH_TOKEN" (or http_headers) — see Codex MCP |
| Google Gemini CLI | gemini mcp add … |
HTTP URL ending in /mcp; -s user = user-level config; Bearer via --header "Authorization: Bearer tok_…" or OAuth with /mcp auth <name> |
| Stdio | process env | MCP_TOKEN=tok_… and python -m src.server_stdio |
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 successfully
With 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/mcp
Use 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 user
If 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_stdio
Available 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-01
Token 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_abc123
Configuration
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 .env
Key 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 timeout
Reverse 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 -d
servers.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.html
See 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 changes
Requirements
- 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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。