Claude Code 跑了 20 分钟你不在电脑前,怎么知道它完成了?
这是一个高频痛点。你启动了 SEO 审计、代码重构或者批量文件处理,然后去泡咖啡、看手机。回来一看——Claude 十分钟前就跑完了,白等。
当前有三种方案解决这个问题:
| 方案 | 原理 | 双向性 | Codex 兼容 | 部署难度 |
|---|---|---|---|---|
| Hooks 原生 | Stop 事件触发 Shell 脚本 | 单向推送 | 不支持 | 极低 |
| Channels 官方 | Bun 插件推入事件到 Claude Code 会话 | 双向对话 | 不支持 | 低 |
| Hermes MCP 反向桥接 | Claude Code 主动调用远程 MCP 发消息 | 单向(可扩展双向) | 完全支持 | 中等 |
接下来按复杂度递进,逐个拆解配置方法、适用场景和真实限制。
方案一:Hooks 原生通知

Hooks 是 Claude Code 内置的生命周期钩子系统。与通知最相关的是 Stop 事件——Claude 完成一轮响应后自动触发你预设的 Shell 命令。
核心事件
| 事件 | 触发时机 | 通知用途 |
|---|---|---|
Stop |
Claude 完成一轮响应 | 任务完成通知(最常用) |
Notification |
Claude 等待用户输入 | "回来看一下"提醒 |
SubagentStop |
子 Agent 完成 | 并行分支完成提醒 |
StopFailure |
API 错误导致终止 | 异常报警 |
最简配置:macOS 桌面通知
在 ~/.claude/settings.json 中添加:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/notify.sh"
}
]
}
]
}
}
对应的通知脚本 ~/.claude/hooks/notify.sh:
#!/bin/bash
set -euo pipefail
INPUT=$(cat)
# 防止 Hook 无限循环(连续阻塞 8 次后 Claude Code 强制覆盖)
if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then
exit 0
fi
REASON=$(echo "$INPUT" | jq -r '.stop_reason // "unknown"')
MESSAGE=$(echo "$INPUT" | jq -r '.stop_message // "Claude 已停止"' | head -c 300)
# macOS 桌面通知
osascript -e "display notification \"$MESSAGE\" with title \"Claude Code\" subtitle \"$REASON\""
# 播放提示音
afplay /System/Library/Sounds/Hero.aiff &
这个方案 5 分钟搞定,零依赖。但问题明显:你必须在电脑前才能看到通知。
Stop 事件的 JSON 输入格式
理解 Stop 事件的输入结构有助于写出更精确的通知脚本。Claude Code 通过 stdin 向脚本传入以下 JSON:
{
"session_id": "abc123",
"stop_reason": "end_turn",
"stop_message": "我已经完成了所有修改,共处理 47 个文件...",
"stop_hook_active": false
}
关键字段说明:
stop_reason——停止原因。end_turn表示正常完成,max_tokens表示达到输出上限,tool_use表示需要工具调用。通知脚本通常只在end_turn时推送stop_message——Claude 最后一条消息的文本内容,可以截取前 300 个字符作为通知正文stop_hook_active——是否已在 Hook 循环中。如果为true,脚本必须立即退出(exit 0),否则会触发无限循环。Claude Code 在 Stop Hook 连续阻塞 8 次且无进展时会强制覆盖该 Hook
Linux 用户需要把 osascript 替换为 notify-send:
# Linux 桌面通知
notify-send "Claude Code" "$MESSAGE" --icon=dialog-information
进阶:Hooks + Telegram 推送
如果需要手机收到通知,在脚本末尾加 Telegram Bot API 调用:
#!/bin/bash
set -euo pipefail
INPUT=$(cat)
if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then
exit 0
fi
REASON=$(echo "$INPUT" | jq -r '.stop_reason // "unknown"')
MESSAGE=$(echo "$INPUT" | jq -r '.stop_message // "任务完成"' | head -c 300)
TELEGRAM_BOT_TOKEN="你的-bot-token"
TELEGRAM_CHAT_ID="你的-chat-id"
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
-d "chat_id=${TELEGRAM_CHAT_ID}" \
-d "text=Claude Code [${REASON}]: ${MESSAGE}" \
> /dev/null 2>&1 &
Hooks 方案的局限
- 单向通知:只能从 Claude Code 向外推送,无法从手机回复控制 Claude
- 触发粒度粗:每轮响应后都触发,不仅限于"真正的任务完成"——Claude 先提交再推送,你会收到两条通知
- 依赖本地 Shell:脚本在 Claude Code 所在机器上运行,需要预装
curl、jq - 无消息历史:通知发出即完毕,没有对话上下文
- Codex 不支持:Hooks 是 Claude Code 专属功能,OpenAI Codex 无法使用
- Stop Hook 阻塞上限:连续阻塞 8 次且无进展时 Claude Code 强制覆盖该 Hook
适合场景:个人开发者、只需要简单提醒、不需要从手机回复。
方案二:Claude Code Channels
Channels(通道)是 Anthropic 于 2026 年 3 月发布的 Research Preview 功能,核心定位是将外部事件推入正在运行的 Claude Code 会话,实现手机端与本机 Claude Code 的双向对话。
架构原理
标准 MCP 流程是 Claude 主动查询外部数据。Channels 反转了这个方向:
- 标准 MCP:用户指令 → Claude → 调用 MCP Server → 返回数据 → Claude 回复
- Channels:外部消息 → Channel 插件(本地 Bun 脚本) → 推入 Claude Code 会话 → Claude 处理 → 通过 Channel 回复
每个 Channel 实质上是一个本地运行的 MCP Server,通过轮询外部平台获取消息,通过 MCP 协议的 notifications/claude/channel 事件推入 Claude Code 会话。
支持的平台
| 平台 | 发布时间 | 状态 |
|---|---|---|
| Telegram | 2026-03-20 | Research Preview |
| Discord | 2026-03-20 | Research Preview |
| iMessage | 2026-03-27 | Research Preview |
配置方法(以 Telegram 为例)
# 1. 安装插件
/plugin install telegram@claude-plugins-official
# 2. 配置 Bot Token
/telegram:configure <your-bot-token>
# 3. 启动 Claude Code(带 Channels)
claude --channels plugin:telegram@claude-plugins-official
# 4. 在 Telegram 中找到你的 Bot,发送任意消息获取配对码
# 5. 在 Claude Code 中配对
/telegram:access pair <code>
# 6. 锁定为仅允许列表
/telegram:access policy allowlist
配对完成后,你在 Telegram 发送的消息会直接进入 Claude Code 会话。Claude 的回复也会出现在 Telegram 聊天中。
核心特性
- 双向通信:从手机发消息到 Claude,Claude 的回复出现在同一聊天中
- 完整文件系统访问:Channel 消息进入的是本地 Claude Code 会话,拥有完整的文件系统和 Git 权限
- 权限远程审批:将权限弹窗转发到手机端远程批准或拒绝
- 会话状态持久:会话存续期间保持上下文
- 事件驱动:不仅限于聊天——可以接收 CI Webhook、监控告警等外部事件
Channels 的局限
- Research Preview 阶段:语法和协议可能变化
- 认证绑定:必须通过 claude.ai 或 Console API key 认证,不支持 Bedrock、Vertex
- 依赖 Bun:官方插件都是 Bun 脚本
- 需要会话存活:事件只在会话打开期间到达,不是持久后台服务
- Codex 不支持:Channels 是 Claude Code 专属功能
- 单会话绑定:一个 Channel 只连接到一个 Claude Code 会话
企业控制
Channels 提供了企业级的管控能力:
| 设置 | 用途 | 默认行为 |
|---|---|---|
channelsEnabled |
总开关 | Team / Enterprise 默认关闭,需要管理员开启;Pro / Max 用户可直接使用 |
allowedChannelPlugins |
插件白名单 | 默认使用 Anthropic 维护的白名单,非白名单插件需要加 --dangerously-load-development-channels 参数 |
Channels 与其他远程方案的区别
Anthropic 同时提供了多种远程使用 Claude Code 的方式。Channels 的定位是"外部事件推入本地会话",与其他方案的边界清晰:
| 方案 | 定位 | 文件访问 |
|---|---|---|
| Channels | 推送外部事件到本地会话 | 完整(本地文件系统) |
| Claude Code on Web | 云端沙箱异步任务 | 云端沙箱 |
| Remote Control | 从 claude.ai 驾驶本地会话 | 完整(本地) |
如果你需要的是在外面用手机向正在跑任务的 Claude Code 发消息,Channels 是最正统的选择。如果你需要的是 Claude Code 跑完后主动告诉你,Hooks 或 Hermes MCP 更直接。
适合场景:需要从手机远程控制 Claude Code、需要双向对话、纯 Anthropic 生态用户。
方案三:Hermes MCP 反向桥接

