MCP 服务
接入远程工具、配置触发方式,了解自动续办、回复窗口与失败恢复。
v0.8.5 为 deferred 第二拍增加自动触发:用户只需发一条消息。原有任务、单工具执行及用户续办路径保留,关键词/斜杠直接调用模式不变。
v0.7.1 将等待提示恢复为模型生成,工具标记统一为 【使用了工具 - 服务名/工具名】,未选择工具时始终不显示标记。
v0.7.0 新增短答、忽略工具上下文、自定义工具说明、斜杠命令和关键词模式。完整设计与配置示例见 MCP 0.7 设计与使用。以下异步流程继续保留。
v0.6.0 增加远程 Streamable HTTP MCP 客户端。工具不限于搜索,支持服务声明的对象 JSON Schema、嵌套参数、数组、组合条件及非递归本地引用。当前消费文本、结构化数据和资源文本;图片、音频仅向模型说明结果类型。不支持本机 stdio、旧式独立 HTTP+SSE 传输、OAuth 登录交互、服务器请求模型采样、长任务轮询或连续 Agent 工具循环。
配置
在 WebUI 的「MCP服务」添加 HTTPS 端点,按需填写认证,然后点击「检测连接并获取工具」。检测只执行初始化和 tools/list,不执行工具。新发现的工具默认关闭;选择需要的工具,启用服务和 MCP 总开关,点击「保存并部署」。支持最多 8 个服务,每服务最多发现 64 个工具,同时启用最多 12 个工具。
认证 JSON 示例(占位值):
{"headers":{"Authorization":"Bearer YOUR_KEY"}}
也支持 {"headers":{"x-api-key":"YOUR_KEY"}} 和 {"query":{"exaApiKey":"YOUR_KEY"}}。查询参数只在发起 MCP 请求时追加;端点本身不保存认证查询串。每个服务的认证最多 4000 UTF-8 字节,保存在 MCP_SECRETS_JSON Secret,工具清单在部署模块中,恢复包加密保存。日常聊天不请求管理 API,不查询 D1 配置,不重新 tools/list。更换地址时需重新填写或删除原认证,避免旧凭据被转发到新服务。
一条任务,两次事件
- 首次请求仍需 @(或通过原有主动发言的积压、冷却判断)。提示与工具定义要求模型提交一次 reply 决策:mcp_tool=none、mcp_arguments={} 表示直接回答;选择工具别名并填写 mcp_arguments 表示预约,content 为等待提示。运行时兼容普通文字及未填写 MCP 字段的旧式 reply,但它们只能回答,不能创建待办。明确填写了错误路由、参数或多个工具调用仍会被拒绝。
- 后端校验参数,先保存待办,再发送 notice。保存失败不承诺已提交。普通文本或历史中夹带的工具 JSON 不会作为任务执行。
- 等待提示发送后,由 QQ 适配器检查原消息的被动回复期限、已用序号和发送余量。满足条件时程序发起内部 POST 请求并原子领取同一个待办。自动触发不可用时,任务保存后的下一条同会话 QQ 消息仍在 @ 判断和主动发言冷却前原子领取任务;原消息重复投递不会领取自己的任务。未 @ 续办消息需要 QQ 已投递全量群消息。
- 领取者初始化被选服务,只发送一次 tools/call,将有界结果、原问题、原提问者和新消息交给模型。
- 工具返回错误或连接失败时明确报告阶段,不再浪费模型请求;工具成功后本轮模型只能回答,不能继续预约工具。若模型整理失败或不回复,程序直接给出有界工具原文节选并标注未经核验;随后结束任务并清空参数正文。每个消息事件最多一次模型 HTTP 尝试,启用 MCP 时不进行提供商失败回退。
普通消息可继续按原配置保存聊天历史。触发消息未启用历史记录时,其内容仅作为本轮临时上下文。工具结果不写 messages;自动续办在独立检查点表暂存有界结果与短答,交付完成后清除。后台续办不写虚构用户消息。Core 和插件命令继续工作;/clear 与 /mcp-cancel 优先取消待办。自动回复使用原问题的发送凭据,降级后使用当前触发事件的发送通道,并保留原问题身份。同一事件的多条回复共享递增 QQ msg_seq。
自动续办不可用时才等待下一条用户消息。每个会话跨所有 MCP 服务共用一个待办,不能追加队列,也不能覆盖未完成任务。保存的 CONFIG_GENERATION 与当前部署不一致时不执行旧任务。
D1 与失败语义
mcp_tasks.session_id 是主键。最多每个会话一行,payload 数据库约束为 10000 字节;工具参数最多 4000 字节。完成或取消后清空 payload;过期数据搭现有低频历史清理删除,使用 expires_at 索引。默认有效期 180 秒,可设 10~600 秒。
- MCP 关闭或当前范围没有可用工具:不查询待办表。
- MCP 异步模式开启且 AI 可用:收到会话事件会执行一次主键定位的条件 UPDATE … RETURNING,同时检查和领取。没有匹配任务时不写行,不扫描聊天历史寻找任务。
- 真实任务有创建、领取、完成等状态写入;执行前和发送前有取消检查。合并数据库操作不能消除实际读取行数,D1 消耗应以 rows_read / rows_written 为准。
- 只保证每个任务至多一次 tools/call 尝试。工具网络失败、404、Worker 中断均不自动重试。running 任务不重新领取,避免有副作用工具被重复执行;用户可取消或等过期后重新提问。
- 取消不能撤回已经发往远端的操作;它会阻止尚未发出的调用和后续回复。任务失败或进程中断不能保证一定产生结果。
时间与大小限制
每个事件使用从入站开始的 25 秒总预算,为当前 Pages waitUntil 窗口留余量。模型、MCP、QQ 发送共享截止时间。工具初始化和调用默认合计 8 秒,可设 1~12 秒;续办至少预留生成回复的预算。工具响应流在读取时限制为 256 KiB,提交模型的结果最多 8000 字符;模型响应限制 128 KiB。JSON/SSE 支持匹配请求 ID、MCP Session ID、协商版本和有界分页;不建立独立 GET 长连接。
等待网络不计入 Workers CPU,但参数验证、JSON/SSE 处理仍消耗 CPU。两次事件分散了模型等待,不代表完全没有额外 D1 成本,也不保证所有模型或 MCP 服务都能在免费额度内完成。工具定义与参数验证器可在实例内复用;任务正确性始终依靠 D1。
升级
核心发布包声明 mcpApi: 1、mcpContinuation: 1 和仅新增表/索引的迁移 SQL。新 WebUI 从旧核心升级时,先创建 MCP 待办及续办检查点表再提交生产部署;聊天、插件、ENV 和现有数据库绑定保留。后端 capabilities.mcp 控制前端模块显示。已有 MCP 清单的部署要求携带 mcpPlan,防止旧前端静默丢失服务。
诊断与回复保障
- MCP 决策沿用人格与旧模型已经熟悉的 reply 函数。0.6.2 恢复普通文字和旧式 reply 的回答兼容,不再把所有纯文本回答当作查询失败;只有经过校验的工具调用可以预约。对常见等待、搜索和重试承诺做有界检查,防止再次出现“正在搜索”却未创建任务。这是措辞保护,不是判断所有自然语言是否需要联网的分类器。
- 预约回合最大输出 1536 tokens,工具结果整理默认 256 tokens(可设 64~512),发送前再限制为一句话和默认 120 字符;每个事件仍最多一次模型请求,不启用失败重试。
- 模型错误保留 HTTP 状态、超时类型和耗时;MCP 日志区分 schedule / initialize / tool / model / fallback。不记录密钥、完整参数或工具原文。
聊天记忆与主动发言(0.6.2)
- 待办由程序在续办结束时标记 done 并清空参数,不依赖模型发出结束指令。完成后的聊天进入新回合,不会重放已完成工具。
- 等待、协议错误、工具失败等临时通知仍发送给用户,但不写 messages,因此不进入后续模型上下文,也不增加主动发言冷却计数。正式短答与标明未经核验的简短资料节选仍保存到聊天记录;0.7.0 默认从模型上下文中排除这些 source=mcp 记录,可关闭“忽略工具回答上下文”以支持追问。
- 旧版已经存入的已知通知、短等待承诺和泄漏的控制字段,在原来的历史读取结果中进行过滤;不删除数据库历史,不增加独立查询。旧通知在 30 分钟冷却统计窗口内仍可能暂时计数。
- MCP 工具说明追加在当前回合指令后,保留原先“看到能接的就接一句”的主动发言提示;不再替换为更保守的独立提示。普通文本回退仅在主动门槛通过后发生,明确 should_reply=false 仍保持沉默。
- 积压、评估间隔、冷却和并发抢占规则不变。每个事件仍至多一次模型尝试、每个待办仍至多一次工具调用。CPU 增量来自有界的字符串过滤,0.8.5 自动第二拍增加有界交付检查点表;仍不增加工具或整理模型尝试。
- 排查时先看
[proactive] 不评估的门槛原因,再看[proactive] 评估后的模型结果。0.6.1 可能在评估后出现[mcp] decision_missing并静默退出;这不能解释为“没有通过冷却”或“模型明确决定不接话”。 - 工具成功但模型失败时保留一句简短资料节选,避免用户把模型整理失败误认为搜索失败。
自动第二拍与降级
runtime/continuation.js 管后台触发和结果交付;mcp/resume.js 沿用单工具续办,只接触通用可回复能力与检查点接口。QQ 适配器负责恢复发送通道及平台窗口。群聊为 5 分钟/5 次,单聊为 60 分钟/4 次(2026-10-24 核对官方消息收发概述);缺少可信事件 timestamp 时保守降级。执行前预留整个 25 秒预算,发送前再次检查期限与序号,获取 token 后还会检查一次。不改成主动消息,也不发送已知超窗的回复。
内部端点为 POST /webhook/internal/mcp-resume,在现有 Pages /webhook/* 路由内。HMAC-SHA256 签名绑定方法、路径与完整正文;短有效期、一次性随机 nonce、task_id、CONFIG_GENERATION、部署构建 ID 共同验证。签名密钥使用部署恢复密钥并作域隔离,首次安装无恢复密钥时使用 QQ AppSecret 作同样的域隔离。端点不接受任意工具参数或目标 URL;自请求仅去配置中的 CF_PAGES_PROJECT.pages.dev,禁止跟随重定向。D1 nonce 消费和原有 pending→running 领取共同防重复;自请求和用户消息竞争时只有一个领取者。
- 自请求失败、缺少新表、鉴权失败、原消息窗口不足:不执行工具,保留 pending,下一条用户消息续办。
- 初始化失败且尚未 tools/call:保留待办,降级到用户触发路径。
- 工具已成功但窗口不足或 QQ 发送失败:保存结果;若已整理则保存短答,下一条消息只完成尚未完成的整理或发送,不重跑工具、不重复整理。
- 工具已经尝试但超时/网络结果不明:沿用至多一次工具尝试语义,不重试该工具;必要时只保存终止通知供下一条消息发送。
- 整理模型失败:直接使用简短、标明未经核验的结果节选,保持一次整理尝试。
mcp_continuations 每会话最多一行,检查点与原任务共享过期时间,随已有清理删除。旧 mcp_tasks 的抢占 SQL 和 TTL 不改。后台续办是独立 HTTP 请求,每次仍只有 25 秒预算,不会扩大 MCP_TIMEOUT_MS。没有队列租约或自动重试;进程在外部副作用发生后硬中断仍无法保证送达,running 不重新执行,避免重复副作用。
Cloudflare 必须开启 global_fetch_strictly_public 才能让全局 fetch 重新经过 Worker 入口,不能用 global_fetch_private_origin。新 WebUI 的 mcpContinuationPlan 由新核心管理 API 自动合并该标志、保留其他标志和兼容日期。首次从 0.8.3 等旧管理 API 升级时,需先在 Pages 生产兼容性设置开启该标志;旧 API 尚不认识这个计划字段。没有开启时自请求会失败并降级,不丢 pending。来源:https://developers.cloudflare.com/workers/configuration/compatibility-flags/#global-fetch-strictly-public 。
正文由 AnnaofArendelle/MoeBot/docs/mcp.md 的 Markdown 快照构建,来源提交 da740d62042c。原仓库为私有,这里展示经审阅的文档内容。