教程Claude Code

Claude Code 的 channels:把 CI 告警和聊天消息推进正在运行的会话,以及走中转站时为什么收不到

channels 让外面的事件自己进到一个开着的 Claude Code 会话里:CI 挂了、监控报警、你在 Telegram 上发的一句话。本文整理它是什么、和远程控制等方式的区别、官方插件怎么配、怎么自己写一个、安全上要守住什么。本站通过中转站试了一次,结果是用不了,文中给出看到的提示。

发布 · 约 11 分钟读完 · 经人工审核()· 本站的内容怎么来的

本文根据公开分享整理,本站尚未实测。操作前请对照文末的原始来源。

本页目录(8 节)
  1. 一、它是什么
  2. 二、和别的方式有什么不同
  3. 三、你能不能用
  4. 四、先用现成的试一下
  5. 五、安全:谁能往你的会话里说话
  6. 六、自己写一个
  7. 七、组织怎么管
  8. 这篇没有验证的地方

这篇教程解决一个问题:Claude Code 的会话开着,你人不在电脑前。CI 挂了、线上报警了,或者你想从手机上问它一句,怎么让这些消息自己进到那个会话里?

官方的答案叫 channels,目前是研究预览。本文按官方文档整理,并在服务器上通过中转站试了一次。先说结论:走中转站用不了,原因和看到的提示在第三节。用 claude.ai 账号或 Console 的 API key 登录的读者,后面几节照着做就行。

一、它是什么

一个 channel 就是一个 MCP 服务器,只多了一样本事:它能主动往会话里推消息。普通的 MCP 服务器只能等 Claude 来调用。

几个要点:

  • 它跑在你自己的机器上。 Claude Code 把它作为子进程启动,两边通过标准输入输出通信。
  • 事件进的是你已经开着的那个会话。 Claude 手边有你的文件,也记得你刚才在查什么。
  • 可以是双向的。 Claude 读到事件后,能通过同一个 channel 把回复发回去,像一座聊天的桥。
  • 会话关了就收不到。 想一直在线,要把 Claude Code 放在后台进程或者不会断的终端里。

两种常见的形态:

形态 怎么工作 例子
聊天桥 插件在本机轮询聊天平台的接口,有人给机器人发消息就转给 Claude。不用对外暴露地址 Telegram、Discord、iMessage
Webhook 接收器 服务器在本机监听一个端口,外部系统往这个端口发 POST CI、报错平台、发布流水线

回复通过 channel 发出去时,终端里看得到进来的消息,看不到回复的正文,只有一次工具调用和一个“sent”。回复的内容在对面的平台上。

二、和别的方式有什么不同

Claude Code 有好几种“连到终端以外”的方式,文档给了一张对照:

方式 做什么 适合
云端会话 在云上新开一个沙箱,从 GitHub 克隆代码去跑 把一件独立的事交出去,回头再看
Slack 里的 Claude 在频道里 @Claude,起一个云端会话 从团队的讨论里直接起任务
普通的 MCP 服务器 Claude 干活时去查它,它不会主动推 让 Claude 按需读某个系统
Remote Control 你从网页或手机上操作本机的会话 人不在座位上,但想自己接着指挥
channels 把别的系统的事件推进本机已经开着的会话 让会话自己对外面发生的事做反应

一句话区分 Remote Control 和 channels:前者是你在远处操作会话,后者是别的系统往会话里送消息。

如果只是想隔一段时间看一眼,做一个定时运行的智能体去轮询就够了,不需要 channel。

三、你能不能用

条件 说明
登录方式 要用 claude.ai 账号或 Console 的 API key。Amazon Bedrock、Google Cloud、Microsoft Foundry 上不提供
个人套餐(Pro、Max) 直接可用,每次会话用启动参数点名要开哪个
Team、Enterprise 默认关着,要组织的 Owner 先打开
Console(API key) 默认可用;组织下发了托管设置时,要在里面显式打开
官方插件的运行环境 都是 Bun 脚本,要先装 Bun
状态 研究预览。启动参数的写法和协议都可能变;claude --help 里暂时不列这两个参数,但能用

本站通过中转站试的结果:不可用

测试机上的 Claude Code 是 2.1.296,用令牌加自定义接口地址接的酷站AI 中转站。本站写了一个带回复工具的 channel 服务器,登记在项目的 .mcp.json 里,然后这样启动:

claude --channels server:webhook

启动画面上多了两行:

▎ --channels ignored (server:webhook)
▎ Channels are not currently available

接着看了三件事:

  • MCP 服务器照常连上了。 /mcp 里显示 ✔ webhook 1 tool,它的工具能用。
  • 事件发出去了,会话没有任何反应。 用 curl 往它监听的端口发了一条“main 分支构建失败”,服务器返回 ok,终端里什么也没出现。
  • 调试日志里有一句原因。 加 --debug 重启后,日志里是:
MCP server "webhook": Channel notifications skipped: channels feature is not currently available

这和文档的两处说法对得上:channels 要用 Anthropic 自己的登录方式;会话没有把服务器登记成 channel 时,事件会被悄悄丢掉,服务器那边收不到任何错误。

所以走中转站的读者目前用不了 channels。想要类似的效果,有两条不依赖它的路:用非交互模式让 CI 在失败时直接起一次 claude -p;或者用定时任务轮询。

四、先用现成的试一下

官方准备了一个叫 fakechat 的演示 channel:在本机起一个聊天页面,不用注册任何平台。

/plugin install fakechat@claude-plugins-official

退出,带上参数重新启动:

claude --channels plugin:fakechat@claude-plugins-official

然后打开 http://localhost:8787,在页面上打一句话。按文档的描述,终端里会出现一行 ← fakechat · web: …,Claude 干完活后调用 fakechat 的 reply 工具,答案出现在聊天页面上。第一次回复时如果问你要不要批准,点同意。

要同时开几个 channel,在 --channels 后面用空格隔开写。

三个正式的插件

Telegram Discord iMessage
事先准备 找 BotFather 建一个机器人,拿到 token 在开发者后台建应用和机器人,打开 Message Content Intent,把机器人拉进你的服务器 只能在 macOS 上用,不需要 token
安装 telegram 插件 discord 插件 imessage 插件
配置 /telegram:configure <token> /discord:configure <token> 第一次读消息库时 macOS 会要权限,点允许
认人 给机器人发条消息拿配对码,再在会话里确认 同左 自己给自己发的消息直接通过

三个插件都装自 claude-plugins-official,安装和启动的写法和 fakechat 一样,把名字换掉就行。

Telegram 和 Discord 配对完,记得再执行一次把名单锁死,之后只有名单里的人能发消息:

/telegram:access pair <配对码>
/telegram:access policy allowlist

token 存在 ~/.claude/channels/ 下各插件自己的 .env 文件里,也可以用环境变量给。iMessage 要加别的联系人,用 /imessage:access allow 加上对方的手机号或 Apple ID 邮箱。

五、安全:谁能往你的会话里说话

channel 等于给会话开了一个入口。文档的原话是:没有把关的 channel 就是一条提示词注入的通道,谁够得着你的端口,谁就能把文字放到 Claude 面前。

有三层限制:

  1. 发送者名单。 每个官方插件都维护一份名单,名单外的消息直接丢掉,不回任何东西。
  2. 每次会话点名。 服务器写在 .mcp.json 里不够,还得出现在这次启动的 --channels 里才能推消息。
  3. 组织开关。 见第七节。

另外两件事要有数:

  • 碰到要批准的操作,会话会停下来等你。 你不在终端前,它就一直等。channel 可以声明“转发审批请求”,让你在手机上答复。也可以用跳过权限检查的模式,但那只适合你完全信任的环境。
  • 能在 channel 里回话的人,就能批准或拒绝你会话里的工具调用。 开了审批转发之后,名单里只放你愿意把这个权力交出去的人。

用 -p 非交互模式跑 channel 时,需要在终端里作答的工具(比如多选题、计划模式的批准)会被关掉,免得会话卡死。

六、自己写一个

系统没有现成的插件时,可以自己写。硬性要求只有一个包:@modelcontextprotocol/sdk,Node.js、Bun、Deno 都能跑。

服务器要做三件事:

  1. 声明 claude/channel 这个能力,Claude Code 才会为它登记监听。
  2. 有事发生时发一条 notifications/claude/channel 通知。
  3. 用标准输入输出和 Claude Code 连接。

官方的例子用 Bun。下面是本站照着改的 Node.js 版,一个文件,监听本机 8788 端口,把收到的 POST 转给 Claude:

#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import http from 'node:http'

const ALLOWED = new Set(['ci', 'tony'])          // 只转发这两个发送者的消息