Hermes Agent(Nous Research 开源)是一个支持多平台消息网关的 AI Agent。v0.16.0 起支持 hermes mcp serve 命令,将自身暴露为 MCP Server。Claude Code 和 Codex 通过 SSH 连接远程机器上的 Hermes,按需调用 messages_send 向已连接的消息平台推送通知。

这是一种逆向桥接架构:不是让外部消息推入 Claude,而是让 Claude 在需要时主动调用 Hermes 的工具发消息。
与 Channels 的根本区别
| 维度 | Channels | Hermes MCP 反向桥接 |
|---|---|---|
| 消息方向 | 外部 → Claude Code | Claude Code → 外部 |
| 双向性 | 原生双向 | 单向通知(可通过 events_poll 读消息) |
| 运行位置 | 插件在本机运行 | Hermes 在远程机器运行 |
| 平台支持 | Telegram / Discord / iMessage | Discord / Telegram / 微信 / Slack / WhatsApp / Signal / Matrix |
| 认证依赖 | 必须 Anthropic 认证 | 无限制,任何 MCP 客户端均可调用 |
| 持久性 | 依赖会话存活 | Hermes 24/7 后台运行(launchd) |
| 工具数量 | Channel 协议(send + reply) | 10 个完整工具 |
| Codex 兼容 | 不支持 | 完全支持 |
SSH stdio 连接原理
SSH stdio 是将远程 MCP Server 暴露给本地 MCP 客户端的轻量方案。Claude Code 启动 ssh 子进程,SSH 将本地与远程 Hermes 的 stdin/stdout 透明桥接:
本地 Claude Code
│
│ 启动子进程: ssh [email protected] hermes mcp serve
│
├─ stdin ──→ SSH 隧道 ──→ 远程 hermes stdin (JSON-RPC 请求)
│
└─ stdout ←── SSH 隧道 ←── 远程 hermes stdout (JSON-RPC 响应)
优势:
- 无需开放额外端口(仅复用 SSH 22 端口)
- 复用现有 SSH 密钥认证,无需额外凭据
- 加密传输
- 对 Claude Code 而言,Hermes 就像一个本地 MCP Server——完全无感
暴露的 10 个工具
Hermes MCP 反向服务暴露了完整的消息操作工具集。通知场景主要用到前四个,其余在调试和高级交互中使用。
| 工具 | 用途 | 通知场景频率 |
|---|---|---|
messages_send |
向指定平台/频道发送消息 | 核心,每次通知必调 |
channels_list |
列出可用的消息通道和目标 | 首次配置验证时调用 |
conversations_list |
列出所有活跃对话(跨平台) | 需要精确定位目标时调用 |
messages_read |
读取对话中的近期消息 | 发通知前检查上下文时调用 |
conversation_get |
获取单个对话详情 | 偶尔使用 |
attachments_fetch |
获取消息中的非文本附件 | 偶尔使用 |
events_poll |
轮询新事件(消息、审批请求等) | 双向交互时使用 |
events_wait |
长轮询等待新事件(最长 30 秒阻塞) | 双向交互时使用 |
permissions_list_open |
列出待处理的审批请求 | 远程权限管理时使用 |
permissions_respond |
响应审批请求 | 远程权限管理时使用 |
messages_send 调用示例
这是通知场景最核心的工具。target 格式为 platform:identifier,支持人类友好的频道名称自动解析:
# 向 Discord 频道发送通知
mcp__hermes__messages_send(
target="discord:#总部",
message="SEO 审计完成,共检测到 12 个死链。报告已保存到 收件箱/运行数据/。"
)
# 向 Telegram 个人聊天发送通知
mcp__hermes__messages_send(
target="telegram:6308981865",
message="代码重构完成,47 个文件已更新,所有测试通过。"
)
channels_list 调用示例
首次配置时用来确认连接是否成功,返回所有可发送消息的通道:
# 查看所有 Discord 通道
mcp__hermes__channels_list(platform="discord")
# 返回:[{target: "discord:#总部", ...}, {target: "discord:#翔宇-官网", ...}]
# 查看所有平台的通道
mcp__hermes__channels_list()
events_poll 调用示例
如果需要实现双向交互——Claude Code 发通知后等待用户回复:
# 发送通知并告知用户可以回复
mcp__hermes__messages_send(
target="discord:#总部",
message="数据库迁移脚本已生成,是否执行?回复 yes 继续。"
)
# 轮询等待用户回复
mcp__hermes__events_poll(after_cursor=0, limit=5)
完整配置教程
前提条件
- 一台常驻机器(Mac Mini / Linux VPS / WSL 均可),已安装 Hermes Agent
- 本地开发机到常驻机器的 SSH 免密登录已配置
- Hermes 已连接至少一个消息平台(Discord / Telegram / 微信等)
如果你的 Hermes 和 Claude Code 在同一台机器上,可以跳过 SSH 配置,直接使用本地 stdio。

