最近在折腾MCP(Model Context Protocol),想把本地跑的Qwen2.5(7B)通过MCP服务器接到自己的知识库工具上。用的Python SDK写的Server,SSE传输,报错是“Connection timed out after 60s”。我本地模型是Ollama起的,端口11434,MCP服务器里回调地址填的是,但日志里模型推理明明已经出结果了,就是回调回不去。查了半天,怀疑是异步循环和Ollama的请求阻塞了,或者SSE的keep-alive设置有问题。有没有大佬遇到过类似情况?是MCP的timeout参数要调,还是Ollama服务端得开CORS?求个排查思路,谢谢!
MCP服务器连本地大模型总超时,是不是我配置姿势不对?
全部回复
共 19 条这问题我踩过差不多的坑,你日志里模型出结果但回调超时,八成不是Ollama的问题,而是MCP服务器里那个异步任务把事件循环占死了。SSE的发送得放单独线程或者用asyncio.create_task丢出去,别跟请求阻塞在同一个循环里。另外timeout那个60s是客户端等的总时长,模型推理慢的话建议直接调大,比如300s,不然就算回调正常也容易卡着。CORS倒是不用管,本地HTTP请求没跨域限制。你先试试把回调改成纯异步非阻塞,再不行就抓包看TCP连接是不是被服务端重置了。
这题我熟,把MCP Server的异步回调改成线程池跑,别跟Ollama抢事件循环,大概率能解决。
这题我熟,之前接本地模型也卡在回调上,问题多半不在MCP的timeout,而是你那个SSE连接被Ollama的同步请求堵死了。试试把Ollama的请求扔到独立线程池里跑,别占着事件循环,回调就通了。另外11434那个地址确认下是不是绑了localhost,有时候Ollama默认只监听本地回环,换成看下日志有没有新连接进来。CORS倒是次要的,本地进程间通信一般不触发这个。
回调地址别用,试试,Ollama默认绑定的就是localhost,走IPv6回环大概率卡死。
这问题我上周刚踩过一模一样的坑,最后发现根本不是MCP超时的事,是SSE的response对象被异步任务提前回收了。你的推理结果能出来但回调回不去,大概率是callback那个coroutine没被正确挂到事件循环上,试试把Ollama请求改成run_in_executor丢到线程池里跑,别在async函数里直接阻塞调用。另外Ollama那边CORS其实跟这个没关系,那是浏览器限制,你本地SDK走HTTP不用管。SSE的keep-alive可以调成15秒发一次注释帧,但60秒超时通常是连接被服务端主动断开,你抓包看看是不是Ollama返回后MCP server的response流没保持住。还有个偷懒的办法,直接把timeout参数从SDK默认的60s改成300s先验证通不通,如果通了就说明是时序问题,再一步步优化。最后检查下你的回调URL是不是被防火墙拦了,别问我怎么知道的。
这问题我踩过一模一样的坑,大概率不是CORS的事,Ollama那边压根不校验这个。你回调地址填localhost,但MCP服务器如果跑在容器或者另一个进程里,这个地址指向的就不是Ollama所在的主机了,换成试试。另外超时60秒对7B模型首token来说确实紧,Ollama默认加载模型就要好几秒,你可以在MCP客户端把timeout调到120秒以上,或者用streamable方式替代SSE,那个对长任务友好得多。
这问题我踩过一模一样的坑,大概率不是CORS的事,Ollama那边压根不查这个。你回调地址填没问题,但SSE的响应流得注意,MCP的SDK默认可能没把Content-Type设成text/event-stream,Ollama那个长连接请求一直占着异步循环,回调就卡死了。试试把MCP服务端的timeout调大点,或者干脆把回调改成异步任务丢给线程池,别跟Ollama请求挤一个事件循环。我之前是这么解决的,你翻翻SDK里SSE的keep-alive参数,改成15秒发个心跳包应该就好了。
我之前也踩过类似的坑,SSE那个keep-alive默认60秒很容易跟Ollama的推理时间撞上,你试试在创建SSE响应时把ping间隔调短到15秒,或者干脆改成streamable HTTP传输。另外回调地址别用,Ollama那边默认绑定的就是localhost,你换成试试,有时候IPv6解析会搞鬼。还有个思路是检查下MCP客户端那边的超时设置,别让服务端等太久,本地7B模型推理慢是正常的。
这问题我踩过差不多的坑,大概率不是CORS的事,Ollama那边压根不校验这个。你试试把MCP的timeout从60s调大到120s,有时候是SSE建立连接后首包回传慢,尤其是模型推理完但连接还在pending。另外检查下异步循环,别用同步requests去调Ollama,会卡住事件循环导致回调发不出去,换成httpx的AsyncClient试试。我之前就是卡在这,改完立马通了。
这个超时问题我踩过类似的坑,大概率不是CORS的锅,Ollama本地服务默认没跨域限制,倒是SSE的keep-alive确实会影响连接,60秒没心跳包就断。你试试把MCP的timeout调到120s,然后检查下回调地址是不是被防火墙拦了,或者换个直连模式(不经过SSE)先排除网络层问题。另外Ollama推理时是阻塞的,你可以在异步回调里加个超时保护,别让主循环卡死。我之前用FastAPI包一层异步转发就解决了,你可以参考下。
说实话你这个现象我太熟了,典型的就是回调地址和模型服务不在同一个事件循环里打架。你日志里模型已经出结果,说明Ollama那边没毛病,问题基本出在MCP服务器往回调地址发SSE响应时,那个异步任务被卡住了。我之前用FastAPI包MCP的时候也遇到过,后来发现是用了同步的requests去调Ollama,直接把事件循环堵死了,换成httpx的AsyncClient才解决。另外你回调地址填localhost,但如果是Docker或者WSL环境,这个地址可能根本不指向宿主机,得用host.docker.internal或者实际局域网IP,这点特别坑。超时参数我建议先别动,60秒够长了,真不是timeout的问题。CORS那个基本不用管,除非你是浏览器里调的,本地Python客户端不受跨域限制。你先试试把Ollama请求改成异步,再看SSE的ping间隔调短一点,比如15秒发个心跳,有些代理中间件会因为长时间没数据自己断开连接。最后实在不行,把SSE换成streamable HTTP模式,那个对连接存活要求更宽松,我换完就再没超时过。
听起来像是SSE的回调地址写成了内网IP,试试改成localhost或者,顺便把Ollama的host设置成更宽松点。
这个报错我太熟了,之前接本地vLLM的时候也卡在这。你日志里模型已经出结果但回调超时,基本可以排除Ollama本身的问题,大概率是MCP服务器里那个异步任务把事件循环堵死了。Python SDK的SSE传输默认是单线程跑回调的,如果你在回调里直接同步调Ollama的接口,推理那几十秒就把keep-alive给拖断了,60秒超时一到连接就没了。你可以试试把Ollama的请求放到线程池里跑,或者干脆用异步HTTP客户端(比如httpx的AsyncClient),别让阻塞调用占着事件循环。另外SSE的keep-alive间隔默认好像是15秒,如果你推理时间超过这个,记得把MCP服务器里的ping间隔调小一点,比如5秒。CORS那个倒是不用管,本地服务之间没浏览器介入,跟跨域没关系。还有个排查技巧,你可以在MCP服务器里加个日志,看看回调地址那边到底有没有收到请求,没有的话就是连接被服务端掐了,收到的话才是数据格式问题。
我之前也踩过类似的坑,问题大概率不在CORS,而是Ollama的请求把事件循环给堵死了。你试试把MCP server里的回调改成线程池或者用asyncio.to_thread包一下,别让推理阻塞SSE心跳。还有一个偏方是把SSE的ping间隔调短一点,比如15秒,不然代理层容易先断开连接。另外Ollama那边不用开CORS,本地回环默认是放行的,重点还是看MCP的timeout是不是设得比推理耗时短了。
这问题我踩过类似的坑,大概率不是timeout或CORS的事。你回调地址填没毛病,但Ollama的请求是同步阻塞的,如果你在SSE的异步循环里直接调它,整个事件循环就被卡死了,回调自然发不出去。我之前是把模型调用丢到线程池里,再配合asyncio.to_thread才解决。另外SSE的keep-alive可以试着设成15秒,别让连接空太久。
这问题看着眼熟,我之前用FastAPI包MCP的时候也栽在回调上。你日志里模型出结果了但回调超时,大概率不是Ollama那边的问题,而是你SSE的streaming response在异步任务里没被正确hold住,试试把回调改成同步阻塞或者用asyncio.Lock包一下。另外timeout那个60s是连接超时不是推理超时,MCP的transport配置里有个heartbeat参数,调成30s试试,顺手把Ollama的OLLAMA_HOST设成:11434,别用localhost,有时候IPv6解析也会卡住。
这问题多半是异步阻塞,Ollama的请求把事件循环卡死了,试试把推理丢线程池里跑。
这问题我踩过一模一样的坑,大概率不是timeout参数的事,Ollama那边也不用开CORS。你回调地址填的如果是本机,试试把SSE的响应头里加个Connection: keep-alive,另外检查下MCP Server的异步循环是不是被Ollama的同步请求卡住了,把推理丢到线程池里跑能解决。我之前用FastAPI改成了streaming响应才彻底好。
你这问题我踩过一模一样的坑,最后发现根本不是timeout或者CORS的事。Ollama的请求是同步阻塞的,你在MCP的async回调里直接调它,整个事件循环就卡住了,SSE那条连接自然就断了。我当时是把Ollama的调用扔到线程池里跑的,用run_in_executor包一层,瞬间就好了。另外你回调地址填的,如果MCP server和Ollama在同一台机器上没问题,但要是走容器或者代理,得确认下网络命名空间是不是隔离的。还有个小细节,SSE的keep-alive默认是注释掉的,很多SDK不会主动发心跳,你可以在server端手动加个ping事件,每15秒推一次,不然代理层容易把空闲连接掐了。调试的时候建议先别用知识库工具,直接用curl模拟SSE请求,把MCP协议那层剥掉,看纯HTTP流是否正常,这样能快速定位是协议问题还是业务逻辑问题。