Codex CLI 完全ガイド:codex exec での MCP 起動エラーと対処法
はじめに
Codex のヘッドレスモードである codex exec から Model Context Protocol (MCP) サーバーを立ち上げたところ、ログに次のようなメッセージが連続して表示されるケースがあります。
ERROR codex_core::mcp_connection_manager: new_stdio_client use_rmcp_client: false program: "uvx" ...
ERROR codex_core::mcp_connection_manager: new_stdio_client use_rmcp_client: false program: "npx" ...
実際にコードをたどると、これは codex-rs/core/src/mcp_connection_manager.rs:112 の info! ログが標準エラーに出力されているだけで、MCP 起動自体は成功していることが確認できました。
// codex-rs/core/src/mcp_connection_manager.rs
info!(
"new_stdio_client use_rmcp_client: {use_rmcp_client} program: {program:?} args: {args:?} env: {env:?} params: {params:?} startup_timeout: {startup_timeout:?}"
);
しかし codex exec 環境では別の要因によって本当に失敗することがあるため、原因・再現シナリオ・解決法を以下に詳しくまとめます。
codex exec を使うシーン
codex exec は TUI を持たないバッチ実行向けのコマンドです。CI/CD、外部スケジューラ、ChatOps など 人の承認待ちを挟まずに Codex に作業を任せたい場面で活用されます。このため、デフォルトでは承認ポリシーが AskForApproval::Never に固定され、ユーザーに確認を求めずにコマンドやファイル操作を進めます。
実装は codex-rs/exec/src/lib.rs:82 付近で確認できます(抜粋)。
// codex-rs/exec/src/lib.rs
let overrides = ConfigOverrides {
model,
review_model: None,
config_profile,
// この CLI はヘッドレスなので承認を挟めない
approval_policy: Some(AskForApproval::Never),
sandbox_mode,
cwd: cwd.map(|p| p.canonicalize().unwrap_or(p)),
model_provider,
codex_linux_sandbox_exe,
base_instructions: None,
include_plan_tool: Some(include_plan_tool),
include_apply_patch_tool: None,
include_view_image_tool: None,
show_raw_agent_reasoning: oss.then_some(true),
tools_web_search_request: None,
};
発生する真のエラー
codex exec + MCP の組み合わせで本当に失敗する代表的な要因は次の 2 点です。
-
codex execがネットワークを遮断した状態でuvxやnpxを起動し、必要なリポジトリからの取得に失敗する。 - キャッシュディレクトリやワークスペース外への書き込みが禁止されたまま
uvxがセットアップを試みてタイムアウトする。
codex-rs/mcp-client/src/mcp_client.rs:224 にある request timed out のエラーがこの状況を示します。
// codex-rs/mcp-client/src/mcp_client.rs
Err(_) => {
let mut guard = self.pending.lock().await;
guard.remove(&id);
return Err(anyhow!("request timed out"));
}
原因詳説
-
codex execはヘッドレスであるため、承認ダイアログを出せない →AskForApproval::Never固定(前掲のソース参照)。 -
--sandbox workspace-writeを指定しても、ネットワークはデフォルトでブロック。codex-rs/protocol/src/protocol.rs:302を見ると、Workspace Write モードはnetwork_access: falseで作られることがわかります。
// codex-rs/protocol/src/protocol.rs
pub fn new_workspace_write_policy() -> Self {
SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: false,
exclude_slash_tmp: false,
}
}
- Workspace Write サンドボックスは
cwdと一部の TMP しか書き込みできないため、uvxが利用するキャッシュディレクトリ(~/.cache,~/.uvなど)へのアクセスが拒否される。 -
uvx/npxは最初の起動時にリソース取得+キャッシュ作成を行う。この処理が進めないと MCP のinitializeリクエストがタイムアウトし、上記のエラーになる。
解決策
- ネットワークと書き込み先を明示的に許可 する。
- MCP サーバーの初期化タイムアウトを延長 する。
- ログのノイズをフィルタリング する。(成功時でも ERROR 表示が残るため)
以下のコマンドでは、それぞれを -c オプションと RUST_LOG で上書きしています。パスは自分の環境に合わせて読み替えてください。
RUST_LOG=warn,codex_core::mcp_connection_manager=off \
codex exec \
--experimental-json \
--sandbox workspace-write \
-c 'sandbox_workspace_write={network_access=true,writable_roots=["/path/to/.cache","/path/to/.uv"]}' \
-c mcp_servers.serena.startup_timeout_sec=30 \
--cd "/path/to/workspace" \
resume <SESSION_ID> "こんにちは"
コマンドのポイント
-
RUST_LOG=warn,codex_core::mcp_connection_manager=off… MCP 管理モジュールからの冗長なエラーログを抑止し、他の WARN 以上だけを表示。 -
--experimental-json…--jsonのエイリアスであり、どちらを指定しても同じ JSONL 出力モードになります。CLI 定義はcodex-rs/exec/src/cli.rs:67にあります。
// codex-rs/exec/src/cli.rs
#[arg(long = "json", alias = "experimental-json", default_value_t = false)]
pub json: bool,
-
--sandbox workspace-write… ワークスペースと一部 TMP に限定した書き込み権を付与。 -
-c 'sandbox_workspace_write=...'… Workspace Write モードに対してネットワーク許可と追加の書き込みルートを設定。writable_rootsに MCP が使用するキャッシュディレクトリを登録するのがポイントです。 -
-c mcp_servers.serena.startup_timeout_sec=30… serena MCP サーバーの初期化タイムアウトを 30 秒へ延長。 -
--cd "..."… Codex の作業ルートを明示。 -
resume <SESSION_ID> "こんにちは"… 指定したセッションを再開し、追加プロンプトを送信。
なぜこれで解決するのか
ネットワークとキャッシュ領域が解放されることで、uvx / npx が外部リポジトリから依存関係を取得できるようになり、初回 initialize リクエストが成功します。タイムアウト延長により、ネットワーク遅延や初回セットアップで時間を要しても失敗しにくくなります。またログフィルターを掛けることで、成功にもかかわらず ERROR 表示が残りユーザーを不安にさせる状況を避けられます。
まとめ
-
codex execは無人実行に便利な反面、デフォルトではネットワークや書き込み権限が厳しく制限される。 - MCP サーバーがリモートから依存物を取得するタイプ(serena、context7 など)では、必要な権限とタイムアウトを適切に緩める必要がある。
-
--experimental-json/--jsonは同じ機能で、警告テキストが古いだけ。 - 一時的には CLI の
-cフラグで上書きし、動作を確認したうえでconfig.tomlに反映すると安全。
Codex CLI をヘッドレス自動化で使う際は、サンドボックスや MCP 起動条件を意識して設定を調整しましょう。
Discussion