最近在折腾MCP(Model Context Protocol)部署本地大模型,按照官方文档一步步来,但启动服务后客户端连接时总报“handshake failed”错误。我试了调整context_window大小和修改tools配置,还是不行。环境是Ubuntu 22.04,用vllm部署的Qwen2.5-7B,MCP server跑在Docker里。怀疑是不是模型版本和MCP协议版本不兼容?或者需要额外设置allow_origin?看GitHub issue里有人说是端口冲突,但我检查过了。求大佬指点一下,这玩意儿是不是有隐藏前提条件?先谢过!
MCP部署大模型时总是报错,是配置问题还是我方法不对?
全部回复
共 186 条vllm配Docker时试试把host改成0.0.0.0,我之前就是卡在这,默认绑定回环地址了。
我前几天刚踩过类似的坑,最后发现是Docker网络模式和宿主机防火墙的锅,vllm默认监听在0.0.0.0但MCP客户端走了IPv6,handshake直接卡死。你试试在启动命令里强制加--host 127.0.0.1,或者把Docker网络改成host模式,另外Qwen2.5的tokenizer有时候会返回奇怪的finish_reason,把max_tokens设成和context_window一样大小试试。如果还不行就抓包看下TCP握手到底断在哪一层,我之前就是被这个误导了半天。
我之前也遇到过类似的handshake failed,后来发现是vllm默认的api服务路径和MCP server里配置的endpoint对不上,你检查下server启动日志里实际监听的路径,别只盯着端口。另外Docker里跑MCP时,容器网络模式如果是bridge,宿主机的localhost和容器内的localhost不是一回事,客户端得用映射后的IP加端口访问。Qwen2.5-7B本身和MCP协议没听说有不兼容,倒是建议把allow_origin设成*先排除跨域干扰,但记得改完重启整个服务链。我上次折腾半天最后是docker-compose里漏了environment的MODEL_NAME变量,导致server拿到的是默认模型名,你可以看看是不是类似这种隐藏配置。
我之前也卡在handshake failed上,后来发现是Docker容器里vllm的host配置默认绑了127.0.0.1,而MCP server从容器外访问根本连不上,改成0.0.0.0就好了。你检查过这个没?另外Qwen2.5-7B配合MCP的话,协议版本其实没太大问题,但建议把client的request timeout调大一点,默认5秒经常不够用。allow_origin我倒是没设过,感觉跟这个关系不大,除非你用了浏览器端的客户端。
我之前也卡在handshake failed上,后来发现是Docker里MCP server的host绑定了127.0.0.1,而vllm在宿主机上,客户端从容器外访问根本连不上。你试试把server的host改成0.0.0.0,再检查下Docker网络模式是不是bridge,host模式有时候反而省事。另外Qwen2.5-7B的chat模板和MCP的tool调用格式确实有兼容坑,建议先用官方示例模型跑通再换。allow_origin那个倒是次要,除非你前端跨域调用。
我之前也卡在handshake failed上,后来发现是Docker容器里hostname没映射对,MCP客户端校验SNI的时候直接崩了,跟模型版本关系不大。你试试在启动命令里加--host 0.0.0.0,然后客户端连接地址用容器的实际IP而不是localhost看看。另外Qwen2.5-7B走vllm的话,记得MCP的tool schema要跟模型generation config对齐,不然即便握手成功,后续调用也会莫名超时。allow_origin那个一般只在浏览器场景才需要,本地CLI工具不用管。
我遇到过类似的handshake failed,最后发现是vllm的openai兼容接口路径没对齐,MCP默认找的是/v1/chat/completions,但docker里映射的端口或者路由前缀可能改了。你可以先curl一下模型服务的完整URL看看返回是不是标准的openai格式,另外allow_origin在跨容器访问时确实要设,但一般不会导致握手失败。还有个小坑是Qwen2.5的tools格式要和MCP的tool schema严格匹配,你检查下模型是不是真的支持function calling,不支持的话光改context_window没用。
这问题我上周刚踩过类似的坑,vllm默认的API server和MCP的握手逻辑对不上,尤其是Qwen2.5系列有时候会返回多余的字段。你可以试试给MCP server加个环境变量强制走OpenAI兼容模式,别直接用原生vllm接口。另外Docker里跑的话,检查一下容器网络是不是host模式,有时候端口映射会把MCP的header搞丢。我之前是卡在health check路径上,MCP要求特定的/health端点,vllm默认不提供,得在配置里手动映射一下。
这报错八成是vllm和MCP的协议版本没对齐,试试在Docker里加个--enable-cors或者检查下tokenizer配置。
大概率是Docker网络模式问题,vllm和MCP server不在同一网络段握手必挂,试试host模式。
我之前也被这个handshake failed卡了好久,后来发现是Docker网络模式的问题,bridge模式下容器里的MCP server监听的是容器内IP,客户端连不到。你可以试试host模式,或者把端口映射配好,尤其是vllm本身也占着端口。另外Qwen2.5-7B用MCP的话,建议确认下你的MCP SDK版本是不是太旧了,有些协议字段会变,allow_origin倒不是必须的。你可以在宿主机上直接跑MCP server排除一下Docker的干扰,如果通了基本就是网络或环境变量的问题。
这报错大概率是vllm和MCP的握手格式对不上,试试直连不用Docker跑一次排除网络代理问题。
vllm的api server默认不启mcp那套握手,得用--enable-mcp或是装个adapter中转,你查下日志里tls握手那步是不是直接拒了。
我之前也卡在这过,后来发现是Docker网络模式的问题,bridge模式下容器外的vllm服务没法直接用localhost访问,你试试把MCP server的网络改成host模式,或者把vllm地址换成容器能访问的宿主机IP。另外Qwen2.5-7B对MCP的tool calling支持其实挺挑版本的,建议把transformers和vllm都升到最新再跑一次,有时候就是版本太旧导致协议握手时参数对不上。
handshake failed大概率不是配置路径的问题,更像是服务发现层面没通。你可以先在容器里curl一下vllm的health接口确认能通,然后再看MCP的日志是卡在HTTP还是WebSocket阶段,这样能缩小排查范围。allow_origin那个一般只在浏览器场景才需要,本地客户端反而容易画蛇添足。
大概率是Docker网络模式和vllm的host配置冲突,试试用host网络模式跑MCP server。
我之前也栽在handshake failed上,后来发现是MCP server的transport模式没对上,官方默认走stdio,但docker里跑就得换成sse或者streamable-http,光调context_window真没用。另外vllm的openai兼容接口和MCP握手时对模型名有严格校验,你确认下服务端返回的model字段和配置里写的一致,大小写都别差。allow_origin那个倒是次要,除非你从浏览器跨域访问,不然先排除掉。可以试试在容器里直接curl一下MCP的endpoint看返回头,能快速定位是不是网络层问题。
我之前也卡在handshake failed上好久,后来发现是MCP server的stdio模式跟Docker的端口映射逻辑冲突了,因为stdio走的是标准输入输出,根本不该暴露TCP端口。你如果用vllm部署,建议把MCP server直接跑在宿主机上,或者用--network host模式,别用默认bridge,不然握手包经常被Docker的NAT搞丢。另外Qwen2.5-7B对MCP的tool calling支持其实有点微妙,官方文档说支持,但实际返回的function_call格式可能跟MCP的JSON-RPC预期不完全一致,你可以在server端加个日志看看是不是模型输出的tool_choice字段没被正确解析。allow_origin那个是给浏览器端用的,你如果是本地客户端连接,跟CORS没关系,别被issue带偏了。还有个坑是MCP协议版本,现在Python SDK和TypeScript SDK的版本号对不上会导致handshake时capabilities协商失败,你检查一下两边用的mcp库是不是都升到最新。建议先跑一遍官方examples里的echo server,排除你自己的代码问题,再慢慢加模型调用逻辑。
我之前也卡在handshake failed上,后来发现是vllm的OpenAI兼容接口和MCP默认的tool calling格式对不上,得在MCP server配置里显式指定model的tool schema。你试试把allow_origin设成*或者客户端实际域名,有时候CORS拦截不会直接报错而是握手阶段就断。Docker跑的话记得用host网络模式,端口映射会莫名丢TCP包,这问题藏得挺深。还有Qwen2.5对function calling支持版本有讲究,换下--trust-remote-code或者升级下vllm说不定就好了。
我最近也遇到类似问题,后来发现是Docker网络模式没配对,vllm和MCP server用host模式直连就通了。另外你这报错信息太笼统,建议把MCP server的日志级别调到DEBUG,看是卡在TLS握手还是协议协商那块。Qwen2.5-7B本身应该没问题,我这边跑的是同架构模型,MCP版本0.4和0.5都试过能兼容。还有个偏方,把客户端连接超时从默认的5秒调到30秒试试,有时候是服务启动慢导致的假失败。
我之前也卡在handshake failed上,后来发现是Docker里MCP server的host配置成了localhost,容器外访问肯定连不上,改成0.0.0.0就好了。另外vllm的--api-key参数如果没设,MCP那边的鉴权握手机制可能会直接拒绝,你可以先试试用curl模拟一下请求看返回啥。Qwen2.5-7B本身跟MCP协议没冲突,问题大概率出在网络层或者服务发现上。你检查过Docker的端口映射和healthcheck吗?有时候服务起来了但没ready,客户端就会误报握手失败。