我发布了一个叫 mcp-probe 的命令行工具,本意是给官方 Node MCP 服务器做体检。第一轮跑完,我以为半个生态都崩了。第二轮仔细看了输出,才发现大部分失败是我客户端的 bug。剩下的问题,全指向同一个设计缺陷。

一个命令,一张成绩单

打开网易新闻 查看精彩图片

mcp-probe 的定位很简单:MCP 服务器的 curl。不用开 Claude Desktop,不用手写配置,不用重启应用盯着工具列表发呆。

标准输入输出、SSE、Streamable HTTP 三种传输方式,零配置文件。跑完输出这样一张成绩单:

Tools callable: 9/9
Resources readable: n/a
Prompts callable: n/a
Schema warnings: 4
ALL CHECKS PASSED

退出码 0 表示全过,1 表示有失败,直接塞进 CI。

实际跑了一遍官方 Node 服务器的结果:37 个工具里 30 个可调用,81% 通过率。两台服务器全绿,另外两台共享同一种失败模式。

一个关键澄清

先说清楚我差点搞砸的地方。Anthropic 的 fetch MCP 服务器是 Python 专属,用 uvx mcp-server-fetch 安装,从没发布到 npm。mcp-probe 其实支持任意语言的 stdio MCP 服务器,但这次成绩单只覆盖官方 Node 服务器。

我最早的 launch 文案说 server-fetch "在 npm 上坏了",这是错的。差点发出去的草稿里有这句话,在这里明确撤回。

真正的病根:参数描述缺失

所有未通过的工具,根因都一样:schema 属性的 description 字段为空。

以 server-filesystem 为例,14 个工具里 6 个失败。read_file、read_text_file、read_media_file、edit_file、write_file 的 path 参数都没有描述。我的客户端不知道这到底是文件路径、目录路径还是任意字符串,只能默认填允许访问的 sandbox 目录本身。

问题不在于服务器实现,而在于 schema 设计。参数描述不是装饰,是负载-bearing 的结构——客户端依赖它生成有效调用

我修了自己客户端的三个 bug 才看清这一点。第一轮跑出来的"生态崩溃",其实是我代码的幻觉。