← [ BACK_TO_NOTES ]

Modern ChatGPT Local MCP Agent Runtime 架构

把 ChatGPT Local MCP 从长同步 remote-shell bridge 演进为短 RPC、持久化 Job、背压、有界数据面与可观测性的 Agent Execution Runtime。

#synthesis #growing #ai #mcp #chatgpt #architecture #ops

[!info] related notes

  • 所属 MOC: mcp-moc
  • 相关概念:
  • 易混淆概念:
  • 相关资源:

Modern ChatGPT Local MCP Agent Runtime 架构

范围

这篇笔记解释的是 ChatGPT 通过 Secure MCP Tunnel 操控本地或私有开发主机时,执行层应该怎样设计才稳定。

它不重新解释 MCP 协议本身,也不重复 Tunnel 的开户和 UI 配置步骤;配置流程见 connect-local-mcp-to-chatgpt-with-secure-tunnel。

[!note] 名词 用户口语里的 “Local NCP” 在这里指 Local MCP(Model Context Protocol)。本文保留 “Modern ChatGPT Local NCP” 作为 alias,避免以后搜索不到。

核心结论

最初的本地 MCP 往往只是:

ChatGPT
  → Secure MCP Tunnel
  → stdio MCP Server
  → filesystem / run_command

这已经能“远程动手”,但如果把构建、全量测试、Agent、递归搜索都直接塞进单次 tools/call,它仍然只是一个 remote-shell bridge。

更成熟的运行模型是:

短同步控制面 + 持久化任务执行面 + 有界数据面 + 背压 + 可观测性。

也就是把 MCP 从“远程命令管道”提升为 Agent Execution Runtime。

从旧模型到 Modern Runtime

旧模型:

Tool call = Task lifecycle

run_command("pnpm test")
  ↓
MCP request 一直悬着
  ↓
shell 结束
  ↓
返回全部 stdout/stderr

只要命令时间变长,ChatGPT、Tunnel、stdio 与 shell 的多个 deadline 就开始互相耦合。

Modern 模型:

Tool call ≠ Task lifecycle

job_start
  ↓
快速返回 job_id
  ↓
RPC 结束

detached process
  ↓
继续执行、落盘日志和状态

job_status / job_output
  ↓
通过新的短 RPC 继续观察

这使网络请求的寿命不再决定任务本身能活多久。对应实现见 mcp-persistent-job-manager。

三个平面

Control Plane:控制面

负责启动任务、查询状态、取消任务、获取一个有界结果窗口、工具发现和健康检查。

要求:快、小、可预测、有 backpressure。MCP RPC 主要属于这一层。

Execution Plane:执行面

负责真正耗时的构建、全量测试、Docker build、Coding Agent、数据迁移和长脚本。

它允许慢,但不能依赖一个长时间保持的 MCP request。

Data Plane:数据面

负责文件内容、搜索结果、directory tree、stdout/stderr 和 Job 日志。

要求分页、截断、有时间预算、有条目或字节预算。对应设计见 mcp-bounded-tool-io。

为什么“只把 timeout 调大”不够

一条工具调用实际穿过:

ChatGPT / hosted orchestrator
        ↓
Secure MCP Tunnel control plane
        ↓
tunnel-client
        ↓
stdio MCP
        ↓
local shell / filesystem

每层都可能有自己的 deadline。尤其是控制面可能已经把 command 下发并开始计时,而请求还在本地队列等待。

所以“本地执行 40 秒”并不等于“上游只消耗 40 秒”。完整机制见 [private note]。

Backpressure:不要让队列提前消耗请求寿命

Modern runtime 不追求“能开多大并发”,而是让下发速度与执行能力匹配。

当前 broad-agent 经验基线:

control-plane inflight = 1
MCP concurrency        = 4

控制面不提前塞入一长串 command;MCP server 对短操作仍保留有限并发。底层通用原理见 backpressure。

短同步 RPC 与长任务 Job 化

当前 broad-agent 基线:

sync default  = 20s
sync hard max = 30s

适合同步:pwd、git status、git diff、小范围 grep、快速文件操作、小测试。

优先 Job:安装依赖、全量测试、构建、大型检查、Coding Agent、未知耗时脚本、持续产生日志的任务。

20/30 秒不是协议真理,而是当前 ChatGPT + Tunnel 链路中用来给上游留下余量的工程参数。

Bounded I/O:工具调用必须有最坏成本

成熟 MCP 工具不应该存在无限递归、无限输出、无限结果、无限文件读取。

当前实践包括:

  • recursive search 有时间预算;
  • scan entries 有上限;
  • search result 有上限;
  • 默认跳过 .git、node_modules、build/cache 等重目录;
  • stdout/stderr 单流限制;
  • 大文件与日志使用 offset / next_offset;
  • 达到限制时显式返回 truncated。

