发现 lark-channel-bridge,能让飞书直接连上本机的 Claude Code CLI。试了下还不错,记录一下。
怎么跑起来
npm i -g lark-channel-bridge
lark-channel-bridge run
第一次跑会输出个二维码,飞书扫一下,自动建一个飞书应用,凭据落到 ~/.lark-channel/。完事在飞书里发消息就行:私聊不用 @,群里 @ bot。
想后台跑:lark-channel-bridge start(macOS launchd / Linux systemd / Windows Task Scheduler 都做了)。
它做了什么
简单讲,bridge 就干一件事:把飞书消息转给本地的 claude 进程,再把 claude 的回复转回飞书。
飞书 App ←→ 飞书开放平台(WebSocket) ←→ bridge ←→ Claude Code CLI
关键点:bridge 在你本地跑,不在云端。所以 claude 能直接访问你的文件系统、Git 仓库、本地工具,跟在终端里用一模一样。代价是电脑得开着。
bridge ↔ claude 怎么通信
这是我觉得最精巧的部分:
bridge 收到飞书消息后,spawn("claude", ["-p", prompt, "--output-format", "stream-json", "--resume", sessionId, ...]) 拉起一个 claude 子进程。claude 通过 stdout 一行行吐 JSON(JSONL),每行是一段文字或一个工具调用。bridge 按 \n 切、JSON.parse,翻译成飞书卡片的 patch 更新——这就是"流式卡片":claude 边想边贴,工具调用也实时显示在同一张卡片上。
bridge 和 claude 之间没有任何自定义协议,就是 OS 父子进程 + 匿名管道。"流式"完全靠 claude CLI 自带的 stream-json 输出模式,bridge 只是读行、解析、翻译——干净利落。一轮 turn 跑完进程自然退出,下次新消息进来再 spawn 新的。
会话怎么维持
bridge 自己不存会话历史。sessionId 由 claude 首次 spawn 时从 {type:"system", subtype:"init"} 事件里抠出来,历史落在 claude 自己的 ~/.claude/projects/.../<sid>.jsonl。bridge 只维护一个 chatId → sessionId 的薄字典。
所以:同时存活的 claude 进程数 ≈ 同时在跑 turn 的 chat 数。每个 turn 跑完进程退出,OS 回收 PID,不会泄漏。
bridge 自己大概 3-5k 行 TypeScript,把重活全甩给 claude CLI——这就是它"轻"的原因。
实用功能
因为底层就是 Claude Code,你本地配置的 skills、workflows、CLAUDE.md 规则全都照常生效。我的博客配了 /check-post 校验格式、/fetch-zhihu 抓取知乎文章,现在手机上发一条 /fetch-zhihu https://zhuanlan.zhihu.com/p/xxx 就行,跟坐在电脑前没区别。
除了"能跑 claude"这个基本盘,bridge 还做了几件让体验更顺畅的事。消息的流式输出、抢占和批处理、每个 chat 独立 session,这三件是绑在一起的——你在飞书里看到的是一张不断更新的卡片,连发新消息会打断旧任务,快速连发则合并成一次;私聊和不同的群互不串扰,话题群里每个话题也独立。
其他零散的:/ws save /ws use 切换项目目录,图片文件直接发(bridge 下载到本地喂给 claude),/status /new /cd /stop /doctor 几个常用斜杠命令(其他 /xxx 透传给 claude)。交互卡片支持 CardKit 2.0,Claude 可以发带按钮、表单的卡片,点击后回调到同一个会话。多 Bot 协作也行,把几个 AI bot 拉进同一个群通过 @ 分工,默认不 @ 其他 bot,避免乒乓死循环。
踩坑
Windows 路径
我的开发环境是 Windows,bridge 里有些路径处理假设 Unix 风格。比如工作目录的传递,Windows 用 D:\homepage 而 bridge 期望 /d/homepage。解决方法:启动时显式指定工作目录,确保项目路径设置正确。
群聊里 bot 只能收到 @ 消息
飞书的机制,不是 bug。机器人只有被真实 @(结构化 mention)才能收到群消息。纯文本写"@机器人名字"不行。把 bot 拉进项目群的话,团队得养成 @ 它的习惯。
授权和进程生命周期
bridge 支持让 Claude Code 用用户身份调用飞书 API,需要 OAuth 授权。但 OAuth 的 device flow 会生成验证链接——群里谁先点谁拿走 token,会绑定到错的身份,所以授权只能在私聊里做。bridge 会自动检测聊天类型,群聊里拒绝执行 lark-cli auth login。
另一个跟进程相关的事:bridge 回复结束后回收 Claude Code 子进程。如果你 run_in_background: true 启动了 lark-cli auth login,后台进程会跟着一起死。授权必须前台阻塞:先 --no-wait 拿验证链接,再 --device-code 阻塞等用户完成。
安全
bridge 通过飞书身份验证控制访问,只有指定聊天里的人发的消息才会被处理。Claude 的权限跟终端里一样,受 CLAUDE.md 约束,也有 Claude Code 本身的权限确认机制。代码执行完全在你本机,不会上传到额外的第三方服务。
用下来
现在的日常:在外面用飞书给 bot 发消息,改 bug、写文章、部署网站;回到电脑前,所有改动已经在本地文件里了。多设备无缝衔接,对话上下文持续保持。
搭一次,用很久。