herdr-mcp源码版本 v1.1.0-rc.2

故障排查

从本机到网页逐层定位问题,再决定是否需要重启。

herdr-mcp 的链路横跨本机 runtime、Herdr、workstation link、Cloudflare Edge、OAuth、MCP 和浏览器。排障时先确认故障所在层级,避免一开始把所有组件全部重启。

推荐始终按这个顺序:

Herdr
  ↓
local herdr-mcp runtime
  ↓
workstation link
  ↓
Cloudflare Edge
  ↓
OAuth / MCP
  ↓
ChatGPT tool snapshot
  ↓
browser continuity

前一层不通,就先不要猜后一层。

30 秒快速定位#

1. 本机 HTTP 在吗#

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8772/

200 或 401 都说明进程正在监听。连接失败才表示本地 runtime 没起来、端口不对或进程异常。

macOS LaunchAgent:

herdr-mcp status
herdr-mcp logs

2. Herdr 在吗#

herdr --version
herdr api schema >/dev/null

如果本地 HTTP 正常但 herdr_inspect 看不到任何真实 workspace,继续检查 HERDR_SOCKET_PATH 和 Herdr daemon,先不要重装 ChatGPT Connector。

二进制已安装但 shell 找不到吗#

ls -l ~/.local/bin/herdr-mcp
zsh -ic 'command -v herdr-mcp'
zsh -lc 'command -v herdr-mcp'

二进制存在但 command -v 为空时,状态是 installed_but_not_on_shell_path。当前进程先执行 export PATH="$HOME/.local/bin:$PATH"。zsh 使用 line='export PATH="$HOME/.local/bin:$PATH"',再执行 grep -Fqx "$line" "$HOME/.zprofile" 2>/dev/null || printf '\n%s\n' "$line" >> "$HOME/.zprofile",保证只写入一次。不要重复安装,也不要创建第二个 PATH owner。

3. Edge 能看到 workstation 吗#

检查 Edge /health / workstation status。OAuth 可以在 workstation 离线时仍然成功,所以“登录成功”不能证明本机已经连上。

Link 复用环境里已有的代理配置,解析顺序:

HERDR_LINK_PROXY > HTTPS_PROXY/https_proxy > HTTP_PROXY/http_proxy > ALL_PROXY/all_proxy
  > macOS 系统代理(scutil --proxy:HTTPS、HTTP、SOCKS)

workers.dev 不可达时,这些细节值得先确认:

  • 支持 socks5:// 与 socks5h://。SOCKS5 拨号使用 remote-DNS 语义:域名不经本地解析、直接交给代理解析,本地 DNS 污染不会影响 workers.dev 连通性。
  • 不支持代理认证(HTTP Basic、SOCKS5 用户名密码);带内嵌凭据的代理 URL 会被拒绝,凭据也不会出现在 status 或错误输出里。
  • macOS 上会检测 PAC 配置但不会执行:Link 不拉取、不运行 PAC 脚本;只配置了 PAC 时 Link 直连。
  • 不要用关 TLS、改系统代理、把 Link 变成通用转发这类方式去“修”连通性。

4. 新 ChatGPT 会话有当前工具吗#

当前 first-party DEV/PROD 的 ChatGPT 公共 contract 是 epoch 8 / 19 actions。workstation execution 是 epoch 5 / 18 tools,其中包含 herdr_skill;额外的公共 action 是只在 Edge 执行的 herdr_devices。紧邻上一代冻结的 epoch 4 与冻结的 epoch 2 catalog 仅作为有界的 rollback/compatibility 基线保留,epoch 3 仅属历史,公共 Edge epoch 3 身份仍作为非 DEV/PROD 的有界基线保留。

旧聊天可能保留旧 tools/list 快照。确认服务端版本后,优先刷新 App/Connector actions(如果当前 ChatGPT UI 提供)并新开会话,不要先重装本机 runtime。

症状:Connector 添加失败或 OAuth 循环#

