Content
# Tool List
**Lightweight Cross-Platform SSH MCP Server** — Securely manage remote servers with AI assistants.
[](https://www.python.org/)
[](https://www.gnu.org/licenses/gpl-3.0)
[](https://modelcontextprotocol.io/)
[English](README_EN.md)
---
## Environment Setup (Detailed Steps)
### Step 1: Install Python and uv
**Windows**:
```powershell
# Install Python 3.10+ (download from python.org, check Add to PATH)
# Install uv (Python package manager)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# Verify
python --version # Should display 3.10.x or higher
uv --version # Should display 0.5.x or higher
```
**macOS / Linux**:
```bash
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Verify
python3 --version # Should display 3.10.x or higher
uv --version
```
> **Why use uv?** 10-100x faster than pip, automatically creates virtual environments, and avoids dependency conflicts.
---
### Step 2: Get the Code
```bash
# Method 1: Git clone (recommended)
git clone https://github.com/albertm88/mcp-ssh.git
cd mcp-ssh
# Method 2: Download ZIP
# Download ZIP from GitHub, extract, and enter the directory
```
---
### Step 3: Install Dependencies
```bash
# Use uv to automatically create a virtual environment and install dependencies
uv sync
# Verify installation (should display mcp-ssh related packages)
uv pip list | grep -E "mcp|paramiko"
```
**Common Issues**:
- `uv: command not found` → Restart terminal or manually add uv to PATH
- `python not found` → Windows: Install Python and check "Add Python to PATH"
- Permission errors → Linux/macOS: Add `sudo`, or check directory permissions
---
### Step 4: Configure SSH Connection
#### 4.1 Generate SSH Key (if not available)
```bash
# Linux/macOS
ssh-keygen -t ed25519 -C "your_email@example.com"
# Windows PowerShell
ssh-keygen -t ed25519 -C "your_email@example.com"
# Key saved in C:\Users\<username>\.ssh\id_ed25519
```
#### 4.2 Configure SSH Host (`~/.ssh/config`)
**File Path**:
- Linux/macOS: `~/.ssh/config`
- Windows: `C:\Users\<username>\.ssh\config`
**Example Configuration**:
```ssh-config
# Host alias: myserver (customizable)
Host myserver
HostName 192.168.1.100 # Server IP or domain
User ubuntu # SSH username
Port 22 # SSH port (default 22)
IdentityFile ~/.ssh/id_ed25519 # Private key path
ServerAliveInterval 60 # Keep connection (optional)
# Another server: production environment
Host prod-web
HostName 203.0.113.10
User admin
Port 2222
IdentityFile ~/.ssh/id_rsa_prod
```
**Verify SSH Connection**:
```bash
# Test alias effectiveness
ssh myserver "echo 'SSH connection successful'"
# If failed, check:
# 1. Server online: ping 192.168.1.100
# 2. Port open: telnet 192.168.1.100 22
# 3. Key permissions: chmod 600 ~/.ssh/id_ed25519 (Linux/macOS)
```
#### 4.3 Password Authentication (alternative, not recommended)
If unable to use key, set password environment variable:
```bash
# Linux/macOS (temporary)
export SSH_PASS_MYSERVER="your-password"
# Linux/macOS (permanent, add to ~/.bashrc or ~/.zshrc)
echo 'export SSH_PASS_MYSERVER="your-password"' >> ~/.bashrc
# Windows PowerShell (temporary)
$env:SSH_PASS_MYSERVER = "your-password"
# Windows (permanent, system environment variable)
# Settings → System → About → Advanced system settings → Environment Variables → New
# Variable name: SSH_PASS_MYSERVER
# Variable value: your-password
```
> **Naming Convention**: `SSH_PASS_` + Host alias (uppercase, dots/hyphens converted to underscores)
> - `myserver` → `SSH_PASS_MYSERVER`
> - `prod-web` → `SSH_PASS_PROD_WEB`
> - `192.168.1.100` → `SSH_PASS_192_168_1_100`
---
### Step 5: Configure MCP Client
#### 5.1 Claude Code (recommended)
```bash
# Execute in project directory
claude mcp add ssh -- uv run --directory $(pwd) python server.py
# Verify configuration
claude mcp list
# Should display: ssh: uv run --directory /path/to/mcp-ssh python server.py
```
#### 5.2 VS Code / Cursor
Edit MCP configuration file:
**Path**:
- VS Code: `~/.vscode/mcp.json` or workspace `.vscode/mcp.json`
- Cursor: `~/.cursor/mcp.json`
**Configuration Content**:
```json
{
"mcpServers": {
"ssh": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/mcp-ssh",
"python",
"server.py"
],
"env": {
"SSH_REVIEW_MODE": "whitelist"
}
}
}
}
```
> **Note**: Windows path uses `\\` or `/`, e.g., `D:/mcp-ssh` or `D:\\mcp-ssh`
#### 5.3 Trae / Qoder / Codex
These clients usually automatically discover MCP configuration or refer to their MCP setting documents.
**General Principle**:
1. Find the client's MCP configuration file (usually JSON)
2. Add `ssh` server configuration (same format as VS Code)
3. Restart client to take effect
---
### Step 6: Verify Installation
#### 6.1 Test MCP Server
```bash
# Run server directly (should display MCP protocol handshake information)
uv run python server.py
# Press Ctrl+C to exit
```
#### 6.2 Test in AI Client
**Claude Code**:
```
Use ssh_list_hosts to view configured hosts
```
**Expected Return**:
```
Configured host aliases:
myserver → ubuntu@192.168.1.100:22
prod-web → admin@203.0.113.10:2222
```
**If Failed**:
1. Check MCP configuration path correctness
2. Check if `uv` is in PATH
3. View client logs (Claude Code: `claude --debug`)
---
### Step 7: First Use Suggestions
```bash
# 1. Test simple commands (whitelist mode allows by default)
ssh_exec("myserver", "whoami")
ssh_exec("myserver", "df -h")
# 2. Test file upload (create a test file)
echo "test" > test.txt
ssh_upload("myserver", "test.txt", "/tmp/test.txt")
# 3. Test review mode switching
ssh_set_review_mode("smart") # Smart mode
ssh_exec("myserver", "ls -la") # Automatically allow
```
---
### Troubleshooting Guide
| Issue | Cause | Solution |
|------|------|------|
| `uv: command not found` | uv not installed or not in PATH | Reinstall uv, restart terminal |
| `python: command not found` | Python not installed or not in PATH | Install Python 3.10+, check Add to PATH |
| `No module named 'mcp'` | Dependency not installed | Run `uv sync` |
| `Connection refused` | SSH service not started | Check remote `sudo systemctl status ssh` |
| `Permission denied` | Key/password incorrect | Check `ssh -v myserver` debug output |
| `command not found` (remote) | Remote command not available | Use another command or install remotely |
| Chinese character corruption | Encoding mismatch | Automatically handled, check remote `locale` if still issues |
| MCP client unresponsive | Server not started | Check client logs, manually run `uv run python server.py` for testing |
---
### Next Steps
- Read [Core Features](#core-features) to understand all tools
- Read [Security Mechanism](#security-mechanism-four-mode-review) to configure review policies
- View [Frequently Asked Questions](#frequently-asked-questions) to solve usage issues
---
## Architecture
```
┌─────────────────┐ stdio ┌─────────────┐
│ MCP Client │ ◄────────────► │ mcp-ssh │
│ (Claude/VSCode/ │ │ Server │
│ Trae/Qoder/ │ │ │
│ Codex/Cursor) │ │ │
└─────────────────┘ └──────┬──────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ SSH Tools│ │ Review │ │ Logger │
│ │ │ Engine │ │ │
│ ssh_exec │ │ │ │ JSON-lines│
│ ssh_scan │ │ 4 modes │ │ to disk │
│ ssh_upload│ │ │ │ │
│ ... │ │ whitelist│ └──────────┘
└────┬─────┘ │ manual │
│ │ smart │
│ │ off │
│ └────┬─────┘
│ │
▼ ▼
┌─────────────────────────────────┐
│ Paramiko SSH Client │
│ (key auth → password fallback) │
└─────────────────────────────────┘
│
▼
┌─────────────┐
│ Remote │
│ Servers │
└─────────────┘
```
**Data Flow**: AI request → MCP protocol → Review engine → SSH execution → Logging → Return result
---
## Core Features
| Feature | Tool | Example |
|------|------|------|
| **Execute Command** | `ssh_exec` | `ssh_exec("myserver", "df -h")` |
| **Batch Execution** | `ssh_exec_batch` | `ssh_exec_batch("myserver", ["df -h", "free -h"])` |
| **File Upload** | `ssh_upload` | `ssh_upload("myserver", "local.txt", "/remote/")` |
| **File Download** | `ssh_download` | `ssh_download("myserver", "/remote/log.txt", "local.txt")` |
| **Host Scanning** | `ssh_scan` | `ssh_scan("192.168.1.0/24")` |
| **Directory Operations** | `ssh_list_dir` / `ssh_mkdir` / `ssh_remove` | Manage remote directory |
> `host` supports `~/.ssh/config` aliases or `user@ip` format.
---
## Security Mechanism (Four-Mode Review)
Default **whitelist** mode, only allows safe commands. Supports runtime switching:
| Mode | Behavior | Scenario |
|------|------|------|
| `off` | All allow | Development debugging |
| `whitelist` | Only whitelist commands | **Production environment (default)** |
| `manual` | Each command manually confirmed | Critical servers |
| `smart` | Intelligent judgment, uncertain to manual | Daily maintenance |
```python
# View current mode
ssh_get_review_mode()
# Switch mode (no restart needed)
ssh_set_review_mode("smart")
```
### Custom Whitelist
Edit `~/.ssh/mcp-ssh-whitelist.conf` (or project `whitelist.conf` template):
```conf
^ls\b # Allow ls
^cat\s+[^|;&]+$ # Allow cat (no pipes)
^docker\s+ps\b # Allow docker ps
```
---
## Configuration
### SSH Host (`~/.ssh/config`)
```ssh-config
Host myserver
HostName 192.168.1.100
User ubuntu
IdentityFile ~/.ssh/id_ed25519
```
### Password Authentication (optional)
```bash
# Linux/macOS
export SSH_PASS_MYSERVER="password"
# Windows PowerShell
$env:SSH_PASS_MYSERVER = "password"
```
### Environment Variables
| Variable | Default | Description |
|------|------|------|
| `SSH_PASS` | - | Global password |
| `SSH_PASS_<HOST>` | - | Single host password |
| `SSH_REVIEW_MODE` | `whitelist` | Review mode |
| `SSH_REVIEW_WHITELIST_FILE` | `~/.ssh/mcp-ssh-whitelist.conf` | Whitelist file |
| `SSH_LOG_LEVEL` | `INFO` | Log level |
---
## Frequently Asked Questions
**Q: Command rejected?**
A: Default whitelist mode. Use `ssh_set_review_mode("smart")` to switch or add whitelist rules.
**Q: Chinese character corruption?**
A: Automatically handled UTF-8/GBK/GB2312/Big5. If still issues, check remote `locale` settings.
**Q: Connection failed?**
A: Manually test with `ssh user@host`. Check `~/.ssh/config` format, password environment variable name (dots/hyphens converted to underscores, uppercase).
**Q: How to execute dangerous commands (e.g., `rm -rf`)?**
A: `ssh_exec(host, "rm -rf /tmp/test", allow_dangerous=True)`. Or switch to `off` mode.
---
## Project Structure
```
mcp-ssh/
├── server.py # MCP server (tool definitions)
├── review.py # Review engine (four modes)
├── logger.py # Logging module
├── whitelist.conf # Whitelist rule template
└── pyproject.toml # Dependency configuration
```
---
## License
[GPL v3](LICENSE)
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available