步骤一:部署 Hermes Agent
# 在常驻机器上安装
pipx install hermes-agent[messaging]
# 验证安装
hermes --version
# 初始化配置
hermes init
# 连接消息平台(以 Discord 为例)
# 在 ~/.hermes/config.yaml 中配置 Discord Bot Token
# 然后启动网关
hermes gateway start
# 确认运行状态
hermes gateway status
详细部署步骤参考 Hermes Agent Docker 部署实战。
步骤二:配置 SSH 免密登录
# 在本地开发机上执行
ssh-keygen -t ed25519 -C "claude-code-hermes"
# 复制公钥到 Hermes 机器
ssh-copy-id [email protected]
# 验证免密登录
ssh [email protected] "hermes mcp serve --help"
步骤三:配置 Claude Code MCP Server
编辑 ~/.claude.json,在 mcpServers 字段中添加:
{
"mcpServers": {
"hermes": {
"type": "stdio",
"command": "ssh",
"args": [
"-o", "StrictHostKeyChecking=no",
"[email protected]",
"/Users/user/.local/bin/hermes",
"mcp", "serve"
]
}
}
}
配置说明:
type: "stdio"——使用标准输入/输出作为传输协议,Claude Code 通过 stdin/stdout 进行 JSON-RPC 2.0 通信command: "ssh"——实际执行的命令是 SSHargs中-o StrictHostKeyChecking=no跳过首次连接的 host key 确认(内网环境安全;公网建议去掉此参数)- 后续参数是远程执行的 Hermes MCP 命令路径
步骤四:配置权限白名单
编辑 ~/.claude/settings.json,在 permissions.allow 数组中加入 Hermes 相关权限:
{
"permissions": {
"allow": [
"mcp__hermes__messages_send",
"mcp__hermes__channels_list",
"mcp__hermes__conversations_list",
"mcp__hermes__messages_read",
"mcp__hermes__events_poll"
]
}
}
也可以用前缀通配:"mcp__hermes" 允许所有 Hermes 工具。
步骤五:配置 Codex(可选)
如果你同时使用 OpenAI Codex,编辑 ~/.codex/config.toml:
[mcp_servers.hermes]
command = "ssh"
args = ["-o", "StrictHostKeyChecking=no", "[email protected]", "/Users/user/.local/bin/hermes", "mcp", "serve"]
startup_timeout_sec = 15.0
tool_timeout_sec = 60.0
配置说明:
startup_timeout_sec = 15.0——SSH 建连 + Hermes 初始化需要时间tool_timeout_sec = 60.0——消息发送可能需要等待网络
Codex 不需要额外的权限白名单配置。
步骤六:验证连接
在 Claude Code 中输入:
列出 Hermes 可用的消息通道
Claude 会调用 channels_list,如果返回了你的 Discord / Telegram 频道列表,说明连接成功。
步骤七:触发通知
帮我跑一下 SEO 审计,完成后通知我 Discord
Claude Code 完成任务后会自动调用:
mcp__hermes__messages_send(
target="discord:#总部",
message="SEO 审计完成,共检测到 12 个死链,报告已保存。"
)
同机配置(无需 SSH)
如果 Hermes 和 Claude Code 在同一台机器上:
{
"mcpServers": {
"hermes": {
"type": "stdio",
"command": "/Users/user/.local/bin/hermes",
"args": ["mcp", "serve"]
}
}
}
三种方案全维度对比

