Cherry StudioMCPJSON Schema故障排查Nbility

Cherry Studio 提示 MCP 连接失败:怎样查出工具 Schema 错误

聊天能用,打开 MCP 就失败?从原始错误、tools/list 和模型请求三处检查 bool、boolean 与工具 Schema,附可离线运行的 Python 检查例子,以及 Cherry Studio v2.1.10 的核验边界。

查看接入文档
Cherry Studio 提示 MCP 连接失败:怎样查出工具 Schema 错误

Cherry Studio 显示“MCP 服务连接失败,请检查服务是否已启动”,先展开原始错误。如果里面还有 400 Invalid schema for function、"bool" is not valid,应先检查被点名工具的参数定义。界面上的故障分类,可能把你带向了错误的设置页面。

一种常见的排查误区是反复重启 Server、改代理、加超时,却没有看模型服务到底拒绝了什么。下面按三处记录定位:Server 给出了什么、客户端发出了什么、模型服务返回了什么。

本文于 2026 年 11 月 8 日查阅 Cherry Studio 当时的最新正式版 v2.1.10、MCP 2026-07-28 规范和近期 Issue。我们离线运行了正式版的错误分类函数,并验证了下文的 JSON Schema 例子;没有运行完整 Cherry Studio,也没有连接真实 MCP Server 或模型服务复现原报告。如果连普通文本聊天也失败,先按 Cherry Studio 接入文档核对基础配置。

工具列表能读到,为什么聊天仍失败

桌面应用与 MCP Server 通信,获取工具列表;应用还要把工具名称、说明和参数定义交给模型服务。这是两段不同的通信。完整角色关系可先看 MCP 工具调用入门。

MCP 工具发现、模型请求校验与实际工具执行是三个不同检查点

检查点成功能说明什么还没证明什么
Server 启动、MCP 工具发现成功应用能获取这次工具列表工具定义一定符合模型服务的要求
带工具定义的模型请求成功本次模型服务接受了这些定义模型一定会选择工具,或工具执行一定成功
实际工具调用返回预期结果这次调用完成了预期工作后续所有工具、参数和历史组合都正常

如果模型请求在校验工具定义时就被拒绝,流程可能还没到真正执行工具的阶段。只有某条工具的定义有问题,也可能使携带整组工具的聊天请求失败;不能因为这次没有要求调用那个工具,就把它排除。

反过来,如果原始记录是进程启动失败、连接拒绝、协议解析失败,或 tools/list 本身无法完成,仍应沿 MCP 启动与传输路径排查。一个 400 状态码本身也不能区分这些情况,要一起看请求发向哪里、使用什么协议、错误正文写了什么。

近期报告说明了什么,还缺什么

Cherry Studio #23645于 11 月 5 日提交。报告引用的模型服务错误包含 Invalid schema for function 和 "bool" is not valid under any of the schemas listed in the 'anyOf' keyword,界面却显示 MCP 连接失败。

原报告没有提供应用版本、系统、原始 tools/list 或实际模型请求体。唯一回复来自机器人,它建议分别检查 Schema 来源和错误分类。因此,不能据此认定 Cherry Studio 把正确的 boolean 改成了 bool,也不能把单条报告推广到所有 MCP 服务。

可以独立核对的是故障分类。正式版 v2.1.10 的 errorCategory.ts中,isMcpErrorMessage 会匹配 mcp_ 子串;这一步发生在通用 HTTP 400 分类之前。离线运行该版本的函数,使用替换过工具名的演示错误,结果如下:

演示输入实际返回的分类
HTTP 400,Invalid schema for function 'mcp__demo__preview_report': ...mcp
同一错误,将工具名改为 preview_reportbad_request
MCP connection is closedmcp

这个小检查验证的是分类函数的行为,没有复现 Electron 界面,也没有证明非法类型来自哪一层。对应的 PR #22345尝试移除工具名触发的误分类;截至本文查阅仍未合并,不能写成正式版已经修复。即使今后提示文字修好了,原工具 Schema 仍可能需要另外处理。

bool、boolean 和 true 分别是什么

JSON Schema 中,声明布尔参数应使用 "type": "boolean"。bool 是 Python 等语言的类型名称,不能直接填成 JSON Schema 的类型字符串。合法类型名由所用 Schema 规范规定,不能靠模型猜。

非法类型字符串 bool、布尔参数声明 boolean 和布尔 Schema true 的不同含义

这三种写法要分开:

写法在 JSON Schema 中的含义
{"type": "bool"}类型名非法
{"type": "boolean"}只接受 JSON 布尔值 true 或 false
子 Schema 直接写 true接受任何值;并不要求值是布尔类型

JSON Schema 官方基础说明明确允许布尔 Schema:true 接受任何值,false 拒绝任何值。因此,不能把 Schema 中所有布尔值都改成字符串,也不要在整个 JSON 文本里全局替换 bool。应修改具体参数的类型声明或生成该声明的代码,保留字段名、说明、枚举和合法布尔 Schema 的含义。

另外,{"include_archived": false} 和 {"include_archived": "false"} 是不同的参数:前者是布尔值,后者是字符串。工具定义正确与本次传参正确,也需要分别验证。

用一个不调用模型的例子检查 Schema

先在单独的演示目录里准备 tool.json。下面是故意写错的单个工具条目,不是完整 JSON-RPC 响应,也不是原报告中的工具:

{
  "name": "preview_report",
  "description": "Read a public demo report",
  "inputSchema": {
    "type": "object",
    "properties": {
      "include_archived": { "type": "bool" }
    },
    "required": ["include_archived"],
    "additionalProperties": false
  }
}

