-
Notifications
You must be signed in to change notification settings - Fork 0
Skills SSH MCP Setup
name: "ssh-mcp-setup" description: "Local setup and configuration guide for SSH MCP. Invoke when user needs to set up, configure, or customize the SSH MCP server locally."
npx ssh-liccoFirst run automatically: detect Python → create venv → install dependencies → verify integrity → start MCP server. No manual setup needed.
This creates an isolated Python venv at ~/.ssh-licco-venv and avoids all conflicts.
npm install -g ssh-liccoPost-install script (install.js) auto-detects existing venv and performs incremental update.
pip install ssh-liccogit clone https://github.com/Echoqili/ssh-licco.git
cd ssh-licco
pip install -e .# npm
npm update -g ssh-licco
# pip
pip install --upgrade ssh-liccossh-licco uses a three-layer architecture for zero-config startup:
User → npx ssh-licco
↓
┌──── ssh-licco.js (Node Layer) ────┐
│ ① Find Python 3.10+ │
│ ② Detect Anaconda environment │
│ ③ Create/reuse ~/.ssh-licco-venv │
│ ④ pip install dependencies │
│ ⑤ Verify dependency integrity │
└──────────┬────────────────────────┘
↓
┌── cli.py (Python Entry) ──────┐
│ Only starts MCP server │
└──────────┬────────────────────┘
↓
┌── SSHMCPServer (MCP Service) ─┐
│ SSH connect, execute, etc. │
└───────────────────────────────┘
| Feature | Description |
|---|---|
| Anaconda Auto-Detect | Detects conda environment, uses isolated venv to avoid conflicts |
| Dependency Integrity Check | Verifies all dependencies on every startup, auto-repairs if missing |
| Incremental Update | Doesn't delete existing venv, uses pip install -e . for incremental install |
| Auto-Repair | Auto re-installs when dependencies are corrupted, no manual intervention |
| File | Purpose |
|---|---|
ssh-licco.js |
Node.js wrapper - environment prep, integrity check, startup |
install.js |
npm postinstall script - incremental install |
smart_install.py |
Standalone diagnostic install script |
cli.py |
Python entry point - only starts the MCP server |
- Python: >=3.10, <3.14
- Core dependencies: mcp>=1.0.0, asyncssh>=2.17.0, paramiko>=2.0.0, pydantic>=2.0.0, pydantic-settings>=2.0.0
- Key management: cryptography (for SSH key generation)
The most stable approach is to use the isolated venv directly, bypassing Node.js wrapper and Anaconda:
{
"mcpServers": {
"ssh-licco": {
"command": "C:\\Users\\<YourName>\\.ssh-licco-venv\\Scripts\\ssh-licco.exe",
"env": {
"SSH_HOST": "192.168.1.100",
"SSH_USER": "root",
"SSH_PASSWORD": "your_password",
"SSH_PORT": "22",
"SSH_TIMEOUT": "60",
"SSH_KEEPALIVE_INTERVAL": "30",
"SSH_SESSION_TIMEOUT": "7200",
"SSH_SECURITY_LEVEL": "balanced",
"SSH_EXTRA_ALLOWED_COMMANDS": "git,pip,npm,docker,sh"
}
}
}
}Why this pattern is stable:
-
~/.ssh-licco-venvis an isolated Python environment created by the auto-installer - It is completely independent of Anaconda, system Python, or npm
- No Node.js wrapper layer means no shell command parsing issues on Windows
- Editor directly communicates with the Python MCP server via stdio
Linux/macOS equivalent:
{
"command": "/home/<user>/.ssh-licco-venv/bin/ssh-licco"
}- Open Trae IDE Settings
- Search for "MCP"
- Add SSH MCP server
- Configure command:
C:\Users\<YourName>\.ssh-licco-venv\Scripts\ssh-licco.exe - Add environment variables
Find MCP config file location:
-
Trae IDE:
C:\Users\<YourName>\AppData\Roaming\Trae\User\mcp.json
MCP (Model Context Protocol) uses stdio (stdin/stdout) for JSON-RPC communication. The editor and MCP server exchange JSON messages over these pipes. This means:
- Any non-JSON output to stdout breaks the protocol — install logs, warnings, progress bars all corrupt the MCP handshake
- stderr is safe — it's a separate pipe for server logs
- Startup must be fast — if the server takes too long to start, the editor times out and abandons the connection
Common failure patterns and solutions:
| Problem | Cause | Solution |
|---|---|---|
| Tools not showing | Server output to stdout corrupted protocol | Use venv directly (no wrapper) |
ModuleNotFoundError |
Anaconda package corrupted | Clean ~ prefix dirs, reinstall to venv |
| Timeout on startup | Wrapper doing pip install on every start | Fix integrity check (don't use shell: true on Windows) |
Cannot find module |
Damaged npm global package | Run npm uninstall -g ssh-licco
|
| Variable | Default | Description |
|---|---|---|
| SSH_HOST | 127.0.0.1 | SSH server hostname |
| SSH_PORT | 22 | SSH server port |
| SSH_USER | root | SSH username |
| SSH_PASSWORD | - | SSH password |
| SSH_TIMEOUT | 60 | Connection timeout (seconds) |
| SSH_KEEPALIVE_INTERVAL | 30 | Keepalive interval (seconds) |
| SSH_SESSION_TIMEOUT | 7200 | Session timeout (seconds) |
| SSH_CLIENT_TYPE | asyncssh | SSH client (paramiko/asyncssh) |
| SSH_FORCE_ENV_CONFIG | false | Force env vars as highest priority |
| SSH_LICCO_AUTO_INSTALL | true | Enable/disable auto-install on first run |
| Variable | Default | Description |
|---|---|---|
| SSH_SECURITY_LEVEL | balanced | Security level (strict/balanced/relaxed) |
| SSH_EXTRA_ALLOWED_COMMANDS | - | Additional allowed commands (comma-separated) |
| SSH_RATE_LIMIT | true | Enable rate limiting (bool: true/false) |
| SSH_RATE_LIMIT_MAX | 30 | Max requests per window |
| SSH_RATE_LIMIT_WINDOW | 60 | Time window in seconds |
| SSH_AUDIT_LOG_PATH | - | Audit log file path |
Location: config/hosts.json
{
"ssh_hosts": [
{
"name": "production",
"host": "43.143.207.242",
"port": 22,
"username": "root",
"password": "",
"timeout": 120,
"keepalive_interval": 30,
"session_timeout": 7200
},
{
"name": "development",
"host": "192.168.1.100",
"port": 22,
"username": "ubuntu",
"password": "",
"timeout": 60
}
]
}- User parameters (when calling tools) - Highest
- hosts.json (config/hosts.json by name) - Medium
- MCP Config (mcp.json env) - Lowest (fallback)
- MCP Config (mcp.json env) - Highest
- User parameters - Fallback
Example:
MCP config has SSH_HOST=192.168.1.100
But tool call specifies host=10.0.0.1
Default mode: Uses 10.0.0.1 (user parameter)
Force env mode: Uses 192.168.1.100 (env config)
- Use environment variables for passwords
- Don't commit passwords to Git
- Use SSH keys when possible
- Rotate passwords regularly
Passwords with special characters work fine in JSON:
{
"SSH_PASSWORD": "P/[KY}+wa7?2|uc"
}No escaping needed!
ssh-keygen -t ed25519 -C "your_email@example.com"ssh-copy-id user@server{
"mcpServers": {
"ssh": {
"command": "ssh-licco",
"env": {
"SSH_HOST": "192.168.1.100",
"SSH_USER": "ubuntu",
"SSH_PRIVATE_KEY_PATH": "/path/to/private/key",
"SSH_PASSPHRASE": "your_passphrase"
}
}
}
}连接 SSH,host=xxx, username=ubuntu, private_key_path=/path/to/key, auth_method=private_key
| Level | Use Case | Description |
|---|---|---|
| strict | Production | Only whitelisted commands, strict path validation |
| balanced | Default | Most commands allowed, dangerous patterns blocked |
| relaxed | Development | Permissive, minimal restrictions |
{
"mcpServers": {
"ssh": {
"command": "ssh-licco",
"env": {
"SSH_HOST": "prod-server",
"SSH_SECURITY_LEVEL": "strict",
"SSH_RATE_LIMIT": "true",
"SSH_RATE_LIMIT_MAX": "10",
"SSH_AUDIT_LOG_PATH": "/var/log/ssh-mcp-audit.json"
}
}
}
}{
"mcpServers": {
"ssh": {
"command": "ssh-licco",
"env": {
"SSH_HOST": "dev-server",
"SSH_SECURITY_LEVEL": "relaxed",
"SSH_RATE_LIMIT": "false",
"SSH_EXTRA_ALLOWED_PATTERNS": "|,>,<,&,;"
}
}
}
}pip install -e .
ssh-licco --help
python -m ssh_mcp.serverpip install pytest pytest-asyncio pytest-cov
pytestruff check ssh_mcp/
mypy ssh_mcp/export DEBUG=1
ssh-licco- Check MCP config file exists
- Validate JSON syntax
- Restart Trae IDE
- Check pip installation:
pip show ssh-licco - Check PATH:
where ssh-licco(Windows) orwhich ssh-licco(Linux) - Reinstall:
pip install --upgrade ssh-licco
Cause: Damaged npm global package
Fix:
npm uninstall -g ssh-licco
# Then retry npx ssh-liccossh-licco auto-verifies dependencies on every startup and auto-repairs if missing. You can also run manually:
node install.js- Restart Trae IDE
- Kill old MCP process:
Get-Process | Where-Object {$_.Name -like "*ssh-licco*"} - Reinstall:
pip install --force-reinstall --no-deps ssh-licco
- Check
SSH_SECURITY_LEVELsetting - Add specific allowed commands:
SSH_EXTRA_ALLOWED_COMMANDS - Add allowed patterns:
SSH_EXTRA_ALLOWED_PATTERNS - Temporarily use relaxed mode for testing
ssh-mcp/
├── ssh_mcp/ # Source code
│ ├── __init__.py # Version info
│ ├── server.py # MCP server (17 tools)
│ ├── security.py # Multi-level security
│ ├── audit_logger.py # Audit logging
│ ├── connection_config.py # Pydantic config model
│ ├── session_manager.py # Session management
│ ├── service.py # Service protocol
│ ├── connection_pool.py # Connection pooling
│ ├── executor.py # Thread pool executor
│ ├── batch_executor.py # Batch execution
│ ├── key_manager.py # SSH key management
│ ├── watchdog.py # Health monitoring
│ ├── logging_config.py # Centralized logging
│ ├── exceptions.py # Exception hierarchy
│ └── clients/ # SSH clients (paramiko/asyncssh/fabric/ssh2)
├── ssh-licco.js # Node.js wrapper (auto-install + startup)
├── install.js # npm postinstall script
├── smart_install.py # Standalone diagnostic installer
├── config/ # Runtime config
│ ├── hosts.json
│ └── mcp.presets.json
├── pyproject.toml # Package config
└── README.md # Documentation
# pip installed
pip uninstall ssh-licco
# npm installed
npm uninstall -g ssh-licco
# Clean up venv if needed
rm -rf ~/.ssh-licco-venvpip show ssh-licco
python -c "from ssh_mcp import __version__; print(__version__)"