优先检查:

  • MCP URL 是否是 https://<stable-origin>/mcp;
  • HERDR_MCP_BASE_URL / OAuth issuer 是否使用同一个 origin,且不带 /mcp;
  • protected-resource / authorization-server / OpenID metadata 是否可访问;
  • Cloudflare Worker 是否真的是你以为的那一份部署;
  • Workspace 是否允许 Developer mode / custom MCP App。

如果 OAuth token 已成功签发但随后失败,问题通常已经从“认证”进入 MCP discovery / workstation routing,不要继续围绕登录页面打转。

详见 ChatGPT Connector。

症状:Connector 显示已连接,但聊天里 0 tools#

这说明“安装 Connector”和“当前聊天接受 tool catalog”不是一回事。

按顺序检查:

  1. 新会话;
  2. 服务端当前 contract/version;
  3. tools/list 是否成功;
  4. 是否有一个不兼容 inputSchema 导致整张 catalog 被客户端拒收;
  5. 是否仍是老 conversation 的 tool snapshot。

如果新会话拿到 18 tools,而旧会话仍是 17 tools,服务端通常没有故障,是会话缓存边界。

症状:能看到 tools,但 herdr_inspect 报 workstation offline#

这已经不是 ChatGPT tool schema 问题。如果 ChatGPT 收到了结构化 workstation_offline,说明 ChatGPT → MCP Edge 这段链路至少能够返回错误;真正不可用的是 Edge 找不到目标 workstation 的可用 Link WebSocket。浏览器扩展不参与这个错误判定。

当前恢复采用分层自愈,而不是“看到错误就全家桶重启”:

  1. 最近在线过的 workstation 刚掉线时,Edge 最多给 15 秒 process-local reconnect grace。新的 Link 通过 validated hello 回来后,等待中的原请求立即继续;这段 grace 不写 Durable Object storage,也不创建 alarm。
  2. 15 秒后仍不可用时,Edge 返回机器可读恢复信息:retryable=true、delivery_state=not_delivered、retry_after_ms=5000,并明确给出用只读 herdr_inspect 做 5s / 10s / 20s 三次 probe 的策略。
  3. 本机 Link 继续执行正常 reconnect/backoff;一旦重新进入 Online,prolonged-offline timer 立即清零。
  4. Link 连续 300 秒 都无法 Online 时,会带诊断证据退出,由 launchd KeepAlive 拉起全新的 dev.herdr-mcp.link-prod。
  5. server health watchdog 只负责真正不健康的本机 server。单独出现 workstation_offline,不应该去重启一个健康的 dev.herdr-mcp.server。

“可以恢复”不等于“mutation 可以盲重放”,判断以 delivery_state 为准:

  • not_delivered:请求明确没有送到 workstation;链路恢复后可以再次发送,有 idempotency key 时复用原 key。
  • delivery_unknown:只读调用在明确 retryable=true 时可以安全重读;mutation 必须先查状态/evidence,确认没有应用后才能重放。
  • delivered 或没有明确 non-delivery 证据:不能仅因为后续断线就再次发送 mutation。

本机按这个顺序检查:

herdr-mcp status
herdr-mcp link status
launchctl print gui/$(id -u)/dev.herdr-mcp.link-prod
tail -n 100 ~/.config/herdr-mcp/link-prod.launchd.err.log

再核对 workstation identity、active runtime generation 是否健康,以及 Edge 最近的 Link 状态。不要通过删除/重建 Connector 来修 workstation link;如果本机 server health 仍正常,也不要把 Link-only 故障升级成全局 herdr-mcp service restart。

症状:herdr_inspect 正常,但文件读写失败#

常见原因:

  • 路径既不在 managed Git root 内,也不在被 live workspace/pane cwd 精确证明的 non-Git operational root 内(借用其它项目的目录,或 live topology 未证明的 sibling,都会被拒绝);
  • 文件名被 secret-path gate 拦截;
  • HERDR_MCP_READONLY=1;
  • HERDR_MCP_WRITE_ROOTS 没包含目标仓库;
  • 文件已经 dirty,写工具要求明确确认;
  • 同一项目有 Agent 正在工作,busy gate 阻止并发写入。

