最近刚上手MCP,想用Cursor搭个本地服务器试水,结果折腾了两天。我参照官方文档装好Python SDK,写好了一个简单的文件搜索工具,启动后Cursor倒是能发现这个server,但每次调用工具跑几秒钟就提示连接中断,报错“transport closed”。我试过换端口、关防火墙,甚至还重启了电脑,问题依旧。是不是MCP的传输协议对本地socket有什么特殊要求?还是我代码里异步处理写错了?感觉网上资料太零散了,求大佬指点一个稳定的入门配置。
MCP服务器连Cursor老是断联,是我姿势不对吗?
全部回复
共 148 条这问题我也遇到过,刚开始以为是网络问题,后来发现大概率是MCP的Server端异步处理没处理好。Python SDK里如果你用asyncio的话,记得确保事件循环不要被阻塞,尤其是文件搜索这种I/O操作,建议用run_in_executor丢到线程池里去跑。另外检查下Cursor的MCP配置里的timeout参数,默认值可能太短了,稍微调大一点试试看。
大概率是stdio传输模式下子进程生命周期没管理好,Cursor一空闲就给你掐了。试试把server挂到sse模式,用supervisor保活。
我之前也踩过这坑,后来发现是Python SDK的asyncio事件循环和Cursor的通信线程冲突了,换个同步写法就稳了。
我之前也踩过这个坑,后来发现多半是MCP的stdio模式跟Cursor的进程生命周期没匹配好,尤其是你代码里如果有长时间运行的任务,socket超时设置得不对就会触发transport closed。你可以试试把工具调用改成短任务,或者直接在客户端配置里把超时时间调大一点,比折腾防火墙有用。另外,异步那块建议检查下是否用了asyncio事件循环没正确关闭,我上次就是这里漏了导致连接被GC回收。如果还不行,换个思路用SSE模式搭远程服务,稳定性会好很多。
八成是stdio的stdout被日志污染了,MCP走JSON-RPC,print一下就直接断开。
把日志全写到stderr或者文件里,再试试长连接超时参数调大点。
我之前也踩过这个坑,后来发现多半不是协议本身的问题,而是MCP的stdio传输模式下进程生命周期没管理好。Cursor这边发起调用时,如果你的Python脚本里存在未处理的异步任务或者主循环提前退出,socket就会立刻关闭,报“transport closed”太正常了。建议你先别急着换端口,直接在代码里把日志级别调到DEBUG,看看server端是不是在收到请求后主动抛了异常——我之前就是漏了个await,结果响应还没发完连接就断了。另外,确认下你用的MCP SDK版本和Cursor内置的兼容性,这俩更新频率都快,有时官方文档的示例代码已经落后于实际API了。要是实在排查不出来,可以试试把server挂成SSE模式,虽然多了层HTTP握手,但至少断联时能看到更具体的状态码,比裸stdio好调试得多。最后问下,你跑工具的时候是单次调用还是连续多次?如果每次都是几秒后断,也可能和超时配置有关,试试把传输层的keepalive间隔调短点,有时候默认值太长会被代理或系统静默杀掉。
之前我也踩过这个坑,最后发现是MCP的stdio传输模式下,子进程的日志输出会污染协议通道,你把print或者logger打到stdout试试,全改成stderr或者文件日志基本就能解决。另外Cursor对server的心跳超时特别敏感,如果工具里有长时间阻塞操作,建议把任务丢到线程池然后立即返回,不然transport closed是必然的。你那个文件搜索工具如果扫的目录太大,八成就是这个原因,可以先拿小目录测试排除一下。
我前几天也踩过这个坑,后来发现多半是MCP的stdio传输和Cursor的进程管理不太对付,尤其是异步任务没及时释放资源的时候,transport closed特别常见。你可以试试把server改成sse模式跑,或者检查下代码里是不是有未await的协程在阻塞事件循环。另外,官方那个fastmcp库比直接撸SDK稳不少,换它基本能省一半折腾时间。
这问题我上周刚踩过一遍,折腾到凌晨三点才搞明白。你那个“transport closed”大概率不是异步写错,而是MCP的stdio传输和Cursor的进程管理方式不兼容——Cursor默认会回收空闲子进程,如果你的server启动后没有及时打印出“ready”标记,或者日志输出频率太低,就会被判定为死连接直接掐掉。建议你先试试在启动命令里加上--log-level DEBUG,看服务端是否在调用前就崩了,或者干脆用npx跑一个官方示例server对比下,排除代码问题。另外,本地socket的话,千万别用localhost,直接绑127.0.0.1,有些系统上IPv6解析会导致连接被重置。还有一个坑是Python SDK的run_stdio_server()默认会注册信号处理器,如果和Cursor的event loop冲突,就会在每次调用后抛异常——你可以把异步入口改成同步的run()试试。最后,如果还不行,检查下Cursor版本,目前2.5.x对MCP支持有已知bug,降级到2.4.8或者升级到最新预览版都能解决。我当时就是靠降级搞定的,网上那些教程全是抄来抄去,没几个真跑通。
大概率是MCP的stdio模式超时设置太短,试试把transport换成sse或者调大超时时间,我前几天也踩过这坑。
这个报错我上周刚踩过,多半不是姿势问题,是MCP的stdio模式跟Cursor的进程生命周期绑定太紧,你那个server要是没做心跳保活或者异步任务没起独立线程,跑几秒就会被判定为死连接。建议先试试用--transport sse起个HTTP服务,把回调地址填进Cursor,稳定性比stdio好不少。另外检查下你的工具函数里有没有阻塞操作,我上次就是文件扫描用了同步递归,直接卡断传输。要是还不行,可以开个--debug看下具体断在哪一步,网上那些教程确实太碎,还是官方example里的filesystem项目最靠谱。
我前两天也踩过这个坑,折腾到半夜差点把电脑砸了。你那个transport closed大概率不是姿势问题,是MCP的stdio传输模式跟Cursor的进程生命周期没对齐,Cursor那边一超时或者GC卡顿,子进程的管道就断了。建议你先试试把server跑成SSE模式,用HTTP长连接代替默认的stdio,稳定性会好很多,虽然配置麻烦点但至少不会几秒就掉。另外你写的异步处理,如果用的是asyncio,记得检查一下loop是不是在同一个线程里跑的,Cursor有时候会多线程调用,你代码里要是没加锁或者没处理好事件循环,很容易出现连接被意外关闭的情况。还有个土办法,在server启动后加个心跳日志,每两秒打印一次,看看到底是客户端断的还是服务端崩的,这样排查起来快很多。最后,如果你非要坚持stdio,试试把Cursor的请求超时时间调大,默认那个值对本地工具来说太苛刻了,稍微慢点就掐断。网上确实资料碎,我后来是去翻MCP的GitHub issue才找到类似案例的,你有空也可以搜下“cursor mcp disconnect”看看是不是同款问题。
我之前也踩过这个坑,八成不是姿势问题,是MCP那个stdio传输在Cursor里天生对超时特别敏感。你那个工具跑几秒就断,大概率是异步任务没在session里保持心跳,试试把工具调用改成同步阻塞,或者给server加个keepalive的ping。另外别用本地回环地址,直接用127.0.0.1有时候比localhost稳,防火墙其实影响不大。要是还不行,换streamable-http那个传输模式,别死磕stdio,我换了之后基本没断过。
这问题我上周刚踩完坑,大概率不是姿势问题,是MCP那个stdio传输在Windows上对子进程的生命周期管理特别敏感。你那个报错transport closed八成是Cursor那边把Python进程给回收了,因为默认超时设置太短,而你的文件搜索工具如果是同步阻塞式的,第一次握手后只要处理超过几秒就会触发断开。我后来是把server端改成用sse模式跑在本地端口上,然后让Cursor连那个http地址,虽然多一步启动但稳定得多。还有个小细节,Python SDK里那个run()函数如果你没用asyncio.run包一层,事件循环没跑起来也会假死,你可以在启动时加个日志看看进程是不是真的在等请求。另外别用系统自带的cmd去跑,用PowerShell或者直接双击启动脚本,不然环境变量路径偶尔会抽风。如果还不行,建议把超时参数在client端手动调大到30秒,网上那些默认配置基本都是给远程服务器用的,本地调试完全不适用。
我之前也踩过这个坑,后来发现多半是SDK版本和Cursor内置的MCP客户端不兼容导致的,建议先确认下两边用的协议版本是不是对得上。另外你那个异步处理里如果有长时间阻塞的调用,确实容易触发transport closed,试着把工具函数改成纯同步或者加个超时控制看看。还有个小技巧,本地调试时别用默认的端口,换个不常见的比如8123能避开很多莫名其妙的干扰。如果还不行,直接去GitHub上看下官方examples里文件搜索那个demo,对照着改基本能稳。
这问题我上周刚踩过,大概率不是你代码写错,是MCP的stdio传输跟Cursor的进程生命周期对不上。你试试把server改成用sse模式起一个HTTP服务,然后连本地端口,稳定性会好很多。另外注意Python那边记得加--enable-threads,不然异步任务一多就把连接卡死了。
我之前也卡在这好久,后来发现多半不是协议问题,是异步任务没跑完连接就被GC了。你试试在工具函数里加个显式的await或者用asyncio.run包一下,另外确认下stdio的编码,Windows上容易踩坑。还有个小技巧,启动MCP前先跑个简单的ping工具测几分钟,稳定了再上复杂逻辑,能省不少排查时间。
我刚开始也这样,后来把stdio换成sse模式就稳了,你可以试试看。
我之前也卡在这个transport closed上过,折腾了两天最后发现是Python SDK版本和Cursor内置的MCP客户端不兼容。你用的stdio传输方式的话,注意一下是不是代码里没有保持事件循环常驻,比如FastMCP的run方法被某些IDE的调试模式干扰了。另外建议你试试把日志级别开到DEBUG,看断连瞬间有没有具体的异常栈,我那次是发现asyncio的task被GC回收了,加个强引用就稳了。还有个取巧的办法,先不用自定义server,直接用官方示例的echo server连一下,如果这样也断那就是环境问题,如果不断就是你代码里的异步逻辑有隐患。端口和防火墙大概率不是主因,本地socket走的是进程间通信,跟网络栈关系不大。你可以试试把MCP配置里的启动命令改成绝对路径,有时候Cursor的工作目录不对会导致子进程启动后读不到配置直接挂掉。最后问一下,你用的Python版本是3.11以上吗?低版本对某些新语法支持不好也会引发这种玄学断连。
这问题我蹲过,八成是stdio和Cursor的进程通信握手没配对,试试把MCP配置里的transportType改成sse。
我上次也这样,后来发现是Python SDK版本和Cursor内置的不兼容,换个0.9.x的版本就稳了。
我遇到过的类似情况,多半是MCP server端没处理keepalive或心跳导致空闲超时,尤其本地socket连接,Cursor那侧等不到响应就主动掐断了。你试试在server里加个简单的ping/pong逻辑,或者把传输超时参数调大点。另外异步那块,确认下是不是用了asyncio的run_in_executor,普通同步函数阻塞事件循环也会触发断连。网上教程确实碎片化,建议直接去翻MCP官方Python SDK的examples目录,那个echo server虽然是基础但够参考。