ssh-mcp-jumpserver
by helloNice
README.md
# SSH MCP JumpServer
[](https://github.com/B143KC47/ssh_mcp/stargazers)
[](https://github.com/B143KC47/ssh_mcp/actions/workflows/ci.yml)
[](LICENSE)
[](https://www.typescriptlang.org/)
[](https://modelcontextprotocol.io/)
**English** | [中文](README.zh-CN.md)
An MCP server that bridges AI agents (Claude Desktop, VS Code Copilot, etc.) to remote servers via SSH — with **dynamic host discovery through JumpServer**. No need to manually configure every host; if JumpServer knows it, you can connect to it.
## Why this project
- **JumpServer dynamic discovery**: connect to any host JumpServer manages — no manual SSH config needed
- **Auto username fallback**: tries `root` → `ec2-user` → `game_server` until one works
- **Standard SSH config support**: still works with your existing OpenSSH config files for static hosts
- **Secure by default**: dangerous command blocking, per-host allowlists/denylists, output caps, and secret redaction
- **Connection pooling**: reuse SSH connections across agent steps for faster multi-turn sessions
## Quick start
### Install
```bash
npm install -g ssh-mcp-jumpserver
# or: npm install && npm run build && npm link
```
### Add to your MCP client
```json
{
"mcpServers": {
"ssh": {
"command": "ssh-mcp-jumpserver",
"args": [
"--ssh",
"name=prod,host=10.0.0.5,port=22,user=root,privateKey=~/.ssh/id_rsa"
],
"env": {
"JUMPSERVER_URL": "https://your-jumpserver.example.com",
"JUMPSERVER_KEY_ID": "your-access-key-id",
"JUMPSERVER_SECRET_ID": "your-access-secret-id"
}
}
}
}
```
Static hosts passed with `--ssh` are searched first. If no static or config-file host matches, the server falls back to JumpServer discovery.
### Try it
Ask your AI agent:
> "Connect to **10.0.0.5** and run `uptime`."
>
> "List all my SSH hosts."
>
> "Test the connection to **prod-db-01**."
The server resolves unknown hosts through JumpServer automatically.
## Features
| Feature | Description |
|---------|-------------|
| 🔍 **JumpServer dynamic discovery** | Search assets by IP or hostname, fetch SSH keys via API |
| 🔄 **Username fallback** | Auto-tries `root` → `ec2-user` → `game_server` for JumpServer hosts |
| 📋 **Static SSH config** | Standard OpenSSH config (`ssh.config`) for predefined hosts |
| 🔒 **Security policies** | Per-host allowlist/denylist, output truncation, secret redaction |
| 🔌 **Connection pool** | Reuse SSH connections with idle cleanup |
| 🌐 **HMAC-SHA256 auth** | HTTP Signature signed requests to JumpServer API |
## CLI Options
```
ssh-mcp-jumpserver [options]
--jumpserver-url <url> JumpServer base URL (enables dynamic host discovery)
--jumpserver-key-id <id> JumpServer Access Key ID
--jumpserver-secret-id <id> JumpServer Access Secret ID
--project-root <path> Project root (for project-level ssh.config)
--ssh <config> Static SSH host, repeatable:
name=prod,host=10.0.0.5,port=22,user=root,password=...
--timeout <ms> Default command timeout (default: 60000)
--max-output <chars> Max output characters (default: 10000)
--max-connections <n> Max concurrent SSH connections (default: 5)
--idle-timeout <ms> Connection idle timeout (default: 600000)
```
Environment variable equivalents: `JUMPSERVER_URL`, `JUMPSERVER_KEY_ID`, `JUMPSERVER_SECRET_ID`.
Host lookup priority: `--ssh` args → project `ssh.config` → user config → JumpServer fallback.
## MCP Tools
| Tool | Description |
|------|-------------|
| `ssh_list_hosts` | List all configured SSH hosts |
| `ssh_exec` | Execute a command on a host (local config or JumpServer) |
| `ssh_get_config` | Show merged config for a host |
| `ssh_test_connection` | Test SSH connectivity |
| `ssh_disconnect` | Close SSH session(s) |
| `ssh_init_config` | Scaffold a new SSH config file |
## How JumpServer resolution works
```
User request: ssh_exec host="10.0.0.5"
→ Is "10.0.0.5" in local ssh.config?
├── Yes → connect directly
└── No → query JumpServer API
├── GET /api/v1/assets/assets/?ip=10.0.0.5
├── GET /api/v1/assets/system-users/?asset=<id>
├── GET /api/v1/assets/system-users/<id>/auth-info/
→ Build SSHHostConfig with discovered key
→ Try root → ec2-user → game_server
→ Execute command
```
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md).
## License
MIT — see [LICENSE](LICENSE).
TDQS
A3.9/5.0
Scored across 6 tools
Disambiguation5/5
Each tool has a distinct purpose: disconnect, execute commands, get config, initialize config, list hosts, and test connectivity. No overlapping functionality.
Naming Consistency5/5
All tools follow a consistent 'ssh_verb_noun' pattern using snake_case, making it easy to predict tool names and their actions.
Tool Count5/5
6 tools cover the core SSH management operations without being excessive or insufficient, fitting the server's scope well.
Completeness4/5
Covers key operations (exec, disconnect, config, list hosts, test), but lacks an explicit 'ssh_connect' tool; however, exec and test effectively handle connection initiation.
Maintenance
ActivitySlowing
ResponsivenessNo issues