DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

MCP initialize 被空 _meta 拒绝

Python MCP 初始化被严格服务端拒绝,检查旧 2.x 是否发送空 _meta。核对 2.3.0 省略空元数据的修复,保留进度、追踪与协议所需字段。

Python MCP 客户端连不上某个服务,initialize 返回 HTTP 400,错误里还有:

-32602 "_meta for Request must be a dict or null"

同一个服务用其他客户端却能连接时,先比较实际发出的请求。Python SDK 的旧 2.x 实现会在没有元数据时也带上 "_meta": {}。部分服务端拒绝这种形状,导致初始化失败;报错写着 “dict or null”,也不能据此认为改成 null 就能通过。

只有空元数据才对应这个问题

这个兼容问题发生在使用 initialize 握手的旧协议连接,例如 2025-11-25 及更早版本。没有调用方元数据、没有进度回调、也没有可注入的 trace context 时,旧客户端仍发送空 _meta。

应通过已有的脱敏请求记录确认这些条件,再对照服务端的错误。不要为了看请求体,把访问令牌或完整业务参数写进公开日志。地址、认证和客户端依赖版本也应保留,避免在比较请求形状时同时改变其他条件。

空 _meta 本身符合协议允许的形状,这里解决的是具体服务端的兼容问题。不能把所有 400 或 -32602 都归到空对象上;缺少普通参数、参数类型错误或认证失败,仍需要按实际响应处理。

正式修复只省略空对象

已核对的 Python SDK 2.3.0 会先注入 trace context,再判断 _meta 是否有内容。内容为空才省略;有调用方字段、progressToken 或 traceparent 时继续发送。

没有其他参数的请求,也不再为了空元数据保留 params。以 ping 为例,旧实现会发送:

{"jsonrpc":"2.0","id":2,"method":"ping","params":{"_meta":{}}}

修复后的形状是:

{"jsonrpc":"2.0","id":2,"method":"ping"}

这是省略可选成员,不能把它改写成 "params": null。带游标的列表请求仍需要自己的参数,普通业务参数也不能一起删掉。

旧部署可选择包含该修复、且与应用接口兼容的版本。这个改动没有新增开关;若仍使用下游封装,要确认它实际加载的 SDK 与请求序列化路径。修改自己并未使用的依赖,无法改变线上请求。

2026-07-28 协议路径的 _meta 还承载协议版本、客户端信息和能力,不属于这里的空对象。不要在代理或中间件中统一删除所有 _meta,否则会丢掉协议和进度、追踪所需的信息。

比较请求形状,也检查保留的信息

升级后,使用原先失败的连接确认空 _meta 已省略,初始化和后续只读请求能够完成。与此同时,有进度回调、调用方元数据或追踪上下文的请求仍应保留非空 _meta;只让最简单的初始化成功,还不能证明这些功能没有被破坏。

正式修复已经包含在 2.3.0,但它没有证明每个严格服务端都能连接。若当前客户端确实不再发送空 _meta,仍收到同样的 400,应保存脱敏后的实际请求与错误,继续检查该服务端的参数契约,而不是反复删减元数据。