模式 | 说明 |
单向 | 只转发事件给 CodeBuddy Code(告警、Webhook),在本地会话中处理 |
双向 | 额外暴露 reply 工具,让 CodeBuddy Code 可以回复消息 |
--channels 参数指定要加载的 channel:# 加载插件类型的 channelcodebuddy --channels plugin:fakechat@claude-plugins-official# 加载 .mcp.json 中配置的 channel servercodebuddy --channels server:webhook# 加载多个 channel(逗号分隔)codebuddy --channels plugin:telegram@claude-plugins-official,plugin:discord@claude-plugins-official
--dangerously-load-development-channels 标志来测试。此标志允许任何 channel 运行,无需在允许列表中:codebuddy --dangerously-load-development-channels server:my-webhook
channelsEnabled 组织策略仍然生效。一旦 channel 提交到官方市场并通过安全审查,就会被添加到允许列表,之后可以直接使用 --channels 加载。<channel> 标签的形式注入到 CodeBuddy Code 的上下文中:<channel source="fakechat" sender="web" chat_id="1">你好,请帮我看看这个问题</channel>
#fakechat · web: 你好,请帮我看看这个问题
settings.json 中可以控制 channel 功能:{"channelsEnabled": true}
false 可完全禁用 channel 功能。claude/channel capability,让 CodeBuddy Code 注册通知监听器notifications/claude/channel 事件#!/usr/bin/env bunimport { 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"] }}}
字段 | 类型 | 说明 |
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' },},})
<channel source="webhook" severity="high" run_id="1234">build failed on main</channel>
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}`)})
mcp.notification() 之前,必须检查发送者身份:const allowed = new Set(loadAllowlist())// 在消息处理器中,发送通知之前:if (!allowed.has(message.from.id)) { // 检查发送者 ID,而非群组 IDreturn // 静默丢弃}await mcp.notification({ ... })
message.from.id)而非聊天室身份(message.chat.id)进行验证。在群聊中,这两个值不同,按群组验证会让群内任何人都能向会话注入消息。Bash、Write、Edit)时,本地终端会打开权限对话框。双向 channel 可以选择同时接收这个提示,让你在远程设备上审批或拒绝。claude/channel/permission:capabilities: {experimental: {'claude/channel': {},'claude/channel/permission': {}, // 启用权限中继},tools: {},},
notifications/claude/channel/permission_request,包含以下字段:字段 | 说明 |
request_id | 5 个小写字母(排除 l),用于匹配回复 |
tool_name | CodeBuddy Code 要使用的工具名,如 Bash、Write |
description | 工具调用的可读描述 |
input_preview | 工具参数的 JSON 字符串,截断到 200 字符 |
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*$/iconst 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 // 作为裁决处理,不转发为聊天}
/plugin install 安装,然后用 --channels plugin:<name>@<marketplace> 启用。文档反馈