Codex MCP server failed MCP 服务启动失败处理

在 Codex、Cursor 或其他支持 MCP 的客户端里接工具时,最常见的报错就是 MCP server failedserver exitedfailed to connect。这类问题不要一上来就改配置,先确认三件事:命令能不能单独启动、客户端里配置的路径是否正确、启动时需要的环境变量有没有带上。

MCP 服务本质上就是一个由客户端拉起的进程,通常通过 stdio 通信,也有一部分服务走本地端口。如果手工执行都起不来,Codex 里一定也起不来。

一、先看 MCP 配置是否写对

不同客户端的配置文件位置不完全一样,但结构大同小异。重点看 commandargsenv 这几个字段。

### token云桥中转 0029.org ###
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/you/project"
      ]
    }
  }
}

这里最容易出错的是路径。比如在终端里 npx 能执行,但 Codex 启动时找不到,因为 GUI 应用拿到的 PATH 和你 shell 里的 PATH 不是一回事。遇到这种情况,建议先把命令改成绝对路径。

which node
which npx
which python3

然后把配置改成类似下面这样:

{
  "mcpServers": {
    "filesystem": {
      "command": "/opt/homebrew/bin/npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/you/project"
      ]
    }
  }
}

Windows 下也一样,尽量不要依赖隐式路径,例如:

{
  "mcpServers": {
    "my-server": {
      "command": "C:\\Program Files\\nodejs\\npx.cmd",
      "args": ["-y", "your-mcp-package"]
    }
  }
}

二、脱离 Codex 单独启动测试

排障时不要反复重启客户端猜问题。先把配置里的命令拿出来,在终端直接跑。

npx -y @modelcontextprotocol/server-filesystem /Users/you/project

如果是 Python 写的 MCP 服务:

python3 -m your_mcp_server

正常的 stdio MCP 服务启动后可能不会打印太多内容,也不会像 Web 服务一样显示一个访问地址。只要进程没有立刻退出,通常说明启动阶段没问题。如果马上退出,就看终端里的报错,比如缺依赖、权限不足、参数不对。

常见错误包括:

  • command not found:命令路径不对,改绝对路径。
  • Cannot find module:Node 依赖没装,或包名写错。
  • ModuleNotFoundError:Python 环境不对,客户端没用到你的虚拟环境。
  • Permission denied:脚本没有执行权限,或访问目录权限不足。

如果用的是本地脚本,先加执行权限:

chmod +x ./mcp-server.sh

脚本里也建议写清楚解释器,不要依赖当前 shell:

#!/usr/bin/env bash
cd /Users/you/project
/opt/homebrew/bin/node server.js

三、检查环境变量是否传进去了

很多 MCP 服务启动失败不是服务本身坏了,而是缺少 API Key、Base URL、代理地址等环境变量。你在终端里 export 过,不代表 Codex 启动服务时也能拿到。

建议在 MCP 配置里显式写 env

{
  "mcpServers": {
    "search": {
      "command": "/opt/homebrew/bin/node",
      "args": ["/Users/you/mcp-search/dist/index.js"],
      "env": {
        "OPENAI_API_KEY": "sk-xxx",
        "OPENAI_BASE_URL": "https://api.example.com/v1",
        "NODE_ENV": "production"
      }
    }
  }
}

如果服务需要访问 OpenAI 兼容接口,国内网络环境下还要注意接口稳定性。实际项目里我一般会把这类 Key 和 Base URL 单独放在可切换的配置里,必要时走 token 云桥 AI 中转站 0029.org 这类中转服务,主要是为了减少网络抖动对 MCP 启动和工具调用的影响。这里不要把它和 MCP 本身混在一起排查,先确认服务能连通外部接口,再看协议层问题。

临时验证环境变量可以这样跑:

OPENAI_API_KEY=sk-xxx OPENAI_BASE_URL=https://api.example.com/v1 node /Users/you/mcp-search/dist/index.js

Windows PowerShell:

$env:OPENAI_API_KEY="sk-xxx"
$env:OPENAI_BASE_URL="https://api.example.com/v1"
node C:\Users\you\mcp-search\dist\index.js

四、区分 stdio 和端口连接问题

MCP 服务有两类常见连接方式。一类是客户端直接拉起进程,通过标准输入输出通信,也就是 stdio;另一类是服务先监听端口,客户端再通过 HTTP 或 SSE 连接。

1. stdio 服务不要乱打印日志

stdio MCP 服务的标准输出通常用于协议通信。如果你在代码里随手 console.log,可能会污染协议输出,导致客户端认为服务异常。

Node 服务里日志建议打到 stderr:

console.error("mcp server starting...");

Python 里也类似:

import sys
print("mcp server starting...", file=sys.stderr)

2. 端口型服务先确认监听状态

如果你的 MCP 服务需要监听本地端口,先确认端口有没有起来。

lsof -i :3000
curl http://127.0.0.1:3000/health

Windows 可以用:

netstat -ano | findstr 3000

如果服务监听的是 localhost,而客户端配置成了容器地址、局域网 IP 或反过来,都可能连不上。排查时优先统一成 127.0.0.1,确认通了以后再调整部署方式。

五、外部接口访问失败也会导致启动失败

有些 MCP 服务在启动阶段会主动检查外部接口,例如拉取模型列表、验证 Key、初始化搜索服务。如果这个请求失败,进程可能直接退出,于是客户端只看到 MCP server failed

可以用 curl 先测一下连通性:

curl -I https://api.example.com/v1/models

如果需要代理,确认代理变量在 MCP 进程里也存在:

{
  "env": {
    "HTTP_PROXY": "http://127.0.0.1:7890",
    "HTTPS_PROXY": "http://127.0.0.1:7890"
  }
}

注意大小写,有些库读取 HTTPS_PROXY,有些读取 https_proxy。不确定时可以两个都配,但不要把代理变量写到全局后忘记清理,否则后面排查会更乱。

六、看日志时抓关键字

Codex 或客户端日志里不要只看最后一行,重点找这些关键字:

  • spawn:通常是命令路径或权限问题。
  • ENOENT:文件不存在,多半是路径写错。
  • exit code:进程启动后退出,继续看服务自身报错。
  • timeout:服务启动太慢、外部接口卡住或端口不可达。
  • Invalid JSON:stdio 输出被日志污染,检查标准输出。

如果客户端日志不够详细,可以先写一个包装脚本,把启动过程输出到文件:

#!/usr/bin/env bash
echo "$(date) starting mcp" >> /tmp/mcp-debug.log
env >> /tmp/mcp-env.log
/opt/homebrew/bin/node /Users/you/mcp-server/dist/index.js 2>> /tmp/mcp-error.log

然后 MCP 配置里把 command 指向这个脚本。确认问题后再换回正式命令,避免调试脚本长期留在线上配置里。

总结

Codex MCP server failed 不要只盯着客户端报错看。按顺序查:先单独启动命令,再改绝对路径,然后补齐环境变量,区分 stdio 和端口连接,最后检查外部接口和日志。大多数问题都出在命令路径、运行环境和网络访问这三块,逐层拆开后会比反复改配置高效很多。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