codebuddy-matrix-channel
codebuddy-matrix-channel
把 Matrix 聊天桥接到 CodeBuddy Code 本地会话的 Channel 插件(MCP 服务器)。
效果等同于 CodeBuddy 内置的 Telegram / Discord / 微信 channel:
在 Matrix 房间里发消息 → 通过 Gateway Protocol(
POST /api/v1/runs,conversation.id = 房间ID)投到本地 CodeBuddy 服务(--serve,默认 9099),目标是让每个房间在 9099 Web UI 里成为一条独立的会话线程CodeBuddy 的回复从 run 的 SSE 流里抓取(或 Agent 直接调用
reply工具),再发回原 Matrix 房间可选:把 CodeBuddy 的权限请求提示转发到“控制室”,在手机上审批/拒绝工具调用
本插件基于 CodeBuddy 的 Channel 扩展机制(见 docs/cn/cli/channels.md 与 channels-reference.md),无需修改 CodeBuddy 本体。
📌 现状速览(Current Status)
本插件已可用于「Matrix ↔ CodeBuddy 数字分身」的双向桥接,但部分设计目标受限于当前 serve 版本尚未达成。下面如实区分「已实现」与「受限 / 未实现」:
✅ 已实现
Matrix 双向桥接:收消息(含 @提及过滤、白名单、加密房间解密)与发回复(文本 /
m.notice/ html)。Gateway Protocol 投递:经
POST /api/v1/runs把消息投到本地--serve(9099),取代旧版notifications/claude/channel注入。回复取回与去重:消费 run 的 SSE 流抓取 assistant 文本,并与 Agent 主动调用的
reply工具去重,避免重复投递。数字分身授权模型:三层任务状态(
approved/pending/unauthorized)、控制室审批(approve/yes <id>/no <id>)、高风险工具硬闸、陌生工作先request_approval。按房间分日志 + 上下文隔离:每房间独立历史文件
matrix-logs/history-<房间>.log;插件侧维护每房间滚动上下文(MATRIX_ROOM_CONTEXT_TURNS,默认 6),转发时注入「本房间历史上下文」块,在模型有效上下文层面做到按群隔离,显著降低跨房间串味。E2EE 支持(matrix-js-sdk 42.x:Rust crypto wasm +
fake-indexeddb内存垫片)。媒体下载(
MATRIX_DOWNLOAD_MEDIA,以[file: 路径]注入)、自检(npm run doctor/health_check工具)。⚠️ 受限 / 未实现(受 serve 版本约束)
每个 Matrix 房间 = 一条独立 Web UI 会话线程:当前做不到。 serve 的
getOrCreateSession(conversationId)在已有主会话时直接return this.primarySession,忽略传入的conversation.id/session.id,所有 Gateway run 都落入同一个主会话线程。因此 9099「对话」里 Matrix 消息统一在主会话(每条带房间作用域头区分)。详见第 8 节「已知限制」与第 11 节「未来迭代方向(路线 B)」。E2EE 密钥不落盘:42.x 下 Rust crypto 走内存垫片,重启需重新协商密钥 / 设备验证。
权限中继依赖 CodeBuddy 的
claude/channel/permission能力;若版本不支持,核心聊天桥接不受影响。
1. 工作原理
Matrix 房间 ──(matrix-js-sdk 收消息)──▶ matrix-channel (本插件)
│ 组装上下文前缀(群名/发信人/成员)
│ Gateway Protocol: POST /api/v1/runs
│ source.conversation.id = 房间ID ← 目标:每房间独立线程(当前 serve 仍合入主会话,见现状/§8)
▼
本地 CodeBuddy 服务(--serve, 默认 9099)
│ Agent 处理;回复经 SSE 抓取 / reply 工具
▼
matrix-channel ──(sendText)──▶ 原 Matrix 房间插件作为子进程由 CodeBuddy 以 stdio 启动,通过 MCP 协议通信;同时把消息以 Gateway Protocol 投到同一个 CodeBuddy 服务实例(即启用 --serve 的进程),从而复用其 Agent 能力并在 Web UI 生成会话线程。
前提:CodeBuddy 必须以
--serve模式运行(默认 9099)且网关密码可读(写入~/.codebuddy/settings.json的gateway.password,或显式用环境变量提供)。详见第 8 节(Gateway / Web UI 会话线程)。
Related MCP server: mcacp
2. 安装
cd matrix-channel
npm install
npm run build # 编译到 dist/(也可直接用 tsx 运行,无需构建)运行时需要 Node >= 20。
2.1 快速开始(数字分身)
安装 / 编译
cd matrix-channel && npm install && npm run build填
.env(最小可用集,详见第 3 节)MATRIX_HOMESERVER=https://im.yiq.pub MATRIX_ACCESS_TOKEN=<从 Element:设置 → 帮助 → 高级 → 访问令牌 复制> MATRIX_USER_ID=@evlon-ai:im.yiq.pub MATRIX_ALLOWLIST=@evlon:im.yiq.pub # 防 prompt 注入,必填 MATRIX_OWNER_ID=@evlon:im.yiq.pub # 分身管理者=你,审批权只认此身份 MATRIX_CONTROL_ROOM_ID=!<控制室房间ID>:im.yiq.pub MATRIX_MENTION_REQUIRED=true # 群里只响应 @分身 # 可选:MATRIX_TRUSTED_SENDERS / MATRIX_TRUSTED_ROOMS / MATRIX_AUTHORIZED_WORK自检(每次改完
.env先跑)npm run doctor # 期望:连接 ✅、账号 ✅、E2EE ✅接入 CodeBuddy:在项目
.mcp.json注册(绝对路径)后启动codebuddy --channels server:matrix --dangerously-load-development-channels日常使用
群里 @分身 派活 → 可信来源/已授权工作自动执行;陌生工作先出计划、进控制室等你
approve。高风险工具(Bash/写文件等)永远进控制室请示你。
你在控制室下命令(只认
MATRIX_OWNER_ID):approve(run/go,可跟房间 ID)→ 授权该房间任务yes <id>/no <id>→ 放行 / 拒绝等待中的高风险权限请求
加密群需
MATRIX_E2EE=true;MATRIX_DEVICE_ID留空会自动从/devices选,报错再填「设置 → 设备」里的设备 ID。
3. 配置
复制 .env.example 为 .env 并填写:
cp .env.example .env变量 | 说明 |
| 家庭服务器地址,如 |
| 账号 access_token(推荐;从 Element「设置 → 帮助」复制) |
| 可选,用于识别“自己的消息”,如 |
| 备选鉴权方式,启动时会 |
| 允许发消息的发送者用户 ID,逗号分隔(务必配置) |
| 允许收听的房间 ID,逗号分隔(留空 = 全部) |
| 权限中继控制室房间 ID(可选,但数字分身模式必填) |
| 分身管理者(owner)的 Matrix 用户 ID(必填)。审批权只认此身份 |
| 可信同事用户 ID,逗号分隔;来自他们的工作自动执行(安全工具) |
| 可信群 ID,逗号分隔;这些房间里的所有工作自动执行 |
| 已授权常规工作描述(自由文本),供分身判断「常用 vs 陌生」 |
| 群内是否仅响应被 @ 提及的消息(默认 true;多分身共存建议开启) |
| 高风险工具列表,逗号分隔;默认 |
| 是否下载图片/文件到本地并以 |
| 媒体下载目录(默认 |
| 是否启用端到端加密(默认 false,见下文第 6 节) |
| 在 matrix-js-sdk 42.x 不生效(见第 6 节):Rust crypto 走 wasm + |
| 抓取 Gateway run 的 SSE 回复的超时(毫秒,默认 |
| 本地 CodeBuddy 服务端口(默认读 |
| 本地 CodeBuddy 服务完整地址(如 |
| 网关密码;缺省自动读取 |
| 设为 |
⚠️ 安全:务必配置
MATRIX_ALLOWLIST(按发送者而非房间校验,避免群聊中任意成员注入会话)。留空表示允许所有人,仅用于本地测试。
4. 接入 CodeBuddy
方式 A:开发期(绕过市场白名单)
把本插件注册到你的 CodeBuddy 项目 .mcp.json:
{
"mcpServers": {
"matrix": {
"command": "npx",
"args": ["tsx", "/绝对路径/matrix-channel/src/index.ts"]
}
}
}然后启动 CodeBuddy:
codebuddy --channels server:matrix --dangerously-load-development-channels编译后用
node运行可改为:"args": ["node", "/绝对路径/matrix-channel/dist/index.js"]
方式 B:打包为插件(提交到官方市场后)
npm run build再将 codebuddy-matrix-channel 作为插件发布,之后用:
codebuddy --channels plugin:matrix-channel@<你的市场>5. 使用
启动后(
codebuddy --serve --channels server:matrix --dangerously-load-development-channels),在允许的 Matrix 房间里发消息,插件会通过 Gateway Protocol 把消息投到本地 CodeBuddy 服务,conversation.id = 房间ID。CodeBuddy 处理完成后,回复会抓回并发回原 Matrix 房间(若 Agent 已通过
reply工具直接发回,则不会重复发送)。在 9099 Web UI 的「对话」里,当前所有 Matrix 消息统一落入同一个主会话线程(每条消息带
(消息来源:Matrix 房间「…」…)作用域头区分房间;插件侧另通过「本房间历史上下文」块在模型上下文层面做到按群隔离)。真正的按房间独立线程需改 serve(见第 8 / 11 节)。若配置了
MATRIX_CONTROL_ROOM_ID:CodeBuddy 调用需审批的工具(Bash / Write 等)时,控制室会收到提示(以m.notice系统提示发送,不触发未读/提醒),回复yes <id>允许 /no <id>拒绝。
reply 工具参数
参数 | 说明 |
| Matrix 房间 ID(取自会话里消息标签的 |
| 要发送的文本 |
| 可选,HTML 正文(与 |
| 可选, |
例如让 CodeBuddy 用
m.notice回一句状态提示:reply({ chat_id: "!abc:server", text: "已处理", msgtype: "m.notice" })。
health_check 工具
可在 CodeBuddy 会话里直接调用,或在 /mcp 健康检查中触发,等价于 npm run doctor 的连通性/E2EE 部分,返回 JSON:
{ "ok": true, "userId": "@alice:matrix.org", "e2ee": true, "cryptoReady": true }ok=false 时附 error 字段说明失败原因(连接/鉴权/E2EE 初始化)。
6. 局限与注意事项
端到端加密(E2EE)房间:默认只支持未加密房间。要桥接加密房间,把
MATRIX_E2EE=true,插件会复用 matrix-js-sdk 自带的 Rust crypto(initRustCrypto),由 SDK 自动完成「接收时解密、发送时加密」——无需自己实现加密协议。开启后:加密消息以
m.room.encrypted到达,SDK 解密完成(Event.decrypted)后类型变为真实类型,再由插件推送给会话;发送到加密房间的回复由 SDK 自动加密;
密钥存储(重要,与版本相关):在 matrix-js-sdk 42.x 下,Rust crypto 后端只有 wasm/IndexedDB 一种实现(
@matrix-org/matrix-sdk-crypto-wasm),没有 Node 原生后端。为了让它在 Node 上跑起来,插件在启动时用fake-indexeddb/auto给 Node 注入一个全局indexedDB垫片——该垫片是纯内存的,因此:密钥实际只存在于进程内存,
MATRIX_CRYPTO_DB在本版本下不会生成真实的 SQLite 落盘文件;重启进程后密钥需重新协商(不影响收发,只是要重新做一次密钥转发/设备验证)。真正的磁盘持久化需要升级到自带
@matrix-org/matrix-sdk-crypto-nodejs原生后端的 matrix-js-sdk 版本,或未来支持 nodejs 入口的版本(届时去掉fake-indexeddb垫片、改走原生后端即可)。注意:依赖里已装的
@matrix-org/matrix-sdk-crypto-nodejs在当前 42.2.0 下不被 SDK 调用,仅作为未来升级的备选;当前加密核心靠 wasm +fake-indexeddb内存垫片工作。
新设备首次进入加密房间,建议在 Matrix 客户端里验证本 bot 的设备(否则对方可能看到“未验证设备”提示,但消息仍可正常收发)。
媒体:默认只把消息文本桥接进会话;开启
MATRIX_DOWNLOAD_MEDIA会把图片/文件下载到本地并以[file: 路径]注入,便于 Agent 读取。权限中继依赖 CodeBuddy 的
claude/channel/permission能力;若 CodeBuddy 版本不支持,核心聊天桥接不受影响。
7. 数字分身:管理者授权模型(核心场景)
把分身当成「群里的同事」,既能被随意 @ 派活,又不会在管理者同意前真正改动任何东西。
场景
同事建多个群(如
#项目A、#客服),群里可能同时有多个分身 bot。同事在群里 @你的分身 派活;只在被 @ 时才响应(直接私聊总响应)。收到派活后:
常用 / 已授权工作(来自你预设的
MATRIX_TRUSTED_SENDERS/MATRIX_TRUSTED_ROOMS,或属于MATRIX_AUTHORIZED_WORK描述的范围)→ 自动执行(安全工具)。陌生工作(不在授权范围)→ 分身先出计划,调用
request_approval升级到你的控制室;你回approve才执行。高风险操作(
MATRIX_HIGH_RISK_TOOLS,如 Bash / 写文件)→ 无论来源,永远请示你。
架构分层
MCP 插件 = 安全传输 + 硬闸(代码强制,不信任模型):
@过滤、权限裁决allow/deny只依据可验证事实(是否 owner、是否可信来源、是否高风险工具)、控制室审批只认MATRIX_OWNER_ID。SKILL = 策略大脑(语义判断,交给 Agent):
skills/matrix-avatar/SKILL.md指导分身判断「常用 vs 陌生」,陌生时进入计划模式并调request_approval。Agent 只申请审批、从不自放行;放行只来自「管理者的可信来源预设」或「管理者approve」。
插件内置的 channel
instructions已内联该策略,因此不额外安装 SKILL 也能工作;skills/matrix-avatar/SKILL.md供你在 CodeBuddy 中复用/微调。
三层任务状态(按房间)
状态 | 含义 | 安全工具 | 高风险工具 |
| 可信来源 / 已 | 自动执行 | 请示管理者(控制室 |
| 已升级待审( | 拦截 | 拦截 |
| 陌生来源未授权 | 拦截 | 拦截(并提示 |
控制室命令(仅管理者 MATRIX_OWNER_ID 有效)
approve(或run/go,可选跟房间 ID,如approve !projectA:server)→ 授权该房间当前任务,分身开始执行。yes <id>/no <id>→ 对等待中的高风险权限请求放行 / 拒绝。其他人的控制室回复一律忽略。
配置示例(.env)
MATRIX_OWNER_ID=@you:matrix.org
MATRIX_TRUSTED_SENDERS=@alice:matrix.org,@bob:matrix.org
MATRIX_TRUSTED_ROOMS=!projectA:server
MATRIX_AUTHORIZED_WORK=回答产品问题、总结会议纪要、起草文档
MATRIX_MENTION_REQUIRED=true
MATRIX_HIGH_RISK_TOOLS=Bash,Write,Edit,MultiEdit,NotebookEdit8. Gateway Protocol 与 Web UI 会话线程
插件把每条 Matrix 消息投到本地 CodeBuddy 服务(Gateway Protocol),而不是旧的 notifications/claude/channel 注入:
投递:
POST /api/v1/runs,请求体为 Gateway 入站消息格式,source.conversation.id取 Matrix 房间 ID,因此同一房间的多条消息落入同一条会话;不同房间各自独立。回复取回:消费
GET /api/v1/runs/:runId/stream的 SSE,抽取 assistant 文本发回 Matrix。为避免与 Agent 主动调用reply工具造成重复投递,插件用一个agentRepliedViaTool标记去重:若 Agent 已通过reply工具把回复发回 Matrix,则不再发送 SSE 抓取到的文本。上下文:房间可读信息(群名、发信人昵称、群成员)以文本前缀形式写入
payload.text,保证 Gateway run 里的 Agent 也能看到原本由 channelmeta携带的上下文。鉴权:请求带
X-CodeBuddy-Request: 1与Authorization: Bearer <网关密码>;密码默认读~/.codebuddy/settings.json的gateway.password。
前提:必须运行
codebuddy --serve(默认 9099)。若服务不可达,插件会向原房间发一条⚠️ 无法连接本地 CodeBuddy 服务(9099)提示,消息不丢失但本次不处理。已知限制(已验证):当前 serve 版本中,Gateway run 无论传
conversation.id还是session.id,都会被附加到已有的主会话(primary session),不会按房间生成独立 Web UI 线程。根因在 serve 的getOrCreateSession(conversationId):只要primarySession存在就直接return this.primarySession,忽略传入的会话标识。因此「每个 Matrix 房间 = 一条独立 Web UI 会话」在本 serve 版本无法通过插件侧实现;Matrix 消息在 9099「对话」里统一落在主会话线程(每条消息带(消息来源:Matrix 房间「…」…)前缀以区分房间)。若要真正的按房间分线程,需二选一:① 推动 serve 在 Gateway run 下尊重
conversation.id/session.id(改动getOrCreateSession的 primary 短路逻辑);② 为 Matrix 编写与企微/微信同级的平台适配器(platform adapter),由适配器自行管理按会话的 Web UI 线程(工作量较大,且需 serve 加载)。排查时设MATRIX_GATEWAY_DEBUG=1看matrix-gateway-debug.log。插件侧缓解(已落地):尽管 serve 侧无法按房间分线程,插件仍在模型有效上下文层面做到按群隔离——每个房间在插件侧维护最近若干轮(用户消息 + 本房间回复)的滚动上下文,转发时注入为「本房间历史上下文」块并明确指示仅依据本房间上下文作答;同时每条入站消息带
(消息来源:Matrix 房间「…」…)作用域头。这样即便 serve 侧历史共享,模型实际看到的仍是按房间裁剪过的上下文,跨房间串味显著降低。轮数用MATRIX_ROOM_CONTEXT_TURNS(默认 6;设 0 关闭)控制;历史另见matrix-logs/history-<房间>.log。
9. 自检(doctor)
填好 .env 后,可先跑自检确认配置、连通性与 E2EE 状态,再启动 CodeBuddy:
npm run doctor自检会打印当前配置(token 脱敏)、验证 homeserver 可达与凭证有效,并在 MATRIX_E2EE=true 时尝试初始化 Rust crypto。任何一项失败都会给出明确原因并以非 0 退出码结束。
11. 未来迭代方向(Roadmap)
按影响面 / 优先级排列。其中路线 B 是真正解决「按房间分线程」的关键。
路线 B(推荐,关键):推动 serve 在 Gateway run 下尊重会话标识 ★
根因:serve 的
getOrCreateSession(conversationId)在已有主会话时直接return this.primarySession,忽略传入的conversation.id/session.id。改动:当 Gateway 入站带会话标识且非显式「主会话」时,按该标识创建 / 复用会话,而非一律塞进
primarySession(单函数短路逻辑)。收益:彻底实现「每个 Matrix 房间 = 一条独立 Web UI 线程」,消除当前插件侧上下文隔离的“权宜”性质,Web UI 可读性与审计大幅提升。
风险与状态:直接改
dist(minified)仅本地生效;正式需走 CodeBuddy 主干 PR。尚未执行,待管理者批准。
路线 C:为 Matrix 编写平台适配器(platform adapter)
思路:与企微 / 微信同级,由适配器自行管理按会话的 Web UI 线程。
现状评估:serve 的
LocalGatewayServer.initialize()中适配器为硬编码注册(GenericAdapter/WecomAdapter/WechatKfAdapter),无外部 / 插件扩展点;且 Webhook 入口同样走handleMessage → getOrCreateSession那条短路。因此路线 C 不仅工作量大,同样绕不开路线 B 的短路,在当前 serve 版本下单独实施收益有限。结论:优先级低于 B;仅在 serve 开放适配器扩展点后再考虑。
E2EE 密钥持久化
升级到自带
@matrix-org/matrix-sdk-crypto-nodejs原生后端的 matrix-js-sdk 版本(或支持 nodejs 入口的版本),去掉fake-indexeddb内存垫片,改为 SQLite 落盘,重启无需重新协商密钥。当前依赖里的@matrix-org/matrix-sdk-crypto-nodejs在 42.2.0 下不被 SDK 调用,作为升级备选已就绪。
增强隔离与上下文管理
MATRIX_ROOM_CONTEXT_TURNS已支持按房间滚动上下文;后续可考量:跨房间「记忆共享」白名单(可信同事房间之间有限共享)、按房间可配置系统提示、长会话摘要压缩以节省 token。
健壮性与可观测性
Gateway 连接失败时指数退避重连;在
matrix-gateway-debug.log之外补充结构化运行指标;多 bot 共存时的身份冲突规避(在MATRIX_MENTION_REQUIRED基础上进一步按user_id分流)。
打包与分发
走「方式 B」发布到官方插件市场,支持
codebuddy --channels plugin:matrix-channel@<市场>,免去--dangerously-load-development-channels开发开关。
10. 目录结构
matrix-channel/
├── src/
│ ├── config.ts # 环境变量 / 白名单 / 授权配置读取与校验
│ ├── matrix.ts # Matrix 客户端封装(连接、@提及过滤、收/发、下载媒体、E2EE、自检)
│ ├── index.ts # MCP 服务:channel 通知、授权硬闸、reply / request_approval 工具、控制室审批
│ └── doctor.ts # `npm run doctor` 自检入口
├── skills/
│ └── matrix-avatar/
│ └── SKILL.md # 分身行为策略(语义判断:常用 vs 陌生)
├── package.json
├── tsconfig.json
├── .gitignore
├── .env.example
├── matrix-history.log # 收发历史(落盘审计,已 gitignore)
├── matrix-gateway-debug.log # Gateway SSE 原始事件(MATRIX_GATEWAY_DEBUG=1 时)
└── README.mdAvailable Tools
6 toolshealth_checkA
运行连接/E2EE 自检(等价于 npm run doctor),返回 Matrix 连接与加密状态。可在 /mcp 健康检查中调用。
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that the tool performs a diagnostic self-check and returns connection and encryption status, which implies a read-only probe. It does not explicitly say it has no side effects, but the self-check framing makes the behavior sufficiently transparent for a zero-parameter tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one compact sentence that front-loads the action and scope, then adds the return value and invocation context. Every clause earns its place; there is no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple zero-parameter diagnostic tool with no output schema, the description covers purpose, method, return value, and invocation context. Nothing essential is missing for an agent to select and call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has no parameters and schema description coverage is 100%, so there is nothing for the description to clarify. Baseline for zero parameters is 4, and the description adds no conflicting or misleading parameter information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: it runs a connection/E2EE self-check equivalent to 'npm run doctor' and returns Matrix connection and encryption status. It also distinguishes this health-check tool from the messaging/approval-oriented sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear usage context by stating it can be invoked during /mcp health checks and is for checking connection/encryption status. It does not explicitly name when-not-to-use conditions, but the sibling tools are clearly different in purpose, so the distinction is implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_roomsA
列出本分身已加入的所有 Matrix 房间(room_id + 标题),用于了解「我在哪些房间 / 群」。当不知道该回哪个房间时,可据此找到与管理者(owner)的私聊房间。
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and discloses the scope (only rooms the avatar has joined) and the output content (room_id + title). For a read-only, zero-parameter listing tool this is adequate, though it omits minor traits like ordering, pagination, and whether the owner room is guaranteed to exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero filler. The first sentence front-loads the core purpose and output fields; the second adds a practical decision aid without repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 0-parameter list tool with no output schema, the description covers what is listed, what fields come back, and when to use it. Minor gaps (e.g., behavior when no rooms exist, pagination) are low-stakes for a read-only listing, so nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so schema coverage is trivially 100% and there is nothing to document. The baseline of 4 applies because no parameter semantics are needed; the description appropriately spends its effort on output and scope instead.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb (列出/list) and resource (all Matrix rooms this avatar has joined), and explicitly states the returned fields (room_id + title). The scope '本分身已加入' clearly separates it from per-room siblings like room_info and room_members, so an agent can tell them apart without opening another schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides a concrete usage scenario: when unsure which room to reply to, use this tool to locate the owner's private chat room. It does not, however, name alternatives or state when not to use it (e.g., room_info for a single room's details), so it lacks explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
replyA
通过 Matrix 把回复发送到指定房间(chat_id)。省略 chat_id 时回复发往最近一次转发进来的房间(原路返回)。发送会按配置自动重试;若多次仍发不回来源房间,则改用默认回复(MATRIX_DEFAULT_REPLY)发往控制室/owner 私聊兜底。
| Name | Required | Description | Default |
|---|---|---|---|
| html | No | 可选,HTML 格式正文(与 text 同时发送) | |
| text | Yes | 要发送的文本 | |
| chat_id | No | Matrix 房间 ID,例如 !abc:server。省略时回复发往最近一次转发进来的房间。 | |
| msgtype | No | 消息类型:m.text 普通消息;m.notice 系统提示(不触发未读/提醒) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
没有 annotations,因此描述承担了全部行为披露责任。描述主动说明了自动重试机制、失败后的默认回复兜底行为(发往控制室/owner 私聊),以及原路返回的逻辑,这些都是非显而易见的关键行为。
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
描述短小精悍,三句话分别说明核心操作、chat_id 省略行为和重试/兜底机制,信息密度高且没有冗余。关键行为前置,结构清晰。
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
对于发送消息类工具,描述配合完整 schema 已覆盖调用所需信息:目标房间、默认回退行为、重试和失败兜底。没有输出 schema 也不影响理解,整体上下文完整。
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema 描述覆盖率为 100%,所有参数在 schema 中已有说明。描述额外强调了 chat_id 省略时的行为,但 schema 中同样包含该信息,因此描述在参数语义上未显著超出 schema 提供的价值。
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
描述明确说明该工具通过 Matrix 发送回复到指定房间,并解释了省略 chat_id 时的原路返回行为。动词和资源都很具体,与 list_rooms、room_info 等只读查询类兄弟工具形成清晰区分。
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
描述清晰说明了何时使用该工具(发送回复)以及省略 chat_id 时的行为,但未明确提及何时不应使用或列举替代工具。整体使用场景清楚,只是缺少显式的排他性说明。
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
request_approvalA
当判断当前任务来自陌生来源或含高风险时调用,把任务升级到管理者控制室等待审批。管理者回复 approve 后任务会被重放并执行。
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | 需要审批的原因/计划摘要 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explains that the task is escalated, that it waits for approval, and that it will be replayed and executed after the manager replies 'approve'. It does not mention rejection behavior, but the core lifecycle is clearly disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one concise sentence that front-loads the trigger condition, then states the action and outcome. Every part is informative and there is no redundant wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with a single required parameter and no output schema, the description covers the key context: when to call, what happens, and what triggers execution. It does not specify behavior on rejection, but the overall guidance is sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers the single parameter 'reason' with 100% coverage, including its meaning as the approval reason or plan summary. The description adds no further parameter-level detail, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies a specific action: escalating the current task to a manager control room for approval. It also gives the triggering condition ('unfamiliar source or high risk'), which distinguishes it from the sibling tools like reply, health_check, and list_rooms.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool: when the task is from an unfamiliar source or carries high risk. It does not explicitly list alternatives or exclusions, but the condition is clear enough that an agent can decide appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
room_infoA
获取指定 Matrix 房间(群/私聊)的可读信息:名称、主题、成员昵称与 ID。用于配置与检查「房间 ID ↔ 名称」映射。chat_id 省略时取最近一次转发进来的房间。
| Name | Required | Description | Default |
|---|---|---|---|
| chat_id | No | Matrix 房间 ID,例如 !abc:server。省略时取最近对话房间。 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the behavioral disclosure burden. It does disclose that the operation retrieves readable info and defines the default behavior when chat_id is omitted, which is useful. However, it does not explicitly state that the operation has no side effects, what happens on invalid room IDs, or any permission requirements — gaps that matter for a tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler. The first sentence states the tool's purpose and outputs, the second gives the use case and default behavior. Critical information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple getter with one optional parameter, the description is mostly complete: it lists return fields, the use case, and the fallback behavior. Since there is no output schema, describing the expected fields is important and done here. Minor omissions around error/not-found behavior prevent a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value beyond the schema by clarifying that 'recent conversation' specifically means the most recently forwarded room, and by explaining why chat_id is optional in terms of the mapping use case.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description specifies a clear verb ('获取' / get) and resource ('指定 Matrix 房间'), and lists the exact data returned (name, topic, member nicknames and IDs). It does not explicitly contrast itself with siblings such as list_rooms or room_members, but the resource scope and output fields are specific enough to distinguish it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states a concrete use case: configuring and checking the 'room ID ↔ name' mapping. It also explains the optional chat_id behavior (fallback to the most recently forwarded room), which guides when to call the tool without an argument. No alternatives or when-not-to-use conditions are mentioned, hence not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
room_membersA
获取指定 Matrix 房间(群聊)的在场成员列表,返回每个成员的 user_id 与 display_name,用于了解「谁在场」。chat_id 省略时取最近一次转发进来的房间。
| Name | Required | Description | Default |
|---|---|---|---|
| chat_id | No | Matrix 房间 ID,例如 !abc:server。省略时取最近对话房间。 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
无 annotations,描述承担行为说明职责。它说明了工具是只读查询、返回成员列表并解释 chat_id 缺省行为,但未披露任何可能的权限要求、失败情形或数据即时性等行为特征。
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
两句话完整说明用途、返回值与缺省行为,信息密度高且无冗余,属于精炼的合格描述。
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
对单参数只读列表工具,描述已说明返回字段、缺省行为和使用场景;缺少输出结构样例或错误条件,但整体足以让 agent 正确调用。
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
参数仅有 chat_id,schema 已包含描述;描述额外说明了省略 chat_id 时的默认行为(取最近对话房间),为参数语义增加了超出 schema 的价值。
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
描述使用明确动词「获取」与资源「指定 Matrix 房间(群聊)的在场成员列表」,并具体说明返回 user_id 与 display_name,足以与 siblings 如 list_rooms、room_info 区分。
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
描述说明 chat_id 省略时取最近转发进来的房间,提供了明确的使用上下文;但未明确说明何时不使用本工具(例如需要房间详情时用 room_info),因此未达满分。
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
health_check - First observed
list_rooms - First observed
reply - First observed
request_approval - First observed
room_info - First observed
room_members
TDQS
Scored across 6 tools
The tools are mostly distinct: reply, health_check, request_approval, list_rooms, room_members, and room_info each target a different action or resource. The only mild overlap is between room_info and room_members, since room_info also includes member names/IDs, but the descriptions are clear enough to guide selection.
All names are lowercase snake_case, but the semantic pattern is mixed: reply is a bare verb, list_rooms and request_approval are verb+noun, while room_members and room_info are noun+noun descriptors. This is readable but not consistently a verb_noun convention.
Six tools is a tight, well-scoped set for a Matrix channel bridge. Each tool supports a distinct part of the workflow—responding, verifying health, escalating approval, and discovering rooms and participants—without redundancy or bloat.
The set covers the core bot workflow on a Matrix channel: replying, understanding room context, checking connection health, and handling approval escalation. Minor gaps like joining/leaving rooms or reading message history exist, but they are outside the apparent core purpose and do not create dead ends.
Maintenance
Related MCP Connectors
Telegram bridge for your MCP-compatible agent. Bidirectional, no LLM in our stack.
BridgeApp workspace over MCP: tasks, chats, threads, pages, and projects.
Real-time chat for AI agents. Claude Code, Cursor, Cline and Codex join channels over MCP.
Discover MCP servers and A2A agents; verify, message, post, follow, react, and receive webhooks.
Related MCP Servers
- AlicenseAqualityCmaintenanceBridges OpenAI Codex CLI to any MCP client, allowing headless Codex sessions via tools like codex and codex-reply.215 npm1MIT
- AlicenseAqualityDmaintenanceBridges any MCP client (like Claude Code, Zed, VS Code) to any ACP coding agent, enabling multi-agent orchestration from a single chat interface.24126 npm11Apache 2.0
- AlicenseNot gradedqualityDmaintenanceBridges a Matrix room with Claude Code's claude/channel feature, enabling chat from Matrix to interact with a running Claude Code session.GPL 3.0
- AlicenseNot gradedqualityCmaintenanceMCP server for Matrix that lets Claude list rooms, search/read messages, send messages and files, react, create rooms, and invite users, with multi-homeserver support and safe-by-default writes; no end-to-end encryption.MIT