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

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 工具调用入门。
| 检查点 | 成功能说明什么 | 还没证明什么 |
|---|---|---|
| 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_report | bad_request |
MCP connection is closed | mcp |
这个小检查验证的是分类函数的行为,没有复现 Electron 界面,也没有证明非法类型来自哪一层。对应的 PR #22345尝试移除工具名触发的误分类;截至本文查阅仍未合并,不能写成正式版已经修复。即使今后提示文字修好了,原工具 Schema 仍可能需要另外处理。
bool、boolean 和 true 分别是什么
JSON Schema 中,声明布尔参数应使用 "type": "boolean"。bool 是 Python 等语言的类型名称,不能直接填成 JSON Schema 的类型字符串。合法类型名由所用 Schema 规范规定,不能靠模型猜。
这三种写法要分开:
| 写法 | 在 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 状态和重试边界见错误与重试文档。
修好后,要验证到哪一步
在临时会话中保持模型、服务商和测试问题一致:
- 关闭 MCP,发一条短文本。 确认基础模型路径是否可用;成功只验证了文本聊天。
- 只启用一个已知正常、没有写入副作用的工具。 确认带工具定义的模型请求能通过。若它也失败,继续查模型工具能力、接口和兼容处理。
- 加入被点名的工具。 如果此时才失败,工具集合已缩小,但还不能直接确定责任方。按上一节比较定义,并在源头修正;无法修改第三方 Server 时,提交脱敏的最小片段给其维护者,暂时停用该工具或 Server。
- 刷新工具列表,再做完整调用。 按客户端支持的方式重新加载定义,确认实际发出的请求已更新。选择只读或演示任务,检查模型服务接受定义、模型确实选择工具、Server 返回预期结果,以及会话能继续。
如果客户端只能按 Server 开关,就按 Server 隔离,不必为排查强行修改内部数据。不要直接删除历史里的工具消息,也不要为让请求通过而取消业务所需的参数校验。Schema 类 400 应先修请求,原样多试几次通常不会改变定义。
准备求助时,留下应用与 Server 版本、传输方式、模型与接口类型、失败阶段、原始错误,以及被点名工具修正前后的最小 Schema。公开材料去掉 Key、认证头、签名 URL、私有路径和业务数据;需要关联的请求 ID 通过私密支持渠道提供。这样维护者才能判断应修 Server、客户端转换、模型兼容,还是错误提示。
核验资料
- Cherry Studio v2.1.10 Release,2026-10-31与对应错误分类源码
- Issue #23645 正文及回复、PR #22345,状态截至 2026-11-08 查阅时;报告不构成完整复现,PR 尚未合并
- MCP 2026-07-28 Tools与JSON Schema 用法
- JSON Schema:类型、布尔 Schema与
jsonschema4.25.1 校验接口


