这是什么
在 Channels 的模型里,一个「频道」本质上就是一个 MCP 服务器:它对外提供发送消息的工具(出站),
并在收到外部消息时向千手大师发送一条 MCP 通知 notifications/claude/channel(入站)。
客户端把通知内容包进一个 <channel> 标签后入队,模型据此判断消息来源,并决定用哪个工具回复。
这意味着 Channels 不是某一家的专有集成,而是一套协议:只要某个 MCP 服务器声明了
capabilities.experimental['claude/channel'] 能力,它就能把外部事件推送进你正在运行的会话。
<channel source="plugin:weixin:weixin" chat_id="..." sender_id="..." message_id="...">
消息正文
</channel>
meta 字段会被渲染成标签属性,因此键名必须是合法标识符([a-zA-Z_][a-zA-Z0-9_]*),
实际使用中常见的键是 chat_id、user、message_id。
Channels 是「外部事件推入会话」,面向 IM 消息;Bridge 面向远程会话控制与交互,二者是独立模块。
前置条件
- 一个正在运行的千手大师会话(交互式或 print/SDK 模式均可,
--channels两者都支持)。 - 一个已连接、且声明了
claude/channel能力的 MCP 服务器。非频道服务器不会被注册通知处理器(连接本身保持正常)。 - 在启动命令中用
--channels显式列出该服务器——这是会话级开关,也是对「允许它推送入站消息」的信任声明。 - 插件型频道需通过市场白名单校验;企业/团队组织可通过托管设置自行指定
allowedChannelPlugins。
源码中 isChannelsEnabled() 恒为 true(已绕过 GrowthBook 开关),无需额外申请即可使用。
启用方式
--channels 的每一项都必须带 plugin: 或 server: 前缀标签,
未打标签或缺少市场的插件项会直接报错并以退出码 1 结束:
plugin:<name>@<marketplace> # 市场插件提供的频道(强制走白名单)
server:<name> # 手动配置的 MCP 服务器
-
安装或配置频道来源:市场插件用
/plugin install安装;手动服务器则在 MCP 配置中加入。 -
在启动命令中声明频道:重复该参数或一次列出多项均可。
# 插件格式(走白名单校验) qsdashi --channels plugin:feishu@claude-code-feishu-channel # 服务器格式(手动配置的 MCP 服务器) qsdashi --channels server:my-slack-bridge # 同时启用多个频道:重复该参数或一次列出多项 qsdashi --channels plugin:feishu@claude-code-feishu-channel --channels server:discord-bot -
确认启动提示:启动界面会打印
Listening for channel messages from: ...,并附带提示注入风险警告。 该项只表示「白名单已设置」,服务器是否真正连上、是否匹配到 MCP 服务器仍需以实际连接为准。
开发模式
测试自定义频道(尚未进入白名单)时,可用 --dangerously-load-development-channels。
它仅限交互式会话,启动时会弹出确认对话框;接受后仅绕过 --channels 的白名单校验,
不会绕过组织策略,且绕过不泄露到同时传入的 --channels 条目。
qsdashi --dangerously-load-development-channels server:my-custom-channel
支持的平台
Channels 通过市场插件或内置插件接入,以下为仓库文档中明确列出的来源:
| Channel | 说明 | 来源 |
|---|---|---|
| Telegram | 官方 Telegram Bot 集成 | /plugin install telegram@claude-plugins-official |
| Discord | 官方 Discord Bot 集成 | /plugin install discord@claude-plugins-official |
| iMessage | macOS 原生消息 | /plugin install imessage@claude-plugins-official |
| 飞书 (Feishu / Lark) | 双向消息、群组聊天、文件附件 | 社区插件 claude-code-feishu-channel |
| 微信 (WeChat) | 内置 channel,扫码登录、双向消息、附件透传 | 内置,plugin:weixin@builtin |
除上述插件外,任何实现了频道协议的 MCP 服务器都可通过 server:<name> 接入,
文档与源码注释中出现的 server:my-slack-bridge 即属此类示例,并非官方预置插件。
参数与配置
| 参数 | 作用 | 说明 |
|---|---|---|
--channels <entries...> |
声明本会话允许推送入站消息的频道 | 每项须为 plugin:name@marketplace 或 server:name;可重复或一次多项 |
--dangerously-load-development-channels <entries...> |
加载未进入白名单的频道 | 仅交互式;启动需确认;不绕过组织策略 |
qsdashi weixin login |
扫码登录微信账号 | 内置微信 Channel 专用 |
qsdashi weixin login clear |
清除已登录的微信账号 | 删除本地账号凭据 |
qsdashi weixin access pair <code> |
确认微信配对码 | 授权后该用户消息才会进入会话 |
白名单与组织策略
插件型频道的白名单来自 GrowthBook 的 tengu_harbor_ledger,粒度为插件级
(插件获批则其下所有频道服务器获批)。团队/企业组织若在托管设置中配置了
allowedChannelPlugins,它会取代该账本,由管理员承担信任决定。
校验是两段式的:先比对「你输入的标签」与「实际安装的插件来源」是否一致(pluginSource 的市场必须匹配),
再比对白名单。标签只是意图,运行时的 plugin:name:X 可能来自任何市场,因此必须核实。
内置微信 Channel
仓库内置了微信 Channel(plugin:weixin@builtin),无需安装外部市场插件。它是一个本地
stdio MCP 服务器,通过轮询微信接口接收消息,并暴露两个出站工具。
登录与会话启用
# 扫码登录(终端展示二维码 / URL)
qsdashi weixin login
# 清除登录状态
qsdashi weixin login clear
# 在会话中启用内置微信 channel
qsdashi --channels plugin:weixin@builtin
账号凭据保存在 ~/.claude/channels/weixin/account.json(权限 0600),
可用环境变量 WEIXIN_STATE_DIR 覆盖状态目录。
配对授权
默认访问策略为 pairing(配对)。当收到未授权用户的消息时,Channel 会回一条
6 位数字配对码(有效期约 10 分钟),并提示运营侧在终端确认:
qsdashi weixin access pair <code>
确认后该用户的 ID 写入 access.json 的 allowFrom 列表,后续消息才会进入会话。
访问策略支持 pairing、allowlist、disabled 三种取值。
可用的 MCP 工具
| 工具 | 参数 | 作用 |
|---|---|---|
reply |
chat_id、text、可选 files[] |
回复微信消息,可附带本地绝对路径的附件 |
send_typing |
chat_id |
发送「正在输入」状态 |
服务器会透传图片、语音、文件、视频附件:下载解密后落到临时目录,并在入站消息里带上
attachment_path / attachment_type 元数据;语音还会附带转写文本。
远程权限审批
声明了 capabilities.experimental['claude/channel/permission'] 的频道服务器,
还能把工具权限对话框转发到你的手机上。流程是双向、结构化的:
-
客户端发送审批请求:当权限对话框打开时,客户端发出
notifications/claude/channel/permission_request, 携带request_id、tool_name、description与截断到约 200 字符的input_preview。 -
你回复简短指令:服务器把提示格式化后发到对应平台,你回复形如
yes <5位短码>或no <5位短码>的消息。 -
服务器回传结构化事件:服务器解析回复后发出
notifications/claude/channel/permission,携带{request_id, behavior}。客户端按request_id匹配待处理项——它不会对普通频道文本做正则匹配, 因此只有服务器显式发出该事件才可能触发审批。
/^\s*(y|yes|n|no)\s+([a-km-z]{5})\s*$/i
短码为 5 位小写字母(字母表去掉易与 1/I 混淆的 l),大小写不敏感以适配手机自动纠错。
内置微信 Channel 会把提示格式化为「Tool / Reason / Input」并附带回复方法。
安全与注意事项
频道消息最终会作为对话内容进入模型上下文。启动提示明确警告:
inbound messages will be pushed into this session, this carries prompt injection risks。
只对可信来源启用频道;不再需要时,重启并去掉 --channels 参数即可关闭。
权限转发依赖频道服务器解析并回传事件。被攻陷的频道服务器可以伪造 yes <id> 事件。
这是已知并接受的残余风险——审批对话框只增加攻击成本,不能彻底阻断已被攻陷的频道。
- 频道服务器必须显式声明能力,客户端才注册对应通知处理器;能力缺失的服务器被跳过,连接本身不受影响。
- 频道是否被信任取决于它出现在
--channels列表里,而非运行时形态推断,这能防止受信服务器「偷偷」加上能力。 - 服务器格式(
server:)的条目不参与插件白名单(schema 仅支持插件),只在开发标志下被放行。 - 权限转发还受独立运行时开关
tengu_harbor_permissions控制,在会话挂载时读取一次,会话中途变更需重启生效。
常见问题与排错
启动时报「entries must be tagged」
--channels 的每一项都必须带 plugin: 或 server: 前缀,且插件项必须含
@marketplace。缺少标签、缺少市场名都会被视为硬错误。
启动提示显示了频道,但没有消息进来
- 提示只代表白名单已设置,不代表服务器已连接。
- 确认对应的 MCP 服务器已配置且连接成功;
server:条目若没有同名服务器配置会被标记为未匹配。 - 确认服务器声明了
claude/channel能力,否则通知处理器不会注册。 - 收到的消息若非白名单用户,需先完成配对授权,否则会被挡在会话之外。
提示「you asked for plugin:X@Y but the installed X is from Z」
标签里的市场与实际安装来源不一致。安装的插件来自其它市场,需改用正确的 @marketplace,或重新安装。
微信扫码后仍提示未连接
检查状态目录下的 account.json 是否存在。会话过期(接口返回 errcode -14)时轮询会暂停约 30 秒后重试,必要时重新执行 qsdashi weixin login。
团队/企业环境里插件被拦
组织若设置了 allowedChannelPlugins,它会取代默认白名单。请让管理员把对应插件加入托管设置。