折腾两天了,真的有点破防。我照着文档用Python写了个很简单的MCP服务器,就暴露了一个get_weather工具,用stdio模式。在终端里直接python server.py能正常启动,用mcp-inspector测试工具调用也一切正常。但是一放到Claude Desktop的配置文件里(claude_desktop_config.json),客户端就报错,说“Failed to connect to MCP server”,日志里也看不到具体原因,只显示连接被拒绝。我确认过路径是绝对路径,Python环境也是对的(用的是系统默认的python3,没走conda)。有没有大佬遇到过类似情况?是不是stdio模式下Claude Desktop对启动命令的参数解析有什么坑?还是说需要额外设置环境变量?求一个比较系统的排查思路,感谢!
MCP服务器本地跑起来了,但Claude Desktop死活连不上,求排查思路?
全部回复
共 88 条之前我也卡在这步过,后来发现是Claude Desktop读配置时不会自动加载shell环境变量,你如果python3是装在/usr/local/bin这种非默认路径下,得在配置里写全路径或者用which python3查一下填进去。另外看看server有没有往stderr输出报错,Claude Desktop日志太简陋了,可以试试用npx @modelcontextprotocol/inspector带参启动,有时候能带出更具体的错误信息。
试试给python3加绝对路径,再确认下JSON里别写注释,这俩坑我踩过。
我之前也是这问题,最后发现是Claude Desktop要等几秒才连,你启动后别急着点重试。
查过JSON配置里的command字段没?必须写成数组形式,比如["python3", "/path/server.py"],很多人卡在这。
八成是Claude Desktop没走你那个python环境,试试在配置里写死python3的绝对路径,比如/usr/local/bin/python3。
试试在config里把stdio的command改成绝对路径的python3,有时候Claude Desktop不会继承shell的PATH环境变量。
我之前也踩过类似的坑,折腾了半天发现是配置文件里command和args的写法问题。Claude Desktop对JSON的解析特别严格,比如路径里如果有反斜杠,或者args数组里每个参数没单独拆开,都会静默失败,最后就给你一个connection refused。你可以试试把启动命令改成类似"command": "python3", "args": ["/绝对路径/你的server.py"],别把整个命令塞进一个字符串里。另外,macOS上还有个权限坑,Claude Desktop可能没有访问终端完全相同的环境变量,尤其是PATH,有时候它用的是LaunchServices的干净环境,导致python3根本找不到或者版本不对。建议在server.py最开头打印一下sys.executable和os.getcwd(),然后把日志重定向到文件里看,比如在args里加个"> /tmp/mcp.log 2>&1",这样至少能知道它有没有真正启动。还有个隐蔽问题是端口占用,虽然你是stdio模式,但Claude Desktop有时候会尝试用HTTP握手,如果系统里有别的服务占用了默认端口,也会报连接被拒。最后检查一下config.json的格式,特别是mcpServers这个顶层键,大小写和缩进错了它也会直接忽略。如果还不行,可以试试用npx或者绝对路径的node来跑一个官方示例服务器,排除是不是客户端版本对自定义服务器支持有bug。
我之前也卡在这过,后来发现是Claude Desktop读配置时不会自动加载shell环境变量,你终端里能跑是因为有PATH,但客户端那边可能就是找不到python3或者某些依赖。试试在config里把command写成绝对路径,比如/usr/local/bin/python3,或者干脆写个启动脚本把环境export进去。另外确认下stdio模式的通信协议版本跟客户端要求的匹配,有时候版本不兼容就是这种连接被拒但没详细日志的鬼样子。
还有个小坑,如果config里用了相对路径或者~符号,客户端不一定展开,建议直接pwd粘贴完整路径。你试试先开个终端手动跑一下客户端看有没有输出,有时候能捕获到具体报错。
试试在config里把command写成python3的完整路径,之前我就是被这个坑了。
这问题我上个月刚踩过,坑基本都在配置文件的JSON格式上,尤其是路径里的反斜杠没转义,或者不小心多了个逗号,Claude Desktop解析失败就直接报连接拒绝。你试试用Python的json模块读一下那个配置文件,能正常load就说明格式没问题。另一个常见原因是stdio模式下,Claude Desktop不会像终端那样继承你的shell环境,所以python3可能不在它的PATH里,得写全路径,比如/usr/local/bin/python3。还有,如果server.py里用了相对路径读文件或者依赖环境变量,那在桌面端启动时也会挂掉,可以试试在代码最顶部把所有路径都改成绝对路径。最后,如果日志真的什么都看不到,把Claude Desktop的日志级别调成debug,或者直接在server.py里加个import sys; sys.stderr = open('/tmp/mcp_debug.log', 'a'),把错误重定向到文件里,这样能定位到是启动崩溃还是握手失败。我之前就是卡在环境变量上,折腾了一天才发现是server.py里读了一个.env文件,而桌面端启动时工作目录根本不对。