SSH MCP Server
SSH MCP Server (paramiko)
Ein Paramiko-basierter SSH-MCP-Server, der Befehle auf entfernten Rechnern ausführen und Dateien über SFTP übertragen kann. Er ist über zwei Transportarten erreichbar, die per Umgebungsvariable / Schalter ausgewählt werden können:
http– MCP-streamable-http-Endpunkt unter/mcp(hier verbindet sich Cherry Studio), zusätzlich eine dokumentierte OpenAPI/Swagger-Oberfläche (/docs,/openapi.json).stdio– klassischer MCP-stdio-Transport (für den lokalen Start / fürdocker exec).
WICHTIG zu den Ports: Port 2222 ist der Port des MCP-Servers, mit dem sich Cherry Studio verbindet. Das ist NICHT der SSH-Port des entfernten Rechners! Der SSH-Port des entfernten Rechners ist in der Regel 22 (
SSH_PORT). Also: Cherry Studio →http://<host-IP>:2222/mcp→ MCP-Server → Paramiko → SSH-Port22des entfernten Rechners.
Verfügbare MCP-Tools
Zustandslose (stateless) Tools – einfache, einmalige Operationen
Tool | Beschreibung |
| Verbindung und Authentifizierung mit einem entfernten Rechner testen. |
| EINEN Shell-Befehl in einer frischen Verbindung ausführen (stdout / stderr / Exit-Code). Kein Gedächtnis: |
| Lokale Datei per SFTP auf den entfernten Rechner hochladen. |
| Datei per SFTP vom entfernten Rechner herunterladen. |
Zustandsbehaftete (stateful), interaktive Session-Tools – Live-Shell
Diese halten eine Live-Shell offen, in der der Zustand zwischen den Aufrufen erhalten bleibt (Verzeichniswechsel nach cd, per export gesetzte Variablen, Behandlung interaktiver Prompts: Sudo-Passwort, apt [Y/n] usw.).
Tool | Beschreibung |
| Schritt 1 – eine neue interaktive Shell öffnen, gibt eine |
| Schritt 2 – Text (Befehl oder Prompt-Antwort) and create Session senden. Die |
| Schritt 3 (optional) – weitere Ausgabe lesen, ohne zu senden (für langsame/lange Befehle). |
| Schritt 4 – die Session schließen. Immer schließen, wenn du fertig bist. |
| Offene Sessions auflisten (host, Benutzer, Inaktivität), z. B. wenn eine |
Die Tool-Beschreibungen (Docstrings) enthalten absichtlich eine sehr detaillierte, einfache "USE THIS WHEN..."-Anleitung auf Englisch, damit das aufrufende Modell genau weiß, wann und wie es die verschiedenen Tools verwenden muss.
Alle Tool-Parameter (host, port, username, password, private_key, private_key_path, passphrase, timeout) können angegeben werden:
pro Aufruf einzeln, oder
als Standardwert in der
.env-Datei (SSH_*-Variablen). Was im Aufruf fehlt, wird von System aus den Umgebungsvariablen geholt.
Unterstützte Authentifizierung: Passwort und Schlüssel (inline PEM oder Dateipfad, optional mit Passphrase). Unbekannte Host-Keys werden vom Server automatisch akzeptiert (AutoAddPolicy), damit die Automatisierung stabil funktioniert.
Related MCP server: SSH MCP Server
Zustandslos vs. zustandsbehaftete (interaktive) Verwendung
** Welche wann?**
Ein einzelner, eigenständiger Befehl (z. B.
ls,uptime,df -h) →ssh_execute. Jeder Aufruf öffnet eine neue Verbindung, führt einen Befehl aus und schließt sie danach. Kein Gedächtnis:cdundexportnicht bis zum nächsten Aufruf erhalten, und auf interaktive Prompts nicht möglich.Alles Interaktive oder mehrstufige (Zustandserhalt nach
cd/export, Sudo-Passwort, apt[Y/n]-Frage, mehrere aufeinander aufbauende Befehle) → interaktive Session:ssh_open_session→ssh_send→ssh_read→ssh_close_session.
Recommended Workflow (Session)
ssh_open_session– du bekommst einesession_idzurück (und das Login-Banner / den ersten Prompt ininitial_output).ssh_send– du gibst einen Befehl ein oder antwortest auf einen Prompt. Diesession_idmuss bei jedem Aufruf übergeben werden. Standardmäßig wird auch Enter gesendet.ssh_read(optional) – bei langsamer/lange laufender Ausgabe mehr Output holen, ohne zu senden.ssh_close_session– wenn du fertig bist, bitte Session schließen.
Mit ssh_list_sessions kannst du dir jederzeit die offenen Sessions anzeigen lassen (host, Benutzer, Inactivity), falls eine session_id verloren gegangen ist.
Beispiele (über REST-Endpunkte)
Session öffnen:
curl -X POST http://localhost:2222/api/ssh/session/open \
-H "Content-Type: application/json" \
-d '{"host":"192.168.1.100","username":"user","password":"secret"}'
# -> {"ok":true,"session_id":"<ID>", "initial_output":"...prompt..."}Verzeichniswechsel, der erhalten bleibt (Zustandserhaltung):
curl -X POST http://localhost:2222/api/ssh/session/send \
-H "Content-Type: application/json" \
-d '{"session_id":"<ID>","input":"cd /var/log && pwd"}'
# a következő ssh_send már a /var/log-ban futnaSudo-Befehl + Passwort-Prompt beantworten:
# 1) elindítod a sudo parancsot
curl -X POST http://localhost:2222/api/ssh/session/send \
-H "Content-Type: application/json" \
-d '{"session_id":"<ID>","input":"sudo apt-get update"}'
# 2) a kimenetben megjelenik a "[sudo] password for user:" prompt -> beküldöd a jelszót
curl -X POST http://localhost:2222/api/ssh/session/send \
-H "Content-Type: application/json" \
-d '{"session_id":"<ID>","input":"my_sudo_password"}'Apt [Y/n]-Frage beantworten:
curl -X POST http://localhost:2222/api/ssh/session/send \
-H "Content-Type: application/json" \
-d '{"session_id":"<ID>","input":"sudo apt-get install htop","read_timeout":5}'
# amikor jön a "Do you want to continue? [Y/n]" kérdés:
curl -X POST http://localhost:2222/api/ssh/session/send \
-H "Content-Type: application/json" \
-d '{"session_id":"<ID>","input":"Y"}'Session schließen:
curl -X POST http://localhost:2222/api/ssh/session/close \
-H "Content-Type: application/json" \
-d '{"session_id":"<ID>"}'Zeitüberschreitung / Inaktivität / Fehler: Jede Session-Operation schließt automatisch Sessions, die seit mehr als
SSH_SESSION_IDLE_TIMEOUT(Standard 600 s) untätig waren, sowie solche, deren Kanal abgestorben ist. Es können gleichzeitig maximalSSH_MAX_SESSIONSSession geöffnet sein – bei Erreichen des Limits gibt es eine eindeutige Fehlermeldung. Wenn einesession_idnicht mehr existiert, wird genau gesagt, was du tun sollst (neu öffnen oder mitssh_list_sessionsprüfen).
Projektaufbau
ssh-mcp-server/
├── app/
│ ├── __init__.py
│ ├── ssh_ops.py # paramiko SSH/SFTP műveletek (közös logika)
│ └── server.py # MCP tool-ok + FastAPI/OpenAPI + transport választás
├── requirements.txt
├── Dockerfile
├── docker-compose.yml # 2222:2222 publikálás
├── .env.example
└── README.md1. Schnellstart mit Docker (empfohlen)
Vorbereitung
cd ssh-mcp-server
cp .env.example .env
# szerkeszd a .env-et: add meg a távoli gép adatait (SSH_HOST, SSH_USERNAME, stb.)Build and start (HTTP-Modus)
docker compose up -d --buildDas startet den Server im HTTP-Modus und port 2222 auf dem Host wird veröffentlicht (ports: "2222:2222").
Überprüfen
curl http://localhost:2222/health
# {"status":"ok","service":"ssh-mcp-server","mcp_endpoint":"/mcp"}Swagger UI (im Browser):
http://localhost:2222/docsOpenAPI JSON:
http://localhost:2222/openapi.jsonMCP-Endpunkt (Cherry Studio):
http://<host-IP>:2222/mcp
Anhalten
docker compose down2. HTTP-Modus manuell (ohne Docker, für Entwicklung)
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
export TRANSPORT=http HOST=0.0.0.0 PORT=2222
python -m app.server3. stdio-Modus
Bei im Container laufender Server per docker exec:
docker exec -i -e TRANSPORT=stdio ssh-mcp-server python -m app.serverOder direkt ohne Docker:
TRANSPORT=stdio python -m app.server4. Cherry-Studio-Integration
A) HTTP (streamable-http) – empfohlen, funktioniert auch über das Netzwerk
Der Container läuft in Docker auf deinem Laptop; Cherry Studio verwendet die Host-IP und den Port 2222.
Starte den Server:
docker compose up -d --buildFinde die (Host-)IP-Adresse des Rechners auf dem Docker läuft:
Linux:
hostname -I→ z. B.192.168.1.50Wenn Cherry Studio auf demselben Rechner läuft, genügt auch
localhost/127.0.0.1.
Cherry Studio → Einstellungen (Settings) → MCP Servers → Add / Neuer Server.
Trage die Folgende ein:
Typ / Típus:
Streamable HTTP(falls nicht verfügbar, dannSSE/HTTP)URL / Endpunkt:
http://<host-IP>:2222/mcpz. B.
http://192.168.1.50:2222/mcpauf demselben Rechner:
http://localhost:2222/mcp
Speichern und Server aktivieren (Enable). Cherry Studio lädt die Tools
ssh_test,ssh_execute,ssh_upload,ssh_downloadusw.
Wenn du dich von einem entfernten Rechner verbindest, stelle sicher, dass Port 2222 erreichbar ist (Firewall regeln) and Docker bind to
0.0.0.0(standardmäßig aktiv).
B) stdio-Modus
Wenn Cherry Studio einen stdio-MCP-Server erwartet (einen Befehl startet):
Command:
dockerArguments:
exec -i -e TRANSPORT=stdio ssh-mcp-server python -m app.server
(Dazu muss der laufen: docker compose up -d.)
5. .env-Konfiguration
Variable | Beschreibung | Standard |
|
|
|
| MCP-Code HTTP-Bind-Adresse |
|
| MCP-HTTP-Port (den Cherry Studio erreicht) |
|
| Adresse des entfernten Rechners | – |
| SSH-Port des entfernten Rechners |
|
| SSH-Benutzername | – |
| SSH-Passwort (oder Schlüssel verwenden) | – |
| Inline privater Schlüssel (PEM) | – |
| Dateipfad zum privaten Schlüssel (im Container) | – |
| Passphrase der private Schlüssel | – |
| Verbindungs-Timeout (Sekunden) |
|
| Automat. Schließen von untätigem Session nach Sekunden (0 = aus) |
|
| Maximale Anzahl gleichzeitig offener interaktiver Sessions |
|
Schlüssel-Authentifizierung in Docker
Schlüssel in Container mounten und Pfad angeben. In der docker-compose.yml die volumes-Zeile auskommentieren:
volumes:
- ./keys:/keys:roDanach in .env:
SSH_PRIVATE_KEY_PATH=/keys/id_ed255196. REST-Endpunkte zum Testen (OpenAPI)
Der HTTP-Modus bietet neben dem Cherry-Studio-MCP-Endpunkt ebenfalls REST-Endpunkte – diese führen die gleichen SSH-Operationen aus und sind gut mit curl / Swagger UI nutzbar:
Method | Route | Operation |
GET |
| Status |
GET |
| Server-Info |
POST |
| Verbindung testen |
POST |
| Befehl ausführen |
POST |
| Datei hochladen (SFTP) |
POST |
| Datei herunterladen (SFTP) |
POST |
| Interaktive Session öffnen (Schritt 1) |
POST |
| Eingabe an Session senden (Schritt 2) |
POST |
| Ausgabe ohne Senden lesen (Schritt 3) |
POST |
| Session schließen (Schritt 4) |
GET |
| Offene Sessions auflisten |
Beispiel (zustandslos):
curl -X POST http://localhost:2222/api/ssh/execute \
-H "Content-Type: application/json" \
-d '{"host":"192.168.1.100","username":"user","password":"secret","command":"uname -a"}'Sicherheitshinweise
Geheimnisse stehen niemals im Code — alles wird aus
.env/ Aufrufparametern gelesen.Die
.env-Datei wird durch.dockerignoreund in der Regel auch.gitignoreausgeschlossen — committe sie nicht in die Versionsverwaltung.Der Server verwendet
AutoAddPolicy(automatische Annahme unbekannter Host-Schlüssel). In einem geschlossenen Netzwerk ist das praktisch; in strengeren Umgebungen sollte man bekannte Host-Schlüssel verwenden.Mach den MCP-Port
2222nur in einem vertrauenswürdigen Netzwerk verfügbar.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceEnables AI assistants to execute commands and transfer files on remote servers over SSH connections.1MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to securely execute commands, transfer files, and manage port forwarding on remote servers via SSH.9836Apache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to securely execute commands on remote hosts via SSH and SFTP, with persistent shells, file transfers, screenshots, and an audit log.1MIT
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
Persistent memory and cross-session learning for AI coding assistants (hosted remote MCP).
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/vait90/ssh-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server