帮你快速理解、总结文档立即下载

Channels 参考 (Beta)

最近更新时间:2026-08-26 17:59:31
我的收藏
说明:
Beta 功能:Channels 目前处于 Beta 阶段,协议和接口可能会根据反馈进行调整。
Channel 是一种特殊的 MCP 服务器,可以将外部事件(Webhook、聊天消息、监控告警等)推送到 CodeBuddy Code 会话中,让 CodeBuddy Code 对终端外部发生的事情做出反应。

概述

Channel 运行在与 CodeBuddy Code 相同的机器上,通过 stdio 与 CodeBuddy Code 通信。CodeBuddy Code 将其作为子进程启动。
典型的使用场景:
聊天平台(Telegram、Discord):插件本地运行,轮询平台 API 获取新消息,转发给 CodeBuddy Code
Webhook(CI、监控):服务器监听本地 HTTP 端口,接收外部系统的 POST 请求,推送给 CodeBuddy Code
Channel 分为两种模式:
模式
说明
单向
只转发事件给 CodeBuddy Code(告警、Webhook),在本地会话中处理
双向
额外暴露 reply 工具,让 CodeBuddy Code 可以回复消息

使用 Channel

启动

使用 --channels 参数指定要加载的 channel:
# 加载插件类型的 channel
codebuddy --channels plugin:fakechat@claude-plugins-official

# 加载 .mcp.json 中配置的 channel server
codebuddy --channels server:webhook

# 加载多个 channel(逗号分隔)
codebuddy --channels plugin:telegram@claude-plugins-official,plugin:discord@claude-plugins-official

开发模式

自定义 channel 在初始阶段使用 --dangerously-load-development-channels 标志来测试。此标志允许任何 channel 运行,无需在允许列表中:
codebuddy --dangerously-load-development-channels server:my-webhook
此标志仅绕过允许列表检查,channelsEnabled 组织策略仍然生效。一旦 channel 提交到官方市场并通过安全审查,就会被添加到允许列表,之后可以直接使用 --channels 加载。

会话中的 Channel 消息

Channel 消息以 <channel> 标签的形式注入到 CodeBuddy Code 的上下文中:
<channel source="fakechat" sender="web" chat_id="1">你好,请帮我看看这个问题</channel>
在 TUI 中,channel 消息以友好格式显示:
#fakechat · web: 你好,请帮我看看这个问题

设置

settings.json 中可以控制 channel 功能:
{
"channelsEnabled": true
}
设为 false 可完全禁用 channel 功能。

构建 Channel

基本要求

一个 channel server 需要:
1. 声明 claude/channel capability,让 CodeBuddy Code 注册通知监听器
2. 发送 notifications/claude/channel 事件
3. 通过 stdio transport 连接(CodeBuddy Code 将其作为子进程启动)

最小示例:Webhook 接收器

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

const mcp = new Server(
{ name: 'webhook', version: '0.0.1' },
{
capabilities: { experimental: { 'claude/channel': {} } },
instructions: '来自 webhook 的事件以 <channel source="webhook" ...> 标签到达。单向通道,只需阅读并处理。',
},
)

await mcp.connect(new StdioServerTransport())

Bun.serve({
port: 8788,
hostname: '127.0.0.1',
async fetch(req) {
const body = await req.text()
await mcp.notification({
method: 'notifications/claude/channel',
params: {
content: body,
meta: { path: new URL(req.url).pathname, method: req.method },
},
})
return new Response('ok')
},
})
注册到 .mcp.json
{
"mcpServers": {
"webhook": { "command": "bun", "args": ["./webhook.ts"] }
}
}

Server 配置选项

字段
类型
说明
capabilities.experimental['claude/channel']
object
必填。始终为 {}。声明后 CodeBuddy Code 注册通知监听器
capabilities.experimental['claude/channel/permission']
object
可选。始终为 {}。声明此 channel 可以接收权限中继请求
capabilities.tools
object
双向 channel 需要。始终为 {}。标准 MCP 工具能力
instructions
string
推荐。注入到 system prompt,告诉 CodeBuddy Code 如何处理此 channel 的事件

通知格式