const mcp = new Server(
  { name: 'webhook', version: '0.0.1' },
  {
    capabilities: { experimental: { 'claude/channel': {} } },   // 有这一项才算 channel
    instructions: '来自 webhook 通道的事件是 <channel source="webhook" ...>。单向:读完后处理,不用回复。',
  },
)
await mcp.connect(new StdioServerTransport())

http.createServer(async (req, res) => {
  let body = ''
  for await (const chunk of req) body += chunk
  const sender = String(req.headers['x-sender'] ?? '')
  if (!ALLOWED.has(sender)) { res.writeHead(403).end('forbidden\n'); return }   // 先看发送者
  await mcp.notification({
    method: 'notifications/claude/channel',
    params: { content: body, meta: { sender, path: req.url } },
  })
  res.end('ok\n')
}).listen(8788, '127.0.0.1')                     // 只听本机
{ "mcpServers": { "webhook": { "command": "node", "args": ["./webhook.mjs"] } } }

这段代码本站验证到哪一步: 原样放到测试机上,Claude Code 能把它启动并连上(/mcp 里显示 ✔ webhook),端口能收到请求,名单外和不带发送者的请求得到 403,名单内的得到 ok。事件真正送进会话这一步没有验证,因为测试机上 channels 不可用。另外不要在这个文件里用 console.log:标准输出是它和 Claude Code 通信的通道。

事件长什么样

content 是正文,meta 里的每一项变成标签上的一个属性,source 自动取服务器的名字。模型看到的是:

<channel source="webhook" sender="ci" path="/">
main 分支构建失败:test_calc.py::test_div
</channel>

几条容易踩的规矩:

  • meta 的键只能用字母、数字和下划线。 带连字符的键会被悄悄丢掉。
  • 没有送达确认。 通知写出去就算完,Claude Code 不回执。会话没登记这个 channel,或者组织策略不允许,事件直接丢,服务器不会收到错误。本站第三节看到的就是这种情况。
  • 事件按顺序排队。 Claude 忙的时候来了好几条,会在下一轮一起交给它。要并行处理互不相干的事件流,开多个会话。
  • instructions 值得认真写。 它会在服务器连上时交给 Claude,告诉它会收到什么事件、要不要回复、用哪个工具回。

让它能回话

双向的 channel 多三样东西,都是普通的 MCP 写法:

  1. 能力里加一项 tools: {}。
  2. 注册一个回复工具(官方例子叫 reply,参数是 chat_id 和 text),在处理函数里调你的平台接口把消息发出去。
  3. 在 instructions 里告诉 Claude:回复时用这个工具,chat_id 从进来的标签上照抄。

把关要按“人”,不按“群”

发通知之前先查发送者在不在名单里。文档特别提醒:按发送者的身份查,不要按聊天室的身份查。 群聊里这两个不是一回事,按群放行,群里任何人都能往你的会话里塞话。

转发审批请求

这是可选的,而且只有双向、认得出发送者的 channel 才应该开。流程是四步:

  1. Claude Code 弹出审批对话框时,生成一个短编号,同时通知你的服务器。
  2. 服务器把请求和编号转到你的聊天软件上。
  3. 你回复“同意”或“拒绝”,带上那个编号。
  4. 服务器把答复变成一条裁决通知发回去。编号对得上一个还开着的请求,Claude Code 才采纳。

终端里的对话框一直开着,两边谁先答算谁的。涉及的名字:

值
要声明的能力 claude/channel/permission
Claude Code 发来的通知 notifications/claude/channel/permission_request
通知里的字段 request_id、tool_name、description、input_preview
你发回去的通知 notifications/claude/channel/permission
发回去的字段 request_id,以及取值为 allow 或 deny 的 behavior

几个细节:

  • 编号是五个小写字母,不含 l,免得在手机上和 1、I 混。终端的对话框上不显示这个编号,只有你的服务器知道。
  • description 只是对这次调用的概括,不是命令本身。有地方显示的话,把 input_preview 也带上,Bash 的命令在那里面。
  • 这两个字段要当成不可信的内容。2.1.234 起 Claude Code 会把认得出的密钥替换成 [REDACTED],但没有固定前缀的密钥不会被遮住。
  • 项目信任和 MCP 服务器授权这两种对话框不转发,只在本机终端出现。
  • 答复的格式不对,会被当成普通消息交给 Claude;编号不对,会被悄悄丢掉。两种情况下本机的对话框都还开着。

测试和发布

研究预览期间,自己写的 channel 不在批准名单上,用 --channels 带不起来。官方给的办法是一个开发用的启动参数:

claude --dangerously-load-development-channels server:webhook

按文档的说明,它会先弹一个全屏的警告让你确认,并且只能在交互会话里用,-p 和 Agent SDK 会忽略它。它只跳过批准名单,组织的总开关照样管着。本站没有用这个参数启动过,这一段是照文档写的。

要分享给别人,把它包成插件发到插件市场。发在自己的市场上仍然不在批准名单里,对方还是要用开发参数;Team 和 Enterprise 的管理员可以把它加进组织自己的名单。

还有一处和 MCP 版本有关的坑:文档说,在新的 MCP 客户端运行时上,服务器如果协商到 2026-07-28 这一版协议,就送不了 channel 消息,Claude Code 不会把它登记成 channel。要让服务器留在旧的握手方式上,设环境变量 MCP_PROTOCOL_NEGOTIATION=legacy。

七、组织怎么管

管理员用两项托管设置控制,用户改不了:

设置 作用 不设的时候
channelsEnabled 总开关。关着时任何 channel 都收不到消息,开发参数也不行 Team、Enterprise:全部禁用
allowedChannelPlugins 哪些插件可以登记成 channel。设了就替换掉 Anthropic 维护的默认名单 用默认名单
{
  "channelsEnabled": true,
  "allowedChannelPlugins": [
    { "marketplace": "claude-plugins-official", "plugin": "telegram" },
    { "marketplace": "acme-corp-plugins", "plugin": "internal-alerts" }
  ]
}

总开关也可以在 claude.ai 的组织设置里开(Claude Code 下的 Channels),要 Owner 角色。开关没开时,MCP 服务器照样连得上、工具照样能用,只是消息进不来,启动时有一条提醒。

这篇没有验证的地方

  • channels 本身没有跑通过。 测试机走中转站,功能不可用。事件送达、回复工具、审批转发、配对流程,都是按文档整理的。
  • 没有用开发参数启动过,不知道它在中转站下会不会有不同的结果。
  • 四个官方插件(fakechat、Telegram、Discord、iMessage)一个都没有装过,测试机上也没有 Bun。
  • “不可用”只在一家中转站、一个版本上看到。 启动提示和日志没有说明具体原因,本站是根据文档对登录方式的要求来理解的。
  • 组织管控的两项设置没有试。

来源

通过 API 中转站使用这些模型?到 Veridrop 免费检测中转站给你的是不是它声称的模型,或者看看中转站排行榜前 100 名。

相关文章

  • Claude Code 插件进阶(上):代码智能插件实测,装之前怎么审,不工作怎么查教程 · Claude Code · 约 11 分钟

    代码智能插件把语言服务器接给 Claude:改完代码自动拿到类型错误,按符号找定义和引用。本站用 TypeScript 实测,连踩三个坑才跑通,并发现第一次编辑的诊断要等到下一步才到。后半篇讲装一个插件之前怎么看清它会在你机器上运行什么,以及卸载之后还留下什么。

  • Claude Security 插件实测:让一组代理把代码库扫一遍找漏洞,再出补丁给你审教程 · Claude Code · 约 11 分钟

    Claude Security 是官方的深度扫描插件:几个代理分头读代码找漏洞,再由三个评审各自投票,通过的才进报告。本站在一个埋了问题的小应用上跑了两次:都找到了路径穿越,还找出一个我们没埋的崩溃问题并验证属实;但两次的结论数量和评级不一样,出补丁两轮都被它自己的评审否决。合计 3.70 美元。

  • Claude Code 安全检查插件:它写代码时自动查三遍,以及怎么确认它真的在查教程 · Claude Code · 约 18 分钟

    security-guidance 是官方的一个插件,装上后在 Claude 改文件、每轮结束、提交时各做一次安全检查。本站把三层都实测了:它查出了我们故意留的 SSRF、开放重定向和凭据外泄。也记下两个让后两层悄悄失效的坑:缺 Python 依赖,以及中转站拦了插件的请求。失效时会话里没有提示,附从日志确认的办法。

  • 做一个靠谱的定时智能体:官方“每日简报”参考实现拆解教程 · Claude Code · 约 10 分钟

    根据 Anthropic 的文章整理:用 Claude Managed Agents 做一个定时读取 Slack 和 GitHub、把要点发到 Slack 的智能体。按来源、去向、代理、定时、记忆、护栏六个部分,讲清每一处常见的失败和官方的六条规则。