MCP 服务器配了 `required = true`,整个 Codex 就起不来了

2026-08-09

Codex(OpenAI Codex)的 MCP 配置里有个键很容易被顺手打开,后果却比想象中大:mcp_servers.<id>.required。官方《Configuration Reference》对它的说明只有一句——启用的服务器初始化失败则启动失败。也就是说,这不是”这个工具用不了”,而是”整个 Codex 用不了”。

这篇按排查的顺序走一遍:先确认现象、再给可执行的判定命令、然后是处置和验证,最后专门留一节讲哪些情况其实不是这个原因。

一、现象是什么样的

典型场景有三种:

  1. 你昨天给某个 MCP 服务器加了 required = true,今天它依赖的进程/端口/凭据变了,Codex 直接起不来;
  2. 换了台机器同步配置,本机没装那个服务器要跑的运行时,配置照抄过去,Codex 起不来;
  3. 服务器本身没坏,只是启动慢,超过了超时阈值被判定为初始化失败,于是”偶发”起不来——今天能起明天不能起,最难查的就是这种。

先把一个边界讲清楚:required = true 导致启动失败时具体打出什么错误文案,我们没有实测过。本机在 codex-cli 0.147.0(Windows 11)上只跑了只读命令,三个 stdio 服务器都是正常 enabled 状态,没有构造过启动失败。所以下面不会引用任何”报错原文”,只给判定方法——判定方法本身是可执行的,比背错误码可靠得多。

二、怎么确认是这个问题

第 1 步:先排除”配置根本没加载”

这一步不能跳。配置文件语法坏掉和 MCP 服务器起不来是两回事,处置方向完全相反。

codex doctor --summary

在 codex-cli 0.147.0(Windows 11)上实测,doctor 的输出里有个 Configuration 分组,里面有 configmcp 两行。我们故意喂了一段语法不合法的 TOML(codex -c 'features=[unclosed' doctor --summary),命令并没有崩溃退出,doctor 照常跑完,只是打出了这么一行:

✗ config       config could not be loaded - Fix the reported config error, then rerun codex doctor.

这条实测结论价值很高:配置坏了 doctor 仍然能跑,而且会明确告诉你配置没加载成功。所以看到这一行,问题就在 TOML 本身,跟 required 没关系,别再往 MCP 方向查了。

如果 config 那行是正常的,就看同一组里的 mcp 行。本机实测这行的格式是 N server (N stdio) · N disabled——它会告诉你 Codex 认为自己有几个服务器、其中几个是停用的。这个数字对不对,直接决定下一步查哪里。

第 2 步:列出服务器,锁定嫌疑对象

codex mcp list

本机在 codex-cli 0.147.0(Windows 11)上实测,这条命令输出七列:Name | Command | Args | Env | Cwd | Status | Auth

有两点值得单独说:

  • Status 列会显示服务器是不是 enabled。本机三个 stdio 服务器都是 enabledAuth 列都是 Unsupported
  • Env 列里环境变量的值会被打成 *****,只显示键名,所以排查时不用担心把某个 token 的值念出来。但要注意脱敏只覆盖了这一列:Command / Args / Cwd 三列是原样打印的,而它们恰恰最容易带出本机绝对路径、用户目录和项目名。把这份输出贴给同事或贴进工单之前,仍然要自己从头到尾看一眼。

codex mcp 还有 get 子命令,可以单看某一个服务器的配置。

第 3 步:临时把嫌疑服务器摘掉,看还起不起得来

这是决定性的一步,而且不需要动配置文件。Codex CLI 的 -c, --config <key=value> 顶层选项支持用点号路径表示嵌套(实测原文就是 foo.bar.baz 这种形式,官方给的例子之一是 -c shell_environment_policy.inherit=all),value 按 TOML 解析。

所以可以这样临时停掉某个服务器:

codex -c mcp_servers.<你的服务器id>.enabled=false doctor --summary

或者只把 required 关掉、保留服务器本身:

codex -c mcp_servers.<你的服务器id>.required=false doctor --summary

以上为按官方文档键位(mcp_servers.<id>.enabledmcp_servers.<id>.required)与实测的 -c 点号语法组合出来的示例,未逐项实测,以官方文档为准。

判定逻辑很直白:摘掉某个服务器之后能正常起来,那它就是元凶;一个个试过去都没用,那多半不是 MCP 这条线的问题。

如果你还想更粗暴地划清界限,codex exec 有个专有选项 --ignore-user-config,实测说明是不加载 $CODEX_HOME/config.toml(注意:auth 仍然使用 CODEX_HOME,所以它不会把你登出)。整份用户配置都不加载还是起不来,那就跟 config.toml 里的任何键都无关了。

另外提醒一句:如果你用了 -p, --profile,它会把 $CODEX_HOME/<name>.config.toml 叠加到基础用户配置之上——required 有可能是从 profile 那一层来的,只翻主 config.toml 会翻不到。

三、处置

确认是某个 MCP 服务器把启动拖死之后,按官方文档给的键位,处置分三种情况。这里只列与本篇直接相关的几个键:

默认含义
mcp_servers.<id>.enabledtrue该服务器是否启用
mcp_servers.<id>.required官方原句:启用的服务器初始化失败则启动失败
mcp_servers.<id>.startup_timeout_sec10启动超时,单位秒

