从上次说起
前两篇文章分别介绍了 cc-wechat 的搭建流程,以及用三个 Hook 脚本把它从"能用"变到"可用"的过程。三个脚本解决了消息无反馈、reply 参数被 XML 污染、用量耗尽时无应答这三个痛点,但它们始终是"外挂"——用户需要手动下载 tar 包、跑 install.sh、合并 settings.json,步骤多,调试也不方便。
于是这次直接把增强点合进代码:fork 了一份上游的 cc-wechat,命名为 claude-weixin-channel,把修复下沉到 MCP server 本体,把 Hook 做成 install-hooks 子命令一键集成,并且补上了两个新的体验增强——工具进度实时推送和Claude 流式输出实时转发。
和源项目一样,本项目直接通过NPM发布,项目地址:claude-weixin-channel。
这篇文章不再重复基础安装,只讲两件事:这个 fork 相对上游到底改了什么,以及在什么场景下它真的派上用场。
先聊聊 Claude Code Channels 是什么
在进入 fork 的改动清单前,有必要花两段篇幅说清楚 Claude Code Channels 这个底座——它才是"微信 ↔ Claude Code"这条链路能成立的前提。
本质上它是一个对外的双向管道。 Claude Code 本身基于 Anthropic 的模型上下文协议(MCP),而 Channels 在 MCP 之上声明了 claude/channel 这项能力:一个 Channel 实际上就是一个本地运行的 MCP server,作为 Claude Code 会话的子进程、通过 stdio 通信。外部消息(微信、Telegram、iMessage……)经由 Channel 推入当前会话,Claude 处理完再通过 Channel 里定义的 reply 等工具把结果发回去。
为什么这件事重要? Channels 把 AI 协作从"同步对话"挪到了"异步协作":Claude Code 会话可以 7×24 在后台挂着等指令,而你不必守在电脑前。这是前两篇文章里那些 Hook 做再多也改变不了的本质——Hook 只能在一次会话内部增强体验,而 Channels 才是让你从手机发起一次会话的通道本身。
有几条前置条件值得先记住:
- Channels 目前还是 Research Preview 状态,功能和协议都可能变;
- 只支持 claude.ai 账号登录(Pro / Max 等付费档),API Key 不支持;
- Claude Code 版本需要 v2.1.80+;
- 本项目不支持官方的
--channels plugin:xxx直接启动方式,它走的是"开发态 Channel"路径(即--dangerously-load-development-channels),所以启动命令和 Telegram 那一套官方插件不完全一样。这点踩过坑的人会知道——如果你照着 Anthropic 的 Telegram 示例想换个--channels plugin:wechat,是起不来的。
这块不展开说明,后面"安装与启动"章节里用的命令都是基于这个前提。
安装与启动(极简版)
如果你从零开始,三条命令:
# 1. 安装并注册 MCP,扫码登录
npx claude-weixin-channel@latest install
# 2. 合并四个生命周期 Hook 到 ~/.claude/settings.json
npx claude-weixin-channel@latest install-hooks
# 3. 启动(必须开 yolo 模式,原因见下文)
claude --dangerously-skip-permissions \
--dangerously-load-development-channels server:wechat-channel
遇到 Channels are not currently available 时跑一次 npx claude-weixin-channel@latest patch 即可。卸载 Hook:npx claude-weixin-channel uninstall-hooks,原 settings.json 会自动备份为 .bak。
和上游 cc-wechat 的三步流程相比,唯一多出来的是 install-hooks,而这一步替代了原来手抄 JSON、手动 chmod +x 等几乎必翻车的环节。
给第 3 步加个 alias
启动命令本身很长,每次手敲会劝退。在 ~/.bashrc(或 ~/.zshrc)里加一行:
alias claude-with-weixin='claude --dangerously-skip-permissions --dangerously-load-development-channels server:wechat-channel'
source ~/.bashrc 之后,后续出门前只要一句 claude-with-weixin 就行。后面"使用场景"里提到的"出门前把 Claude Code 跑着",实际上就是跑这一条。
相比上游做了哪些改变
下面这份清单是本次 fork 的核心产出。
1. sanitizeReplyArgs() 下沉到 MCP server 本体
上一篇里那个 wechat-reply-fix.sh——在 PreToolUse 里用 jq 清洗被 XML 污染的 context_token 和 content——现在不需要了。它已经变成 server 端 TypeScript 代码里的一个纯函数 sanitizeReplyArgs(),并且有 node:test 的单元测试覆盖。
这意味着:
- 装机即修:不依赖用户是否装好 Hook,reply 工具调用一定会走清洗逻辑;
- 更快:少一次外部进程拉起(jq + bash),参数处理就在 MCP 进程内完成;
- 可测:纯函数 + 单测,后续遇到新的污染模式直接加 case。
wechat-reply-fix.sh 从 Hook 清单里被移除,外挂减少一个。
2. 新增 wechat-progress.sh(PostToolUse 进度推送)
上一篇只做到"收到,处理中..."这一条即时确认,再之后微信那边就又沉默了。对于短任务无所谓,对于跑构建、跑测试、批量改文件这种需要几分钟的任务,用户是在盲等。
新的 wechat-progress.sh 挂在 PostToolUse:每次 Claude 执行完一个工具(Read / Edit / Bash ...),Hook 就把"工具名 + 关键参数摘要"推送到微信。好处是你在手机上能看到 Claude 现在正在读哪个文件、跑哪条命令,而不是只有一头一尾。
默认关闭(会比较吵),在微信里发 /progress on 即可开启。
3. 新增 wechat-stream.sh(PostChunk 流式转发)
这是体验提升最大的一块。PostChunk 是 Claude Code 较新的 Hook 事件,每当模型产出一段流式 token 就触发。wechat-stream.sh 把这些 chunk 合并、限速、再通过 iLink 的 sendmessage 持续推送到微信。
效果是:不用等 Claude 把全部答案生成完再一口气回复,手机上你能像在终端那样看到答案正在"打字"出来。尤其是问一个需要长篇解释的问题,边等边读,体感完全不一样。
默认开启,想关掉发 /stream off 即可。
4. install-hooks / uninstall-hooks 一键集成
上一篇我用的是 tar.gz + install.sh 的方式。这次做成 MCP 包里自带的子命令:
npx claude-weixin-channel@latest install-hooks
脚本做的事:
- 把
hooks/*.sh复制到~/.claude/hooks/并赋可执行权限; - 读取现有
~/.claude/settings.json,做 deep-merge 合并 hook 配置(不是覆盖); - 原文件备份为
settings.json.bak。
卸载对称:uninstall-hooks 只撤走本 fork 注入的四条,不影响用户自己加的其他 Hook。
5. 斜杠命令扩展
上一篇只有 /new、/help、/status 三条。这次由 wechat-ack.sh 在 UserPromptSubmit 里拦截和处理,扩展到:
| 命令 | 作用 |
|---|---|
/new |
开始新话题,清除上下文链接 |
/clear |
清空 Claude Code 编辑器上下文(截断 transcript) |
/mode <name> |
切换角色模式(code / review / explain / concise / off) |
/compact |
精简响应模式 |
/think |
开启深度思考模式 |
/stream on|off |
切换流式转发(默认 on) |
/progress on|off |
切换工具进度通知(默认 off) |
/session-status |
查看当前会话状态 |
/help |
帮助 |
注意这些命令不是 Claude Code 原生 slash command,所以终端里可能看到 Unknown command 的提示——这是预期行为,实际动作由 Hook 完成,可以忽略。
6. 彩蛋:新版微信其实已经支持 Markdown 渲染
这一点不是 fork 新加的改变,而是调试过程中意外确认的事实——iLink Bot 下发的消息在微信客户端里会原样渲染 Markdown:代码块带语法高亮、行内代码有灰底、链接可点击跳转、标题有层级字号。

Claude Code 的回复里如果包含 ```js 代码块、[文字](链接)、## 标题 这些 Markdown 语法,微信对话框里会直接渲染出来,不再是一大段纯文本
这意味着:你完全不用为了适配微信去要求 Claude 输出纯文本。该用代码块就用代码块,该贴链接就贴链接——手机上的阅读体验和读博客差不多。对于"在地铁上审稿"这种场景特别关键,因为长回答读起来不会变成一坨。
7. 路线图:PreToolUse 安全校验
必须开 --dangerously-skip-permissions(yolo 模式),是因为微信侧根本不存在"允许/拒绝"这种交互界面——Claude Code 弹权限审批框时,会话就卡住了。yolo 模式让 Claude 直接执行工具,才能把远程链路走通。
但代价是模型生成的命令没有二次校验。下一步的计划是在 Hook 层加 PreToolUse 安全校验:拦截 rm -rf /、curl … | sh、写入 ~/.ssh 等高危模式,命中时推送告警到微信,等用户显式放行后再继续。这样既保留 yolo 的便利,又恢复一道兜底。
手机端和终端端,对照着看

微信端完整交互:上方是用户提问,中间是"收到,处理中..."以及工具执行进度推送,下方是 Claude 的流式正文与最终回复

在微信中发 /session-status、/mode code 等命令的返回效果

在电脑终端上能看到 MCP server 加载成功、消息到达、工具调用、reply 发送的完整日志,与微信端一一对应

npx claude-weixin-channel@latest install-hooks 的终端输出,包括脚本复制、settings.json 备份与合并提示
使用场景
先说它不是什么:它不是一个多模型 AI 微信助手,也不是把 Claude Code 搬到云端的服务端方案。它就是一条从微信回到你自己电脑终端上那个 Claude Code 实例的远程通道。
在这个定位下,我觉得真正值得用的场景有这么几个。
场景一:跑步结束回家路上,用手机把博客发出去
这是触发我写这篇的具体场景。今天上午去苏州河边跑了 11 公里(详见跑步日志),回家路上一身汗、不想立刻再坐到电脑前,但又想把白天想好的博客主题落地。
流程是这样的:
- 出门前在家里电脑上一句
claude-with-weixin(即上文那个 alias)把会话跑着,确保电脑不会待机或休眠; - 跑完步在回家路上,微信里发一句"我会发你一组照片和一个.GPX文件,根据这些文件调用跑步日志生成SKILL生成文章。";
- 手机上看着 Claude 一边调 Read、Grep、一边流式吐回复(得益于
wechat-progress.sh和wechat-stream.sh),经过几轮交互文章生成并发送给我确认; - 确认完成后直接一句
提交MR并监视状态自动推送分支到GitLab启动合并Pipeline; - Pipeline结束后再次发送发布文章,等待反馈后就能在网站上看到最新发布的文章了。(因为Pipeline的实行和S3上传基本得等待10分钟左右)
整个过程里,不需要呆在电脑面前整理内容,发送图片(连微信文件传输都用不上了)
场景二:监视长任务
一些任务是启动容易、等待难——跑 CI、跑 Prisma migration、批量改一百多个文件、甚至是让 Claude 做一次全仓依赖升级。以前这种任务要么盯着终端、要么时不时 tmux attach 看一眼。
现在是:启动命令之后人离开电脑,进度推送(/progress on)和流式输出直接在微信里实时刷。手机一震,看一眼,大概率不用管,出问题了也第一时间看到。
场景三:会议/上课间隙的短反馈
15 分钟的间隙不够你坐回电脑、切上下文、跑起 Claude Code,但足够你在手机上发一句"帮我看下昨天 MR 里的第 3 处评论怎么回合适"。一问一答结束,关掉微信,继续开会。
不适合的场景
- 需要审批权限的操作——yolo 模式下没有审批这回事,但你如果关 yolo,微信侧就卡住。别在生产仓库上这么玩。
- 完全脱离电脑的长期运行——iLink session 会过期,路由器掉线、电脑休眠都会中断链路。它是"遥控器",不是"服务器"。
- 多人群聊——iLink Bot 本身只支持单人对话。
已知限制
- 权限审批仍需终端,这是 Claude Code 自身限制,yolo 是唯一绕法;
- 语音消息只取转写文本,不传原始音频;
- Session 会过期,需要偶尔
npx claude-weixin-channel login重新扫码; - 必须用户先发消息,iLink 的
context_token是按消息发放的,Claude 不能主动推送; - 部分非官方模型不支持 vision,发图可能被忽略;
- 无法通过微信清空上下文,应该是基于安全的考虑。通过hook的slash命令只能指示Agent忽略之前的对话,但并不能清空上下文窗口;
- Hooks命令不支持Windows,因为基于bash脚本做成,所以无法直接支持Windows,但可以在WSL环境下运行。
总结
本身项目的改造优先:把上一篇三个 Hook 脚本里,能下沉的下沉(sanitizeReplyArgs)、能扩展的扩展(新增 progress 和 stream 两个 Hook)、能省步骤的省掉(install-hooks 子命令),顺便把斜杠命令从 3 个扩到 9 个。代码量上没有增加多少,但安装复杂度和使用体验是两档的差距。
顺便,把原项目里已经过期的定义等做了修复,并添加了test和lint。(感谢Claude Code)
对我自己来说,判断一个小工具值不值得长期用,就看它能不能无缝嵌进某个真实场景。 刚好也可以试试NPM包的发布规则。(比想象中要方便多了)
GitHub项目地址: dranixj/claude-weixin-channel,MIT,欢迎拍砖和 PR。
NPM包地址: claude-weixin-channel
评论