现场是这样的。自建 MCP server 注册了 120 个工具,客户端启动后只看到 50 个,tools/list 的返回里没有 nextCursor 字段,客户端也就不再翻页,剩下七十个工具全调不到,日志里没有任何报错。

中间走过弯路,把「客户端版本不支持分页,即使收到 nextCursor 也忽略」当成主因,改完现象没变。

这类报错背后常见的原因有几处,逐个排除就行。服务端实现里固定截断 50 条但没写 nextCursor;cursor 参数没有解析,始终按第一页返回;工具按需注册,进程启动时只加载了前 50 个。

直接发一次 tools/list 看返回字段

echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | mcp-cli --stdin

带上 cursor 再请求一页核对数量

echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{"cursor":"50"}}' | mcp-cli --stdin

客户端侧开调试日志确认是否解析该字段

MCP_LOG=debug mcp-cli --list-tools 2>&1 | grep -i cursor

等前面都确认过,再把工具数降到 40 验证是否恢复正常

python tools_registry.py --max 40 --reload

恢复的判定其实很直接。两页合计返回 120 条工具,nextCursor 为空时客户端停止翻页,模型侧能看到全部工具。

MCP 的分页是可选实现,服务端截断却不算错,客户端也不会报警,只能拿注册总数去对。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189