使用说明
MCP代理中心
一个网络MCP服务器,用于通过共享SQLite数据库协调多个AI代理。它作为Docker守护进程运行,所有代理都通过HTTP连接。
快速开始
test -f deploy/hub.local.env || cp deploy/hub.local.env.example deploy/hub.local.env
grep -q '^MCP_HUB_REGISTER_TOKEN=' deploy/hub.local.env || \
printf 'MCP_HUB_REGISTER_TOKEN=%s\n' "$(openssl rand -hex 32)" >> deploy/hub.local.env
chmod 600 deploy/hub.local.env
./hub.sh build # Build Docker image
./hub.sh start # Start daemon on port 3000
./hub.sh status # Check that it is running
./hub.sh smoke # Verify handshake + registration + authenticated tool call
管理
./hub.sh build # Build Docker image
./hub.sh test # Run tests
./hub.sh start # Start server daemon
./hub.sh stop # Stop
./hub.sh restart # Restart
./hub.sh status # Status + health check
./hub.sh smoke # MCP handshake + registration/auth smoke test
./hub.sh logs # Logs (use logs -f to follow)
./hub.sh db # SQLite shell for DB inspection
./hub.sh clean # Remove everything
KPI轮次(8-12名员工)
对于比较基线与哈希/blob模式运行:
set -a; . deploy/hub.local.env; set +a # expose the same registration secret to helpers
./scripts/kpi-round.sh # default: 10 workers
WORKERS=12 ./scripts/kpi-round.sh # upper load boundary
USE_AUTH_TOKEN=true WORKERS=12 ./scripts/kpi-round.sh # for auth_mode=enforce
报告保存到 /tmp/exp5/exp5-kpi.json (或 $OUT_DIR/exp5-kpi.json).
该报告还包括运输领域(transport_wait_*, transport_polling_calls)以及它们的基线与优化的增量。
脚本将编排器/workers注册到 onboarding_mode=none 以避免基准测试期间不必要的入职令牌开销。
Smart Swarm Round(真正的Claude/Codex工人)
要运行真正的CLI worker而不是合成调用:
set -a; . deploy/hub.local.env; set +a
./scripts/smart-swarm-round.sh
WORKERS=12 WORKER_BACKEND=mixed ./scripts/smart-swarm-round.sh
WORKERS=10 WORKER_BACKEND=claude ./scripts/smart-swarm-round.sh
USE_AUTH_TOKEN=true WORKERS=12 WORKER_BACKEND=mixed ./scripts/smart-swarm-round.sh
本轮工人合同使用 register_agent(onboarding_mode=none) 没有 get_onboarding 以减少服务令牌开销并在实验中保持有用的流量。
关键变量:
ENDPOINT=http://127.0.0.1:3000/mcp
WORKERS=8
WORKER_BACKEND=mixed # claude | codex | mixed
USE_AUTH_TOKEN=auto # auto | true | false
ENABLE_NAMESPACE=auto # auto | true | false
WORKER_TIMEOUT_SEC=900
OUT_DIR=/tmp/smart-swarm
SNAPSHOT_RESPONSE_MODE=auto # auto | tiny | nano (auto => nano when server supports it)
ALLOW_BACKEND_FALLBACK=1 # 1 = fallback to another backend on worker runtime failure
SKIP_CLI_PREFLIGHT=0 # 1 = skip CLI availability/auth preflight checks
脚本:
- 寄存器编排器;
- 为每个工人创建一个任务;
- 通过以下方式并行启动真正的工人
claude/codex; - 捕获快照(
list_tasks/read_messages/get_context)innano如果支持(或tiny回退); - 可以自动重新启动失败的
claude工人在codex当ALLOW_BACKEND_FALLBACK=1(exit!=0或空输出); - 收集KPI(完成率、延迟、消息/上下文字符、令牌代理);
- 将报告写入
$OUT_DIR/smart-swarm-<experiment>.json(包括backend_health,backend_runtime_health,fallback_used,snapshots.*_bytes,以及snapshots.total_tokens_est).
等待模式A/B(微型vs微型vs纳米)
测量运输有效载荷的节省 wait_for_updates:
ENDPOINT=http://127.0.0.1:3300/mcp ROUNDS=12 WAIT_MODES=default,tiny,micro,nano ./scripts/wait-mode-ab.sh
输出:
- JSON报告
avg_bytes和avg_ms对于选定的模式(WAIT_MODES,默认值tiny,micro,nano); - 支持
default模式(无response_mode)验证服务器默认值; - 增量
default_vs_tiny,default_vs_nano,micro_vs_tiny,nano_vs_tiny,nano_vs_micro用于直接运输比较; - 场景只监听
messages溪流(wait_for_updates.streams=["messages"]); - 默认文件:
/tmp/wait-mode-ab-<ts>.json(或$OUT_FILE).
回购隔离工作流(没有存储库访问权限的工作人员)
如果工作人员不得更改项目文件:
- 工作人员仅通过MCP发送结构化切换(
intent,evidence,patch_plan,verification_plan,risk_notes); - 使用
send_blob_message/share_blob_context与compression_mode=lossless_auto对于大型有效载荷; - 只有编排者/审阅者将代码更改应用于存储库;
- 工作人员不创建本地项目文件(中的临时文件除外
/tmp).
先决条件:
claude和codexCLI已安装并经过身份验证;- 集线器可通过以下方式访问
ENDPOINT. - 桥梁工人不需要直接配置MCP;跑步者故意禁用后端 MCP服务器并协调所有经过身份验证的集线器调用。
空隔离目录的现成模板:
templates/CLAUDE.isolated-swarm.md
快速使用:
mkdir -p /tmp/isolated-swarm-worker && cd /tmp/isolated-swarm-worker
cp /path/to/mcp-local/templates/CLAUDE.isolated-swarm.md ./CLAUDE.md
claude
观察者模式(实时指标)
对于实时集线器的连续只读监控:
./scripts/observe-hub.sh
INTERVAL_SEC=10 SAMPLES=12 TAG=peak-window ./scripts/observe-hub.sh
脚本从中读取指标 mcp-hub 容器SQLite数据库和存储:
- 原始JSONL:
/tmp/hub-observer/<tag>.jsonl - JSON摘要:
/tmp/hub-observer/<tag>.summary.json
主要摘要字段:在线代理、任务积压、活动声明、活动/消息强度、5分钟内的顶级操作、命名空间分布和观察窗口内的趋势。
N小时总结报告
对于回顾池报告(SQLite只读,JSON+Markdown):
./scripts/pool-report.sh --hours 12
./scripts/pool-report.sh --hours 24 --out-dir /tmp/hub-reports --tag day-1
./scripts/pool-report.sh --hours 6 --db "$HOME/.mcp-hub/hub.db"
输出:
- JSON:
/tmp/hub-reports/<tag>.json - MD:
/tmp/hub-reports/<tag>.md
该报告包括:任务/声明吞吐量、身份验证覆盖率(valid/missing/invalid),所选窗口的顶部操作/代理、失败原因、每小时趋势和命名空间吞吐量。
覆盖端口或数据库路径:
MCP_HUB_PORT=8080 MCP_HUB_DATA=/path/to/dir ./hub.sh start
关键协议模式:
MCP_HUB_AUTH_MODE=observe|warn|enforce
MCP_HUB_REGISTER_TOKEN=<bootstrap-secret>
MCP_HUB_ALLOW_LEGACY_AGENT_CLAIM=false
MCP_HUB_REGISTER_RATE_LIMIT_RPS=5
MCP_HUB_REGISTER_RATE_LIMIT_BURST=20
MCP_HUB_NAMESPACE_GOVERNANCE=off|warn|require
MCP_HUB_EXTRA_BIND_HOSTS=100.107.1.68[,192.168.1.50]
MCP_HUB_SESSION_IDLE_TIMEOUT_MS=21600000 # <=0 disables idle session eviction (sessions live until DELETE /mcp or server restart)
MCP_HUB_SESSION_PROVISIONAL_TTL_MS=60000 # absolute deadline to present valid agent auth after initialize
MCP_HUB_SESSION_GC_INTERVAL_MS=60000
MCP_HUB_MAX_SESSIONS=500
MCP_HUB_MAX_SESSIONS_PER_SOURCE=100
MCP_HUB_SESSION_INITIALIZE_RPS=10
MCP_HUB_SESSION_INITIALIZE_BURST=20
MCP_HUB_UNKNOWN_SESSION_POLICY=error
MCP_HUB_AGENT_OFFLINE_AFTER_MS=1800000
MCP_HUB_AGENT_RETENTION_MS=604800000
MCP_HUB_AUTO_PACK_MIN_PAYLOAD_CHARS=2048
MCP_HUB_AUTO_PACK_MIN_GAIN_PCT=3
MCP_HUB_LOSSLESS_AUTO_MIN_PAYLOAD_CHARS=1024
MCP_HUB_LOSSLESS_AUTO_MIN_GAIN_PCT=3
MCP_HUB_WAIT_MAX_MS=25000
MCP_HUB_WAIT_DEFAULT_MS=10000
MCP_HUB_WAIT_RETRY_FACTOR=1.5
MCP_HUB_WAIT_RETRY_CAP_MS=10000
MCP_HUB_WAIT_RETRY_JITTER_PCT=0.2
MCP_HUB_MAX_CONSENSUS_VOTES=1000
MCP_HUB_CONSENSUS_QUALITY_WEIGHTING=on|off
MCP_HUB_DONE_EVIDENCE_MIN_REFS=1
MCP_HUB_MAX_EVIDENCE_REFS_PER_CALL=16
MCP_HUB_MAX_EVIDENCE_REF_CHARS=256
MCP_HUB_ARTIFACT_MAX_BYTES=52428800
MCP_HUB_ARTIFACT_TICKET_TTL_SEC=300
MCP_HUB_ARTIFACT_UPLOAD_TICKET_MAX_ACTIVE=10000
MCP_HUB_ARTIFACT_UPLOAD_TICKET_MAX_PER_AGENT=100
MCP_HUB_ARTIFACT_UPLOAD_RESERVATION_TTL_MS=300000
MCP_HUB_ARTIFACT_DOWNLOAD_TICKET_MAX_ACTIVE=20000
MCP_HUB_ARTIFACT_DOWNLOAD_TICKET_MAX_PER_AGENT=200
MCP_HUB_ARTIFACT_UPLOAD_TTL_SEC=300
MCP_HUB_ARTIFACT_DOWNLOAD_TTL_SEC=180
MCP_HUB_ARTIFACT_RETENTION_SEC=86400
MCP_HUB_WAIT_DEFAULT_RESPONSE_MODE=compact|tiny|micro|nano|full
MCP_HUB_WAIT_DEFAULT_TIMEOUT_RESPONSE=default|minimal
MCP_HUB_WAIT_LOG_HITS=true|false
MCP_HUB_WAIT_LOG_TIMEOUTS=true|false
MCP_HUB_DEFAULT_ONBOARDING_MODE=full|compact|none
MCP_HUB_EPHEMERAL_DEFAULT_ONBOARDING_MODE=compact|full|none
MCP_HUB_REREGISTER_ONBOARDING_MODE=none|compact|full
MCP_HUB_PUBLIC_BASE_URL=http://localhost:3000
持久生产配置文件存储在存储库中:
deploy/hub.production.env(带注释和优化的默认值)deploy/hub.local.env(可选局部覆盖,gitignored)
港口 127.0.0.1 总是出版。要添加外部接口,请定义 MCP_HUB_EXTRA_BIND_HOSTS 在 deploy/hub.local.env.
hub.sh 拒绝开始生产 auth_mode=enforce 配置文件直到
MCP_HUB_REGISTER_TOKEN 在该受保护的覆盖层中设置。
本地覆盖示例:
cp deploy/hub.local.env.example deploy/hub.local.env
# then edit deploy/hub.local.env and set:
# MCP_HUB_EXTRA_BIND_HOSTS=100.107.1.68
# MCP_HUB_PUBLIC_BASE_URL=http://100.107.1.68:3000
./hub.sh 自动拾取它(如果文件存在)。优先:
- 在命令中传递的环境变量(
MCP_HUB_* ./hub.sh start) MCP_HUB_LOCAL_ENV_FILE=/path/to/local.env(或违约deploy/hub.local.env)MCP_HUB_ENV_FILE=/path/to/file.envdeploy/hub.production.env(自动默认)
应用配置文件更改:
./hub.sh restart
./hub.sh status
金丝雀流不停止工作容器:
MCP_HUB_CONTAINER=mcp-hub-canary \
MCP_HUB_PORT=3300 \
MCP_HUB_DATA="$HOME/.mcp-hub-canary" \
MCP_HUB_AUTH_MODE=warn \
MCP_HUB_NAMESPACE_GOVERNANCE=require \
./hub.sh start
克劳德代码连接
全局配置(适用于任何目录) ~/.claude/.mcp.json:
{
"mcpServers": {
"agent-hub": {
"url": "http://localhost:3000/mcp"
}
}
}
对于一个项目,将相同的格式放置在 .mcp.json 在项目根。
此存储库提供了一个入门模板 .mcp.example.json.
Claude桌面连接
文件: ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"agent-hub": {
"url": "http://localhost:3000/mcp"
}
}
}
Codex连接
将正在运行的Streamable HTTP服务器添加到Codex:
codex mcp add agent-hub --url http://127.0.0.1:3000/mcp
codex mcp get agent-hub --json
网络连接(其他机器)
如果配置了额外的绑定(例如 MCP_HUB_EXTRA_BIND_HOSTS=100.107.1.68),远程客户端可以使用该IP/主机名,而不是 localhost:
{
"mcpServers": {
"agent-hub": {
"url": "http://192.168.1.100:3000/mcp"
}
}
}
集 MCP_HUB_PUBLIC_BASE_URL 也可以连接到外部可达的原点;工件上传/下载
否则URL默认为 localhost 并且不会在远程客户端上工作。持票人和登记
令牌需要加密的可信网络(例如VPN)或TLS反向代理;不要
在不受信任的网络上发布纯HTTP端点。浏览器客户端还需要其确切的
起源于 MCP_HUB_ALLOWED_ORIGINS.
建筑学
一个Docker守护进程服务器,所有代理通过HTTP(流式HTTP传输)连接。
┌─────────────┐ ┌────────────────────────┐
│ Claude Code ├─── HTTP ────►│ │
└─────────────┘ │ │
│ MCP Agent Hub │
┌─────────────┐ │ :3000 │ ┌──────────┐
│ Claude Desk ├─── HTTP ────►│ ├─►│ SQLite │
└─────────────┘ │ Docker container │ │ hub.db │
│ │ └──────────┘
┌─────────────┐ │ │
│ Codex/Other ├─── HTTP ────►│ │
└─────────────┘ └────────────────────────┘
可用工具(65)
| 工具 | 说明 |
|---|---|
register_agent |
注册代理(先致电;使用 lifecycle: "ephemeral" 对于短命工人;提供 runtime_profile 用于精确的任务路由) |
update_runtime_profile |
更新注册代理 runtime_profile (启动后更改工作目录/模式时有用) |
list_agents |
列出所有代理和状态(response_mode: full/compact/summary) |
suggest_agents |
对能力/模型/运行时请求的代理进行排名 |
get_onboarding |
了解协议功能和规则 |
send_message |
向一个代理发送消息或广播,支持 trace_id/span_id |
send_blob_message |
将消息作为哈希引用发送到已消除重复的blob(单次调用,默认 compression_mode=lossless_auto;支持 trace_id/span_id) |
read_messages |
阅读收件箱消息(response_mode: full/compact/tiny/nano; full 在以下情况下被禁止 polling=true) |
start_thread |
启动由跟踪范围消息支持的主题线程 |
reply_thread |
回复现有讨论线索 |
read_thread |
使用光标分页读取可见的讨论线程 |
search_hub |
搜索消息、任务、上下文、活动、工件和共识 |
fetch_hub_refs |
水合物选择的搜索/事件参考,没有广泛的列表阅读 |
save_filter |
保存可重复使用的信号馈送过滤器 |
list_filters |
列出当前代理拥有的筛选器 |
read_filter_feed |
读取并可选择前进已保存的筛选器光标 |
delete_filter |
删除已保存的自有筛选器 |
read_signal_feed |
跨中心源读取低令牌可操作收件箱 |
ack_feed_items |
确认已处理的信号馈送项目 |
get_hub_digest |
阅读有界多源协调摘要 |
write_memory |
存储持久的、命名空间范围的共享内存 |
search_memory |
按文本/标签/重要性搜索共享内存 |
get_memory_digest |
启动时读取紧凑型高值内存 |
get_trace_timeline |
读取跨源跟踪时间线 |
create_task |
在共享板上创建任务(execution_mode: any/repo/isolated, consistency_mode: auto/cheap/strict,支持 trace_id/span_id) |
update_task |
更新任务(状态、分配、, execution_mode, consistency_mode,用 confidence/verification_passed/evidence_refs,支持 trace_id/span_id) |
list_tasks |
查看任务板(response_mode: full/compact/tiny/nano; full 在以下情况下被禁止 polling=true) |
suggest_task_agents |
对特定任务的兼容代理进行排名 |
poll_and_claim |
按优先级原子性地声明下一个可用任务(include_artifacts 小附件参考选项) |
claim_task |
在租赁模式下声明特定任务(防重复; include_artifacts 选项) |
renew_task_claim |
续订任务租约 |
release_task_claim |
释放租约并设置最终状态(done 需要 confidence/verification_passed/evidence_refs;严格模式也要求 verified_by 有验证者撰写的证据) |
list_task_claims |
列出活动租用任务和到期时间 |
attach_task_artifact |
将工件附加到任务并自动共享给当前受让人(用于仓库隔离切换) |
list_task_artifacts |
列出附加到任务的工件(full/compact/tiny,支持 limit/offset) |
get_task_handoff |
获取整合的任务切换包(deps+证据参考+工件提示),可选择下载工单(include_downloads) |
delete_task |
安全存档/删除无人认领的任务 |
share_context |
共享上下文(键值),支持 trace_id/span_id |
share_blob_context |
将上下文作为哈希引用共享到已消除重复的blob(单次调用,默认 compression_mode=lossless_auto;支持 trace_id/span_id) |
get_context |
从其他代理获取上下文(response_mode: full/compact/tiny/nano/summary, updated_after 三角洲; full 禁止当 polling=true) |
resolve_consensus |
解决多代理分歧:内联投票或 votes_blob_hash/votes_blob_ref,质量加权(quality_weighting: on/off), response_mode: full/compact/tiny, emit_blob_ref_policy (never/always/on_escalate/on_conflict) |
resolve_consensus_from_context |
直接达成共识 context (context_id 或 context_agent_id+context_key)无需手动提取哈希值 |
resolve_consensus_from_message |
直接达成共识 message (message_id)无需手动散列胶代码 |
list_consensus_decisions |
查看持续的共识决策(response_mode: full/compact/tiny) |
pack_protocol_message |
使用自适应无损策略将有效载荷打包到CAEP-v1数据包中(mode:auto 仅启用具有足够大小/增益的词典) |
unpack_protocol_message |
解压缩CAEP-v1数据包并验证哈希值 |
hash_payload |
计算引用/数据删除的确定性有效载荷哈希 |
store_protocol_blob |
存储已消除重复的blob;默认情况下为私有,具有明确的公共/代理授权 |
get_protocol_blob |
获取经过身份验证的代理可见的blob |
list_protocol_blobs |
仅列出可见的blob和访问计数器 |
create_artifact_upload |
为二进制侧通道传输创建上传票证+URL(不带MCP有效载荷令牌) |
create_artifact_download |
创建下载票+共享工件下载的URL |
create_task_artifact_downloads |
为任务绑定工件创建批量下载票(单次调用,支持 limit) |
share_artifact |
授予工件对特定代理的访问权限,可选择绑定到任务(task_id)并通知 |
list_artifacts |
列出代理可见的工件(full/compact/tiny) |
get_activity_log |
代理活动日志(response_mode: full/compact/summary) |
get_kpi_snapshot |
内置KPI聚合超过1m/5m/30m(response_mode: "tiny" 最小有效载荷;包括 collective_accuracy, execution_backlog、配置文件不匹配、工件活动、任务工件切换使用和传输度量 wait_hits/timeouts/retry_after) |
get_transport_snapshot |
窗口的轻量级等待/轮询传输效率快照(window_sec),模式 tiny/full |
wait_for_updates |
更新的长期投票(streams 为了过滤信道, cursor 用于紧凑三角模式; response_mode: "nano" 用于最短的机器格式 c/s/u/r; response_mode: "micro" 用于紧凑兼容模式; timeout_response: "minimal" 超时时仅返回更改的标志;正常超时返回 retry_after_ms 或 r 在具有自适应退避+抖动的纳米模式下,可以通过以下方式禁用 adaptive_retry:false) |
read_snapshot |
轮询循环的批读取:一个调用返回 messages+tasks+context 使用单个光标(compact/tiny/nano) |
read_event_deltas |
从游标读取可回放的流事件增量 |
evaluate_slo_alerts |
重新计算SLO警报(未决年龄/索赔流失/过时in_progress) |
list_slo_alerts |
列出打开/关闭的SLO警报 |
get_auth_coverage |
按时间窗口和工具划分的身份验证令牌使用覆盖率 |
run_maintenance |
运行保留、索赔清理、归档和SLO整理 |
工件上传/下载工单工具需要一个实际具有MCP工具访问权限的客户端/运行时
已协商 artifact_tickets: true.桥梁启动的CLIs由桥梁运营商和
不得致电 create_artifact_upload, create_artifact_download,或 share_artifact 直接
当大桥做广告时 artifact_tickets: false;他们应该返回结构化的交接和
/tmp 取而代之的是集线器连接的网桥/运营商的路径。
nano 读取工具模式(无损,仅限短键):
read_messages:{ m, h, n }+m[]带钥匙的物品i/f/t/u/r/c/d(+x/y对于轨迹/跨度,b/z对于blob ref)list_tasks:{ t, h, n }+t[]带钥匙的物品i/s/a/p/n/e/cm/u/tc/t/dc(+x/y用于轨迹/跨度)get_context:{ c }+c[]带钥匙的物品i/a/k/u/c/d(+x/y对于轨迹/跨度,b/r对于blob ref)read_snapshot:{ s, h, ch, n, u },在哪里s={m,t,c}是批处理数据u是统一光标
对于轮询循环,通过 polling:true 到 read_messages/list_tasks/get_context;当 polling:true,服务器禁止 response_mode:"full" 并返回 FULL_MODE_FORBIDDEN_IN_POLLING.
回购隔离工作者的最佳实践:工作者仅通过blob/hash引用、审阅者调用发送结构化提案/投票 resolve_consensus,并且存储库更改由编排器/审阅器应用。
运行来自不同目录的代理
使用全局配置(~/.claude/.mcp.json),每个代理都可以在单独的项目中工作:
# Terminal 1 - frontend agent
cd ~/projects/frontend
claude -p "$(cat ~/mcp-local/AGENT_PROMPT.md)
You are claude-frontend. Your responsibility area: React UI.
Register and check the task board."
# Terminal 2 - backend agent
cd ~/projects/backend
claude -p "$(cat ~/mcp-local/AGENT_PROMPT.md)
You are claude-backend. Your responsibility area: API and database.
Register and check the task board."
角色启动器 /hub
统一角色启动器 codex 和 claude 使用运行时配置文件自动检测(repo/隔离):
./hub --role orchestrator --backend codex --endpoint http://localhost:3000/mcp
./hub --role reviewer --backend claude --endpoint http://localhost:3000/mcp
./hub --role assistant --backend codex --namespace EXP-123
./hub --role orchestrator --backend codex --runtime-mode repo
./hub --role assistant --backend claude --runtime-mode isolated
./hub --role assistant --backend codex --lifecycle ephemeral
启动器的功能:
- 检测
runtime_profile(mode,cwd,has_git,file_count,empty_dir); - 通过以下方式支持强制模式
--runtime-mode repo|isolated|unknown(或快捷方式--repo-runtime/--isolated-runtime); - 寄存器
orchestrator/reviewer/assistant角色为lifecycle: "persistent"默认情况下(设置--lifecycle ephemeral短期工人); - 将配置文件注入
register_agent合同; - 加载系统入职+角色提示;
- 在网桥运行器后面启动选定的CLI。后端CLI接收只读预检
上下文,并返回结构化结果;该桥处理枢纽登记、证据
发布和任何工件侧通道只有在其协商的能力包括
artifact_tickets: true. - 通过stdin而不是进程参数和strip-hub向模型后端发送组合提示 来自环境的证书;
- 将私有线程结果保存在该线程内:没有共享内存/上下文/广播发布, 并且任何完整结果blob都是私有的,仅授予其他参与者访问权限。
角色技能备忘单:
skills/codex-hub.mdskills/claude-hub.md
端点
| 端点 | 方法 | 描述 |
|---|---|---|
/mcp |
POST | MCP流式HTTP(主) |
/mcp |
GET | SSE流用于通知 |
/mcp |
DELETE | 关闭会话 |
/events |
GET | SSE专用推送通道,用于高负载轮询替换(agent_id, streams, cursor, response_mode;通过身份验证 Authorization: Bearer <token>) |
/artifacts/upload/:artifactId |
POST | 侧通道上传二进制工件(需要票证/令牌) |
/artifacts/download/:artifactId |
GET | 侧通道下载二进制工件(需要票证/令牌) |
/health |
GET | 健康检查(auth_mode、命名空间配额模式、SSE设置、会话计数器) |
握手诊断
如果你在Codex/Claude中看到错误,比如:
error decoding response body, when send initialize request
检查服务器状态:
./hub.sh status
./hub.sh smoke
如果 smoke 失败,在大多数情况下,过时的容器正在运行。修复:
./hub.sh build
./hub.sh restart
./hub.sh smoke
客户端自动恢复 -32000
容器重启后,之前 mcp-session-id 值变为无效。
服务器返回JSON-RPC错误 code: -32000 与 error.data.reinitialize_required=true.
推荐客户端算法:
- 抓住
error.code == -32000. - 重新运行握手:
initialize->notifications/initialized. - 重试原始请求一次。
- 用于宣传工具
idempotency_key,保留完全相同的键和参数。
一个明确的 -32000 未知会话响应意味着被拒绝的呼叫没有被执行
会议。超时、断开连接或丢失的HTTP响应是不同的:执行可能已经
坚信的。在这种情况下,只有当其工具模式通告时,才会自动重试变异
idempotency_key.副作用读取还需要参数感知处理:重试
read_messages 唯有 mark_read=false, read_filter_feed 只是没有
advance_cursor=true, fetch_hub_refs 只是没有 mark_messages_read=true,以及
get_task_handoff 只是没有 include_downloads=true.
Idempotency键限制为256个字符。密钥只能以相同的语义重复使用
参数(有效载荷指纹中不包括身份验证和注册秘密)。
使用不同参数重用密钥失败 IDEMPOTENCY_KEY_CONFLICT;预指纹
旧记录无法关闭,需要新密钥。
工件上传/下载票证响应在静态时使用进程临时密钥进行加密。
它们在同一服务器进程中重播,但在重新启动后返回
IDEMPOTENCY_VOLATILE_RESPONSE_EXPIRED;请求具有新幂等性密钥的新票证。
讨论线程根是服务器拥有的记录。从仅存储的版本升级的数据库 消息元数据不会自动导入这些遗留根,因为伪造的元数据无法区分 从一个合法的老根。在升级之前重新创建或导出重要的遗留线程。
服务器还添加了:
error.data.reason(unknown_or_expired_session/server_not_initialized)error.data.recovery_sequence- HTTP标头
x-mcp-reinit-required: 1
对于长期池,保持长但有限的空闲超时和绑定会话准入:
MCP_HUB_SESSION_IDLE_TIMEOUT_MS=21600000
MCP_HUB_SESSION_PROVISIONAL_TTL_MS=60000
MCP_HUB_MAX_SESSIONS=500
MCP_HUB_MAX_SESSIONS_PER_SOURCE=100
在未注册之前,新会议是临时的 tools/call 提供有效的代理主体
和 auth_token 在 enforce 模式。进入 observe/warn,一个已知的呼叫者主题就足以保留
传统推出行为。临时截止日期自 initialize 并且未扩展
通过通知, tools/list未知工具或匿名流量。晋升后,正常
空闲超时适用。 /health 报告临时/认证计数和两个TTL。
为什么Redis不能用于“实时”MCP会话:
- 在SDK中,传输会话保持内存连接状态,不可序列化。
- Redis对于度量/队列/事件存储很有用,但在进程重启后,传输本身不会从Redis恢复。
- 实用的可靠性路径:有限空闲超时+有界准入+客户端自动重新控制未知会话。
代理启动时的入职培训
最小引导合同:
register_agent- 保存
auth.token从响应 - 调用所有后续工具
auth_token - 叫
get_onboarding { mode: "compact" }一次
集 MCP_HUB_REGISTER_TOKEN 只要启用了身份验证强制。 hub.sh 拒绝启动
没有它的生产强制配置文件。没有秘密直接启动的服务器已打开
注册:即使在以下情况下,客户端也可以创建新的代理身份并接收其令牌
MCP_HUB_AUTH_MODE=enforce.保守秘密
deploy/hub.local.env (或另一个受保护的env文件),然后传递与相同的值
register_token 仅在注册期间。现有ID还需要其当前
auth_token;注册永远无法恢复丢失的代理令牌。令牌仅作为以下内容存储在SQLite中
SHA-256摘要。客户可以提供强有力的初始 auth_token (32..512个字符)并保持不变
在注册之前;当第一个响应丢失时,桥接器使用此功能进行恢复。
升级由明文令牌版本创建的数据库时,逻辑行将迁移到
消化,但该中心不会运行昂贵的 VACUUM 在启动期间。旧令牌字节可以保留
在WAL中,释放页面或备份,直到操作员压缩数据库。在维护窗口期间,
停止集线器,备份数据库,然后使用本地 sqlite3 作为集线器的操作系统用户:
./hub.sh stop
DB="${MCP_HUB_DATA:-$HOME/.mcp-hub}/hub.db"
sqlite3 "$DB" 'PRAGMA wal_checkpoint(TRUNCATE); PRAGMA secure_delete=ON; VACUUM; PRAGMA wal_checkpoint(TRUNCATE);'
chmod 600 "$DB"
./hub.sh start
将预压缩备份视为包含明文凭据,并对其进行轮换或安全退役。
默认情况下,在代理令牌之前的旧数据库行是不可声明的。对于监督
迁移窗口,配置 MCP_HUB_REGISTER_TOKEN,临时设置
MCP_HUB_ALLOW_LEGACY_AGENT_CLAIM=true,迁移预期的代理,然后禁用该标志。从不
通过开放注册启用此模式。
代理令牌验证调用者身份;它们不是一个完整的项目/任务RBAC系统。跑 为相互不信任的团队提供单独的中心实例,直到命名空间/任务授权策略 在部署边界处配置。
大规模重新注册的令牌优化:
- 关于一个经过认证的重复
register_agent(同样id加电流auth_token)服务器默认为onboarding_mode=none; - 第一
register_agent仍然详细(full为了持久,compact对于短暂的); - 行为可通过以下方式配置
MCP_HUB_DEFAULT_ONBOARDING_MODE,MCP_HUB_EPHEMERAL_DEFAULT_ONBOARDING_MODE,MCP_HUB_REREGISTER_ONBOARDING_MODE.
供蜂群工作人员使用 register_agent { ..., lifecycle: "ephemeral" }:
- 更快的离线标记,
- 更快地清理陈旧代理,
- 在维护过程中,从失踪的临时工中自动重新排队。
示例场景
- 克劳德代理人登记:
register_agent { id: "claude-1", name: "Claude", type: "claude", runtime_profile: { mode: "repo", has_git: true, file_count: 120 } } - 食品法典代理人登记簿:
register_agent { id: "codex-1", name: "Codex", type: "codex", runtime_profile: { mode: "isolated", has_git: false, file_count: 0, empty_dir: true } } - Claude创建任务:
create_task { title: "Refactor auth", created_by: "claude-1", execution_mode: "repo" } - 食品法典委员会声称:
poll_and_claim { agent_id: "codex-1", lease_seconds: 300 } - 执行期间,Codex续签租约:
renew_task_claim { task_id: 42, agent_id: "codex-1", lease_seconds: 300, claim_id: "<from claim response>" } - 食品法典委员会分享进展:
share_context { agent_id: "codex-1", key: "status", value: "refactoring auth.ts" } - 完成后,食品法典委员会记录结果:
release_task_claim { task_id: 42, agent_id: "codex-1", next_status: "done", claim_id: "<from claim response>", confidence: 0.95, verification_passed: true, evidence_refs: ["context_id:123", "message_id:456"] }
对于 strict 任务中,独立审查员必须首先附上证据 update_task;然后,索赔人将审核人的ID作为 verified_by 在 release_task_claim。服务器拒绝自我验证、未知审阅者和没有为任务编写证据的审阅者ID。
关于Swarm轮询的建议
- 如果
poll_and_claim回报task: null,等等retry_after_ms在下次投票之前。 - 在突发负载下,这减少了空轮询和代理之间的冲突。
- 在路由循环中,替换三个呼叫(
list_tasks+read_messages+get_context)与一read_snapshot使用单个cursor. - 对于高负载模式,启用
/events仅推送通道(SSE)和进程update事件而不是循环长轮询。 - 为了安全续订/发布,请通过
claim_id从索赔回复中。 retry_after_ms自适应于活动代理的数量(约5/10/20+代理的配置文件),并包括抖动。- 对于较大的切换有效载荷,请使用
send_blob_message/share_blob_context;阅读时,启用resolve_blob_refs. - 在生产集群回合中,设置
namespace关于任务流和启用命名空间配额(MCP_HUB_NAMESPACE_QUOTA_MODE=warn|enforce).