通过 Secure MCP Tunnel 让 ChatGPT 读写 oracle3 上的 BodySense
在 oracle3 VPS 上部署 filesystem MCP + tunnel-client,使 ChatGPT 网页端能经 Secure MCP Tunnel 读取/编辑 /home/ubuntu(用户 home,默认含 BodySense 项目)。是本地知识库版本的「远程同款」。
[!abstract] 当前状态(2026-08-15 已上线,架构已收敛为单 MCP server) oracle3 上常驻运行一个合并 MCP server(
combined-mcp.mjs,经 tunnel-client v0.0.11 → Tunneltunnel_6a7dcd7f3f348191b9d07ca771a3d2c0):
- filesystem 能力:复用官方
@modelcontextprotocol/server-filesystem(作为子进程代理),作用域/home/ubuntu,可列/读/写/改文件;run_command能力:同一 server 内自建,可在 oracle3 上执行任意 shell 命令(默认 cwd/home/ubuntu,含 120s 超时与 200KB 输出截断保护)。 两者合并在同一tools/list里,ChatGPT 拉取工具清单时一次即可看到全部(避免「多 command 是否被正确合并」的未知数)。/healthz、/readyz均 200、systemd —user 服务bodysense-tunnel为active。 用户侧最后一步(见步骤 4)已亲测:ChatGPT Business 下已发布的 custom MCP app 的 action 快照是冻结的——「重新连接 / 刷新 / 卸载重装 Connector」都不会重抓工具清单。正确做法是在 Workspace Settings → Apps 里重新创建一个新 App(本次重建为agent-v2,run_command随即出现并可用,/home/ubuntu上的 filesystem + shell 完整打通)。
[!warning] 凭据记录约定 真实 runtime key 仅存在于 oracle3 上的
~/bodysense-tunnel/.env(mode 600),不进入z/、Git、截图和聊天。 本文记录tunnel_id(标识符,非密钥):tunnel_6a7dcd7f3f348191b9d07ca771a3d2c0。它与本地 KB 隧道tunnel_6a76d490adcc8191befd401c111cb910是两条独立 Tunnel,互不干扰。
[!info] related notes
- 对照实现(本地库版本): 通过 Secure MCP Tunnel 连接本地 MCP 与 ChatGPT
- 对象页: OpenAI Secure MCP Tunnel
- 主机: oracle3(Oracle 大阪 AMD 开发 VPS,详见 VPS MOC)
- 项目: BodySense 项目概览
- 架构对照: ChatGPT 网页端维护本地 Obsidian 的架构
- 使用层(接通后如何当 agent 用): 把 ChatGPT 网页端变成 Coding Agent Harness(远端 MCP 桥方案)
- 代码配方(这个 combined-mcp.mjs 怎么写): 用代理模式给官方 MCP Server 注入自定义工具(run_command 例)
通过 Secure MCP Tunnel 让 ChatGPT 读写 oracle3 上的 BodySense
目标
让 ChatGPT 网页端(Business/Enterprise + Developer mode / full MCP)能经 Secure MCP Tunnel 调用一个运行在 oracle3 上的 filesystem MCP,从而:
- 读取
/home/ubuntu下任意文件(含~/projects/bodysense代码仓、配置、文档等); - 直接编辑该 home 下的文件(走「直接写工作区 + git 兜底」模型,不做 inbox 提案式改写);
- 经自建 shell MCP 在 oracle3 上执行任意 shell 命令(跑测试、构建、git 操作等);
- 不把 oracle3 暴露成公网服务,不开放入站端口。
这与本地知识库的 KB MCP 是同一家族,只是运行位置和作用域不同:KB 版跑在本地 Windows、作用域是 Obsidian vault、写动作走提案+二次确认;本版跑在 oracle3、作用域是 /home/ubuntu(用户 home,含 BodySense 代码仓)、写动作直接落盘、靠 git 回滚。
架构
ChatGPT 网页端 (Business/Enterprise)
│ MCP 工具调用 (出站 HTTPS)
▼
OpenAI 托管隧道端点 (tunnel_id = tunnel_xxx,本版独立 Tunnel)
│ 长轮询 / 回传 (出站 HTTPS,仅出站)
▼
tunnel-client (oracle3 常驻守护进程,~/bodysense-tunnel)
│ stdio / 本地转发 (profile.mcp.commands[] = 单条 run-combined.sh)
▼
combined-mcp.mjs (单 stdio 进程 = 隧道唯一目标)
├─ 代理官方 filesystem server (子进程, 作用域 /home/ubuntu) → 文件工具
└─ 自建 run_command → 任意 bash (默认 cwd /home/ubuntu)
▼
/home/ubuntu (ubuntu 用户的 home;bodysense 只是其中一个子目录;shell 默认在此下)
关键点:
- 本版 tunnel-client 跑在 oracle3 上,与本地 Windows 上跑 KB tunnel-client 是两个独立 Tunnel、两个独立进程,互不干扰。
- 架构已收敛为单个 MCP server:早期曾用
mcp.commands[]挂两个并行 command(main=filesystem +shell=自建 shell),但实测 tunnel-client 的启动摘要只把第一条 command 注册为mcp_target,且 ChatGPT 侧也只看到了 filesystem 工具、run_command始终不出现。因此改为写一个combined-mcp.mjs:它内部拉起官方 filesystem server 作为子进程(保留原文件工具名),并自己实现run_command,在同一个tools/list里把两组工具合并返回。这样隧道只有一个目标、ChatGPT 一次拉取即可见全部工具,彻底消除「多 command 是否被正确合并」的未知数。 - filesystem MCP 只能访问
/home/ubuntu一个根(由 server 子进程启动参数锁定),越界路径(如/etc、/root)会被 server 拒绝。 run_command执行任意 bash 命令(等同给 ChatGPT 一个 oracle3 的 shell 权限),默认 cwd/home/ubuntu,带 120s 超时 + 单流 200KB 输出截断。⚠️ 风险高于 filesystem:误删系统文件/误操作能搞崩 VPS。用户已明确选择「任意命令全开」,故不做命令白名单;oracle3 是 8/18 到期的赠金实例,风险窗口有限。- 「编辑」直接写工作区;安全网是 git——任何误改都可用
git diff/git checkout/git stash在 oracle3 上回滚。run_command也可直接跑git命令。
oracle3 上已落地的文件
| 文件 | 作用 |
|---|---|
~/bodysense-tunnel/ | 部署根目录(npm 项目,含 filesystem MCP 依赖) |
~/bodysense-tunnel/run-mcp.sh | (遗留)早期单独启动 filesystem MCP 的脚本,现已不用 |
~/bodysense-tunnel/run-shell.sh | (遗留)早期单独启动 shell MCP 的脚本,现已不用 |
~/bodysense-tunnel/shell-mcp.mjs | (遗留)早期独立 shell MCP server,现已由 combined-mcp.mjs 取代 |
~/bodysense-tunnel/combined-mcp.mjs | 当前生效:合并 MCP server——代理官方 filesystem 子进程 + 自建 run_command,单 stdio 进程 |
~/bodysense-tunnel/run-combined.sh | 启动 combined-mcp.mjs 的包装脚本(profile 实际指向它) |
~/bodysense-tunnel/start.sh | 从 .env 载入 runtime key,校验后启动 tunnel-client |
~/bodysense-tunnel/.env | CONTROL_PLANE_API_KEY(mode 600,需填真实值) |
~/bodysense-tunnel/.env.example | 模板 |
~/bodysense-tunnel/tunnel-client-bin/tunnel-client | tunnel-client v0.0.11 linux-amd64(含 cloudflared) |
~/bodysense-tunnel/node_modules/@modelcontextprotocol/server-filesystem | filesystem MCP(2026.7.10),被 combined 作为子进程代理 |
~/.config/tunnel-client/bodysense.yaml | tunnel-client profile(tunnel_id = tunnel_6a7dcd7f3f348191b9d07ca771a3d2c0,mcp.commands[] 现仅一条 → run-combined.sh) |
~/.config/systemd/user/bodysense-tunnel.service | systemd —user 常驻服务 |
实测 tools/list(combined server)返回 14 个工具:官方 filesystem 的 13 个(read_text_file, read_media_file, read_multiple_files, write_file, edit_file, create_directory, list_directory, list_directory_with_sizes, directory_tree, move_file, search_files, get_file_info, list_allowed_directories;已废弃的 read_file 在合并时过滤掉)+ 自建 run_command。
run_command(源码 ~/bodysense-tunnel/combined-mcp.mjs)入参 { command: string, cwd?: string, timeout_ms?: number },返回 exit=… / cwd=… / 合并的 stdout+stderr 文本;非零退出 isError=true。实测可经它执行 echo / pwd / whoami / git --version 等任意命令(默认 cwd /home/ubuntu)。它是 Node stdio 实现,与 filesystem 子进程同处一个 server。
[!tip]
edit_file入参是 camelCase(实测坑) 官方@modelcontextprotocol/server-filesystem的edit_file入参为{ path, edits: [{ oldText, newText }], dryRun? },不是old_text/new_text平铺(那样会报Input validation error -32602)。dryRun: true会用 git 风格 diff 预览改动。其余工具(write_file/read_file等)用path/content等 snake_case 即可。
步骤 1:在 OpenAI Platform 创建 Tunnel 并拿密钥(用户侧)
- 打开 Tunnels management,Create Tunnel,命名如
oracle3-bodysense。 - 记下生成的
tunnel_id(格式tunnel_+ 32 位十六进制)。 - 在 tunnel 的 association 中加入:所属 Platform 组织 + 你要在 ChatGPT 里使用它的 ChatGPT 工作区(只关联组织不关联工作区,则工作区看不到该隧道)。
- 打开 Runtime API keys,创建一个专用于该 daemon 的 key(主体需有
Tunnels Read + Use)。不要给常驻 daemon 用 Admin key。 - 多组织账号记下目标
org_...ID(本版 profile 未硬编码 org,如需可加control_plane.organization_id)。
与 KB 版共用同一套 Platform 权限(Tunnels Read/Use/Manage)。新角色赋值后最多等 30 分钟生效。
步骤 2:把两个值填入 oracle3(用户侧或交由本机代理)
只需改两个文件:
~/.config/tunnel-client/bodysense.yaml里的tunnel_id: "tunnel_REPLACE_WITH_REAL_ID"→ 替换为真实tunnel_id。~/bodysense-tunnel/.env里的CONTROL_PLANE_API_KEY=REPLACE_WITH_YOUR_RUNTIME_KEY→ 替换为真实 runtime key。
最简做法(本机代理代填 tunnel_id,key 由你本地写入 .env 以保持私密):
# 1) 把真实 tunnel_id 写进 oracle3 的 profile(ID 非密钥,可走此通道)
ssh oracle3 "sed -i 's/tunnel_REPLACE_WITH_REAL_ID/<你的_tunnel_id>/' ~/.config/tunnel-client/bodysense.yaml"
# 2) 你本地把 runtime key 写进 oracle3 的 .env(交互编辑,key 不落聊天/笔记)
ssh -t oracle3 "nano ~/bodysense-tunnel/.env"
校验填好了:
ssh oracle3 'grep tunnel_id ~/.config/tunnel-client/bodysense.yaml; grep -c REPLACE ~/bodysense-tunnel/.env || true'
# 应看到真实 tunnel_xxx;.env 不应再含 REPLACE
步骤 3:启动常驻守护进程
推荐 systemd —user(需 loginctl enable-linger ubuntu 让服务在无登录会话时也常驻):
ssh oracle3 'bash -s' <<'EOF'
systemctl --user daemon-reload
systemctl --user enable --now bodysense-tunnel
loginctl enable-linger ubuntu
EOF
临时前台验证(不依赖 systemd):
ssh -t oracle3 '~/bodysense-tunnel/start.sh'
# 出现 connected / ready / polling 即正常;Ctrl+C 退出
查看状态与健康端口(本版 127.0.x.x:8091):
ssh oracle3 'systemctl --user status bodysense-tunnel --no-pager; journalctl --user -u bodysense-tunnel -n 50 --no-pager'
# 或:curl http://127.0.x.x:8091/healthz 经 ssh -L 8091:127.0.x.x:8091 oracle3 转发后本地访问
doctor 自检(填好值后应全绿):
ssh oracle3 'cd ~/bodysense-tunnel && CONTROL_PLANE_API_KEY=$(grep = .env | cut -d= -f2) ./tunnel-client-bin/tunnel-client doctor --profile bodysense'
步骤 4:在 ChatGPT 创建应用 / Workspace Agent
[!warning] ChatGPT Business:app 的 action 快照是冻结的,更新必须「重新创建」而非「刷新/重连」 OpenAI 官方明确:custom MCP app 批准/发布后,ChatGPT 使用一份冻结的工具 + 输入 schema 快照,开发者后来改 MCP server 不会自动更新已批准的 app。因此:
- ❌ 「重新连接 / Reconnect」「刷新会话」「在 Connectors 里卸载→重装插件」都无效——这些只重连链路或重建连接,不会重抓 action 快照。(用户实测:卸载重装旧
agent后仍只有 14 filesystem 工具。)- ✅ 唯一正确更新方式(Business):保留旧 app 不删,去 Workspace Settings → Apps → Create 新建一个 custom MCP app(本次重建为
agent-v2,仍选同一条 Tunneltunnel_6a7dcd7f3f348191b9d07ca771a3d2c0);创建时 ChatGPT 会重新从 live MCP server 拉取 actions,此时应看到 diff:read_file消失、run_command出现;确认列表正确后 Publish,再连接agent-v2、开新会话测试。- 注:Enterprise/Edu 走 Workspace Settings → Apps → … → Action control → Refresh 即可原地刷新;但 miracle-maker 是 Business,不支持原地刷新,只能 recreate + republish。
-
ChatGPT → Workspace Settings → Apps(Business/Enterprise 管理员入口),Create / 创建,选择 Custom MCP app / 自定义 MCP 应用;Connection 选 Secure MCP Tunnel。
-
列表选
oracle3-bodysense(或粘贴tunnel_id = tunnel_6a7dcd7f3f348191b9d07ca771a3d2c0)。若看不到,确认 tunnel 的 association 含目标 ChatGPT 工作区、主体有Tunnels Read + Use。[!note] 平台命名提示 这个
tunnel_id在 OpenAI Platform 上当前名为 “agent”、描述为「用来让网页端具备读取和编辑本地文件的能力」(疑似早期某本地文件隧道的复用/遗留命名)。功能上完全可用于 BodySense,但建议在 Platform 上把它改名为oracle3-bodysense以免和本地 KB 隧道混淆。改名不影响已连客户端。 -
创建/草稿阶段先检查 actions 列表(这是成功判据):ChatGPT 从 live MCP server 拉出的工具应包含
run_command、且不应再含read_file;其余见上「工具清单」。命名如:- Name:
agent-v2(旧 app 仍在,临时区分用,验证稳了再整理) - Description:
Read and edit files on oracle3 (home /home/ubuntu) and run dev commands via one MCP server.
- Name:
-
点 Create / 创建(进入草稿);确认 actions 列表正确后点 Publish / 发布,再连接该 app。
-
(推荐)在 Workspace Agent Builder 里把该应用挂进一个 Agent,并给 Agent 一句约束指令,例如:
You operate on oracle3 (home /home/ubuntu, includes the BodySense project) via ONE MCP server that exposes both a filesystem toolset (read/write/edit files) and a
run_commandtoolset (execute arbitrary shell commands, default cwd /home/ubuntu). Always read_file (or read the relevant file) before edit_file/write_file. Prefer edit_file for small changes; keep diffs minimal. Never delete directories or rewrite files wholesale without confirmation. You MAY run build/test/git via run_command. Before running pytest/jest, ensure deps are available (pytest is NOT on PATH by default on oracle3 — activate the venv orpip install pytestfirst; check the project’s README/CONTRIBUTING for the exact command). The repo is a git checkout; the user reviews and rolls back with git on oracle3. Answer in Chinese unless asked otherwise.
权限档:本项目是代码仓、编辑直接落盘,建议至少选 Ask before making changes,对
write_file/move_file/edit_file保持确认。
与本地 KB MCP 的差异
| 维度 | 本地 KB MCP | 本版 oracle3 BodySense |
|---|---|---|
| tunnel-client 位置 | 本地 Windows | oracle3 VPS |
| 作用域 | Obsidian vault(多目录白名单) | /home/ubuntu 单根(用户 home,含 BodySense) |
| MCP server | 自研 kb-mcp(提案+二次确认) | 官方 filesystem MCP(直接读写) |
| 写模型 | 先入 inbox/ 提案,二次确认后合并 | 直接写工作区,git 兜底 |
| 安全边界 | 服务端强制 inbox-only | filesystem server 路径锁定 + git 回滚 |
| 命令执行 | 无 | 有(run_command,同 server 内自建,任意 bash,默认 cwd /home/ubuntu) |
oracle2 实例(同模式、更广作用域 + 全开无黑名单 + run_command 与 oracle3 同构,2026-08-15 落地,当晚用户反转去掉黑名单、并补 run_command)
oracle3 是「单项目(BodySense)」的窄作用域桥;oracle2 是按 Alex/hermes 安全评估做的「尽可能大但仍安全」的通用桥。两者共用同一套 tunnel-client 机制,但作用域与威胁模型不同。
- 主机:SSH 别名
oracle22(=129.225.x.x),aarch64/Ubuntu 24.04,HOME=/home/ubuntu,即 hermes 机。⚠️ 注意本地~/.ssh/config里别名是oracle22不是oracle2。 - Tunnel:
tunnel_6a80507e7e7881918f99e24e2634691b;Platform 上该 Tunnel 名为agent-oracle2(描述「操控 oracle2」)。 - 作用域(激进 + 全开,无黑名单):白名单根
/workspace+/opt/data+/home/ubuntu,三个根内全部路径可读写、不做任何黑名单拦截(2026-08-15 当晚用户明确反转此前「加黑名单」的决定:要求全部开放权限)。/opt/data按 Alex 的选择取全量(含hermes-ai-office/rehab-guide/context/skills等)。⚠️ 这意味着~/bodysense-tunnel/.env(含 runtime key)、/opt/data/secrets等敏感路径现在可通过本桥被 ChatGPT 读取——与 oracle3 同状。建议:若此桥会长期用,去 Platform 把该 runtime key rotate/revoke 一次,避免 key 长期暴露。 - 能力已与 oracle3 对齐(2026-08-15 当晚补
run_command):oracle2 现在与 oracle3 一样是「filesystem(3 根)+ 自建run_command」的合并 server(共 14 工具 = 13 filesystem + run_command),不再是纯文件编辑面。默认 cwd/home/ubuntu,120s 超时 + 200KB 输出截断,与 oracle3 的combined-mcp.mjs同构(仅作用域根不同)。 - oracle2 上落地的文件(均位于
~/bodysense-tunnel/):oracle2-mcp.mjs:合并 server,spawn 官方 filesystem server(3 个根)并自建run_command,与 oracle3 的combined-mcp.mjs同构;无黑名单拦截(历史黑名单版见oracle2-mcp.mjs.bak.*);run-oracle2.sh/start.sh/oracle2.yaml(profile)/oracle2-tunnel.service(systemd —user)/.env(runtime key,mode 600);tunnel-client-bin/tunnel-client:v0.0.11 linux-arm64(oracle2 是 ARM,不可复用 oracle3 的 amd64 二进制)。
- 实测验证(2026-08-15 当晚,去黑名单 + 补 run_command 后):
tools/list返回 14 个工具(13 filesystem +run_command;已废弃read_file已过滤,与 oracle3 一致);run_command含title/annotations/execution/outputSchema完整字段(不会被连接器静默丢弃),实测whoami→ubuntu、pwd→/home/ubuntu、exit=0;/home/ubuntu/bodysense-tunnel/.env经read_text_file可读(187 字节)、/opt/data/secrets可列出——全开放生效。 - 安全现状(2026-08-15 当晚用户反转 + 补 run_command 后):oracle2 与 oracle3 现处于完全同状——不仅 filesystem 全开放(
.env/secrets 可读),run_command还等于把 oracle2 的 shell 权限(任意 bash,默认 cwd/home/ubuntu)也交给了 ChatGPT,自然能cat任何路径。无黑名单兜底,这是用户明确接受的「全开」取舍。如需恢复隔离:可改回oracle2-mcp.mjs.bak.*的纯黑名单版、或只收窄 filesystem 作用域到非凭据目录、或去掉run_command。 - ChatGPT 侧接入(同样受 Business 快照规则约束):去 Workspace Settings → Apps → Create 新建(或重建)custom MCP app(命名
agent-oracle2),选同一条 Tunneltunnel_6a80507e7e7881918f99e24e2634691b;创建时会从 live server 重抓 actions,应能看到run_command出现、工具总数 14。⚠️ 若你之前已连过agent-oracle2:因为本次工具清单从「14 文件系统」变成「13 fs + run_command」,属于 action 快照变更,Business 下必须 recreate 新 app(旧 app 不会自动出现run_command,刷新/重连/重装均无效)。Enterprise/Edu 才支持 Action control → Refresh。 - 回滚:
ssh oracle22 'systemctl --user disable --now oracle2-tunnel';在 Platform 撤销该 Tunnel 的 runtime key;保留 Tunnel record 待诊断。
常见问题
doctor 报 invalid tunnel ID
tunnel_id 还是占位符。确认已替换为真实 tunnel_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(32 位小写字母/数字)。
doctor 报 401 / access 失败
runtime key 错、过期、组织不对,或主体缺 Tunnels Read + Use。多组织账号需在 profile 加 control_plane.organization_id。
ChatGPT 看不到 Tunnel
tunnel 的 association 没含目标 ChatGPT 工作区;或主体缺 Tunnels Read + Use。企业工作区无法自动关联时联系 OpenAI 客户团队。
run_command 不出现在 ChatGPT 工具里(已定位真实根因,2026-08-15)
排查时三层根因别混,前两层在 oracle3 侧(已解决),第三层在 ChatGPT 侧(本次真凶,已实测):
-
架构坑(已解决,oracle3 侧):早期把 filesystem 与 shell 拆成
mcp.commands[]两个并行 command,tunnel-client 只注册第一条,ChatGPT 永远只看到 filesystem 工具。→ 已改为单个combined-mcp.mjs(同tools/list合并返回),profile 仅一条 command 指向run-combined.sh。 -
OpenAI 连接器 schema 校验坑(已解决,oracle3 侧):即便合并成单 server,ChatGPT 仍只看到 14 个 filesystem 工具、
run_command消失。抓tools/list比对发现——官方工具带title/annotations/execution/outputSchema及inputSchema.$schema,run_command当初只写了name+description+inputSchema,缺字段被连接器静默丢弃。→ 已在combined-mcp.mjs落地修复:RUN_COMMAND_TOOL完全镜像 filesystem 字段形状;合并时一并过滤掉废弃的read_file,使总数稳定在 14(13 filesystem +run_command)。直驱tools/list实测已返回含run_command的 14 工具。 -
ChatGPT Business 的 app action 快照冻结(真凶,2026-08-15 实测确认):即便 oracle3 侧已 100% 正确(
tools/list已返回含run_command的 14 工具、healthz/readyz200、tunnel 已连),ChatGPT Business 已发布的 custom MCP app 仍只显示旧快照(含read_file、无run_command)。OpenAI 官方:custom MCP app 批准/发布后,ChatGPT 使用一份冻结的工具 + 输入 schema 快照,开发者改 server 不会自动更新已批准的 app。- ❌ 无效操作:app 详情页点「重新连接 / Reconnect」、在 Connectors 里「卸载→重装」插件、刷新会话。这些只重连链路或重建连接,不会重抓 action 快照。(用户实测:卸载重装旧
agent后仍只有 14 filesystem 工具。) - ✅ 正确操作(Business 官方支持的唯一更新方式):保留旧 app 不删,去 Workspace Settings → Apps → Create 新建一个 custom MCP app(本次命名为
agent-v2),仍选同一条 Tunneltunnel_6a7dcd7f3f348191b9d07ca771a3d2c0;创建过程中 ChatGPT 会重新从 live MCP server 拉取 actions,此时应看到 diff:read_file消失、run_command出现;确认列表正确后 Publish,再连接agent-v2、开新会话测试。 - ✅ 实测结果(2026-08-15):用户按上述重建
agent-v2后,run_command成功出现并可用,本链路(filesystem + shell)在 ChatGPT Business 下完整成立。旧agent(App IDasdk_app_6a7dd7b80ebc8191a78f043dfbddd46e)为旧快照,验证新 app 稳后可删。 - 注:Enterprise/Edu 走 Workspace Settings → Apps → … → Action control → Refresh 即可原地刷新;但 miracle-maker 是 Business,不支持原地刷新,只能 recreate + republish。
- ❌ 无效操作:app 详情页点「重新连接 / Reconnect」、在 Connectors 里「卸载→重装」插件、刷新会话。这些只重连链路或重建连接,不会重抓 action 快照。(用户实测:卸载重装旧
[!tip] 一句话记忆 oracle3 改了 server ≠ ChatGPT 自动更新。Business 下要让新工具生效,必须在 Apps 里「重新创建」一个 app,而不是「刷新/重连/重装」旧 app。
[!note] 验证手段 在 oracle3 上
node /tmp/...mjs跑一段 stdio 客户端发initialize→tools/list,可看到合并 server 实际返回的工具名与每个工具的字段。2026-08-15 实测返回 14 个:read_text_file, read_media_file, read_multiple_files, write_file, edit_file, create_directory, list_directory, list_directory_with_sizes, directory_tree, move_file, search_files, get_file_info, list_allowed_directories, run_command,且run_command含title/annotations/execution/outputSchema。
⚠️ filesystem 作用域过宽,凭证可被 ChatGPT 读取(安全,2026-08-15 提出)
当前 filesystem MCP 作用域是 /home/ubuntu(整个 home),而 ~/bodysense-tunnel/.env(含 OpenAI runtime key,mode 600)也在其内。经实测,ChatGPT 能直接读取到这个 .env——也就是说一旦 agent-v2 连上,任何能调用该 app 的会话都能读到这把 key。
建议(待办,未执行):
- 立刻 rotate/revoke 那把 runtime key(在 Runtime API keys 撤销,再发新 key 写回
.env); - 把 filesystem +
run_command的作用域收窄到项目目录,例如/home/ubuntu/projects或/home/ubuntu/projects/bodysense,不要把~/.ssh、~/.config、.env及各种凭据与项目源码一起暴露给通用 filesystem + shell MCP; - 修改 scope 后需重新创建 app(Business,见上)才能生效。
对照:oracle2 实例(见上「oracle2 实例」一节)用代理层黑名单从根上解决了这个问题——其自身
.env也在/home/ubuntu下,但被.env黑名单命中,ChatGPT 无法通过该桥读取 runtime key。
run_command 报 pytest: command not found
oracle3 默认 pytest 不在 PATH(实测 python3 3.12.3 在,但 pytest 未装/未激活 venv)。解决:在 run_command 的命令里先激活虚拟环境(如 source ~/projects/bodysense/backend/.venv/bin/activate && pytest …)或 pip install pytest;具体命令以 BodySense 仓库 README/CONTRIBUTING 为准。
工具调用失败 / 超时
tunnel-client 没在跑(oracle3 重启后 systemd —user 服务未起,或 linger 未开)。systemctl --user status bodysense-tunnel 看状态。
oracle3 赠金到期(约 2026-08-18)
oracle3 是 300 美元赠金开的按需实例,到期销毁后本链路随之中断(届时 ~/projects/bodysense 工作区也没了,代码以 GitHub 为主副本)。若需续用,先决定销毁/降配/绑定付费方式,再按本笔记重新拉起 daemon。
回滚
ssh oracle3 'systemctl --user disable --now bodysense-tunnel';- 在 Platform 撤销 runtime key;
- 保留 Tunnel record 以便诊断,确认不再使用后由管理员删除;
- 本地 KB 的 tunnel-client 不受影响,二者独立。