折腾两天了,真的有点破防。我照着文档用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死活连不上,求排查思路?
全部回复
共 100 条之前我也卡在这步过,后来发现是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文件,而桌面端启动时工作目录根本不对。
我之前也踩过这个坑,大概率是Claude Desktop没读到你的系统PATH,它启动子进程时环境变量和终端不一样。试着在配置里把python路径写成绝对路径,比如/usr/local/bin/python3,或者干脆在server脚本第一行加上#!/usr/bin/env python3然后给执行权限。另外检查下stdio模式有没有往stderr打日志,客户端有时候会把错误吞掉,你先手动在终端跑个简单的stdio握手测试看看输出格式对不对。
我之前也踩过这个坑,八成不是服务器本身的问题,而是Claude Desktop调用时用的启动命令和你手动跑的不一样。你试试在config里把command改成python3的绝对路径,比如/usr/bin/python3,有时候它会找不到环境变量里的python。另外,检查一下server.py里有没有用到相对路径读文件,工作目录变了也会导致启动失败,最好把路径都写死。还有个隐蔽的点,macOS上如果没给Claude Desktop完全磁盘访问权限,它可能连子进程都拉不起来,去系统设置里看一眼。
我之前也踩过这个坑,折腾半天发现是Claude Desktop对stdio模式的路径解析有点问题,你试试把启动命令写成绝对路径的python3加脚本绝对路径,别用简写。另外检查下config里有没有多余的空格或者逗号,JSON格式错一个字符它就直接拒连,日志还特糊弄。还有个笨办法,先用which python3确认下系统默认路径,有时候它内部用的shell环境跟你终端不一样,conda或者pyenv的干扰挺常见的。
查查config里command是不是写成了数组,我之前就是路径对但参数格式错了卡好久。
我之前也卡在这过,后来发现是config里command和args的写法问题,得拆成"command": "python3", "args": ["/绝对路径/server.py"]这样。另外Claude Desktop有时会缓存旧配置,改完文件最好完全退出进程再重开,光重启窗口没用。还有个坑是如果用了虚拟环境,即便终端里是系统python,客户端也可能走别的地方,可以试试把env里的PATH显式写进去。最后实在不行开一下客户端的debug日志,那个能直接看到它实际执行的命令。
试试把config里的command换成绝对路径的python3,我之前就是被环境变量坑了。
大概率是配置文件里command写错成python3但Claude Desktop用的是自己打包的环境,试试绝对路径指到/usr/bin/python3。
我之前也踩过类似的坑,折腾了半天结果发现是配置文件里JSON格式的问题。你检查一下claude_desktop_config.json里有没有不小心多加了个逗号或者引号没转义,Claude Desktop对格式特别敏感,稍微有点错就直接连不上。另外,你用的是stdio模式对吧,那command那块得写绝对路径,但args里如果带了参数,比如--port之类的,有时候Claude Desktop不会正确解析,建议把所有参数都拆开写。还有个可能性是环境变量,Claude Desktop启动MCP服务器时可能没有继承你终端的PATH,导致它找不到python3或者某些依赖库,你可以试试在配置里直接写python3的完整路径,比如/usr/local/bin/python3,而不是简单的python3。如果还是不行,可以开一下Claude Desktop的详细日志,macOS上日志在~/Library/Logs/Claude/,里面会有更具体的报错,比客户端提示的“连接被拒绝”有用多了。最后想问下,你服务器启动后有没有打印类似“listening on stdio”的确认信息?有时候服务器卡在初始化阶段没进入监听状态,客户端也会报连接失败。
试试把stdio换成http模式,我之前也卡这儿半天,Claude Desktop对stdio的路径解析有时挺迷的。
我之前也栽在过这个坑里,后来发现是Claude Desktop对config.json的JSON格式要求极其严格,多一个注释或者尾逗号都直接拒连。你可以试试用在线JSON校验器查一下,另外看看日志里有没有报“spawn”相关的词,如果有就是路径或者参数写错了。还有个偏方,把stdio模式改成SSE模式先排除传输层问题,有时候能快速定位是代码问题还是客户端配置问题。
我之前也踩过这个坑,最后发现是Claude Desktop启动时的环境变量跟我终端里完全不一样。你试试在配置里把command写成python3的绝对路径,比如/usr/bin/python3那种,别只写python3。另外stdio模式下服务器千万别往stdout打日志,一打就把协议流冲乱了,连接直接挂。mcp-inspector能过说明代码没问题,基本就是启动环境或者输出污染的事。
Claude Desktop 连不上但 inspector 正常,大概率是环境变量的问题。Desktop 启动子进程时不会继承你终端里的 PATH,配置文件里得显式指定 python3 的绝对路径,或者用 /usr/bin/env python3 这种写法。另外看看日志目录 ~/Library/Logs/Claude/ 下面的 mcp.log,那里通常有真正的报错,比界面上的提示有用多了。我之前也卡在这,换成绝对路径的 python 解释器立马就好了。