先看错误返回里的 gate/reason,不要换成 shell 绕过保护作为默认解决方案。

herdr_exec 是显式的高权限边界,不具备 herdr_fs_* 的 secret-path 过滤。

症状:Herdr 控制面偶发 TaskGroup / ExceptionGroup#

表现通常是:

  • Agent 明明仍在工作;
  • 一次 inspect/snapshot/pane 操作失败;
  • 几秒后重新观察又恢复。

这类瞬时控制面错误不等于仓库坏了。

herdr-mcp 对只读路径有若干退化策略:

  • snapshot 失败时组合 list APIs;
  • Git 在安全条件下直接读取本机仓库;
  • exec 只有在命令尚未投递时才可能 fallback;
  • 已投递 mutation 永远不因为控制面错误自动双跑。

正确处理:重新 herdr_inspect / herdr_since 获取当前事实。

症状:prompt / exec timeout,不知道任务到底有没有执行#

最重要的规则:mutation 不盲重试。

herdr_prompt#

正常长任务不应让 Parent 一直等待:herdr_prompt 默认提交一次后立即返回 task_id / dispatch_id / Runtime turn_id,Parent 随即继续其它工作;Runtime 通过 herdr_mcp.agent.task.status / herdr_mcp.agent.task.inbox 持久追踪本轮任务。如果调用者显式使用兼容 wait,它等待的是这个 task_id,不是 Agent 之前遗留的 idle/done。等待超时仍不等于未投递;先看返回的 task/inbox,再决定是否重试。重复意图继续复用 idempotency_key。

herdr_exec#

如果工具明确表示已经向 pane 投递,不能因为响应超时再执行同一命令。先看 pane / Git /产生的文件 / 测试状态。

“客户端没收到成功回复”不等于“服务端没做”。

症状:本地 Agent 做完了,ChatGPT 不继续#

这是最容易被误判成 MCP 故障的情况。

MCP 完成的是:

ChatGPT → workstation

对由当前 WebChat 派出的 Agent task,Runtime 会先把 terminal 写入 durable parent inbox,再由浏览器扩展读取属于当前 browser session_ref 的 inbox 并触发下一轮 WebChat。默认不会要求 Parent 挂住当前 turn 等 Child。

如果 Agent 已结束但 ChatGPT 没继续,请确认:

  1. Native Messaging host 正常;
  2. 当前 conversation 已注册出稳定 browser_session_ref 并绑定正确 workspace;
  3. 相应 Auto scope 已开启;
  4. herdr_mcp.agent.task.inbox 中该 task 已 terminal 且未 acknowledged;
  5. 需要 Parent guidance 时用 advisory=true 读取 inbox。只有存在未 acknowledge 的 terminal work 时,Runtime 才对冻结的 child batch 最多做一次 attention 判断;verify_completion 表示进入确定性 validation,continue_unobserved 表示让独立运行的 sibling 继续。Jev 未配置、超时或报错都不会抑制确定性 terminal wake,Browser 也不再有第二层 semantic wait loop。

HUD 手动继续仍保留为显式兜底。详见 浏览器连续工作。

症状:HUD 显示了错误 workspace 名称#

绑定身份以 workspace_id 为准,label 只是展示信息。

如果 ID 正确但名称陈旧,扩展应从实时 workspace catalog 更新 label。不要为了改一个展示名称就删除正确 binding;先确认扩展已经加载当前构建并刷新页面。

如果 ID 本身错了,再重新绑定。

症状:standalone status 已是最新,但 Chrome 仍运行旧的/意外的 unpacked 构建#

这是加载路径 ownership 漂移。herdr-mcp extension standalone status 只能证明 Herdr 在磁盘上管理的是哪份副本,不能证明已经配置过的 Chrome profile 当前到底从哪个 unpacked 目录加载。macOS 上执行:

