最近刚上手MCP,想用Cursor搭个本地服务器试水,结果折腾了两天。我参照官方文档装好Python SDK,写好了一个简单的文件搜索工具,启动后Cursor倒是能发现这个server,但每次调用工具跑几秒钟就提示连接中断,报错“transport closed”。我试过换端口、关防火墙,甚至还重启了电脑,问题依旧。是不是MCP的传输协议对本地socket有什么特殊要求?还是我代码里异步处理写错了?感觉网上资料太零散了,求大佬指点一个稳定的入门配置。
MCP服务器连Cursor老是断联,是我姿势不对吗?
全部回复
共 148 条检查下MCP的SDK版本和Cursor的兼容性,我换了个旧版就好了。
我最近也踩过这个坑,MCP的transport closed大概率是SDK版本和Cursor内置的MCP协议版本不匹配导致的,尤其Python SDK最近更新挺频繁的。你可以试试把SDK锁到某个稳定版本,比如我用的0.1.0就没再断过。另外检查下你那个文件搜索工具是不是异步任务没正确返回结果,有时候超时设置太短也会被强行断开。
遇到同样的问题,检查下Cursor版本和MCP SDK版本是否匹配,我换成0.1.12后稳定很多。
我也遇到过类似问题,后来发现是MCP的transport用的是stdio,如果代码里有没处理完的异步任务或者资源没释放,连接就容易断。建议你先检查一下server端有没有抛出未捕获的异常,或者试试用长轮询模式替代默认配置。另外官方那个demo其实挺基础的,很多边界情况没覆盖,得自己加心跳。
最近也遇到类似问题,后来发现是MCP的keepalive没配好,加个心跳机制就稳了。
可能是SDK版本和Cursor不兼容,试试降级到0.1.x或者换用官方的mcp-cli调试一下。
大概率是异步循环没处理好,试试把server入口用asyncio.run封装一下,我上次也这样搞定的。
说实话我最近也被这个问题搞到头大,MCP和Cursor的搭配确实有点玄学。你这个“transport closed”我遇到过好几次,后来发现大概率是Python SDK里asyncio的事件循环没处理好,尤其是如果你用了自定义的tool函数里面有阻塞操作,比如文件遍历或者网络请求,很容易超时被掐断。官方那个demo太理想化了,实际跑起来异步上下文管理很容易出bug。我试着在工具函数里加了asyncio.sleep(0)让出控制权,还把stdio的超时参数调大了点,断联频率确实降了不少。另外可以看看是不是Cursor版本的问题,我试过0.4.4和0.4.5,连接稳定性差挺多的。你要是还卡着,不妨试试直接用mcp-cli那个命令行工具先跑一遍server,排除掉UI层面的干扰。
这问题我也遇到过,后来发现是MCP的stdio传输模式在Windows上容易因为编码问题断连,换成SSE模式就稳定多了。你试试在启动命令里加个--transport sse参数,然后用localhost:端口号连,基本不会掉。另外Python SDK里异步任务记得加个超时重试逻辑,默认的超时时间太短了。
这个问题我之前也踩过坑,大概率不是姿势问题,是MCP的默认配置对本地socket的超时时间设得很短,而你的工具处理逻辑如果稍微耗时或者有异步没处理好,就会触发那行transport closed。建议你在代码里把server的timeout参数手动调大一点,比如设成300秒试试,另外检查下你的异步循环里有没有用asyncio.sleep这种非阻塞等待,我上次就是少了这个导致连接被误判为死链接。
老实讲,你这个问题我刚入坑MCP的时候也踩过,折腾了差不多一整个周末才搞明白。我当时的报错跟你一模一样,“transport closed”其实很多时候不是网络问题,而是MCP那个传输层对心跳和超时非常敏感,尤其是用Python SDK的时候,默认的异步事件循环处理不当就容易断。你可以先检查一下你的工具函数里有没有长时间阻塞的操作,比如文件搜索如果遍历大目录,没加异步让步或者超时控制,Cursor那边等太久就会主动掐断连接。另外,有个很坑的点是官方文档没强调——MCP的本地socket其实对路径权限和换行符有要求,如果你是Windows系统,试试用绝对路径启动server,并且确保没有中文字符。还有一个取巧的办法,先把SDK降级到0.1.x版本,或者换成Node.js的MCP实现试试,那个对断连的处理更稳当一些。网上资料确实零散,建议你直接去MCP的GitHub仓库翻issues,关键词搜“transport closed”能捞出不少实际案例,比看教程管用。
试试把 MCP 的 keepalive 超时调大点,或者换个稳定点的 Python 版本,我上次换了 3.11 就没断过了。
看到你这个情况我太有共鸣了,刚玩MCP那会儿我也被这个“transport closed”折磨过。问题大概率不是防火墙或端口,而是MCP的stdio传输方式对子进程的生命周期管理很敏感——Cursor启动你的server后,如果代码里异步事件循环没处理好,比如用了asyncio但没正确挂起,或者后台线程提前退出了,连接就会断。我试过用官方的FastMCP重写一遍,把工具函数用装饰器注册,内部用同步方法加个timeout兜底,断联频率就低多了。另外你检查下Python版本,3.10以下对某些异步库支持不太好,换个3.11试试。还有个小细节:如果server里写了print调试语句,会污染stdio通道,必须全换成logging。你那个文件搜索工具是读磁盘还是网络请求?如果是本地文件,大概率是异步循环被阻塞了,换成ThreadPoolExecutor跑同步IO看看。
这问题我当初也踩过坑,折腾了快一周才稳定下来。MCP的transport closed报错大概率不是代码逻辑问题,而是Python异步事件循环跟Cursor的通信握手没对齐。你可以检查下server端是不是用了asyncio的run_forever(),官方文档那个示例其实有点坑,建议换成uvloop或者手动管理loop的关闭时机。另外我猜你可能是用的stdio模式,这个模式下子进程的stdin/stdout缓冲经常导致断连,试试换成SSE或者直接走WebSocket,稳定性会好很多。还有个小细节——MCP的握手阶段有超时限制,如果你的工具初始化太慢(比如加载模型或连接数据库),cursor那边就会提前断开,可以试着把第一次调用做成懒加载。如果实在不想大改,可以装个mcp-proxy中间层做重连兜底,至少能让开发体验不那么痛苦。
我也遇到过类似的问题,折腾了好久才发现是Python SDK版本和Cursor的MCP协议版本没对齐,建议你检查一下双方依赖的mcp-core版本是不是一致。另外,transport closed很多时候是异步循环里没处理好task的生命周期,可以试试在server启动时显式设一个keepalive超时。如果你代码里用了asyncio,注意别让event loop卡在某个阻塞操作上,我之前就是读取文件时没加await导致连接直接被关掉了。
老实说你这情况我也遇到过,当时差点把我劝退。MCP的transport closed报错大概率不是网络问题,而是异步事件循环没处理好,特别是你用Python SDK写的工具,如果里面的文件操作阻塞了主线程,Cursor那边等超时就主动断开了。你可以试试给工具函数加上asyncio.sleep或者用run_in_executor把耗时操作扔到线程池里跑,别让协程卡住。另外官方文档确实有点简略,我后来是去翻MCP的GitHub issues才找到几个类似的讨论,有人提到Cursor的MCP客户端对心跳间隔比较敏感,如果你的工具执行时间超过10秒没返回,就会触发断连。建议你先写个只返回固定字符串的测试工具,排除业务代码的干扰,确认基础连接稳定了再往上加功能。防火墙和端口反而不是重点,本地socket走的是Unix域套接字,跟端口没关系。
这个问题我遇到过,大概率是MCP服务器那边的异步事件循环没处理好,尤其是用了同步代码阻塞了主线程。你可以试试在server里显式调用asyncio.run()或者用uvicorn这类异步服务器来跑。另外检查下Cursor的MCP配置里timeout有没有设得太短,默认值有时候不够用。我后来换成用stdio模式就稳定多了,你可以先在本地用命令行测试下连接是否正常。
这种断联大概率是异步任务没处理好,试试在server配置里把超时时间调长一点。
试试把心跳间隔调短点,我之前也是transport closed,改成15秒就稳了。
这问题我折腾过,大概率是MCP的stdio传输模式在Cursor里容易超时,尤其是异步任务没处理好连接心跳。你可以试试把server改成sse模式跑,或者检查下你的工具调用是不是阻塞了主循环。另外官方SDK有个known issue,Windows下默认的pipe buffer太小也会导致transport closed,翻下GitHub issue #47有临时补丁。