| 维度 | Hooks 原生 | Claude Code Channels | Hermes MCP 反向桥接 |
|---|---|---|---|
| 提供方 | Anthropic 官方 | Anthropic 官方 | Nous Research 开源 |
| 成熟度 | 正式发布 | Research Preview | v0.16.0 |
| 通知方向 | Agent → 用户(单向) | 用户 ⇆ Agent(双向) | Agent → 多平台(可扩展双向) |
| 支持平台 | 任意(Shell 脚本可达) | Telegram / Discord / iMessage | Discord / Telegram / 微信 / Slack / WhatsApp / Signal / Matrix |
| Codex 兼容 | 不支持 | 不支持 | 完全支持 |
| 部署复杂度 | 极低(一个 Shell 脚本) | 低(Bun 插件) | 较高(需独立部署 Hermes) |
| 认证依赖 | 无 | Anthropic 认证必须 | 无(SSH 密钥) |
| 持久性 | 依赖会话存活 | 依赖会话存活 | 24/7 后台运行 |
| 工具丰富度 | 无(纯脚本) | Channel 协议 | 10 个完整工具 |
| 权限远程管理 | 否 | 是 | 是 |
| 触发方式 | 自动(事件驱动) | 外部推入 | 按需调用(用户指令触发) |
| 上下文保持 | 无(通知即忘) | 是(会话内持久) | 是(Hermes 有独立记忆) |
| 维护成本 | 低 | 低 | 中等 |
真实场景对比
场景 A:Claude Code 跑 SEO 审计(30 分钟),用户去吃饭
| 步骤 | Hooks | Channels | Hermes MCP |
|---|---|---|---|
| 启动任务 | claude -p "审计 SEO 死链" |
claude --channels plugin:telegram -p "审计 SEO" |
claude -p "审计 SEO 死链,完成后通知我 Discord" |
| 用户离开 | 离开终端 | 离开终端 | 离开终端 |
| 任务完成 | macOS 通知中心弹窗 | Telegram 收到完整结果 | Discord 收到消息 |
| 用户查看 | 回到电脑看通知中心 | 手机上直接读结果 | 手机上直接读结果 |
| 追问 | 必须回到终端 | 在 Telegram 里追问 | 在 Discord 里通过 Hermes 追问 |
场景 B:Codex 跑代码重构(20 分钟)
| 方案 | 可用性 |
|---|---|
| Hooks | Codex 不支持 |
| Channels | Codex 不支持 |
| Hermes MCP | 通过 config.toml 配置,完全可用 |
Hermes MCP 反向桥接是当前 Codex 唯一可用的按需通知方案。
场景 C:多品牌内容分发通知
| 事件 | Hooks | Channels | Hermes MCP |
|---|---|---|---|
| 翔宇官网发布完成 | 一条通用通知 | 推送到 Telegram | 推送到 #翔宇-官网 频道 |
| SYL 推文发布完成 | 一条通用通知 | 推送到同一 Telegram | 推送到 #SYL-推特 频道 |
| 品牌隔离 | 无 | 弱(同一聊天窗口) | 强(物理频道隔离) |
使用场景与最佳实践
何时让 Claude Code 主动通知
Hermes MCP 的设计是按需调用——只有用户明确说"通知我"时 Claude Code 才会调用 messages_send。这种零开销设计意味着:
- 短任务(< 2 分钟):不需要通知,直接等结果
- 中等任务(2-10 分钟):看个人习惯,可以加声音提示
- 长任务(> 10 分钟):建议配置手机通知
消息 target 格式
messages_send 的 target 参数格式为 platform:identifier:
discord:#频道名称
telegram:chat-id
slack:#频道名
支持人类友好的频道名称自动解析。调用前可以先 channels_list 查看所有可用目标。
与其他 MCP 通知方案的互补
社区中还有不少专注通知的 MCP Server,各有定位:
| 方案 | 定位 | 适合谁 |
|---|---|---|
| ntfy-mcp-server | ntfy 推送,跨设备订阅话题 | 想要最简部署的个人开发者 |
| omni-notify-mcp | 全平台通知 + 双向交互 + TTS 语音 | 需要多通道但不需要完整 Agent |
| telegram-notification-mcp | Telegram 专用,Cloudflare Workers 部署 | 只用 Telegram 的用户 |
| Claude-Code-Notifier | 钉钉通知 + ActionCard 权限确认 | 国内团队使用钉钉 |
| Hermes MCP | 完整 Agent + 消息网关 + 知识库集成 | 需要 Agent 能力 + 多平台分发 |
关于 MCP 最佳实践和通知方案的选型思路,可以参考通用指南。
成本控制
Hermes MCP 反向桥接本身没有额外的 API 成本——SSH 连接走内网流量,消息发送走各平台免费 Bot API。唯一的成本是 Hermes Agent 自身的模型调用费用,但 MCP 反向服务模式下 Hermes 不需要运行推理,只做消息转发。
详细成本分析参考 Hermes Agent 成本控制实战。
进阶:Hermes 的指针架构
Hermes 最巧妙的设计决策是"指针架构(Pointer Architecture)"——它的配置文件(SOUL / MEMORY / USER)只存两类内容:
- 不可能从外部读到的行为约束
- 怎么找到外部内容的路径和方法
所有事实性内容让 Hermes 在对话中通过 read_file 现场读取。这意味着 Claude Code 改了知识库任何文件,Hermes 下次对话自动感知,零维护成本。
静态层(系统提示词,每次都在)
├── SOUL.md → 身份 + 语言规则 + "知识库路径在这"
├── MEMORY.md → 根路径 + 导航方法
└── USER.md → 极简画像
动态层(对话中按需 read_file)
├── ~/knowledge-base/CLAUDE.md → 总路由表
├── ~/knowledge-base/品牌/*/身份/*.md → 品牌详情
├── ~/knowledge-base/工具/CLAUDE.md → 工具索引
└── ... 一切以文件系统当前内容为准
这个架构对消息通知的意义:当 Claude Code 通过 Hermes 发通知到 Discord 品牌频道时,Hermes 知道该频道对应哪个品牌——因为频道的 channel_prompts 指向了知识库中的品牌目录。通知内容自动带上品牌上下文,不需要人工标注。
Hermes 运维命令速查

配置完成后,日常运维主要用这几个命令:
# 网关管理
hermes gateway status # 查看运行状态
hermes gateway start # 启动后台服务
hermes gateway stop # 停止
hermes gateway restart # 重启
# MCP 服务器管理
hermes mcp list # 列出已连接的 MCP Server
hermes mcp test <名称> # 测试连通性
# 全面诊断
hermes doctor # 自检(配置、模型、平台连接)
hermes status # 模型与 Provider 状态
# 日志排查
tail -30 ~/.hermes/logs/gateway.log # 网关日志
tail -30 ~/.hermes/logs/agent.log # Agent 日志
cat ~/.hermes/logs/gateway.error.log # 错误日志
Hermes 与 Channels 的互补关系
在实际使用中,Hermes MCP 反向桥接和 Channels 并非竞争关系,而是互补的。两者覆盖的场景几乎没有重叠:
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| Claude Code 长任务完成后手机推送 | Hermes MCP | Claude Code 主动调用,零开销,Codex 也可用 |
| 在外面手机控制本机 Claude Code | Channels | 双向对话,适合远程交互 |
| 跨品牌频道分发通知 | Hermes MCP | 品牌分区频道 + 动态路由 |
| CI/CD Webhook 触发 Claude Code 行动 | Channels | 事件驱动,适合外部系统推入 |
| 微信端收通知 | Hermes MCP | Channels 不支持微信 |
| 远程审批权限弹窗 | Channels 或 Hermes MCP | 两者都支持权限远程管理 |
最务实的搭配方式:Channels 作为双向交互的主通道(从手机控制 Claude Code),Hermes MCP 作为单向通知的专用出口(多平台、多品牌、Codex 兼容)。两者共存不冲突,也不会产生重复通知——因为触发机制完全不同。
社区中也出现了融合两种方案的项目。hermes-CCC(117 Stars)将 Hermes 的 46 个原生技能移植为 Claude Code Channel 插件,无需 OAuth、无需外部进程。这代表了两种方案融合的趋势,但目前仍处于早期阶段。
部署拓扑参考
一个典型的 Hermes MCP 反向桥接部署拓扑如下:
┌──────────────────────────────────────────┐
│ 开发机 — 主力开发环境 │
│ ├── Claude Code(多窗口并行) │
│ ├── Codex(独立窗口) │
│ └── SSH → 常驻机器 │
│ ↓ hermes mcp serve │
│ ↓ JSON-RPC over SSH stdio │
├──────────────────────────────────────────┤
│ 常驻机器 — 7x24 后台服务 │
│ ├── Hermes Agent(launchd / systemd) │
│ ├── Discord Bot(多频道) │
│ ├── Telegram Bot(私聊) │
│ └── 微信 iLink Bot(可选) │
├──────────────────────────────────────────┤
│ 用户手机 │
│ ├── Discord → 在对应频道收通知 │
│ ├── Telegram → 收到私聊通知 │
│ └── 微信 → 收到 iLink Bot 消息 │
└──────────────────────────────────────────┘
关键设计决策:
- 开发机与常驻机器分离——开发机可以关机、重启、切换网络,Hermes 在常驻机器上 24/7 运行。即使开发机断电,之前发出的通知不受影响
- SSH 免密认证——消除每次连接的交互确认。内网环境用
StrictHostKeyChecking=no即可,公网环境配置~/.ssh/known_hosts精确校验 - 多客户端共享——同一个 Hermes 实例同时服务 Claude Code 和 Codex,消息通道统一管理
如果你的场景更简单(单机开发、不需要 24/7 常驻),直接在同一台机器上跑 Hermes 和 Claude Code,省掉 SSH 配置。
常见问题排查
问题一:Claude Code 启动后 MCP Server 连接超时
现象:Claude Code 启动时报 MCP server hermes failed to start 或连接超时错误。
排查步骤:
# 1. 验证 SSH 连接
ssh [email protected] "echo ok"
# 2. 验证远程 Hermes 可执行
ssh [email protected] "hermes --version"
# 3. 验证 MCP serve 模式
ssh [email protected] "hermes mcp serve --help"
# 4. 检查 Hermes 路径是否正确(pipx 安装在 ~/.local/bin/)
ssh [email protected] "which hermes"
常见原因:
- SSH 密钥未配置免密,连接时等待密码输入导致超时
- Hermes 安装路径与
~/.claude.json中配置的路径不一致 - 远程机器防火墙阻止了 SSH 22 端口
问题二:messages_send 调用成功但手机没收到通知
现象:Claude Code 显示工具调用成功,但 Discord / Telegram 没有新消息。
排查步骤:
# 1. 在远程机器上检查 Hermes 网关状态
hermes gateway status
# 2. 检查消息平台连接
hermes status
# 3. 查看网关日志
tail -30 ~/.hermes/logs/gateway.log
# 4. 查看错误日志
cat ~/.hermes/logs/gateway.error.log
常见原因:
- Hermes 网关未启动(
hermes gateway start启动) - Discord Bot Token 过期或权限不足
- Telegram Bot 被封禁或 Chat ID 不正确
问题三:首条消息延迟明显(约 20 秒)
现象:第一次调用 Hermes MCP 时响应很慢,后续调用正常。
原因:冷启动时 SSH 建连 + Hermes 进程初始化 + 模型 API 端点探测(如果配置了智谱等国内模型,会自动探测 3 次 HTTPS 请求)。
解决办法:
- 在 Hermes 的
.env中显式设置模型端点 URL,跳过自动探测 - 在 Codex 的
config.toml中将startup_timeout_sec设为 15-20 秒 - 使用 SSH 连接复用(
~/.ssh/config中配置ControlMaster auto)减少后续连接耗时:
Host hermes-server
HostName 192.168.1.100
User user
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
问题四:Hermes 工具在 Claude Code 中不可见
现象:配置了 ~/.claude.json 但在 Claude Code 中无法调用 Hermes 工具。
排查步骤:
- 确认
~/.claude.json格式正确(JSON 语法校验) - 重启 Claude Code 使配置生效
- 检查
~/.claude/settings.json的permissions.allow中是否包含"mcp__hermes"前缀 - 使用
/mcp命令在 Claude Code 内部查看已连接的 MCP Server 列表
选型决策树

你需要 Claude Code / Codex 任务完成后收到通知吗?
├── 是
│ ├── 你用的是 Codex 吗?
│ │ ├── 是 → Hermes MCP 反向桥接(唯一方案)
│ │ └── 否(Claude Code)
│ │ ├── 你需要双向对话(从手机控制 Claude)吗?
│ │ │ ├── 是
│ │ │ │ ├── 需要微信端收通知?
│ │ │ │ │ ├── 是 → Hermes MCP(Channels 不支持微信)
│ │ │ │ │ └── 否 → Channels(Telegram / Discord / iMessage)
│ │ │ │ └── 需要多品牌频道隔离?
│ │ │ │ ├── 是 → Hermes MCP
│ │ │ │ └── 否 → Channels
│ │ │ └── 否(只需单向通知)
│ │ │ ├── 5 分钟内搞定 → Hooks + Shell 脚本
│ │ │ └── 需要多平台同时通知 → Hermes MCP
│ │ └── 需要接收外部事件触发 Claude 行动?
│ │ ├── 是 → Channels(事件驱动架构)
│ │ └── 否 → 按上面的树走
│ └── 否 → 不需要配置
核心结论:
- 最简单:Hooks,一个脚本搞定桌面通知
- 官方双向:Channels,适合远程控制 Claude Code
- 最灵活:Hermes MCP,跨客户端、跨平台、可编程
三种方案互不冲突,可以同时使用。
常见问答
Hooks、Channels、Hermes MCP 可以同时使用吗?
可以。三种方案互不冲突。实际组合例子:Hooks 负责本地声音提示(afplay),Channels 负责 Telegram 双向对话,Hermes MCP 负责向 Discord 品牌频道分发通知。根据场景灵活搭配。
Hermes MCP 反向桥接会不会影响 Claude Code 性能?
不会。hermes mcp serve 只在被调用时才通过 SSH 建立连接并启动 MCP Server 进程。日常使用中 Claude Code 不会主动调用 Hermes,只有用户明确要求"通知我"时才触发。零开销设计。
SSH stdio 连接安全吗?
SSH 隧道本身是加密的,安全等级与直接 SSH 登录相同。关键是 SSH 密钥管理——确保只有授权机器能连接到 Hermes 所在的机器。内网环境下可以使用 StrictHostKeyChecking=no,公网环境建议启用严格校验并配置 ~/.ssh/config 限制连接参数。
Channels 现在值得用吗?还是等正式发布?
如果你只需要 Telegram 或 Discord 双向对话,Channels 已经够用。Research Preview 的主要风险是 API 语法可能变化,但核心架构不太会大改。建议把 Channels 作为主方案使用,Hermes MCP 作为补充——覆盖 Channels 不支持的场景(微信、Codex、品牌频道隔离)。
没有额外服务器也能用 Hermes MCP 吗?
可以。Hermes Agent 可以部署在任何 Python 3.12+ 的机器上——Linux VPS、WSL、另一台 Mac 都行。也可以在同一台机器上运行 Hermes 和 Claude Code,此时不需要 SSH:
{
"mcpServers": {
"hermes": {
"type": "stdio",
"command": "/path/to/hermes",
"args": ["mcp", "serve"]
}
}
}
Codex 能用哪种通知方案?
OpenAI Codex 目前不支持 Hooks 和 Channels——两者都是 Claude Code 专属功能。Hermes MCP 反向桥接是当前 Codex 唯一可用的按需通知方案,通过 ~/.codex/config.toml 配置即可获得与 Claude Code 相同的通知能力。
omni-notify-mcp 和 Hermes MCP 有什么区别?
omni-notify-mcp 是专注于通知的轻量 MCP Server,提供 notify(发通知)、ask(发问等回复)、poll(轮询)等工具。Hermes 是一个完整的 AI Agent,MCP 反向服务只是它的一个功能模块。选择标准:
- 只需要通知 → omni-notify-mcp 更轻量
- 还需要 Agent 能力(知识库集成、多品牌路由、技能系统) → Hermes 更合适
Stop Hook 每轮都触发会不会通知太多?
会。Stop 事件在 Claude 每次完成一轮响应后都触发,不仅限于"真正的任务完成"。三种解决办法:
- 在脚本中判断
stop_reason字段,只在end_turn时推送 - 设置耗时阈值,只在运行超过 N 分钟的任务完成后通知(社区项目 ai-cli-complete-notify 支持此功能)
- 用 Hermes MCP 替代 Hooks——只有用户明确说"通知我"时才调用,从根本上避免误触发
延伸阅读
- Hermes Agent 完全指南——从安装到生产部署的完整路径
- Hermes Agent Docker 部署实战——容器化部署方案
- Hermes Agent 成本控制实战——模型选型与 Token 优化
- Claude Code MCP 新手指南——MCP 基础概念与配置入门
- Claude Code Hooks 新手指南——Hooks 详细配置与排查
- 我替翔宇测了 Hermes Agent,说说真实感受——第三视角体验评测
- MCP 最佳实践——MCP Server 选型与集成模式






















