Skip to main content
Glama

runpod-mcp — 用于 Learning-to-Swim 复现的自定义 MCP 服务器

独立部署说明: 本服务器是从 learning-to-swim-replication 项目(完整历史)中提取出来的。类似 ../runbook/RUNBOOK.md 这类相对链接指向父项目,仅当本仓库位于该父项目内部(或通过符号链接指向它)时才能解析;服务器本身可以独立运行。

这 14 个任务形态的工具与父项目的 runbook/RUNBOOK.md 相对应,而不是提供 ~50 个通用 API 镜像。之所以是自定义服务器,是因为 没有任何 RunPod API 能在 pod 上执行命令 —— 官方 MCP 只覆盖控制平面;运行 pod_setup.sh、轴健康扫描和训练均需要 SSH + rsync,并以代码中的成本护栏形式实现。

架构

.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)
  • 无状态且按载具(per-vehicle)隔离:"pod" = GET /pods 返回结果中,匹配所选载具配置名称的那一个(hippocampuslts-replicationbluerov2lts-replication-bluerov2;每个工具的 vehicle 参数默认为 hippocampus,stop_pod/terminate_pod 必须显式指定);控制台与 MCP 始终一致。唯一的本地状态:每个载具 Runtime 的 60 秒 (host, port) 缓存。

  • 异步任务:一次 SSH 调用运行 setsid bash job_wrapper.sh <dir> <pod_id> <ceiling> <auto_stop>;状态存放在网络卷上,因此能经受住 MCP 重启、Mac 睡眠和 pod 停止。timeout --kill-after 强制执行墙钟时间上限(退出码 124);auto_stop 后缀在 exit_code 已写入之后才运行,因此超时永远不会阻止它发起电码。Pod id 通过 argv 注入(容器环境变量在分离的 BatchMode shell 中不可靠);会 source /etc/rp_environment 以获取 runpodctl 凭据;启用 auto_stop 时会同步探测 runpodctl,若不可用则明确报错。该探测(2026-08-09)是三路诊断:bare-shell 检查不下定论(它们区分 H1-vs-H2,并捕获 bare PATH),随后无条件 source /etc/rp_environment,而“source 后”那一对承载了结论——NO_RUNPODCTL(source 后仍无该二进制,退出码 90)、NO_RUNPODCTL_AUTH_SOURCED(source 后仍被拒绝认证,退出码 91)、PROBE_OK(仅当 source 后成功);NO_RUNPODCTL_AUTH_BARE 是继续执行的中间诊断。

  • 空闲看门狗:每次转换到 running 都会重新安装 —— 容器磁盘清机会移除运行时安装的内容(idle_watchdog.sh 本身、apt 的 X11/GL 库、rsync),所以每次转换都保留安装;runpodctl 随镜像提供,每次开机都会恢复(清机是从镜像恢复磁盘,而不是清空磁盘;2026-08-09 修正)。每 5 分钟:没有活动任务,需要刷新任务 + 没有 sshd 会话 + /workspace/.keepalive 超过 60 分钟未刷新 → 运行 runpodctl stop podtouch /workspace/.keepalive 是“手动会话”的逃生舱口。成功安装会报告 armed (stop path unverified) —— 该探测只证明 READ(get pod),而看门狗需要 WRITE(stop pod);第一个真正的确认是 /workspace/.idle_watchdog.log 中出现成功停止的条目。状态(2026-08-09):安装探测在此前每次记录的 bring-up 中均失败(修复前是不透明的 rc=91)——看门狗从未真正布防;缺陷 2 以 DIAGNOSED 而非 CLOSED 交付,并将由下一次 bring-up 的哨兵(sentinel)来定案。idle_watchdog: FAILED ⇒ 在任何任务开始前先布防 Mac 侧的死手开关。

  • 护栏即代码:每个声明的载具只能有一个 pod(账号上任何其他名称的 pod 都会被拒绝)、RTX 4090 ×1、SECURE、interruptible 强制为 false、必须使用网络卷、terminate_pod 需要显式的 vehicle 参数以及逐字匹配的字符串 terminate <对应载具的 pod_name>(例如 terminate lts-replication)、在没有 force 的情况下每个 pod 同一时间只能运行一个任务。

安装 / 注册

在项目的 .mcp.json(Claude Code)中,以 run.sh 的绝对路径注册该服务器 —— run.sh 会在首次启动时自行创建 .venv

{
  "mcpServers": {
    "runpod": {
      "command": "bash",
      "args": ["/path/to/runpod-mcp/run.sh"]
    }
  }
}

设置

  1. API key(绝不出现在磁盘/DVC 中,也不在 Git/argv 里 —— 仅存于 macOS Keychain;服务器通过 security find-generic-password 读取,并从所有错误和日志中清除 rpa_ 值):

    security add-generic-password -a kyle -s runpod-api-key -w '<KEY>'

    (当前 runpod_mcp/config.py 中查找账户硬编码为 kyle —— 如果你的 macOS 账户不同,请一起调整这两处。)

  2. SSH 密钥~/.ssh/id_ed25519(.pub) 必须存在;.pub 通过 PUBLIC_KEY 环境变量在创建 pod 时注入(这是 runpod/pytorch 镜像实际支持的环境变量——已实际验证;同时设置 SSH_PUBLIC_KEY 作为双保险)。直接 SSH 连接 root@publicIp:portMappings["22"];不使用 RunPod 的代理 SSH(没有 scp)。主机密钥存放在专用的 ~/.ssh/known_hosts_runpod 中,每次 pod 启动时截断(容器磁盘清机会重新生成主机密钥,过时条目只会造成误报的中间人失败)。

  3. 其他项无需处理 —— run.sh 在首次启动时创建 .venv/ 并安装 requirements.txt(受 stamp 门控)。

