折腾了两天,快破防了。我在本地用Python写了一个简单的MCP服务器(就一个get_weather工具),用mcp.run(transport="stdio")启动,然后在Cursor的MCP配置里填了python /path/to/server.py。配置文件里能看到服务器状态是connected,但工具列表一直是空的,怎么刷新都没用。我试过用官方的@mcp.tool()装饰器,也试过直接暴露函数,都不行。看日志也没报错,就是加载不出来。是不是Cursor对MCP的协议版本有要求?还是我少配了name和version字段?有没有老哥用MCP踩过类似的坑,求指点一下排查思路。
MCP服务器接入Cursor后工具列表是空的,有人遇到过吗?
全部回复
共 63 条这问题我上个月也卡了快一整天,最后发现是MCP协议版本不匹配导致的。Cursor现在默认走的是2025-03-26那个协议版本,但你本地Python包如果装的是旧版mcp库,stdio握手时返回的initialize响应里少了protocolVersion字段,工具列表就会静默失败。建议你先在终端里手动跑一下python /path/to/server.py,然后用JSON-RPC手动发个tools/list请求看看返回什么,如果返回的是空数组但没报错,基本就是协议版本问题,直接pip install -U mcp升级到最新版试试。另外你提到少配name和version,这个其实不影响工具加载,但有些客户端会在初始化时校验serverInfo,缺了可能导致后续请求被忽略。还有个排查点:如果你用的是Python 3.12以上,检查下是不是asyncio事件循环和stdio读写冲突了,我之前就是没加asyncio.run()包裹导致工具注册成功后进程直接退出。实在不行可以试试用npx跑官方示例服务器,如果那个能加载,就对比一下两边返回的JSON结构差异。
我之前也卡在这过,后来发现是Cursor的MCP客户端对协议版本卡得比较严,你试试把mcp库升到最新,然后server.py里显式加上server = Server("weather-server")再注册工具,别用那个快捷装饰器。另外检查下stdio的日志,有时候是Python的print输出污染了协议流,工具列表就解析不出来。我那次就是多打了一行调试信息,去掉就好了。
遇到过,跟你一模一样,后来发现是Cursor要求MCP server在stdio模式下必须显式声明protocol version,不写的话它默认按老版本解析,工具列表就空着。你试试在server初始化时加上mcp.run(transport="stdio", version="2025-03-26")这种参数,或者去看下官方示例的完整配置。另外检查下你Python环境里mcp库版本,太旧也可能跟Cursor不兼容,升级到最新版再试。
我之前也卡在这过,最后发现是Python环境的问题。Cursor自带的Python解释器跟你终端里的不是同一个,导致它压根没装上mcp那个库,你试试在配置里直接写死绝对路径的python,比如/usr/local/bin/python。还有个小坑,stdio模式一定要保证server端代码里有if name == "main":这个入口,不然进程起不来但日志又不报错。协议版本的话,Cursor目前只支持2024-11-05那个版本,你检查下SDK是不是最新的,老版本返回的initialize响应格式对不上就会静默失败。
排查下MCP配置里有没有写--transport参数,我之前就是漏了这个工具列表死活不出来。
大概率是stdio握手时缺了初始化响应里的protocolVersion,检查下server端有没有按MCP规范返回version。
我之前也卡这,后来发现cursor只认新协议,老版本直接静默失败。
我之前也卡在这过,后来发现是Python环境的问题,Cursor那边用的解释器跟你终端里跑的不一定是同一个。你试试在配置里直接写绝对路径到venv里的python,别用全局的。另外那个name和version字段虽然看着不起眼,但最好还是加上,我记得MCP的initialize握手会校验这个,缺了可能导致工具列表拉不出来。如果还不行,可以开一下MCP的debug日志,看下具体的JSON-RPC返回,比干瞪眼强。
我之前也卡在这过,查了半天发现是Cursor对MCP的初始化握手要求比较严格,尤其需要server端正确返回tools/list,建议先用mcp-inspector单独测一下你的server,能排除大部分问题。另外,如果Python环境有多个版本,确认Cursor用的解释器和你的命令行python是同一个,有时候压根没连到你的进程上。
我之前也卡在这过,后来发现是MCP协议版本不匹配,Cursor对tools/list的响应格式要求很严格,你检查下返回的inputSchema是不是标准的JSON Schema格式。另外官方装饰器在stdio模式下有时会吞掉错误,建议直接手动实现list_tools和call_tool方法试试。name和version字段确实要配,但只影响元数据显示,不会导致列表为空。如果还不行,可以在启动脚本里加个print打印收到的请求,看看是不是没走到handshake那步。
这问题我上个月刚踩过,一模一样,状态connected但工具列表空白。后来发现是Python环境变量的问题,Cursor默认调用的python可能不是你终端里那个,尤其是用了conda或者pyenv的话,路径指向的stdlib版本不一样,MCP的SDK初始化就会静默失败。你可以先在终端跑一下which python,然后把绝对路径直接写进配置里,别用python这种简写。另外协议版本确实有讲究,Cursor目前只认MCP的2024-11-05版,你本地SDK如果太新(比如0.9+),它发的initialize请求字段可能不兼容,建议直接锁版本装mcp==0.8.0再试。还有个小坑,@mcp.tool()装饰器必须放在class外面,你要是写在类里面当方法了,工具列表也会空。日志没报错不代表没问题,你可以手动跑一下python server.py,然后另开终端用mcp dev去连,能看到更详细的握手过程。我最后是把server文件放到项目根目录,配置里写相对路径./server.py才好的,你可以试试这个组合。
大概率是Cursor要求MCP走SSE格式,stdio协议它支持得比较挑版本,试试用mcp.run(transport="sse")起个HTTP服务再填URL。
我之前也卡这过,最后发现是Cursor缓存了旧配置,重启大法或者删掉~/.cursor里的mcp缓存目录就好了。
我之前调MCP也卡在工具列表空白这步,后来发现是stdio模式下Cursor对协议握手顺序特别敏感,尤其是initialized通知必须在工具列表请求之前发出去。你用的Python SDK如果是新版,它可能默认走的是HTTP传输,但Cursor的MCP客户端对stdio的兼容性反而更老,建议检查一下sdk版本,降到0.9.x试试,或者用--transport stdio显式指定。另外你提到没配name和version,理论上不是必须的,但有些客户端会拿这个做缓存key,缺了可能导致工具列表被错误缓存成空,可以随便填个值看看。还有个排查思路:用mcp dev命令行工具直接跑你的server,如果它能正常列出工具,那就是Cursor侧解析问题,否则就是server代码里tool注册时机不对,比如在生命周期回调里动态注册工具,Cursor可能只扫描初始化快照。最后实在不行,换个思路用sse模式起个本地服务,把URL填进Cursor,很多这种工具列表为空的情况换传输方式就解决了。
我也踩过这坑,检查下mcp.run()里有没有显式传name和version,缺了这俩Cursor直接不认。
八成是协议版本问题,试试把mcp库升到最新,或者换transport="sse"看能不能拉出来。
我之前也卡在这过,后来发现是Cursor的MCP客户端对initialize响应里的protocolVersion卡得特别死,必须得是2024-11-05那个版本,你试试在server代码里显式声明一下。还有,工具列表为空八成是tools/list返回的schema格式问题,Cursor要求inputSchema里必须带type: "object"和properties,缺一个就静默忽略,根本不报错。你抓一下stdio的原始通信,看response里到底返回了啥,比瞎猜快多了。
我上周刚被这个坑过,最后发现是Python环境的问题。你试试在终端里直接跑一下python /path/to/server.py,看会不会报错,尤其是如果用了虚拟环境,Cursor那边可能没加载到你用的那个解释器。另外MCP的stdio模式对启动握手很敏感,你的server启动后如果没在5秒内打印出初始化响应,Cursor就会显示connected但拿不到工具列表——我后来在server.py最开头加了个print("started", flush=True),虽然不解决根本问题,但能确认进程有没有被拉起来。
还有一个很隐蔽的点:如果你用的MCP SDK版本太新,比如0.9以上,有些协议字段变了,Cursor对tools/list的响应格式要求比较死,缺name和version倒不至于,但tools数组里每个元素必须带inputSchema,哪怕是个空对象。你可以先手动发一个JSON-RPC请求测试一下,用echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | python server.py,看返回的原始数据长啥样。我当时就是发现SDK默认返回的schema里多了一层$schema字段,Cursor不认,直接过滤掉了。你把这个字段去掉再试试。
另外检查下你的MCP配置里是不是有--transport参数冲突,或者路径里有空格。我最后是改用绝对路径加引号解决的,之前用相对路径也是这鬼样子。如果还不行,直接在Cursor的日志文件夹里翻mcp.log,里面会记录每次握手的具体响应内容,比控制台输出详细很多。
大概率是Cursor只认MCP官方SDK的初始化格式,检查下server.py里有没有写mcp = Server("name")再注册工具,光装饰器不够。
之前用Claude Desktop接MCP也遇到过类似情况,后来发现是stdio模式下Cursor对初始化握手要求比较严格,你试试在server.py里显式加上server.name和server.version,还有记得把mcp.run()改成asyncio.run(server.run_stdio_async()),我这么改完就正常了。另外检查下Python环境是不是用了虚拟环境,路径写绝对路径试试,我之前就是相对路径导致进程起了但工具没注册上。
大概率是stdio传输下Cursor没识别到工具名,试试在server.py里显式加上server.name和server.version再重启。
我之前用Claude Desktop也遇到一模一样的情况,后来发现是MCP协议版本兼容性的问题,Cursor那边默认走的可能是老版协议,但新版Python SDK默认输出的是带protocolVersion的2025-03-26格式。你试试在初始化Server的时候手动指定protocol_version="2024-11-05",或者干脆降级一下mcp库到0.9.x,很多工具列表空白都是这个原因。另外name和version字段其实是必须的,我一开始也漏了,直接在Server("my_server", "1.0.0")里补上就行,不然服务端握手虽然成功,但初始化工具列表那一步会静默失败。还有个小坑,如果你用的是fastmcp而不是官方SDK,它的stdio传输格式有细微差别,Cursor识别不了就只显示connected但不拉取工具。你可以先用npx @modelcontextprotocol/inspector跑一下你的server,再在浏览器里连上去看看工具列表能不能正常拉取,这样能快速定位是SDK层的问题还是Cursor端的问题。最后建议把日志级别开到DEBUG,mcp.run(transport="stdio", log_level="DEBUG"),有时候工具注册失败会记录在stderr里,Cursor界面不显示但终端能看到的。
我之前也卡在这过,后来发现是Cursor的MCP配置里那个command参数不能直接写python,得用绝对路径或者写成/usr/bin/python3这种,不然它连上了但握手有问题。另外你检查下MCP server的日志输出,用--debug模式跑一下,看看有没有发tools/list请求的痕迹,没发的话大概率是协议版本不匹配。还有个坑是Python环境,Cursor有时候会用它自带的python解释器去跑你的脚本,导致依赖装不上,工具自然加载不出来。