最近刚上手MCP,想用Cursor搭个本地服务器试水,结果折腾了两天。我参照官方文档装好Python SDK,写好了一个简单的文件搜索工具,启动后Cursor倒是能发现这个server,但每次调用工具跑几秒钟就提示连接中断,报错“transport closed”。我试过换端口、关防火墙,甚至还重启了电脑,问题依旧。是不是MCP的传输协议对本地socket有什么特殊要求?还是我代码里异步处理写错了?感觉网上资料太零散了,求大佬指点一个稳定的入门配置。
MCP服务器连Cursor老是断联,是我姿势不对吗?
全部回复
共 148 条我之前也栽在transport closed上,后来发现多半是MCP的stdio传输跟Cursor的进程生命周期没匹配好,工具跑完或超时后管道就被回收了。你可以试试把server改成用sse模式,或者给工具调用加个keep-alive心跳。另外检查下代码里有没有在异步函数里做阻塞操作,那玩意儿最容易把连接卡死。稳定配置的话,官方那个fastmcp库比裸用SDK省心不少,我换了之后就没断过。
我上周也踩过一模一样的坑,后来发现多半是SDK版本和Cursor内置的MCP客户端不兼容导致的,建议你直接升级到mcp库最新版试试。另外如果你用的是stdio传输,注意本地server别在代码里print任何调试信息,会污染协议通道直接触发transport closed。我之前就是被一个print('started')坑了整整半天,删掉立马稳了。实在不行可以换个思路,用streamable HTTP模式跑本地服务,比stdio抗断连能力强不少。
我之前也踩过这个坑,后来发现多半是MCP的stdio传输模式下,子进程的输出缓冲区没处理好,尤其是异步打印日志会跟协议帧抢通道。你可以试试把server端的日志全部重定向到文件,别往stdout写,然后给每个工具调用加上超时控制。另外Cursor那边有个设置是自动重连,关掉它有时候反而更稳。如果还不行,就换sse模式跑一下,虽然配置多点,但至少断线能看得见原因。
我之前也踩过这个坑,后来发现多半是MCP那个stdio传输方式和Cursor的进程生命周期没配合好,尤其你代码里如果有长任务或者异步回调,很容易被当成超时断开。你可以试试把server改成SSE模式跑在HTTP端口上,或者给工具调用加个超时重试逻辑,官方文档里其实有提但这个细节特别容易忽略。另外你用的Python SDK版本和Cursor的MCP客户端版本最好对齐一下,我上次就是版本不匹配导致传输层报错,升级完就稳了。如果还不行,可以把日志级别调到DEBUG看看断之前有没有异常堆栈,比瞎猜高效得多。
我之前也遇到过一模一样的问题,后来发现是Python SDK版本和Cursor内置的MCP客户端不兼容,你试试把mcp库降到0.9.x或者直接升到最新版,有时候版本漂移会莫名其妙触发transport closed。另外异步循环里别用那种阻塞式文件扫描,改成asyncio.to_thread包一下,不然事件循环卡住几秒就会被服务端判定为心跳超时。如果还不行,可以试试在启动server时显式指定host为127.0.0.1而不是默认的localhost,有些系统解析IPv6会出幺蛾子。我这么调完就稳定了,你可以先照着排查下。
我前两天也踩过这个坑,后来发现多半不是传输协议的问题,而是MCP的stdio模式跟Cursor的进程生命周期绑得太紧,你那个server只要稍微有点异步任务没处理完,或者主线程提前退出了,连接就会立刻报transport closed。我之前写工具时就是没注意keepalive,事件循环里漏了await,跑几秒就断,加了asyncio.sleep保活之后稳定多了。另外如果你用的是stdio transport,别去折腾端口和防火墙,那玩意根本不走网络,反而该看看Cursor这边的工作目录权限,有时候它连不上是因为启动server的shell环境跟你的Python虚拟环境对不上。建议你直接改用streamable HTTP模式试试,虽然配置麻烦点,但断联问题会少很多,我换成这个之后基本没再掉过线。还有个小细节,错误日志别只看Cursor弹窗,去终端里把server的stdout和stderr都打出来,很多真实原因都在那里面藏着。
我之前也踩过这坑,多半不是协议问题,而是MCP server那边stdin/stdout被缓冲了,Cursor等不到心跳就断。你试试在启动命令前加个python -u强制无缓冲,或者把日志写进文件看看是不是代码里异步任务提前退了。另外别用本地socket,直接用stdio传输模式最稳,官方示例基本都能跑通。
我最近也踩过这个坑,后来发现大概率不是传输协议的问题,而是MCP server那边用了同步阻塞式的stdin/stdout通信,Cursor默认给的超时时间又很短,工具跑几秒没返回就掐断了。你可以试试把工具函数改成异步,或者直接在启动命令里加个环境变量把超时调大,比如MCP_TIMEOUT_MS=30000,我之前这样改完就没再断过。另外检查下是不是代码里print了调试信息,这玩意儿会污染JSON-RPC的管道,一旦混入非协议内容,连接必断。我之前就是被一个日志输出坑了一晚上。还有个小细节,本地socket的话,别用localhost,直接写127.0.0.1,有时候IPv6解析会抽风。官方文档确实写得太简略了,社区里也没个统一的最佳实践,基本靠试错。你试下把stdio的缓冲关掉,或者在启动server前加个延迟,等Cursor握手完成再开始监听,我这边稳定跑了一周没掉过线。
这问题我上周刚踩过,大概率不是socket的锅,多半是MCP server那边没做好心跳保活或者超时处理,Cursor这边空闲几秒就主动断。你可以试试在server端把日志级别调到DEBUG,看看断之前有没有收到shutdown请求,另外检查下你的异步循环是不是被阻塞了,比如文件搜索如果是同步的,得扔到线程池里跑。我之前就是没加asyncio.to_thread,一搜大目录就卡死然后触发transport closed。
遇到过类似的坑,多半不是协议问题,而是MCP server那边没处理好生命周期。Cursor对连接空闲超时很敏感,你那个文件搜索工具如果执行时间长或者异步任务没及时返回心跳,transport就会先断开。建议把server端改成流式响应,或者把超时时间调大点试试。另外检查下Python SDK版本,有些旧版对stdio的keep-alive支持有bug,升级到最新版能解决不少玄学问题。
我之前也遇到过一模一样的“transport closed”,后来发现是MCP的stdio传输模式下,Cursor那边对子进程的stdout输出特别敏感,你代码里但凡有个print或者日志写到了stdout,就会把协议数据包冲掉。建议把所有调试信息改写到stderr或者日志文件,另外异步任务里别让event loop被阻塞太久,试试把工具函数改成同步的,让SDK自己管理线程池,稳定性会好很多。
我之前也踩过这个坑,大概率不是姿势问题,是MCP的stdio模式跟Cursor的进程生命周期绑太紧,跑长任务时容易掐断。你可以试试把server改成SSE模式,或者用supervisor之类的工具保活进程,我换成sse后基本没断过。另外异步代码里如果用了asyncio.create_task,记得要持有task引用,不然容易被GC回收,这也会导致transport closed。建议你先把官方那个example server跑通再改自己的逻辑,排除法最省时间。
我之前也踩过这个坑,后来发现多半是MCP的stdio模式跟Cursor的进程生命周期没对齐,异步任务没跑完就被回收了。你可以试试把工具改成同步阻塞,或者在server启动时加个keep-alive的定时心跳。另外检查下Python版本,3.11以下有个asyncio的事件循环bug会间歇性断连。要是还不行,干脆先换streamable-http模式,本地起个Flask转发,稳定很多。
我也踩过这个坑,一开始以为是防火墙或者端口问题,折腾半天发现大概率是MCP的stdio传输模式和Cursor的进程管理方式冲突了。你用的本地server如果是走stdio,那每次调用时子进程的stdout和stderr如果被混在一起,或者有额外打印,就特别容易触发transport closed,我之前写了个打印日志的装饰器直接就给搞崩了。建议你先把server端代码里所有print都去掉,换成logging输出到文件,然后测试一下裸跑工具是否稳定,排除异步事件循环没正确关闭的问题。另外Cursor对MCP的进程超时控制比较严格,如果你那个文件搜索工具处理大目录时耗时超过十几秒,连接被掐断也很正常,可以试试把搜索逻辑改成异步流式返回,或者干脆缩小测试范围。还有个小细节,如果你是在Windows上跑,记得确认Python的asyncio子进程支持没问题,Windows下这个老出幺蛾子。网上资料确实碎,官方那个python-sdk的examples其实有完整可跑的server,你可以直接拿那个改,别自己从零搭。要是还不行,试试用remote方式跑,虽然配置麻烦点,但连接稳定性比本地stdio好不少。
我之前也踩过这个坑,后来发现多半是stdio的stdout被日志输出污染了,MCP走的是JSON-RPC over stdio,你代码里任何print都会把连接搞崩。建议把所有调试信息写到stderr或者文件里,另外看看是不是用了asyncio的loop没跑对,官方示例里那个serve函数要确保在async上下文里启动。我换成用sse模式连远程服务器后反而稳定很多,本地调试还是先确认下进程是不是被系统杀掉了。
八成是stdio传输模式超时了,试试把MCP配置里加个低延迟心跳参数,或者换streamable-http走本地端口稳一点。
我也遇到过一模一样的报错,最后发现是Python SDK版本和Cursor内置的MCP客户端不兼容,把mcp库降到0.9.x就好了,你可以试试。另外如果你用的是stdio传输,建议把日志级别调到DEBUG看看是不是某个参数类型对不上,我这边之前就是工具返回了非JSON序列化的东西导致连接被掐断。
八成是stdio的通信超时设置问题,试试在server代码里把read_timeout调大点。
我之前也卡这,后来发现是Python SDK默认的等待时间太短,改完就稳了。
之前我也遇到过一模一样的报错,后来发现是Python SDK版本和Cursor内置的MCP客户端不兼容,建议你直接升级到最新的mcp库再看看。另外如果工具是长耗时任务,默认的stdio传输确实容易超时,试试在server端把读超时调大,或者换个streamable-http的传输方式。还有个小坑,本地socket路径别用特殊字符,有时候Windows下会莫名断开。
八成是SDK版本和Cursor内置的MCP客户端不兼容,试试把stdio换成SSE模式能稳很多。我之前也卡这问题,换个传输方式就再没断过。