测试

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-only

离线测试使用 httpx.MockTransport + 鸭子类型的伪 SSH —— 不联网、不读取 SSH 密钥。实时测试为只读 GET + 通过 run.sh 完成的 MCP stdio 握手(断言所有 14 个工具均已注册)。DR 数据表通过解析 BLUEROV2/config/bluerov2_heavy.yamlRUNBOOK.mdAPPLY.md 进行交叉核对;补丁脚本对已固定提交 7c5ebe7 的源码做 fixture 摘录进行运行(若存在真正的引用克隆,则外加 SHA 门控测试;该测试只读、使用 tmp 副本)。

test_supervise.py 用注入的 fakes + 假时钟驱动 supervise CLI 的核心(不需要真实等待),并覆盖每个安全分支:正常完成、任务失败、最大等待强制停止、pod 未运行拒绝、启动拒绝、瞬态轮询错误、捕获失败仍停止、--no-stop,以及所有场景下断言 terminate_pod 从未被调用。

仓库根的 pytest -q 通过 conftest.pycollect_ignore 忽略此目录 — 精简后的根 venv 没有 mcp/httpx

监督运行(supervise.sh

一条命令串联整次运行:验证 pod 运行中 → dry-run 推导出一个有限的墙钟时间上限 → launch(auto_stop=false) → 轮询 job_status → 无条件拉取 /workspace/jobs/<job_id>/ + sync_logs + spend_reportstop_pod → 输出持久的 JSON 摘要 —— 因此智能体只需作为后台任务启动它一次,并在完成时收到通知。它复用 runpod_mcp.tools.*(无逻辑重复,继承全部护栏),并且从不调用 terminate_pod。这是一个 Mac 侧 CLI,是第 15 个 MCP 工具:需要轮询几分钟的工具会阻塞 stdio 服务器。

# 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]

资金安全:轮询循环只有两个退出出口 —— 正常完成 → stop_pod;或 --max-wait(始终有限)超时后仍处于 running → 强制停机 + 非零退出码 + force_stopped 摘要标记。启动 拒绝 → 不停机(修复后重试),退出码为 2。载具日志目录中的 supervise-<job_id>.json 摘要(hippocampus 为 logs/pod/,bluerov2 为 logs/pod/bluerov2/)是恢复契约(后续会话根据它协调停机状态)。存活保障说明:caffeinate -i 可防止空闲睡眠,但无法防止休眠回调;run_in_background 能否在 WarmLifecycle 回收后存活尚未验证 —— 作业的 timeout 上限是保证的兜底;pod 侧空闲保护前的 counter 会回也称不上完全可靠(DIAGNOSED,未 CLOSED —— 见上文的“空闲看门狗”条目),所以当 ensure_pod 报告 idle_watchdog: FAILED 时,请布防 Mac 侧死手保护开关。

Campaign 链(CUREE/chains/

每个 campaign 一个 bash 脚本(按 campaign ID 命名,例如 chain-011-CUREE_Adaptive-weights.sh):该 campaign 的整个 pod 侧任务序列——补丁、门槛、训练、评测、同步——作为有序的、按 SHA 固定的链接。这些链通过 supervise.sh 启动(由它负责捕获与停机),绝不手动执行;它们是某个 campaign 实际执行内容的数据保留记录。

Dry-run

ensure_podrun_pod_setuprun_joblaunch_trainingapply_bluerov_patches 都接受 dry_run=true,并返回精确的目标负载/改动/命令,且不修改任何内容($0)。supervise 在正式启动之前利用这条 dry-run 路径来推导其有限的 --max-wait

NGC 后备镜像(手动切换——请先阅读)

nvcr.io/nvidia/isaac-sim:4.5.0(RUNBOOK Day-1 后备方案)没有 sshd —— 这会让本服务器的整个 SSH 机制失效。切换需要替换 docker-start 命令,使其能安装/启动 sshd(这不是一行改动):在切换 pod_defaults.yaml 中的 image_name 之前,请先告诉 Kyle 考虑是否需要更改。

已知风险(计划时已接受)

  • pod_setup.sh 中 IsaacSim 4.5.0 的下载 URL 可能 404 —— 会在 job_status 日志尾部出现;修复方法是修改 runbook,而不是修改 MCP。

  • 各数据中心 4090 库存不稳定;网络卷会锁定单个 DC。用 gpu_availability(data_center_id=...) + ensure_pod 的“无 GPU”事件恢复方案覆盖;最坏情况下,在另一个 DC 中创建第二个卷。

许可证

MIT — 见 LICENSE

-
license - not tested
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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.

View all MCP Connectors

Latest Blog Posts

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