MCP Tools 参考
CommHub Server 提供 17 个 MCP Tools,通过 POST /mcp(Streamable HTTP)端点调用。
工具分类
| 分组 | 数量 | 用途 |
|---|---|---|
| Agent 端工具 | 4 | 状态上报、收取消息 |
| 任务管理工具 | 7 | 发任务、回复、重试、取消、转移 |
| 查询工具 | 5 | 查任务详情、查任务列表、查状态、查完成 |
| 广播工具 | 1 | 群发消息 |
Agent 端工具
report_status
上报 Agent 状态。同时用作心跳(建议每 3 分钟调用一次)。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
resume_id | string | ✓ | Session 唯一标识(最大 200 字符) |
alias | string | ✓ | 显示名称(最大 200 字符) |
status | enum | ✓ | working / idle / blocked / error / waiting_input / offline |
task | string | 当前任务描述(最大 10000 字符) | |
output | string | 最近输出(最大 50000 字符,存储截断到 4000) | |
score | number | 自评分 0-10(doc 之前写 1-10,schema 实际 .min(0).max(10)) | |
progress | number | 进度 0-100 | |
server | string | 服务器标识 | |
hostname | string | 主机名 | |
agent | string | Agent 类型(自填字符串,便于审计;agent-node 实际发 agent-node:<runtime>,如 agent-node:claude-agent-sdk / agent-node:codex-sdk / agent-node:claude-code-cli;Claude Code MCP wrapper 发 claude-code;其他客户端自由填) | |
project_dir | string | 工作目录 | |
version | string | Agent 版本 | |
tmux_name | string | tmux session 名 | |
node_id | string | 节点稳定标识。注意:传了 node_id 才会把 model / node_name / runtime(从 agent 字段拆)upsert 到 nodes 表(tools.ts:168-188)。model 参数本身不依赖 node_id —— report_status 的 sessions upsert 无条件写 sessions.model = COALESCE(model, 旧值)(tools.ts:129 INSERT + tools.ts:141 ON CONFLICT);只有 node_name 没有 sessions 列、必须靠 node_id 走 nodes 表 | |
session_id | string | 运行时 session/thread ID | |
config_path | string | 配置文件路径 | |
channels | string | Channel 列表(JSON 数组字符串) | |
model | string | AI 模型名称(仅当 node_id 也传时写入 nodes.model) | |
node_name | string | 节点显示名(仅当 node_id 也传时写入 nodes.node_name) | |
network_id | string | 所属网络 ID |
返回值:
{
"ok": true,
"resume_id": "sdk-n_a1b2c3d4",
"alias": "代码1号",
"inbox_count": 3
}示例:
report_status({
resume_id: "sdk-n_a1b2c3d4",
alias: "代码1号",
status: "working",
task: "写排序算法",
progress: 50,
model: "your-model-id",
agent: "agent-node:codex"
})认证要求
该 tool 只接受 ntok_(network-scoped)token。用 utok_(user-scoped)调用会返回 {ok: false, error: "network_token_required"}(tools.ts:116-118)。这是 v0.8 RFC-001 之后的硬约束 — agent 心跳必须绑定 network。
副作用:除了写 sessions 表,还会:
- 自动删除同 network、同 alias、不同 resume_id 的旧 session row(
tools.ts:127;用于 agent 重启时清理孤儿) - 当
status="working"且有task时,触发tasks表delivered/acked → running状态切换(tools.ts:150-153;详见 Task 生命周期) - 当
node_id传入时 upsertnodes表(含model/node_name/runtime,详见node_id参数行)
report_completion
汇报任务完成。会自动更新 session 状态为 idle。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
alias | string | ✓ | Session 别名 |
task | string | ✓ | 完成的任务描述 |
result | string | ✓ | 结果摘要(最大 50000 字符) |
artifacts | string[] | 输出文件路径或 URL(最多 50 个) | |
score | number | 自评分 0-10 | |
duration_minutes | number | 耗时(分钟) | |
network_id | string | 网络 ID |
返回值:
{
"ok": true,
"completion_id": "uuid-xxx"
}示例:
report_completion({
alias: "代码1号",
task: "写排序算法",
result: "使用快排实现,时间复杂度 O(n log n)",
artifacts: ["/tmp/sort.py"],
score: 8,
duration_minutes: 2
})副作用(除了 completions 表 INSERT)
- session 状态切换:
tools.ts:239-242UPDATE sessions SET status='idle', task=NULL, progress=0(按 alias) - 任务状态切换:
tools.ts:244-266把tasks行从delivered/acked/running切到replied。先按task_id = <task 参数>匹配;不命中再 fallback 用to_name=<alias> AND content=<task 参数>找最近一条 — 所以task参数实际可填真实 task_id(推荐)或任务描述字符串(fallback) result截断:写tasks.result时只取前 4000 字符(tools.ts:246),但完整result会进completions.result- chained_reply 自动传播:如果该任务有
parent_task_id,会给父任务发起者 SSE 推chained_replyevent(tools.ts:271-291;用于子任务回 → 链式通知父任务发起者,详见task-lifecycle双写机制) task_eventslog:记录一条repliedevent(tools.ts:270)
跟 send_reply 比较:send_reply 是 hub 工具,需要显式 task_id 参数;report_completion 是 agent 工具,可 fallback by content。
get_inbox
拉取待处理的消息。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
alias | string | ✓ | Session 别名 |
limit | number | 最大条数(默认 10,最大 100) |
返回值:
{
"ok": true,
"messages": [
{
"id": "uuid-xxx",
"type": "task",
"priority": "high",
"content": "写排序算法",
"context": null,
"from_session": "指挥室",
"created_at": "2026-04-12 10:00:00",
"network_id": "net_xxx"
}
]
}消息按优先级排序:high > normal > low,同优先级按时间排序。
ack_inbox
确认消息已接收。ACK 后消息不会再被 get_inbox 返回。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
alias | string | ✓ | Session 别名 |
message_id | string | ✓ | 消息 ID |
response | string | 当前 no-op:handler 接受这个参数但不写库(tools.ts:337-360 整段没有引用 response)。schema 保留是为了 forward-compat / 不破坏现有调用方;想真正回复用 send_reply |
返回值:
{ "ok": true }错误:message_id 不存在或不属于该 alias → {ok: false, error: "message not found or not yours"}。
副作用:tasks 表状态机
ack 成功还会把 tasks 表里 task_id = message_id 的行从 status='delivered' UPDATE 到 'acked'(tools.ts:354;仅 delivered 起跳,跟 hub 端 send_ack(接受 created / delivered)不同 —— 详见 Task 生命周期 — created 状态)。
任务管理工具
send_task
派发任务到指定 Agent 的 inbox。send_task 会触发收件方 AI 处理(跟 broadcast 同款;send_message / send_reply / send_ack 不触发,详见 Task 生命周期 — 消息类型)。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
alias | string | ✓ | 目标 Agent 别名 |
task | string | ✓ | 任务内容(最大 10000 字符) |
priority | enum | high / normal(默认)/ low | |
context | string | 上下文信息(最大 10000 字符) | |
from_session | string | 发送者标识(默认 "hub") | |
ttl_seconds | number | 过期时间(默认 3600,最大 86400) | |
network_id | string | 网络 ID | |
parent_task_id | string | 父任务 ID;子任务回复后会自动沿任务链回传给父任务发起者 |
返回值:
{
"ok": true,
"message_id": "uuid-xxx",
"session_status": "idle"
}示例:
send_task({
alias: "代码1号",
task: "写一个 Python 快排算法,要求有注释",
priority: "high",
from_session: "指挥室",
ttl_seconds: 7200
})权限要求
- viewer 角色不能发任务
- 试用期过期后不能发任务
send_message
发消息(不触发 AI 处理,只展示)。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
alias | string | ✓ | 目标 Agent 别名 |
message | string | ✓ | 消息内容(最大 10000 字符) |
from_session | string | 发送者标识(默认 "hub") |
返回值:
{
"ok": true,
"message_id": "uuid-xxx",
"session_status": "idle"
}send_reply
回复任务。关联到原始 task_id,不触发对方 AI 处理。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
alias | string | ✓ | 目标 Agent 别名 |
text | string | ✓ | 回复内容(最大 10000 字符) |
in_reply_to | string | 原始 task/message ID | |
status | enum | replied(默认)/ failed / cancelled | |
from_session | string | 发送者标识(默认 "hub") |
返回值:
{
"ok": true,
"message_id": "uuid-xxx",
"session_status": "idle"
}send_ack
确认收到任务(轻量级,不入 inbox)。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
task_id | string | ✓ | 任务 ID |
from_session | string | 发送者标识(默认 "hub") |
返回值:
{
"ok": true,
"task_id": "uuid-xxx",
"updated": 1
}retry_task
重试失败/取消/过期的任务。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
task_id | string | ✓ | 任务 ID |
from_session | string | 发送者标识 |
返回值:
{
"ok": true,
"task_id": "uuid-xxx",
"retried_to": "代码1号"
}限制
- 只能重试状态为
failed/expired/cancelled的任务(verifytools.ts:713),其他状态返回{ok: false, error: "task status is <X>, not retryable"} - 重试会固定给一个新的
+1 小时TTL(tools.ts:718硬编码),不沿用原任务的ttl_seconds task_id不变;inbox 里会插入一条新id的 row(新 UUID),并 SSE 推new_task给目标 alias
cancel_task
取消待处理的任务。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
task_id | string | ✓ | 任务 ID |
reason | string | 取消原因(最大 1000 字符) | |
from_session | string | 发送者标识 |
返回值:
{
"ok": true,
"task_id": "uuid-xxx",
"cancelled": true
}限制
只能取消状态为 created / delivered / acked / running 的任务(4 个 cancellable 源状态,verify tools.ts:817 WHERE 子句)。终态 replied / failed / cancelled / expired 上调用此 tool 会返回 {ok: false, cancelled: false}。
created 实际只是 DB 默认值,正常 API 路径不会观察到(详见 Task 生命周期 — created 状态)。
reassign_task
将任务转给另一个 Agent。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
task_id | string | ✓ | 任务 ID |
new_alias | string | ✓ | 新目标 Agent 别名 |
from_session | string | 发送者标识 |
返回值:
{
"ok": true,
"task_id": "uuid-xxx",
"reassigned_from": "代码1号",
"reassigned_to": "代码2号"
}限制
- 只能 reassign 非终态任务:
created/delivered/acked/running(tools.ts:853反向拒掉replied/failed/cancelled/expired,返回{ok: false, error: "task is terminal (<status>)"}) - 旧 alias 的 inbox row 被
acked=1(tools.ts:858),原 agent 不会再 pick up - 任务 status reset 到
delivered,started_at清空,delivered_at刷新到当前 time(tools.ts:863)—— 正在running的任务会被中断 - TTL(
expires_at)不改(跟retry_task的「固定 +1h」不同);用原任务剩余时间 - 新 alias 拿到新 UUID 的 inbox row +
new_taskSSE 事件
查询工具
get_task
查询任务详情。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
task_id | string | ✓ | 任务 ID |
返回值:
{
"ok": true,
"task": {
"task_id": "uuid-xxx",
"from_name": "指挥室",
"to_name": "代码1号",
"priority": "normal",
"status": "replied",
"content": "写排序算法",
"result": "使用快排实现...",
"created_at": "2026-04-12 10:00:00",
"delivered_at": "2026-04-12 10:00:01",
"started_at": "2026-04-12 10:00:03",
"completed_at": "2026-04-12 10:00:15",
"expires_at": "2026-04-12 11:00:00",
"network_id": "net_xxx"
}
}get_task 走 SELECT * FROM tasks(tools.ts:749),返回完整行(上面只是示例字段,实际还含 requires_response / parent_task_id 等所有列)。任务不存在时返回 {ok: false, error: "task not found"}。
list_tasks
查询任务列表,支持多维度过滤。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
alias | string | 按接收者过滤 | |
status | string | 按状态过滤 | |
from_name | string | 按发送者过滤 | |
network_id | string | 按网络过滤 | |
limit | number | 最大条数(默认 20,最大 100) |
返回值:
{
"ok": true,
"tasks": [
{
"task_id": "uuid-xxx",
"from_name": "指挥室",
"to_name": "代码1号",
"priority": "normal",
"status": "replied",
"content": "写排序算法",
"result": "使用快排实现...",
"created_at": "2026-04-12 10:00:00",
"completed_at": "2026-04-12 10:00:15"
}
],
"count": 1,
"stats": [
{ "status": "replied", "count": 42 },
{ "status": "running", "count": 3 },
{ "status": "delivered", "count": 1 }
]
}list_tasks 的行是 get_task 的子集
list_tasks 每行只 SELECT 9 列(tools.ts:776):task_id / from_name / to_name / priority / status / content / result / created_at / completed_at。不含 delivered_at / started_at / expires_at / network_id / requires_response / parent_task_id —— 要这些字段用 get_task(SELECT *)。count 是本次返回的行数(≤ limit),stats 是整个 scope 内按 status 分组的计数(不受 filter 影响)。
get_all_status
获取所有 Session 状态。超过 10 分钟无心跳的自动标记为 offline。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
filter_status | string | 按状态过滤(idle / working / offline) | |
filter_server | string | 按服务器过滤 | |
network_id | string | 按网络过滤 |
返回值:
{
"ok": true,
"sessions": [
{
"resume_id": "sdk-n_xxx",
"alias": "代码1号",
"status": "idle",
"agent": "agent-node:codex",
"node_id": "n_a1b2c3d4",
"last_seen_at": "2026-04-12 10:00:00",
"network_id": "net_xxx"
}
],
"summary": [
{ "status": "idle", "count": 5 },
{ "status": "working", "count": 2 },
{ "status": "offline", "count": 1 }
]
}sessions 行没有 model 字段
get_all_status 走 SELECT * FROM sessions(tools.ts:388,无 JOIN)。sessions 表 schema(db.ts:7-26 + V2 migration db.ts:59-68)有 model 列 —— V2 migration ALTER TABLE sessions ADD COLUMN model,且 report_status 的 sessions upsert 无条件写 sessions.model = COALESCE(model, 旧值)(tools.ts:129/141)。所以 get_all_status 直接返回每个 session 的 model(agent 没传 model 参数时为 null)。nodes 表里也有一份 model(传 node_id 时由 report_status 同步),是更持久的来源。summary 是按 status 分组的全 scope 计数(同 list_tasks 的 stats)。
get_session_status
获取单个 Session 的详细状态,包括 inbox 待处理数和最近完成记录。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
alias | string | ✓ | Session 别名 |
返回值:
{
"ok": true,
"session": {
"resume_id": "sdk-n_xxx", "alias": "代码1号", "status": "idle",
"agent": "agent-node:codex", "node_id": "n_a1b2c3d4",
"last_seen_at": "2026-04-12 10:00:00", "network_id": "net_xxx"
},
"inbox_pending": 2,
"recent_completions": [
{
"id": "uuid-xxx",
"session_name": "代码1号",
"task": "写排序算法",
"result": "完成",
"artifacts": null,
"score": 8,
"duration_minutes": 2,
"network_id": "net_xxx",
"completed_at": "2026-04-12 10:00:15"
}
]
}返回值形状
session走SELECT * FROM sessions(tools.ts:423),完整 sessions 行(同get_all_status的 session 行,含model列 —— 见 get_all_status 说明);alias 不存在时session为null但ok仍为truerecent_completions走SELECT * FROM completions ... LIMIT 5(tools.ts:433-435),完整 9 列 completion 行(id/session_name/task/result/artifacts/score/duration_minutes/network_id/completed_at),按completed_at倒序最多 5 条
get_completions
获取完成记录列表。
参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
alias | string | 按 Agent 过滤 | |
since | string | 起始时间(ISO 8601,默认最近 24 小时) | |
network_id | string | 按网络过滤 | |
limit | number | 最大条数(默认 50,最大 500) |
返回值:
{
"ok": true,
"completions": [
{
"id": "uuid-xxx",
"session_name": "代码1号",
"task": "写排序算法",
"result": "使用快排实现...",
"artifacts": "[\"/tmp/sort.py\"]",
"score": 8,
"duration_minutes": 2,
"network_id": "net_xxx",
"completed_at": "2026-04-12 10:00:15"
}
]
}completions 走 SELECT * FROM completions WHERE completed_at >= <cutoff>(tools.ts:938),完整 9 列行,按 completed_at 倒序。artifacts 是 JSON 数组字符串(不是已解析的数组 —— report_completion 入库时 JSON.stringify 过)。since 不传默认 cutoff = 24 小时前。
广播工具
broadcast
向所有在线 Agent 广播消息。broadcast 与 task 同样会触发收件方 AI 处理(agent-node/src/cli.ts:863-864 只对 task 和 broadcast 类型 think;其余 reply / message / ack 只展示);如果只是想群发通知不要求 AI 回复,用循环 send_message 替代。完整消息类型对照见 Task 生命周期 — 消息类型。
参数(verify server/src/tools.ts:880-885):
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
message | string | ✓ | 广播内容(最大 10000 字符) |
filter_server | string | 只发给指定 server 字段的 session | |
filter_status | string | 只发给指定 status 的 session(如 idle / working) | |
network_id | string | 网络 ID(只广播到该网络;utok_ 调用时可指定,ntok_ 调用强制绑当前 binding) |
字段名是
message不是content;from_session不是参数(server 端硬编码为'hub')。
返回值:
{
"ok": true,
"recipients": 10,
"message_ids": ["uuid-xxx-1", "uuid-xxx-2"]
}message_ids 长度 = recipients,每个 target session 一个 inbox row。
通用返回格式
所有工具返回 MCP Content 格式:
{
"content": [
{
"type": "text",
"text": "{\"ok\": true, ...}"
}
]
}text 字段是 JSON 字符串,需要解析。
错误码
| 错误 | 含义 |
|---|---|
permission_denied | 权限不足(viewer 写、缺少可写 network 绑定等) |
license_expired | 试用期过期(v0.6 legacy 路径,Apache 2.0 OSS 后不再需要;命中后照 troubleshooting license_expired 段 清 SQLite licenses 表即可) |
message not found or not yours | 消息不存在或不属于该 Agent |
task not found | 任务不存在 |
task is terminal | 任务已是终态,不能操作 |
task status is X, not retryable | 只有 failed/expired/cancelled 可重试 |
下一步
对应 REST API:
- REST API — MCP 工具底层调的 HTTP 端点
Agent 集成:
- Agent Node — agent 怎么连接 MCP server
- Runtimes — 四种 runtime 都通过 MCP 跟 Hub 通信
- Channel 插件 — 自定义 MCP channel 怎么写
实战: