← [ BACK_TO_NOTES ]

MCP 持久化 Job Manager

解释为什么长任务不应绑定单次 MCP RPC,以及如何用持久化 Job 状态、日志和取消语义把任务生命周期与请求生命周期解耦。

#concept #growing #ai #mcp #architecture #ops

[!info] related notes

MCP 持久化 Job Manager

一句话定义

MCP 持久化 Job Manager 是一种把“启动长任务”和“等待长任务完成”拆开的执行模式:MCP 工具调用只负责快速创建、查询、读取或取消 Job,真正的构建、测试、Agent 运行等长任务由独立进程继续执行。

核心不变量是:

MCP request lifecycle ≠ task lifecycle

网络请求可以结束,任务仍然继续;下一次 MCP 调用通过 job_id 恢复观察和控制。

为什么同步 run_command 不适合长任务

最朴素的远程 shell MCP 往往这样工作:

ChatGPT
  → tools/call(run_command)
  → tunnel
  → stdio MCP
  → shell process
  → 等 shell 完成
  → 返回 stdout/stderr

如果命令需要几秒,这很简单;如果需要几分钟,请求会同时占住多层生命周期:

  • ChatGPT / hosted orchestrator 的工具等待;
  • Secure MCP Tunnel 的 command response budget;
  • stdio request;
  • shell timeout;
  • stdout/stderr 缓冲。

任意一层先过期,都会出现“远端任务可能还在跑,但本次 RPC 已经失效”的状态。继续单纯提高 timeout,只会把一次请求变得更长,并不能消除跨层 deadline 不一致。

Job 模型

一个最小、稳定的工具面通常包括:

工具作用
job_start创建任务,快速返回 job_id
job_status查询 running / completed / failed / cancelled
job_output分页读取 stdout/stderr 或统一日志
job_cancel终止任务及其进程组
job_list查看近期或当前任务

典型流程:

job_start("pnpm test")
  ↓
job_20261001_xxx

MCP RPC 结束
  ↓
任务继续执行

job_status(job_id)
  ↓
running

job_output(job_id, offset=0)
  ↓
返回一段日志 + next_offset

job_status(job_id)
  ↓
completed, exit_code=0

Job 需要持久化什么

至少应保存:

job_id
command / command 摘要
cwd
created_at
started_at
finished_at
status
pid / process group
exit_code
stdout/stderr 日志位置
cancelled_at

“持久化”不一定意味着数据库。对单机开发 Agent,一个类似下面的目录已经足够:

~/.local/state/<agent>/jobs/
  <job-id>/
    meta.json
    output.log
    exit-code

关键不是存储技术,而是Job 状态不能只存在于发起那次 RPC 的内存栈里。

为什么要使用独立进程组

如果长任务通过 shell 又拉起子进程:

shell
 ├─ pnpm
 │   ├─ node
 │   └─ worker
 └─ test runner

只 kill 最外层 PID 可能留下孤儿进程。因此 Job Manager 应创建独立 process group,并在取消或超时时终止整个组。

这使 job_cancel 的语义接近:

取消这次执行,而不是只杀掉一个父 shell。

日志为什么要分页读取

如果 Job 已经跑了十分钟,把完整日志一次性返回会重新制造一个“大 RPC”。

因此 job_output 应提供:

offset
limit
next_offset
truncated / eof

这和文件分页读取是同一原则:长生命周期和大数据量都不应绑在单次 MCP response 上。

Job Manager 不解决什么

它不负责:

  • 业务工作流编排;
  • 跨机器分布式调度;
  • exactly-once;
  • 自动重试所有失败;
  • Agent 的高层计划。

如果需要跨服务、跨主机、事务补偿、长期数小时/数天工作流,应该进一步考虑队列系统、CI runner、Temporal 等更完整的任务系统。

MCP Job Manager 的定位更窄:

给本地或单机远程 Agent 提供一个可靠的“长命令执行面”。

何时使用同步工具,何时 Job 化

经验规则:

  • 几百毫秒到几秒:直接同步。
  • 可确定在较短预算内结束:同步。
  • 构建、全量测试、安装依赖、Coding Agent、未知耗时脚本:Job。
  • 会持续产生日志:优先 Job。
  • 用户希望稍后继续查看状态:Job。

具体秒数是运行环境的工程参数,不是 MCP 协议规范。当前 ChatGPT broad-agent 基线采用默认 20 秒、同步最大 30 秒,是为了给 Tunnel 与 hosted orchestration 留出足够余量。

学习检查

  1. 为什么“把 run_command timeout 从 60 秒调到 5 分钟”不能从根本上解决长任务问题?
  2. job_start 为什么应该快速返回,而不是等待任务进入稳定阶段?
  3. 为什么 Job 的日志仍然需要 pagination?
  4. 为什么取消长任务时要处理进程组,而不是只 kill 一个 PID?
  5. Job Manager 与 Temporal / Celery 这类工作流系统的边界在哪里?
创建于 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
关闭浮层 / 取消命令;输入框内清空文本