Codex MCP server 启动超时:默认只有 10 秒

2026-08-09

有一类问题特别容易被误判成”配置写错了”:MCP server 在你自己机器上跑得好好的,换一台机器、或者刚开机第一次启动 Codex(OpenAI Codex)时就是接不上;有时候重开一次又正常了。这种”时好时坏、跟机器状态有关”的表现,配置文件本身往往一个字都没错——真正卡住你的是一条默认值:MCP server 的启动超时,官方给的默认只有 10 秒。

下面按排查顺序走一遍。文中所有配置键都取自官方《Configuration Reference》页,标注「本机实测」的部分来自 codex-cli 0.147.0(Windows 11)上执行的只读命令。

先把两个超时分清楚

在 Codex 的配置里,mcp_servers.<id> 这一层底下有两个长得很像的超时键,含义完全不同:

默认值管什么
startup_timeout_sec10server 启动(初始化)阶段的等待上限
tool_timeout_sec60单次工具调用的等待上限

同一层还有一个 startup_timeout_ms。官方配置参考里列了这个键,但没有给它的默认值,也没有说明它和 startup_timeout_sec 同时出现时谁优先——我不打算替官方推断这件事,所以下面的例子统一只写 startup_timeout_sec

10 秒这个数字是本篇的关键。一个 stdio 型的 MCP server,启动时要做的事情可能包括:拉起运行时进程、加载依赖、读取环境变量、建立第一次握手。这些在温机状态下也许两三秒就完事,但冷启动、磁盘忙、杀毒软件扫描新进程、或者依赖包第一次解包的时候,超过 10 秒一点都不稀奇。这就解释了为什么它”时好时坏”:你不是在跟一个必然失败的配置打交道,你是在跟一条卡在临界线上的耗时打交道。

配置参考里还有一个相关的开关:features.skill_mcp_dependency_install,默认 true,官方说明是”允许提示并安装 MCP 依赖”。如果某次启动恰好触发了依赖安装,耗时会跟平时完全不是一个量级——这也是同一台机器上第一次特别慢、后面就正常的一种可能来源。

怎么确认是启动超时,而不是别的毛病

先做一件事:确认你当前跑的是哪个版本。本机实测过一个很有意思的现象——同一台机器上,采集开头 codex --version 输出 codex-cli 0.131.0,十几分钟后再执行同一条命令变成了 codex-cli 0.147.0,而 which -a codex 全程只有一个可执行文件。配置项的默认值是会随版本变的,所以排查任何”默认行为”问题,都得以当次的实时输出为准,别用记忆里的版本号。

codex --version

第二步,看 Codex 到底认到了几个 MCP server:

codex mcp list

在 codex-cli 0.147.0(Windows 11)上,这条命令输出的表头逐字是 Name | Command | Args | Env | Cwd | Status | Auth。本机三个 stdio server 的 Status 列都是 enabledAuth 列都是 Unsupported。这里要说清楚一个容易误读的点:Status 列反映的是这个 server 有没有被启用,不能直接当成”启动成功了”来读——本机只观测到 enabled 这一个取值,我没有构造过超时场景,所以不知道超时之后这一列会显示成什么,也不会替它编一个。

顺带一个实用信息:codex mcp listEnv 列会把环境变量的值打成 *****,只显示键名。也就是说这条命令的输出自带脱敏,贴到工单或群里问人是安全的(当然,命令行本身和 Cwd 列仍可能带出你的目录结构,贴之前扫一眼)。

第三步,跑一次总体体检:

codex doctor --summary

本机实测这条命令的 Configuration 分组里有一行专门给 MCP,格式是 mcp 后面跟着 N server (N stdio) · N disabled 这样的计数。把这个计数和你 config.toml 里实际写了几个 server 对一下——如果数目对得上,说明配置是被读进去了,问题出在”读进去之后启动不起来”这一段,往启动超时这个方向查是合理的。

codex mcp 还有 get 子命令(本机只核对过子命令清单,没有逐一取过它的输出),可以用来看单个 server 的配置。另外 codex doctor --json 的官方说明是 “Emit a redacted machine-readable report”,是脱敏过的报告,需要交给别人分析时用这个更稳妥。

处置:把启动超时显式调大

官方配置参考里给出的做法就是在对应 server 下把 startup_timeout_sec 写大。配置文件位置是 $CODEX_HOME/config.toml,默认 ~/.codex/config.toml

[mcp_servers.slow_server]
command = "<启动这个 server 的可执行文件>"
args = ["<参数1>", "<参数2>"]
startup_timeout_sec = 120

以上为按官方文档键位组合的示例,未逐项实测,以官方文档为准。本机的 config.toml 里确实有一个 stdio server 把这个值设成了 120——这不是官方推荐值,只是一个”重的 server 需要远超默认值”的实际例证。

调多大合适?我没有耗时数据可以给你(本机没有跑过任何模型对话请求,也没有采集过 server 的实际启动耗时),所以只能给方法:先设一个明显宽松的值确认问题确实消失,再往回收。这么做的意义在于先证伪——如果设到很宽松还是接不上,那就不是超时的锅,可以马上转向别的方向,别在这个键上继续磨。