herdr-mcp doctor

如果默认 doctor 摘要提示 standalone 扩展加载路径漂移,运行 herdr-mcp doctor --verbose 查看 expected 与 actual 路径;机器读取可用 herdr-mcp doctor --json,其中 standalone_extension 提供同样的证据,包括 Chrome profile 和 drift_count。打开 chrome://extensions,找到 Herdr,按 expected_path(通常是 ~/.config/herdr-mcp/extensions/standalone/current)重新 Load unpacked/Reload,然后再次运行 doctor。除非另有证据证明 Native Host identity 也有问题,否则不要顺手切换 Native Host ownership 或删除扩展数据。这个 doctor 探针是只读的,只检查 Chrome preferences 中 Herdr 固定 extension ID 的精确条目。

症状:浏览器控制中心打不开、没有 workspace,或一直显示本机运行时不可用#

先区分 Side Panel UI 问题、Native Messaging 身份问题 和 runtime 问题:

  1. 点击 Herdr 工具栏图标,确认 Chrome 直接打开 Control Center Side Panel;不要把 control-center.html 当普通网页直接访问;
  2. herdr-mcp status / herdr-mcp doctor 应该先证明本机 runtime 正常;
  3. herdr-mcp native-host status 应显示 Native Messaging host 已注册;
  4. Chrome 刚更新商店扩展后,刷新受影响网页(必要时重启 Chrome),让当前 content script 重新加载;
  5. herdr-mcp native-host status 应显示用户明确选择的扩展 identity/channel,并确认 Native Host runtime 与当前 runtime generation 一致。当前 runtime 支持 STORE / STANDALONE / DEV;更老的 runtime 可能只暴露部分通道。出现 origin mismatch 时不要猜测另一个通道并直接覆盖;先检查当前 runtime 实际支持的命令和 Chrome 中真实安装的扩展身份;
  6. 顶部如果显示“运行时正常 · 事件流正在重连”,说明已有 snapshot,但增量事件正在恢复,不等于整个 runtime 离线;可以先点刷新让 Side Panel 做一次权威 reconciliation。

Control Center 的发送指令会走本地可信控制链真实执行;调整当前任务会返回真实 provider capability/outcome,绝不会偷偷降级成 Prompt。普通终端可以通过有 target fencing 的 pane.send_input + Enter 路径直接运行命令;任意 Herdr API 仍是 Preview-only。任何 mutation 返回 uncertain 时都先检查 live state 再考虑重试;Steer 返回 session_not_resolved 表示当前所选 provider session 没有可验证的 control endpoint/thread/active-turn 映射,这是 capability 结果,不是 transport 故障。

详见 浏览器控制中心。

症状:ChatGPT 回复一半停住、连接中断或显示发送超时#

不要第一反应就重新提交原用户任务。工具 mutation 可能已经发生。

当前 continuity recovery 的策略是 evidence-first:

  1. 尝试读取同源 conversation state;
  2. 如果服务端已经比 DOM 更靠前,刷新页面同步;
  3. 如果明确是请求未接受,才进行受限重试;
  4. delivery 不确定则 fail closed;
  5. 普通恢复耗尽后,才考虑 handoff/rollover。

如果自动恢复没有证据可用,可以人工刷新后用 HUD 的 herdr监控 先重新获取本地状态,再继续。

详见 自动继续、恢复与接力。

症状:ChatGPT “排队”后没有立即发送,或排队内容还留着#

“排队”的设计目标就是不立即发送:assistant 仍在回复时,内容应该留在当前 conversation 的持久队列,等 turn settled 后再优先于通用 auto-continue 发送。

