Containerized MCP server exposing SSH command execution and SFTP file transfer as tools over Streamable HTTP. Centralized gateway with per-client authorization, layered command policies, audit logging, rate limiting, circuit breakers, and connection pooling. Docker-ready.
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Documented (README)
claude mcp add ssh-mcp -- uvx ssh-mcp{
"mcpServers": {
"ssh-mcp": {
"command": "uvx",
"args": ["ssh-mcp"]
}
}
}Resumen de MCP Servers
# ssh-mcp
A centralized MCP gateway that gives AI agents controlled access to SSH infrastructure over Streamable HTTP.
ssh-mcp runs as a single HTTP service. Multiple AI clients — agents, CI pipelines, dashboards — connect to one gateway. SSH credentials stay on the gateway. Authorization policies, audit logging, and rate limiting are applied centrally before any SSH command executes.
[](LICENSE)
[](https://ghcr.io/gelse/ssh-mcp)
[](https://modelcontextprotocol.io/)
[](docs/SECURITY.md)
[](https://m8ven.ai/mcp/gelse-ssh-mcp-btei1o)
---
## Table of Contents
- [Architecture](#architecture)
- [Why ssh-mcp?](#why-ssh-mcp)
- [Multi-agent access control](#multi-agent-access-control)
- [The Problem](#the-problem)
- [Use Cases](#use-cases)
- [Security Model](#security-model)
- [Quick Start](#quick-start)
- [MCP Client Configuration](#mcp-client-configuration)
- [Tools](#tools)
- [Configuration](#configuration)
- [Observability](#observability)
- [Configuration API](#configuration-api)
- [Deployment](#deployment)
- [Limitations and Threat Model](#limitations-and-threat-model)
- [Development](#development)
- [Roadmap](#roadmap)
- [License](#license)
---
## Architecture
### Local stdio MCP (common pattern)
```text
AI client
│
▼
local MCP process ──► SSH target
```
Each agent runs its own process. SSH credentials live on every machine. No centralized control.
### ssh-mcp (centralized HTTP gateway)
```
AI clients ───────┐
CI agents ────────┼──► ssh-mcp ──► SSH targets
Dashboards ───────┘ │
├─ API-key authentication
├─ per-client authorization
├─ rate limiting
├─ audit logging
└─ connection pooling
```
A single deployment serves all clients. Credentials, policies, and logs live in one place.
---
## Why ssh-mcp?
- **Centralized HTTP gateway** — One deployment serves all AI agents, CI pipelines, and dashboards over Streamable HTTP
- **Per-client authorization** — Different API keys grant different command sets on different servers
- **Layered command policies** — Block patterns, dangerous-shell detection, and per-target allowlists work together
- **Centralized SSH access** — SSH credentials live on the gateway, not on every agent's machine
- **Audit trail** — Every command, every client, every result — structured JSONL logs with request tracing
- **Operational resilience** — Connection pooling, circuit breakers, and retry with exponential backoff
- **Observability** — Prometheus metrics and health endpoints for monitoring
---
## Multi-agent access control
Different agents need different permissions. ssh-mcp enforces this at the gateway:
```
monitoring agent → API key A → read-only commands → all servers
deployment agent → API key B → deploy commands → web servers only
database agent → API key C → db commands → database server only
```
```
┌─ monitoring agent (read-only, all servers)
├─ deployment agent (deploy commands, web only)
MCP clients ──────┼─ database agent (db commands, db server only)
└─ ...
│
▼
ssh-mcp
│
centralized policies
│
┌──────────┼──────────┐
▼ ▼ ▼
web db monitoring
servers servers servers
```
A minimal config demonstrating this setup:
```json
{
"version": 1,
"ssh_targets": {
"web-1": { "host": "10.0.1.10", "username": "deploy" },
"db-1": { "host": "10.0.1.20", "username": "dbadmin" }
},
"allowed_commands": {
"default": {
"web-1": { "allow": ["uptime", "df -h", "free -m"] }
},
"api_keys": {
"deploy-key": {
"web-1": { "allow": ["systemctl restart app", "deploy *"] }
},
"db-key": {
"db-1": { "allow": ["systemctl restart postgres", "pg_dump *"] }
}
}
}
}
```
---
## The Problem
Most MCP SSH servers run as local stdio processes — one per client, with no shared state, no centralized authorization, and no audit trail. When multiple AI agents, CI pipelines, or dashboards need SSH access, each one independently manages its own SSH keys and runs its own MCP process. This creates:
- **No centralized access control** — every client decides what it can run
- **No audit trail** — commands are invisible to the ops team
- **SSH key sprawl** — keys scattered across every machine running an agent
- **No rate limiting** — a runaway agent can overwhelm a target
- **No connection pooling** — each client opens and closes SSH sessions independently
**ssh-mcp** solves this by deploying a single MCP server as an HTTP gateway. All clients connect to it; it connects to your SSH targets. Authorization, authentication, rate limiting, connection pooling, and audit logging happen in one place.
---
## Use Cases
### Multi-Agent Server Management
Run a team of AI agents with different access levels. The deployment agent can `systemctl restart nginx` on web servers; the monitoring agent can `journalctl` everywhere; the database agent can only run `psql` on the DB server. Each agent authenticates with its own API key; each key has its own permission set.
### CI/CD Pipeline Integration
Point your CI pipeline at ssh-mcp instead of managing SSH keys on every runner. A single API key per pipeline, network-based rules for your CI subnet, and command allowlists ensure your deployment scripts run exactly what they should — nothing more.
### Centralized Log and Config Retrieval
Use [`ssh_download_file`](#ssh_download_file) to pull logs, config files, or database dumps from remote servers without leaving your MCP client. The 8-layer path validation and sandbox root settings ensure file transfers stay within safe boundaries.
### Server Health Dashboards
Build an MCP-powered dashboard that queries `uptime`, `free`, `df`, and `ps` across your fleet. The connection pool reuses SSH sessions, the circuit breaker isolates failing targets, and Prometheus metrics at [`/metrics`](#metrics) feed your existing monitoring stack.
### Compliance and Audit
Every command is logged with structured JSONL: who ran what, on which server, from which IP, whether it was allowed, and how long it took. The `matched_via` field traces exactly which authorization layer made the decision. Config changes are logged separately with before/after state.
---
## Security Model
ssh-mcp applies defense-in-depth at every layer. The full security model is documented in [`docs/SECURITY.md`](docs/SECURITY.md).
**Security boundary:** ssh-mcp adds an authorization, authentication, and auditing layer in front of SSH. It does not replace the permissions of the underlying SSH accounts. If a command is allowed, the SSH user executes it with whatever privileges that account has. The gateway itself should be protected with TLS and network access controls. Logs may contain command output and should be treated accordingly.
### Command Authorization Chain
Commands are evaluated through an **ordered, layered chain**. If any layer denies, the request stops there:
| Layer | What it checks |
|---|---|
| 1. Target validation | Is the server name known? |
| 2. `block_patterns` | Does the command match a blocked regex? |
| 3. Dangerous patterns | Does it contain `$()`, backticks, or newlines? |
| 4. Redirection guard | Do shell redirects target `/dev/`, `/proc/`, `/sys/`? |
| 5. Segmentation | After stripping redirects and splitting on `&&`, `||`, `;`, `\|`, each segment runs the full chain |
| 6. `default` rules | All-client allow/deny rules |
| 7. `api_keys` rules | Per-key allow/deny rules |
| 8. `networks` rules | Per-CIDR allow/deny rules |
| 9. Deny | Implicit fallback |
### Authentication
API keys are sent via `X-API-Key` or `Authorization: Bearer` headers. Keys are hashed with PBKDF2-HMAC-SHA256 (100,000 iterations, random 16-byte salt) and verified with constant-time comparison. Raw keys are never stored.
### Input Sanitization
Commands, target names, and log strings are sanitized before processing: null bytes stripped, control characters removed, NFKC-normalized, and run through [ReDoS protection](docs/SECURITY.md#redos-protection) for `block_patterns`.
### Path Traversal Prevention
SFTP transfers go through 8-layer path validation including null-byte checks, control-character stripping, dot-segment normalization, symlink resolution, and sandbox-root enforcement.
### Rate Limiting
Sliding-window rate limiter per client IP (60 requests / 60 seconds, `/health` exempt). Violations return HTTP 429 with `Retry-After`.
Rate limiting is configurable under `settings.rate_limit`:
```jsonc
"settings": {
"rate_limit": {
"enabled": true, // set false to disable entirely
"max_requests_per_minute": 60, // max requests per client IP in the window
"window_seconds": 60.0, // sliding-window duration
"cleanup_interval_seconds": 300.0 // expired-entry GC interval
}
}
```
> **Note:** the rate limiter is built **once at container startup** from the initial config and is **not** rebuilt on config hot-reload. To disable rate limiting you must set `settings.rate_limit.enabled` to `false` in the config present at boot (e.g. `config/ssh-mcp-config.json` in the mounted volume). This is useful for high-volume clients or test suites that issue many requests from a single IP.
---
## Quick Start
### Prerequisites
- Docker wiLo que la gente pregunta sobre ssh-mcp
¿Qué es gelse/ssh-mcp?
+
gelse/ssh-mcp es mcp servers para el ecosistema de Claude AI. Containerized MCP server exposing SSH command execution and SFTP file transfer as tools over Streamable HTTP. Centralized gateway with per-client authorization, layered command policies, audit logging, rate limiting, circuit breakers, and connection pooling. Docker-ready. Tiene 4 estrellas en GitHub y su última actualización registrada es del 2026-08-26.
¿Cómo se instala ssh-mcp?
+
Puedes instalar ssh-mcp clonando el repositorio (https://github.com/gelse/ssh-mcp) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.
¿Es seguro usar gelse/ssh-mcp?
+
Nuestro agente de seguridad ha analizado gelse/ssh-mcp y le ha asignado un Trust Score de 87/100 (tier: Trusted). Revisa el desglose completo de comprobaciones superadas y flags en esta página.
¿Quién mantiene gelse/ssh-mcp?
+
gelse/ssh-mcp es mantenido por gelse. La última actividad registrada en GitHub es del 2026-08-26, con 0 issues abiertos.
¿Hay alternativas a ssh-mcp?
+
Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.
Despliega ssh-mcp en tu cloud
Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.
¿Mantienes este repo? Añade un badge a tu README
Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.
[](https://claudewave.com/repo/gelse-ssh-mcp)<a href="https://claudewave.com/repo/gelse-ssh-mcp"><img src="https://claudewave.com/api/badge/gelse-ssh-mcp" alt="Featured on ClaudeWave: gelse/ssh-mcp" width="320" height="64" /></a>Más MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!