runpod-mcp
runpod-mcp — Einzelanfertigung eines MCP-Servers für die Learning-to-Swim-Replikation
Hinweis für den Standalone-Betrieb: Dieser Server wurde (mit vollständiger Historie) aus dem Projekt
learning-to-swim-replicationextrahiert. Relative Links wie../runbook/RUNBOOK.mdbeziehen sich auf dieses übergeordnete Projekte und lösen nur auf, wenn dieses Repository darin liegt (oder dorthin symlinklt ist); der Server selbst läuft eigenständig.
Aufgabenförmige Tools (14), die das runbook/RUNBOOK.md des übergeordneten
Projekts spiegeln, statt ~50 generischer API-Spiegel. Eigenentwicklung, weil
keine RunPod-API Befehle auf einem Pod ausführt — das offizielle MCP deckt
nur die Control Plane ab; das Ausführen von pod_setup.sh, der Achsen-
Sanity-Sweep und das Training erfordern SSH + rsync, hier mit Cost Guardrails
im Code verankert.
Architektur
.mcp.json → run.sh (venv bootstrap) → server.py (FastMCP, stdio; thin)
└── runpod_mcp/
config.py Keychain key fetch + rpa_ scrubber
api.py REST v1 (pods/volumes/billing) + unauth GraphQL gpuTypes
guardrails.py one-pod-per-vehicle (unknown refused) · 4090-only · no spot · volume required · confirm gate
ssh.py hardened ssh/scp/rsync; known_hosts_runpod; 60s conn cache
jobs.py detached jobs: /workspace/jobs/<id>/{cmd.sh,pid,out.log,exit_code,meta.json}
training.py DR tables (RUNBOOK/yaml-cross-checked) + verbatim train cmd
supervise.py Mac-side background CLI: launch→poll→pull→sync→spend→stop (reuses tools.*)
watch.py Mac-side ADVISORY observation CLI: discover job→tail out.log→parse metrics→page on plateau/failure/stall (read-only; never stops pods)
remote/ job_wrapper.sh · idle_watchdog.sh · apply_bluerov2_patch.py
deadman.py Mac-side stop-pod fuse: arm --vehicle → sleep → stop with retries (per-vehicle pid/summaries)
supervise.sh → caffeinate -i wrapper around python -m runpod_mcp.supervise
watch.sh → caffeinate -i wrapper around python -m runpod_mcp.watch (live-pod behavior UNVERIFIED — fixture/mock-verified only; see CLAUDE.md §D)
deadman.sh → caffeinate -i wrapper around python -m runpod_mcp.deadman (arm/cancel REQUIRE --vehicle; bare status reports all vehicles)Zustandslos & pro Fahrzeug: „der Pod“ = das, was
GET /podsals Treffer auf den konfigurierten Namen des gewählten Fahrzeugs zurückgibt (hippocampus→lts-replication,bluerov2→lts-replication-bluerov2; dasvehicle-Argument jedes Tools ist standardmäßig hippocampus,stop_pod/terminate_podverlangen es ausdrücklich); Konsole und MCP stimmen immer überein. Einziger lokaler Zustand: ein 60-Sekunden-Cache für (Host, Port) pro Fahrzeug-Runtime.Asynchrone Jobs: Ein SSH-Aufruf führt
setsid bash job_wrapper.sh <dir> <pod_id> <ceiling> <auto_stop>aus; der Zustand liegt auf dem Netzwerk-Volume und übersteht so MCP-Neustarts, Mac-Schlafmodus und Pod-Stopp.timeout --kill-aftererzwingt Wanduhr-Deadlines (exit 124); das Auto-Stop-Suffix läuft erst, NACHDEM der exit_code geschrieben ist, sodass ihn ein Timeout nie aushebeln kann. Die Pod-ID wird per argv injiziert (Container-Env-Vars sind in abgekoppelten BatchMode-Shells unzuverlässig);/etc/rp_environmentwird gesourced, um die runpodctl-Zugangsdaten zu laden; beim Scharfschalten prüft auto_stop runpodctl synchron und schlägt laut fehl, falls es nicht funktionieren kann. Die Probe (2026-08-09) ist eine Dreier-Diagnostik: Die Bare-Shell-Checks entscheiden nichts (sie beantworten H1-vs-H2 und halten den nackten PATH fest), danach wird/etc/rp_environmentbedingungslos gesourced, und das gelieferte Paar (SOURCED) trägt das Urteil —NO_RUNPODCTL(Binary auch nach dem Sourcen nicht vorhanden, exit 90),NO_RUNPODCTL_AUTH_SOURCED(verweigert auch nach dem Sourcen weiterhin, exit 91). In 91,PROBE_OK(nur gesourcer Erfolg;NO_RUNPODCTL_AUTH_BAREist die Stufen-Diagnose, die fortläuft).Idle-Watchdog: wird bei jedem Übergang in „running“ neu installiert — die Container-Platten-Bereinigung entfernt das zur Laufzeit installierte Material (
idle_watchdog.shselbst, die apt X11/GL-Bibliotheken,rsync), deshalb bleibt die Installation-bei-jedem-Übergang;runpodctlwird mit dem Image mitgeliefert und ist nach jedem Boot wieder da (eine Löschung stellt die Platte aus dem Image wider her, sie leert sie nicht — korrigiert 2026-08-09). Alle 5 Minuten: keine offene Job-PID + keine sshd-Sitzung +/workspace/.keepaliveälter als 60 min →runpodctl stop pod.touch /workspace/.keepaliveist die Fluchtklappe für manuelle Sitzungen. Eine erfolgreiche Installation meldetarmed (stop path unverified)— die Sonde zertifiziert READ (get pod), der Watchdog braucht WRITE (stop pod); die erste echte Bestätigung ist ein erfolgreicher Stop-Eintrag in/workspace/.idle_watchdog.log. Status (2026-08-09): Die Installations-Sonde ist bei jedem aufgezeichneten Bring-up fehlgeschlagen (undurchsichtiges rc=91vor dem Fix) — der Watchdog hat sich tatsächlich nie geschärft (armed); Defekt 2 geht als DIAGNOSED, nicht als CLOSED raus, und der Sentinel des nächsten Bring-ups entscheidet das.idle_watchdog: FAILED` ⇒ vor jedem Job den Mac-seitigen Deadman scharfschalten.Guardrails sind Code: ein the Pod pro deklariertem Fahrzeug (jeder andere Pod-Name auf dem Konto wird verweigert), RTX 4090 ×1, festgezogen SECURE, interruptible erzwungen false, Netzwerk-Volume erforderlich,
terminate_podbraucht ein ext productsvehicleplus die wörtliche Zeichenketteterminate <Podnamen dieses Fahrzeugs>(z. B.terminate lts-replication) und ohneforcenur ein Job pro Pod.
Installation / Registrierung
Registrieren Sie den Server in einem .mcp.json eines Projekts (Claude Code)
mit einem absoluten Pfad zu run.sh — run.sh erzeugt sein eigenes .venv
beim ersten Start:
{
"mcpServers": {
"runpod": {
"command": "bash",
"args": ["/path/to/runpod-mcp/run.sh"]
}
}
}Einrichtung
API-Schlüssel (niemals auf Datenträger/Git/argv — nur macOS Keychain; der Server liest ihn über
security find-generic-passwordund entferntrpa_-Werte aus jedem Fehler und Log):security add-generic-password -a kyle -s runpod-api-key -w '<KEY>'(Der Kontoname-Name für den Lookup ist derzeit in
runpod_mcp/config.pyaufkylehartkodiert — passen Sie beides an, falls sich Ihr macOS-Konto unterscheidet.)SSH-Schlüssel: Es muss
~/.ssh/id_ed25519(.pub)existieren; die.pubwird bei der Pod-Erstellung über die UmgebungsvariablePUBLIC_KEYinjiziert (was die Abbilderrunpod/pytorchtatsächlich beachten — selbst-live verifiziert;SSH_PUBLIC_KEYwird zusätzlich gesetzt als doppelte Absicherung). Direkte SSH zuroot@publicIp:portMappings["22"]— der Proxy-SSH von RunPod wird nicht genutzt (kein scp). Host-Key landen mit in einer dedizierten~/.ssh/known_hosts_runpod, die bei jedem Pod-Start abgeschnitten wird (die Platten-Bereinigung des Containers generiert Host-Key neu; überholte Einträge fällen nur falsche MITM-Fehler aus).Sonst nichts —
run.sherzeugt.venv/und installiert beim ersten Start requirements.txt (durch eine Stempel-Datei gesteuert).
Tests
runpod-mcp/.venv/bin/python -m pytest runpod-mcp/tests -q # offline (default)
RUNPOD_MCP_LIVE=1 runpod-mcp/.venv/bin/python -m pytest \
runpod-mcp/tests/test_live.py -q # live $0 read-onlyOffline-Tests verwenden httpx.MockTransport + duck-typisiertes Fake-SSH —
kein Netzwerk, kein Schlüssel. Live-Tests sind lesende GETs + ein
MCP-stdio-Handshake über run.sh (prüft, dass alle 14 Tools registriert
werden). DR-Tabellen werden per Quervergleich geprüft durch Analysieren von
BLUEROV2/config/bluerov2_heavy.yaml,
RUNBOOK.md und
APPLY.md; das Patch-Skript wird gegen
committete Fixture-Auszüge der gepinnten 7c5ebe7-Quellen ausgeführt
(zusätzlich ein SHA-Gate-Test gegen den vorhandenen referenzierten Klon —
nur lesen, tmp-Kopien).
test_supervise.py treibt den Kern der supervise-CLI mit injizierten
Stubs + einer Fake-Uhr (kein echtes Warten), und deckt jeden Sicherheits-
Zweig ab: normaler Abschluss, Jobfehler, Spländung Force-Stop, Ablehnung bei
nicht laufendem Pod, Ablehnung beim Start, kurzzeitige Poll-Fehler,
Scheitern des Zwischenzustands stoppt trotzdem, --no-stop, und in jedem
Fall wird geprüft dass terminate_pod nie aufgerufen wird.
Root-Repo pytest -q ignoriert diesen Ordner (conftest.py collect_ignore) —
die schlanke Root-Venv hat kein mcp/httpx.
Überwachte Läufe (supervise.sh)
Ein einziger Befehl, der einen kompletten Lauf verketten: prüfen-ob-Pod-läuft →
dry-run eine endliche Wanduhr-Decke ableiten → launch(auto_stop=false) →
pollte job_status → bedingungslos /workspace/jobs/<job_id>/ ziehen +
sync_logs + spend_report → stop_pod → dauerhafte JSON-Zusammenfassung —
so startet der Agent es einmal hintergründig und wird bei Abschluss
benachrichtigt. Er verwendet runpod_mcp.tools.* (keine Logikverdopplung,
alle Guardrails geerbt) und ruft niemals terminate_pod. Das ist eine CLI
für die Mac-Seite, kein 15. MCP-Tool: ein Minuten Polling-Tool würde den
stdio-Server blockieren.
# training run (background task)
supervise.sh --training curee --dr DR_0 --seed 1 \
[--interval 45] [--max-wait N] [--backstop 300] [--no-stop] \
[--sync-subdir rsl_rl/warpauv_direct] [--summary-path PATH]
# generic job — --sync-subdir REQUIRED (pass 'none' to skip the analysis sync;
# the job-dir pull always happens); --vehicle routes the pod (default
# hippocampus; --training mode derives it from the training vehicle instead)
supervise.sh --job-name eval --command "…" --workdir /workspace \
--sync-subdir <dir|none> [--max-runtime-sec N] [--vehicle bluerov2]Geld-Sicherheit: Die Poll-Schleife hat exakt zwei Ausgänge — normaler
Abschluss → stop_pod; oder --max-wait (immer finite) verstrichen, während
der Status noch running ist → Force-Stop + Exit-Kode ungleich 0 +
force_stopped-Flag in der Zusammenfassung. Eine Scheme*-Weigerung beim
Start → kein Stopp (reparieren und neu), exit 2. Die Zusammenfassung
supervise-<job_id>.json im Logverzeichnis des Fahrzeugs (logs/pod/ für
hippocampus, logs/pod/bluerov2/ für bluerov2) ist der
Wiederherstellungsvertrag (eine spätere Sitzung gleicht den Stopp-Zustand
daraus ab). Liveness-Hinweise: caffeinate -i schützt vor Schlaf bei
Leerlauf, aber nicht vor zugeklapptem Deckel; das Überleben von
run_in_background über WarmLifecycle-Reaping ist ungeprüft — die
timeout-Grenze des Jobs ist der garantierte Rückfall; der Pod-idle watchdog
würde ihn abstützen, hat sich aber in keinem aufgezeichneten Bring-up je
gescharft (DIAGNOSED, nicht CLOSED — siehe der Idle-Watchdog-Punkt), also
aktivieren Sie den Mac-seitigen Notaus, wenn ensure_pod
idle_watchdog: FAILED meldet.
Kampagnen-Ketten (CUREE/chains/)
Ein Bash-Skript pro Kampagne (benannt nach Kampagnen-ID, z. B.
chain-011-CUREE_Adaptive-weights.sh): die komplette pod-seitige
Job-Sequenz der Kampagne — Patches, Gates, Trainings, Evals, Syncs — als
geordnete, SHA-gepinnte Verbindungen. Ketten werden über supervise.sh
gestartet (das das Abfangen-und-Anhalten übernimmt), niemals von Hand
ausgeführt; sie sind das dauerhafte Protokoll dessen, welche genau Kampagne
was ausgeführt hat.
Dry Läufe
ensure_pod, run_pod_setup, run_job, launch_training,
apply_bluerov_patches akzeptieren alle dry_run=true und geben die genauen
geplanten Payloads/Edits/Befehle alle zurück, ohne irgendetwas zu verändern ($0).
supervise nutzt diesen Dry-Run-Pfad, um vor dem echten Start seine endliche
--max-wait abzuleiten.
NGC-Fallback-Image (manueller Wechsel — zuerst lesen)
nvcr.io/nvidia/isaac-sim:4.5.0 (Day-1-Fallback aus RUNBOOK) hat
kein sshd — es bricht die ganze SSH-Geschichte dieses Servers. Ein
Wechsel erfordert einen Docker-Start-Befehl, der sshd installiert/ststartet
(keine Einzeilenänderung): Kyle frühzeitig informieren, bevor Sie jemals
image_name in pod_defaults.yaml tauschen.
Bekannte Risiken (bei der Planung akzeptiert)
Die Download-URL für Isaac Sim 4.5 in
pod_setup.shkann 404 liefern — das taucht im Log-Ende vonjob_statusauf; die Behebung ist eine Runbook- Änderung, keine MCP-Änderung.Der 4090-Bestand schwankt je Datenknoten; das Netzwerk-Volume pinnt einen DC.
gpu_availability(data_center_id=...)zusammen mit dem „Kein-GPU“-RecoveryRezept von ensure_pod deckt das ab; schlimmstenfalls legen Sie ein zweites Volume in einem anderen DC an.
Lizenz
MIT — siehe LICENSE.
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 Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Create and manage AI agents that collaborate and solve problems through natural language interacti…
Build, validate, and deploy multi-agent AI solutions from any AI environment.
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/kyle-nelson-berkeley/runpod-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server