检查:

  • 当前页面是 ChatGPT;其它站点目前没有同一套 Queue UI;
  • assistant 是否仍处于 generating / tool / permission-card 状态;只要 turn 仍在进行,队列就不应强行发送;
  • turn-in-progress 或提交未确认时,队列不会 ACK 删除,这是为了避免丢消息;
  • composer 为空时再次点击“排队”可以尝试重发仍待交付的 batch;
  • 右键“排队”会明确清空当前 conversation 队列;
  • handoff 成功后,未发送内容会迁移到新 conversation,不应该在旧 conversation 重复发送。

如果队列在没有确认 delivery 的情况下消失,才属于可靠性问题;记录 conversation、当前 turn 状态和浏览器 console 后提 Issue。

症状:手动接力不可用#

直接使用页面 HUD 的“接力”。如果入口不可用或被禁用,再确认:

  • 当前站点/会话类型支持 handoff;
  • 当前作用域可以是 自动 开 或 自动 关;目标会话会继承源会话 Auto 状态;
  • 如存在已绑定 workspace,它没有仍处于 working 的 Agent;
  • 没有已经进行中的 transfer。

接力必须先生成 packet、建立新 conversation、确认 seed 存在,再执行 cutover。如存在 workspace binding,只能在这之后切换或迁移 binding。如果停在“恢复接力”,不要手工解绑已有 binding;它在 cutover 完成前是安全锚点。

症状:z.ai / DeepSeek 输出 JSON tool call 后停住#

这属于 JSON→MCP bridge,不是 ChatGPT Connector。

检查:

  • Native Messaging host;
  • 本机 MCP catalog 是否可取;
  • 当前 conversation identity 是否稳定;
  • assistant 最后一条真实消息是否仍是 tool-call JSON;
  • bridge round 是否有工具结果回填;
  • 页面刷新后是否仍保留足够 bridge context 进行恢复。

不要把内部 tool-call JSON 当作最终自然语言答案。详见 JSON → MCP Bridge。

症状:Chrome 提示“设备上的应用”/loopback 权限#

Chrome/Chromium 对本机 loopback 网络可能要求单独授权。

进入扩展管理页面,检查该扩展的网站/本地设备访问权限。Native Messaging 是主链路,但某些诊断/兼容路径仍可能触发 loopback 权限提示。

如果 Options 的连接测试一直 pending,先排这个权限,而不是轮换 Herdr 凭据。

症状:Cloudflare 部署失败#

先分清是哪一类:

  • 凭据失败:Cloudflare API 权限/identity;
  • 构建失败:Edge TypeScript/test;
  • Worker 部署成功但 health 失败:配置/runtime link;
  • workers.dev 正常但 Custom Domain 失败:domain/route/DNS 层。

最小权限凭据见 Cloudflare Edge 凭据,部署结构见 Cloudflare Edge 部署。

不要为了一个 route/DNS 问题扩大长期 Worker token 为账号管理员。

症状:Runtime 升级后出问题#

如果只是同一 contract epoch 内的新 runtime implementation:

bin/herdr-runtime-generation status

确认 active/previous generation,再按 Runtime A/B 回滚。

如果 tool catalog / contract epoch 改了,这不是普通 A/B 问题,必须按 contract migration 单独处理。不要用 herdr-self-update 偷跨 epoch。

日志和 Issue 最有用的信息#

比“不能用了”更有价值的是:

  • 当前 boot_id;
  • runtime version / contract epoch;
  • workstation id;
  • 出错的具体 tool;
  • failure / failure_phase / delivery_state;
  • mutation 前后是否看到 Git/pane/Agent 状态变化;
  • Edge /health 是否看到 workstation;
  • 新会话还是旧会话;
  • 浏览器扩展是否绑定正确 workspace。

注意清理 token、OAuth JWT、Cloudflare secret 和项目敏感内容后再提交日志。

最后再考虑重启#

有些错误当然可以通过重启恢复,但排障时最好先抓住事实:

  1. 记录当前状态;
  2. 确认故障层;
  3. 再只重启相关组件;
  4. 重启后重新验证这一层和下一层。

这样不会把“偶发好了”误认为“根因已经修复”。

文档

搜索 herdr-mcp

输入以搜索文档。