You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
letcalls=0constclient=createMockClient([])client.listTools.mockImplementation(async()=>{calls+=1if(calls>3)thrownewError('sentinel: pagination did not stop')return{tools: [],nextCursor: 'same-cursor'}})awaitexpect(syncTools(clientasnever,ctx,defaultOpts,newMap())).rejects.toThrow(/repeated.*cursor/i)expect(client.listTools).toHaveBeenCalledTimes(2)
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
问题概述
在当前
master(141eb6fef83422698aef7a981029e843e8161534)中,MCP Client 的syncTools()会持续拉取tools/list,直到nextCursor为空,但没有检测服务端是否重复返回同一个 continuation cursor。如果异常或不受信任的 MCP Server 返回空工具页并重复同一个非空
nextCursor,该循环不会触发现有的重复工具名校验,也不会结束,会持续发送tools/list请求。源码位置:
影响
apply()等待的connection.ready无法完成,插件启动会一直挂起;notifications/tools/list_changed触发重同步时,串行的syncChain会被永久占用,后续同步无法执行;failOnStartupError无法处理,因为当前路径既不 resolve 也不 reject。最小复现
可以在
packages/mcp/mcp-client/tests/mcp-client.spec.ts中构造一个 mock client:当前实现不会在第二次响应后拒绝,而会继续请求,最终只会被上面的 sentinel 人为中断;移除 sentinel 后会持续循环。
期望行为
当
tools/list返回已经出现过的非空nextCursor时,syncTools()应立即以明确错误终止 fetch phase,并保持上一代已注册工具不变。建议修复
在 fetch phase 内维护
Set<string>:nextCursor后,先检查是否已经出现;MCP server repeated a tools/list continuation cursor的错误;仓库中已有一致的防环模式,可直接复用设计:
去重情况
提交前已搜索 Discussions 和 PR 中的
nextCursor、continuation cursor、repeated cursor、tools/list pagination等关键词,暂未发现相同报告。All reactions