发送 notifications/claude/channel 通知时,params 包含两个字段:
字段
类型
说明
content
string
事件内容,成为 <channel> 标签的正文
meta
Record<string, string>
可选。每个键值对成为 <channel> 标签的属性。键名仅允许字母、数字和下划线,包含连字符或其他字符的键会被静默丢弃
示例:
await mcp.notification({
method: 'notifications/claude/channel',
params: {
content: 'build failed on main',
meta: { severity: 'high', run_id: '1234' },
},
})
到达 CodeBuddy Code 时的格式:
<channel source="webhook" severity="high" run_id="1234">
build failed on main
</channel>

暴露 Reply 工具

双向 channel 需要暴露标准 MCP 工具让 CodeBuddy Code 回复消息:
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js'

mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [{
name: 'reply',
description: '通过此 channel 发送回复消息',
inputSchema: {
type: 'object',
properties: {
chat_id: { type: 'string', description: '要回复的对话 ID' },
text: { type: 'string', description: '要发送的消息' },
},
required: ['chat_id', 'text'],
},
}],
}))

mcp.setRequestHandler(CallToolRequestSchema, async req => {
if (req.params.name === 'reply') {
const { chat_id, text } = req.params.arguments as { chat_id: string; text: string }
// 调用你的聊天平台 API 发送消息
await sendToPlatform(chat_id, text)
return { content: [{ type: 'text', text: 'sent' }] }
}
throw new Error(`unknown tool: ${req.params.name}`)
})

发送者安全管控

未设防的 channel 是 prompt 注入攻击向量。任何能访问你端点的人都可以向 CodeBuddy Code 注入文本。
在调用 mcp.notification() 之前,必须检查发送者身份:
const allowed = new Set(loadAllowlist())

// 在消息处理器中,发送通知之前:
if (!allowed.has(message.from.id)) { // 检查发送者 ID,而非群组 ID
return // 静默丢弃
}
await mcp.notification({ ... })
重要:始终基于发送者身份(message.from.id)而非聊天室身份(message.chat.id)进行验证。在群聊中,这两个值不同,按群组验证会让群内任何人都能向会话注入消息。

权限中继

当 CodeBuddy Code 调用需要审批的工具(如 BashWriteEdit)时,本地终端会打开权限对话框。双向 channel 可以选择同时接收这个提示,让你在远程设备上审批或拒绝。
本地终端和远程 channel 的对话框同时打开,先到的回答生效,另一个自动关闭。

启用权限中继

在 Server 构造器中添加 claude/channel/permission
capabilities: {
experimental: {
'claude/channel': {},
'claude/channel/permission': {}, // 启用权限中继
},
tools: {},
},

权限请求字段

CodeBuddy Code 发送 notifications/claude/channel/permission_request,包含以下字段:
字段
说明
request_id
5 个小写字母(排除 l),用于匹配回复
tool_name
CodeBuddy Code 要使用的工具名,如 BashWrite
description
工具调用的可读描述
input_preview
工具参数的 JSON 字符串,截断到 200 字符

发送裁决

你的 channel 需要发送 notifications/claude/channel/permission 通知:
await mcp.notification({
method: 'notifications/claude/channel/permission',
params: {
request_id: '<收到的 request_id>',
behavior: 'allow', // 或 'deny'
},
})

处理入站裁决

在入站消息处理器中识别 yes <id>no <id> 格式的回复:
// 匹配 "y abcde", "yes abcde", "n abcde", "no abcde"
// [a-km-z] 是 CodeBuddy Code 使用的 ID 字母表(小写,跳过 'l')
const PERMISSION_REPLY_RE = /^\\s*(y|yes|n|no)\\s+([a-km-z]{5})\\s*$/i

const m = PERMISSION_REPLY_RE.exec(message.text)
if (m) {
await mcp.notification({
method: 'notifications/claude/channel/permission',
params: {
request_id: m[2].toLowerCase(),
behavior: m[1].toLowerCase().startsWith('y') ? 'allow' : 'deny',
},
})
return // 作为裁决处理,不转发为聊天
}

打包为插件

将 channel 包装为插件可以方便分享和安装。用户通过 /plugin install 安装,然后用 --channels plugin:<name>@<marketplace> 启用。

参考

fakechat 示例:完整的双向 channel 实现,包含 Web UI、文件附件和 reply 工具
MCP 协议:channel 基于 MCP 协议实现