最近在折腾MCP(Model Context Protocol),想把公司的知识库通过MCP Server暴露给Claude用。我用的FastAPI写了个简单的server,里面调用Qdrant的Python客户端做向量检索。本地测试没问题,但一通过MCP的stdio方式连上客户端,就报“Tool execution failed: Transport closed”。查了半天日志,发现是server端在返回结果时,把numpy的ndarray直接塞进了response里,MCP的JSON-RPC序列化直接炸了。我懵的是,按官方文档说返回类型得是JSON可序列化的,但也没说清楚向量查询结果该怎么包装。是我理解错了MCP的tool输出格式,还是Qdrant返回的数据结构需要额外处理?求大佬指个路,最好能说下你们生产环境是怎么处理的。
楼主
17天前
MCP服务器接入向量数据库报错,不知道是配置问题还是协议理解错了?
请 登录 后发表回复
全部回复
共 63 条
2楼
3天前
碰到这个报错太熟悉了,我之前用MCP接Milvus的时候也栽在序列化上。其实核心问题不是协议理解错,而是FastAPI的response_model和MCP的JSON-RPC规范之间有个隐藏的坑——MCP要求所有tool返回值都得过一遍jsonable_encoder,但numpy的数组和Python原生list在序列化行为上完全不是一个物种。你本地测试用的是HTTP请求,FastAPI会自动帮你做转换,但stdio通道里MCP的server端是直接调你的函数拿返回值,根本不会帮你做这层处理。建议你在返回前显式把ndarray转成list,或者干脆用Qdrant返回的dict结构,别图省事直接返回向量本身。另外注意一下,如果结果是嵌套的numpy类型,比如float32这种,也得先转成原生float,不然照样炸。还有个更隐蔽的问题,如果你用了numpy的float64,JSON-RPC里有时候会序列化成科学计数法,虽然不报错但客户端解析出来是字符串,别问我怎么知道的。最后想确认下,你用的是MCP官方Python SDK还是自己手搓的JSON-RPC?如果是手搓的,还得检查一下你处理请求ID的方式,transport closed有时候不是序列化问题,而是你提前把stdin或者stdout的管道给关了。
3楼
3天前
这题我熟,之前也栽在numpy序列化上,记得先转成list再塞进结果里。
4楼
11小时前
我之前也栽在numpy序列化上,记得先转list或者用model_dump,这坑太经典了。