为检查脚本安装独立环境,以下例子使用 Python 3,验证时使用 jsonschema 4.25.1:

python3 -m venv .venv-schema
.venv-schema/bin/python -m pip install jsonschema==4.25.1

把下面代码保存为 check_tool_schema.py:

import json
import sys
from pathlib import Path

from jsonschema import Draft202012Validator
from jsonschema.exceptions import SchemaError

tool = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
schema = tool["inputSchema"]
if not isinstance(schema, dict):
    sys.exit("This example expects an inputSchema object")

dialect = "https://json-schema.org/draft/2020-12/schema"
if schema.get("$schema", dialect).rstrip("#") != dialect:
    sys.exit("Use a validator for the declared schema dialect")

try:
    Draft202012Validator.check_schema(schema)
except SchemaError as error:
    location = "/" + "/".join(str(part) for part in error.path)
    sys.exit(f"Invalid schema at {location}: {error.message}")

print("Schema valid under 2020-12; provider acceptance not checked")

运行:

.venv-schema/bin/python check_tool_schema.py tool.json

本地执行这个演示时,错误指向 /properties/include_archived/type,并以非零状态退出。只将该处的 bool 改成 boolean 后,再次检查会正常退出,输出:

Schema valid under 2020-12; provider acceptance not checked

它不需要 API Key,不启动 Server,也不发送模型请求。当前 MCP JSON Schema 规则规定,未声明 $schema 时默认使用 2020-12;声明了其他版本,就应使用对应的检查器,不能为了通过检查而随意改版本号。

通过这个检查,只说明 Schema 符合本例所检查的规范。 它不验证完整 MCP 消息、所有引用能否解析、模型服务支持的 Schema 子集、实际工具参数或业务结果。比如缺失的 $defs 引用需要进一步检查引用目标;模型服务不支持的合法关键字,也可能导致请求失败。需要设计工具参数或最终 JSON 输出时,可接着看 JSON Schema 与结构化输出的区别。

从三处记录定位,别先猜是谁改坏了

对真实故障,从 Server 的工具列表中导出被点名的那一个条目。移除业务内容和私有地址,保留有关的 inputSchema、$defs、$ref 与类型声明;不要把整个认证配置一起导出。随后对照客户端实际发出的模型请求中对应工具的参数定义。

观察到的差异接下来查哪里
原始 tools/list 已有 "type": "bool"Server 的 Schema 生成逻辑、插件版本和对应工具实现
Server 返回合法定义,客户端发出的定义发生了破坏性变化客户端、SDK 或适配步骤;用前后两份最小片段定位
定义符合 JSON Schema,但模型服务拒绝某个结构该服务和模型支持的子集、接口类型,以及中间转换
只有界面分类与原始错误不一致客户端错误展示;同时继续处理原始请求错误

v2.1.10 的 createMcpInputSchema会把传入的 Schema 交给 SDK 并附加本地校验;后续还有兼容处理。只读一个函数,无法证明整条链路原样保留,所以这里仍以两端记录为准。

使用 Nbility 时,可在用量日志核对同一时刻的模型请求状态,并保留请求 ID 供支持人员定位。日志是否包含足够细节,要看实际记录;不要假定网关能看到桌面应用与本地 MCP Server 之间的全部通信。HTTP 状态和重试边界见错误与重试文档。

修好后,要验证到哪一步

保存原始错误、隔离问题工具、修正来源、验证完整调用的四步检查顺序

在临时会话中保持模型、服务商和测试问题一致:

  1. 关闭 MCP,发一条短文本。 确认基础模型路径是否可用;成功只验证了文本聊天。
  2. 只启用一个已知正常、没有写入副作用的工具。 确认带工具定义的模型请求能通过。若它也失败,继续查模型工具能力、接口和兼容处理。
  3. 加入被点名的工具。 如果此时才失败,工具集合已缩小,但还不能直接确定责任方。按上一节比较定义,并在源头修正;无法修改第三方 Server 时,提交脱敏的最小片段给其维护者,暂时停用该工具或 Server。
  4. 刷新工具列表,再做完整调用。 按客户端支持的方式重新加载定义,确认实际发出的请求已更新。选择只读或演示任务,检查模型服务接受定义、模型确实选择工具、Server 返回预期结果,以及会话能继续。

如果客户端只能按 Server 开关,就按 Server 隔离,不必为排查强行修改内部数据。不要直接删除历史里的工具消息,也不要为让请求通过而取消业务所需的参数校验。Schema 类 400 应先修请求,原样多试几次通常不会改变定义。

准备求助时,留下应用与 Server 版本、传输方式、模型与接口类型、失败阶段、原始错误,以及被点名工具修正前后的最小 Schema。公开材料去掉 Key、认证头、签名 URL、私有路径和业务数据;需要关联的请求 ID 通过私密支持渠道提供。这样维护者才能判断应修 Server、客户端转换、模型兼容,还是错误提示。

核验资料

相关文章

Gemini CLI 聊天正常,摘要却报 503:后台模型怎么配
Gemini CLI模型配置故障排查

Gemini CLI 聊天正常,摘要却报 503:后台模型怎么配

Gemini CLI 主模型能用,后台会话摘要却提示 flash-lite 无可用渠道?对照 v0.67.0,区分聊天、会话摘要和上下文压缩,用任务级配置修改摘要模型,再核对实际请求。

用 Nbility 跑通你的 Agent 工作流

获取 API Key,统一接入 OpenAI 兼容模型和开发工具。

获取 API Key