把本地 Claude Code CLI 包装成 MCP 服务器——异步任务模型、持久化 session、飞书回调通知。本报告梳理架构、调用链与通知回传身份逻辑。
三层结构:MCP 客户端 → bridge daemon → Claude CLI 子进程 + 飞书回调。daemon 以 HTTP 模式常驻,所有客户端共享同一任务注册表。
两种接入方式。生产环境用 HTTP daemon 模式,所有客户端共享一个任务注册表和 Session Store。
一个进程服务一个 MCP 客户端。进程退出,所有任务记录消失(纯内存注册表)。适合 Cursor / Claude Desktop 单机直连。
所有客户端共享同一任务注册表 + SessionStore。launchd 守护进程常驻,监听 127.0.0.1:8787。Hermes 和 Pi 同时可见对方的任务。
4 个模块分工明确。Notifier 是回调身份问题的唯一来源。
封装 claude CLI 子进程,把 stdout NDJSON 转成 AgentEvent 异步迭代器流。
内存注册表。每个 task 独立事件缓冲(最多 5000 条)+ waiters 队列,供 claude_wait 长轮询。
持久化 Claude session ID 到 sessions.json。重启后可用 session_id 续传对话。
任务完成/失败时 fire-and-forget 调 lark-cli。身份由 as_identity + lark_home 共同决定。
从 Hermes 发起到飞书收到通知卡片的全流程。claude_run 立即返回 task_id,Claude 在后台持续跑。
发起方 → Bridge
mcp_cc_claude_run传入 prompt、cwd、model、session_id(续传)、notify_target(回调配置)
校验 cwd-root 约束 → 生成 UUID task_id → 调用 TaskRegistry.start()
claude -p <prompt> --output-format stream-json ,stdout 持续推送 JSON 事件
task_id(不阻塞)Hermes 拿到 task_id 后可用 claude_status / claude_wait 轮询进展
text_delta 累加文本 · tool_use 更新 currentTool · agent_end 触发状态变 done/error → 释放 waiters → 触发 Notifier
回调通知卡片内容
task_id · cwd · model
duration · tools 数 · tokens · cost · 最后 1500 字输出
消息路由规则(anchor 优先)
| 条件 | 命令 | 效果 |
|---|---|---|
anchor_msg_id + reply_in_thread:true | +messages-reply --reply-in-thread | 进话题 thread |
anchor_msg_id,无 reply_in_thread | +messages-reply | Reply 主聊流 |
无 anchor,有 chat_id | +messages-send --chat-id | 发群主聊 |
| 两者都没有 | — | 静默丢弃,只打 warn |
as_identity(默认 "user")+ lark_home 共同决定飞书里谁在发通知消息。这也是"有时 user 有时 bot"的根本原因。
lark_home: "~/.hermes" + as_identity: "user"
lark_home: "~/.pi" + as_identity: "user"
as_identity: "bot"(任意 lark_home)
lark_home,as_identity 走默认 "user"
as_identity: "user" + 主聊 + 群在 gateway 监听
触发条件(三条并成立):
① as_identity: "user" ② reply_in_thread: false(发主聊) ③ 目标群在 gateway 监听中
真实案例:2026-06-25 01:31,pi-yunzhan 群,notify_target 三条同时命中,session 20260625_013140_e0ab8582 被开,Hermes 懵逼查了 thread/task,01:34 主动回复。
通知进话题,gateway 通常不监听 thread 子消息,不会误触发
gateway 识别为自家 bot 消息,直接 ignore,不开新 session
reply_in_thread=false 时,必须配 as_identity="bot"。禁止 user + 主聊 + 被监听群三条同时出现。
7 个工具。异步任务模型:claude_run 立即返回,claude_status / claude_wait 轮询,claude_cancel 终止。
| 工具 | 功能 | 关键参数 |
|---|---|---|
claude_run | 启动异步任务,立即返回 task_id | prompt · cwd · model · session_id · notify_target |
claude_status | 获取任务快照(文本 / 状态 / 计数器) | task_id |
claude_wait | 长轮询新事件,chunk-by-chunk 流式 | task_id · from_seq · timeout_ms |
claude_cancel | SIGTERM → SIGKILL 终止任务 | task_id |
claude_list | 列出所有任务(运行中 + 已结束) | — |
claude_forget | 从内存删除已结束任务记录 | task_id |
claude_sessions | 列出持久化 session,可用 session_id 续传 | — |