Skip to main content
Glama
vait90
by vait90

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ür docker 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-Port 22 des entfernten Rechners.


Verfügbare MCP-Tools

Zustandslose (stateless) Tools – einfache, einmalige Operationen

Tool

Beschreibung

ssh_test

Verbindung und Authentifizierung mit einem entfernten Rechner testen.

ssh_execute

EINEN Shell-Befehl in einer frischen Verbindung ausführen (stdout / stderr / Exit-Code). Kein Gedächtnis: cd/export werden nicht an den nächsten Aufruf vererbt. Man kann damit nicht auf interaktive Prompts antworten.

ssh_upload

Lokale Datei per SFTP auf den entfernten Rechner hochladen.

ssh_download

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

ssh_open_session

Schritt 1 – eine neue interaktive Shell öffnen, gibt eine session_id zurück.

ssh_send

Schritt 2 – Text (Befehl oder Prompt-Antwort) and create Session senden. Die session_id muss immer mitgegeben werden.

ssh_read

Schritt 3 (optional) – weitere Ausgabe lesen, ohne zu senden (für langsame/lange Befehle).

ssh_close_session

Schritt 4 – die Session schließen. Immer schließen, wenn du fertig bist.

ssh_list_sessions

Offene Sessions auflisten (host, Benutzer, Inaktivität), z. B. wenn eine session_id verloren gegangen ist.

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: cd und export nicht 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.

  1. ssh_open_session – du bekommst eine session_id zurück (und das Login-Banner / den ersten Prompt in initial_output).

  2. ssh_send – du gibst einen Befehl ein oder antwortest auf einen Prompt. Die session_id muss bei jedem Aufruf übergeben werden. Standardmäßig wird auch Enter gesendet.

  3. ssh_read (optional) – bei langsamer/lange laufender Ausgabe mehr Output holen, ohne zu senden.

  4. 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 futna

Sudo-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 maximal SSH_MAX_SESSIONS Session geöffnet sein – bei Erreichen des Limits gibt es eine eindeutige Fehlermeldung. Wenn eine session_id nicht mehr existiert, wird genau gesagt, was du tun sollst (neu öffnen oder mit ssh_list_sessions prü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.md

1. 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 --build

Das 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/docs

  • OpenAPI JSON: http://localhost:2222/openapi.json

  • MCP-Endpunkt (Cherry Studio): http://<host-IP>:2222/mcp

Anhalten

docker compose down

2. 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.server

3. stdio-Modus

Bei im Container laufender Server per docker exec:

docker exec -i -e TRANSPORT=stdio ssh-mcp-server python -m app.server

Oder direkt ohne Docker:

TRANSPORT=stdio python -m app.server

4. 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.

  1. Starte den Server: docker compose up -d --build

  2. Finde die (Host-)IP-Adresse des Rechners auf dem Docker läuft:

    • Linux: hostname -I → z. B. 192.168.1.50

    • Wenn Cherry Studio auf demselben Rechner läuft, genügt auch localhost / 127.0.0.1.

  3. Cherry Studio → Einstellungen (Settings) → MCP Servers → Add / Neuer Server.

  4. Trage die Folgende ein:

    • Typ / Típus: Streamable HTTP (falls nicht verfügbar, dann SSE / HTTP)

    • URL / Endpunkt: http://<host-IP>:2222/mcp

      • z. B. http://192.168.1.50:2222/mcp

      • auf demselben Rechner: http://localhost:2222/mcp

  5. Speichern und Server aktivieren (Enable). Cherry Studio lädt die Tools ssh_test, ssh_execute, ssh_upload, ssh_download usw.

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: docker

  • Arguments:

    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

TRANSPORT

http oder stdio

http

HOST

MCP-Code HTTP-Bind-Adresse

0.0.0.0

PORT

MCP-HTTP-Port (den Cherry Studio erreicht)

2222

SSH_HOST

Adresse des entfernten Rechners

–

SSH_PORT

SSH-Port des entfernten Rechners

22

SSH_USERNAME

SSH-Benutzername

–

SSH_PASSWORD

SSH-Passwort (oder Schlüssel verwenden)

–

SSH_PRIVATE_KEY

Inline privater Schlüssel (PEM)

–

SSH_PRIVATE_KEY_PATH

Dateipfad zum privaten Schlüssel (im Container)

–

SSH_PASSPHRASE

Passphrase der private Schlüssel

–

SSH_TIMEOUT

Verbindungs-Timeout (Sekunden)

15

SSH_SESSION_IDLE_TIMEOUT

Automat. Schließen von untätigem Session nach Sekunden (0 = aus)

600

SSH_MAX_SESSIONS

Maximale Anzahl gleichzeitig offener interaktiver Sessions

20

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:ro

Danach in .env:

SSH_PRIVATE_KEY_PATH=/keys/id_ed25519

6. 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

/health

Status

GET

/

Server-Info

POST

/api/ssh/test

Verbindung testen

POST

/api/ssh/execute

Befehl ausführen

POST

/api/ssh/upload

Datei hochladen (SFTP)

POST

/api/ssh/download

Datei herunterladen (SFTP)

POST

/api/ssh/session/open

Interaktive Session öffnen (Schritt 1)

POST

/api/ssh/session/send

Eingabe an Session senden (Schritt 2)

POST

/api/ssh/session/read

Ausgabe ohne Senden lesen (Schritt 3)

POST

/api/ssh/session/close

Session schließen (Schritt 4)

GET

/api/ssh/session/list

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 .dockerignore und in der Regel auch .gitignore ausgeschlossen — 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 2222 nur in einem vertrauenswürdigen Netzwerk verfügbar.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to securely execute commands, transfer files, and manage port forwarding on remote servers via SSH.
    183 npm
    37
    Apache 2.0
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables remote server management via SSH, including command execution, file transfer (SFTP), and interactive shell sessions, with support for multiple hosts.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to securely execute commands on remote hosts via SSH and SFTP, with persistent shells, file transfers, screenshots, and an audit log.
    4
    MIT