这里顺带澄清一个容易被想当然的做法:Codex CLI 确实有 -c, --config <key=value>,支持点号路径表示嵌套(官方给的例子之一就是 -c shell_environment_policy.inherit=all),value 按 TOML 解析,解析失败则按字面字符串处理。看上去很像可以”临时覆盖一下超时值试试”,但我要把话说明白:本机没有验证过用这种方式覆盖 MCP 启动超时的实际效果,而且 codex mcp list 的表头里压根没有跟超时相关的列,你也没法靠它看出这次覆盖有没有起作用。所以这条选项只当作”配置覆盖能力”来了解,别把它当成验证超时值的手段——要验证,还是老老实实改 config.toml 再走下面那套流程。

required 决定这次故障有多严重

同一层还有一个键值得单独说:required。官方说明是”启用的服务器初始化失败则启动失败”。

这条决定了同样一次启动超时,你看到的症状完全不同:

  • required 没开:这个 server 挂掉,Codex 本身照常可用,你只是发现某些工具”不见了”。
  • required 开着:这个 server 初始化失败会把整个启动一起拖垮。

所以如果你的症状是”Codex 整个起不来”而不是”某个工具没了”,就顺手看一眼有没有哪个 server 设了 required。反过来,如果某个 server 你近期根本不用,比调超时更干脆的处置是把它的 enabled 设成 false(这个键默认 true),先让主流程恢复,回头再单独收拾它。

改完怎么验证

别改完就直接开会话赌一把,按下面顺序验证,每一步都是只读命令:

  1. codex doctor --summary,先在 doctor 输出里找 config 这一项。本机实测过一个很有价值的边界:故意用 codex -c 'features=[unclosed' doctor --summary 传一段语法不合法的 TOML,命令没有崩溃退出,doctor 照常跑完,但 Notes 区出现了一行 ✗ config config could not be loaded - Fix the reported config error, then rerun codex doctor.。也就是说,配置坏了不会立刻报错让你发现,得靠 doctor 这一行告诉你。你手改 TOML 之后第一件事就该看它。
  2. 同一份 doctor 输出里看 mcp 那一行的计数有没有变化。
  3. codex mcp list,确认目标 server 还在表里、Status 列没有变差。
  4. 最后才是开一次真实会话,看那个 server 提供的工具是不是回来了。

顺带说一下 --strict-config 这个选项:它的作用是”config.toml 里出现本版本不认识的字段时直接报错退出”,听起来像是拼写检查神器,但本机实测有边界——执行 codex -c model_reasoning_effortt=high --strict-config exec --help(注意 effortt 是故意拼错的),命令正常打印了 help,没有报未知字段错误。说明这个校验发生在真正加载配置去跑会话的时候,--help 这类不进入会话的路径不触发。所以别指望用 --strict-config--help 来”快速检查配置有没有拼错”,那样什么都检查不出来。

什么情况说明不是启动超时

这一节比上面几节更重要——排查最怕的是一条道走到黑。出现下面这些迹象,说明你该换方向了:

doctor 报 config could not be loaded 那你改的那些键根本没被加载,超时值写多大都不起作用。先把 TOML 语法修好。

工具”少了几个”而不是”整个 server 没了”。 这更像是工具级的开关在起作用。配置参考里 enabled_toolsdisabled_tools 都在 mcp_servers.<id> 这一层,并且官方明确说明 disabled_toolsenabled_tools 之后生效的——两个都配的时候以 deny 为准。这条挺反直觉,很容易写完之后奇怪”我明明在白名单里放了它”。

你的 server 是 url 型(streamable HTTP)而不是 stdio 型。 这类 server 走的是另一套配置:auth(默认 oauth,可设 chatgpt)、bearer_token_env_varhttp_headersscopesoauth_resource,另外顶层还有 mcp_oauth_credentials_storemcp_oauth_callback_portmcp_oauth_callback_url。接不上的时候先排查认证与回调,而不是启动耗时。密钥一律走 bearer_token_env_var 指向的环境变量,别把 <YOUR_API_KEY> 直接写进 config.toml

卡在了某个需要你确认的弹窗上。 配置参考里 approval_policy.granular.mcp_elicitations 这个键的说明是”MCP elicitation 弹窗允许还是自动拒绝”。如果这类交互被自动拒绝,你看到的表现可能是”这个 server 就是不干活”,跟超时是两码事。

你其实在找 codex mcp-server 本机 codex --help 里这两个子命令同时存在,说明也完全不同:mcp 是 “Manage external MCP servers for Codex”(管理你接进 Codex 的外部 server),mcp-server 是 “Start Codex as an MCP server (stdio)“(把 Codex 自己当成一个 MCP server 起起来)。想接第三方工具却敲了后者,怎么调超时都不会有结果。

最后提一句 experimental_environment 这个键,取值 local / remote。名字里带 experimental,属于实验阶段的配置项,排查阶段不建议顺手把它开起来当解法——把变量控制住,一次只动一个键,才知道到底是哪一下起的作用。

相关阅读


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

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