这不只是性能优化,也是模型上下文治理。

stdio 生命周期正确性

本地 stdio MCP 的典型初始化顺序是:

initialize
  ↓
notifications/initialized
  ↓
tools/list
  ↓
tools/call

在 Tunnel 重建子进程时,如果生命周期不完整,会出现 MCP server is not initialized。

当前实践在 profile 中启用 initialized notification shim,让 tunnel-client 重建 stdio session 后补齐生命周期。

Secret 边界

Modern runtime 的安全目标不是“所有机器都用同一种 secret 文件”,而是保证:

secret 不进 argv
secret 不进 Git
secret 不进知识笔记
secret 不进普通日志

Windows / WSL 可以使用 ACL 限制的 secret file;Linux systemd 可以通过 EnvironmentFile 或受控环境注入。统一的是安全 contract,不是实现形式。

Observability:能回答“到底是哪一层坏了”

工具层至少应该记录 tool_start、tool_end、tool_fail、tool name、request id、duration、error class,以及按需记录 truncation / result size。

默认不记录 raw args,避免 command、文件内容、prompt、token 泄漏。

有了结构化日志后,才能区分 Hosted response stream、Tunnel command deadline、stdio lifecycle、MCP tool timeout、filesystem budget 和 shell timeout,而不是把所有现象都叫“MCP 卡了”。

Source of Truth:现场热修不算完成

如果线上已经改成 20/30 秒 + Job Manager,但基础设施模板仍是旧版 90 秒同步 shell,那么下一次重建就会把故障重新部署回来。

完整闭环:

live diagnosis
  ↓
hotfix
  ↓
smoke verification
  ↓
canonical source update
  ↓
reconcile / install script
  ↓
future rebuild

对应实施规范见 mcp-agent-reliability-baseline。

不同 MCP 不应机械复制同一套参数

Broad shell agent

能执行 shell,耗时高度不确定,需要 Job 和严格 backpressure。当前实践:

inflight = 1
concurrent = 4
sync = 20/30s

Knowledge MCP

搜索、读笔记通常短,工具语义窄,不存在通用长 shell。可以使用更高短请求并发,不必实现通用 Job Manager,重点做 read/search/result budget。

Thought Forest 当前实践:

inflight = 4
concurrent = 8

这体现一个重要原则:统一 reliability contract,不机械统一所有 runtime 参数。

2026-10-01 实践效果

Oracle2

旧生命周期曾累计观察到 MCP TTL 16 次、response deadline 16 次、stdio MCP failed 14 次、file already closed 14 次、systemd restarts 54 次。

完成 runtime 改造并重新开始服务生命周期后,当前观察窗口中的这些关键错误为 0,服务重启计数也保持 0。

WSL

完成短同步上限、Job Manager、有界 filesystem、secret argv 修复与 initialized shim 后,新生命周期关键 Tunnel/stdio 错误为 0。

请求 timeout_ms=60000 不再继续等待,而是立即拒绝并提示改用 Job API。

GCP

仅升级 tunnel-client 并把同步上限设为约 60 秒后,历史上仍观察到 17 次 response deadline。

继续分析后才发现核心问题是“长同步 RPC + queue deadline consumption + 预取”。进一步收紧为 20/30 秒并加入 control-plane backpressure 后,新生命周期关键错误为 0。

因此真正有效的不是“升级版本”,而是改变运行模型。

架构图

                    ChatGPT
                       │
                       ▼
                Secure MCP Tunnel
                       │
               ┌───────┴────────┐
               │ Backpressure   │
               │ bounded queue  │
               └───────┬────────┘
                       │
                       ▼
                Modern MCP Server
          ┌────────────┼─────────────┐
          │            │             │
          ▼            ▼             ▼
      Short RPC    Bounded I/O   Job Manager
       <= budget    pagination    durable state
          │            │             │
          ▼            ▼             ▼
        shell      files/search   detached process
                                      │
                               status/log/exit

决策规则

如果一个新工具执行时间不可预测、可能扫描大量对象、可能输出大量文本、会创建子进程、需要在恢复后继续观察,或者结果可能超过模型合理上下文,就应先设计 runtime contract,再暴露给模型。

不要先写出“能工作的 tool”,再把可靠性全部交给调用者。

学习检查

  1. 为什么 Modern MCP 的核心不是 tunnel-client 版本升级?
  2. Control Plane、Execution Plane、Data Plane 分别承担什么?
  3. 为什么 Task 生命周期不能和 MCP request 生命周期绑定?
  4. 为什么 Backpressure 会直接影响 response deadline?
  5. Bounded I/O 为什么也是 context engineering?
  6. 为什么 broad shell agent 和 knowledge MCP 不应该使用完全相同的并发参数?
  7. 怎样判断一次线上修复已经真正进入可重建的 source of truth?
创建于 2026/10/1 更新于 2026/10/1
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本