这张表里只有 required 那行是官方文档的原句,另外两行是按键名给的说明,默认值则逐字照抄自官方文档。

情况 A:服务器启动慢,不是真坏。 startup_timeout_sec 官方默认只有 10 秒。一个需要拉运行时、装依赖、连远端的服务器,10 秒是相当紧的。本机(codex-cli 0.147.0 / Windows 11)的 config.toml 里就给一个 node_repl 服务器显式设了 startup_timeout_sec = 120——慢启动的服务器必须显式调大,否则它会稳定地”初始化失败”,配上 required 就是稳定地起不来。

[mcp_servers.<你的服务器id>]
command = "<启动命令>"
args = ["<参数>"]
startup_timeout_sec = 120
required = true

以上为按官方文档键位组合的示例,未逐项实测,以官方文档为准。

情况 B:这个服务器现在真的用不了。enabled 设成 false,它就不参与初始化,required 也就无从触发(官方对 required 的表述是”启用的服务器初始化失败则启动失败”,前提是启用)。这是最快恢复可用状态的做法。

情况 C:它压根就不该是 required。 说句实话:required 应该留给”没有它这次工作根本没法开展”的服务器。一个只在特定任务里偶尔用一下的服务器挂上 required,等于把它的可用性绑定成了 Codex 的可用性,性价比很低。把这个键去掉,服务器初始化失败就只是这个服务器不可用,其余照常。

如果服务器是需要认证的类型(auth 默认 oauth,也可设 chatgpt;另有 bearer_token_env_var 走环境变量),codex mcp 下有 login / logout 子命令可用。凭据一律走环境变量,配置文件里写 <YOUR_API_KEY> 这种占位就好,不要把真值贴进 config.toml。

四、处置后怎么验证

别只看”这次起来了”,按顺序核三处:

  1. codex mcp list——看目标服务器的 Status 列是不是你期望的状态。改成 enabled = false 的,这里应该能看出来。
  2. codex doctor --summary——看 Configuration 分组的 mcp 行,N server (N stdio) · N disabled 这几个数字要和你改完的预期对得上。同时确认 config 那行没有变成
  3. 看 doctor 结尾的统计行。本机在 codex-cli 0.147.0(Windows 11)上实测的格式是 17 ok · 1 idle · 1 notes · 0 warn · 0 fail ok,状态符号有 (ok)、(idle)、(notes/warn)、(fail)四种。fail 计数回到 0,才算真验证过。

要把诊断结果发给别人时可以用 codex doctor --json,官方说明是 “Emit a redacted machine-readable report”——是脱敏的,可以贴。

顺带说一个反直觉的边界:--strict-config 的作用是”config.toml 里出现本版本不认识的字段时直接报错退出”,听起来正好能拦住拼错的键名,但本机在 codex-cli 0.147.0(Windows 11)上实测,codex -c model_reasoning_effortt=high --strict-config exec --help 正常打印了 help,没有报未知字段错误。说明这个校验发生在真正加载配置去跑会话的时候,--help 这类不进入会话的路径并不触发。所以别把它当成”任何情况下都会拦住拼写错误”的保险丝。

五、什么情况说明不是这个原因

以下几种,方向就得换了:

  • doctor 打了 ✗ config config could not be loaded 这是 TOML 本身的问题,先修语法。-c 传值时也要注意:value 按 TOML 解析,解析失败会按字面字符串处理,所以拼错了不一定报错,可能只是悄悄变成了一个字符串。
  • doctor 的 mcp 行显示的服务器数量对不上,甚至是 0。 那就不是某个服务器初始化失败,而是这段配置压根没被读到——去查是不是 CODEX_HOME 指错了、是不是 profile 叠加层覆盖掉了。
  • Codex 能起来,只是某个工具调不出来。 这跟 required 无关。查 enabled_tools / disabled_tools——官方说明里 disabled_tools 是在 enabled_tools 之后套用的,两个都配时以 deny 为准,这是很容易配反的地方。另外工具调用超时看的是 tool_timeout_sec(默认 60),跟启动超时是两个键。
  • 是登录/认证问题。 先跑 codex login status,本机在 codex-cli 0.147.0(Windows 11)上实测,正常时输出一行 Logged in using ChatGPT。认证不对是全局症状,不会因为摘掉某个 MCP 服务器就好。
  • 昨天好好的今天不行,而你什么都没改。 先跑 codex --version。本机采集时遇到过一次实打实的情况:同一台机器开头执行得到 codex-cli 0.131.0,十几分钟后再执行同一命令得到 codex-cli 0.147.0which -a codex 全程只有一个可执行文件。Codex 有自更新能力(config 里 check_for_update_on_startup 默认 true),所以排查任何版本相关问题,都要以当次 codex --version 的实时输出为准,不能用记忆里的版本号。

最后重复一遍那条最该记住的:required 把一个可选依赖变成了硬依赖。加它之前先问自己一句——这个服务器挂了,我今天是不是就真的不干活了?如果答案是否定的,这个键就不该出现在你的 config.toml 里。

相关阅读


本文依据 Codex 官方文档(learn.chatgpt.com/docs/ 的《Configuration Reference》页面)整理,核对日 2026-08-09;文中标注「本机实测」的部分基于 codex-cli 0.147.0 / Windows 11 环境下的只读命令输出。产品功能、模型与价格以官方最新说明为准。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。