development·

Codex MCP設定ガイド|config.tomlの書き方と繋がらないときの切り分け

CodexにMCPサーバーを接続する方法を、OpenAI公式ドキュメントで全設定キーを照合して整理しました。config.tomlの置き場所と6層の優先順位、codex mcp addの使い方、承認モードの設計、Claude Codeとの書き方の違い、繋がらないときの切り分け手順まで。2026年8月時点の仕様です。

Codex MCP設定ガイド|config.tomlの書き方と繋がらないときの切り分け

CodexにMCPサーバーを繋ごうとして、config.toml に書いたのに /mcp に出てこない。2箇所に設定を書いたら、想定と違うほうの定義で動いていた。Claude Codeで動いていた設定をコピーしたら、設定ファイルごと読み込まれなくなった — MCP接続でつまずくポイントは、実はほぼ決まっています。

本記事は、CodexでMCPサーバーをどう設定し、実務で何に使うかの1点に絞って解説します。設定ファイルの置き場所と読み込みの優先順位、codex mcp add の使い方、config.toml の全設定キー、権限の設計、そして繋がらないときの切り分け手順までを、OpenAIの公式ドキュメントと照合したうえで整理しました。

MCPというプロトコル自体の仕組みについてはClaude CodeのMCPサーバー導入ガイドで解説しているため、本記事ではCodex固有の設定・作法・制約に集中します。

本記事の更新方針: 本記事は定期的に内容を見直しています。記事内の判断軸・運用パターンは執筆時点での koromo の実務的知見に基づくものであり、個別環境での効果を保証するものではありません。仕様の最新情報は必ず OpenAI 公式ドキュメント「Model Context Protocol」 をご確認ください。

この記事の要点(Key Takeaways)

  • CodexのMCP設定は config.toml 1枚に集約される。 ユーザー設定は ~/.codex/config.toml、プロジェクト設定は .codex/config.toml。CLI・IDE拡張・ChatGPTデスクトップアプリはこの設定を共有するため、一度書けばどのクライアントからでも同じサーバーが使える
  • プロジェクト設定が効かない最大の原因は「信頼」。 .codex/config.toml は、そのプロジェクトを信頼済みにしていないと読み込まれない。未信頼のプロジェクトでは .codex/ 配下の設定・hooks・rules がまるごとスキップされる
  • トランスポートは明示せず、キーの有無で決まる。 command があればSTDIO、url があればStreamable HTTP。Claude Codeの --transport に相当するフラグはない
  • タイムアウトの単位に罠がある。 startup_timeout_sec は秒(既定10秒)、startup_timeout_ms はそのミリ秒エイリアス。秒のキーにミリ秒の値を書くと、10秒のつもりが約2.8時間になる
  • Claude Codeの設定はそのまま移植できない。 TOMLとJSON、暗黙のトランスポート決定と --transport、6層の優先順位と3つのスコープ、秒とミリ秒 — 主要な設計がすべて違う

なお、Codexそのものの定義や成り立ちはCodexとは何かを解説した記事、CLIの基本操作はCodex CLIの使い方ガイド、プランごとの利用枠はCodexの料金プラン比較で扱っています。

結論 — CodexのMCP設定は「config.toml 1枚」に集約される

CodexにおけるMCPの設定とは、config.toml[mcp_servers.<サーバー名>] というテーブルを1つ書くことです。 サーバーを1つ増やすたびにテーブルが1つ増える、それだけの構造です。

この設計がCodexの分かりやすいところで、ChatGPTデスクトップアプリ・Codex CLI・IDE拡張は同じ設定を共有します。つまり、ターミナルで設定したMCPサーバーは、そのままIDE拡張からも使えます。クライアントごとに設定をやり直す必要はありません。

一方で、この「1枚に集約される」設計が、つまずきの原因にもなっています。設定ファイルは1種類でも、読み込まれる場所は6箇所あり、優先順位が決まっているからです。書いた場所が想定と違えば、当然反映されません。経験上、「繋がらない」の多くは、サーバー側やネットワークの問題ではなく、この読み込み順の理解不足から起きています。

そのため本記事は、設定の書き方より先に「どこに書くとどう読まれるか」から始めます。

CodexがサポートしているMCPの機能

設定に入る前に、Codexが対応している範囲を確認しておきます。繋ごうとしているサーバーがこの範囲に収まっているかで、そもそも接続できるかが決まります。

分類対応内容
STDIOサーバーローカルプロセスとして起動するタイプ。環境変数の受け渡しに対応
Streamable HTTPサーバーアドレスに接続するタイプ。bearerトークン認証、OAuth認証(CIMDおよび動的クライアント登録を含む)、信頼済みファーストパーティサーバー向けのChatGPTセッション認証に対応
Server instructions初期化時にサーバーが返す instructions フィールドを読み、サーバー全体への指針として、そのサーバーのツール群と併せて使用する

ここで押さえておきたいのは、トランスポートはSTDIOとStreamable HTTPの2種類という点です。Claude CodeはこのほかにSSEとWebSocketも扱えます(ただしSSEはClaude Codeの公式ドキュメントで非推奨とされ、HTTPサーバーの利用が推奨されています)。他クライアント向けにSSE前提で書かれた手順書を持ってきた場合、Codexではそのままでは繋がりません。

自社用のMCPサーバーを開発する場合は、この instructions の使い方が効いてきます。複数ツールにまたがるワークフロー・制約・レート制限といった、ツール単位の説明では書けない情報をここに入れます。そのうえで、先頭512文字を自己完結させることが推奨されています。Codexがそのサーバーをどう使うか判断する時点で、最も重要な情報が読めている状態にするためです。

なお、これらはCodexホストに設定したMCPサーバーの話です。ChatGPT側のプラグインが提供するツールは、また別の扱いになり、対応している機能の範囲も異なります。手順書を探すときは、どちらについて書かれたものかを最初に確かめてください。

CodexのMCP設定はどこに書くのか — 場所と優先順位

2つの置き場所

Codexは設定を複数の場所から読み込みます。MCPサーバーの設定に関係するのは、主に次の2つです。

種類パス用途
ユーザー設定~/.codex/config.toml全プロジェクト共通で使うサーバー
プロジェクト設定.codex/config.toml(リポジトリ内)そのプロジェクトだけで使うサーバー

Codexはローカルの状態を CODEX_HOME(既定は ~/.codex)配下に保存します。Windowsであれば C:\Users\<ユーザー名>\.codex\config.toml が相当します。

IDE拡張を使っている場合は、ファイルパスを探さなくても開けます。右上の歯車アイコンから Codex Settings > Open config.toml を選ぶと、設定ファイルがエディタで開きます。

読み込みの優先順位は6層

多くの解説記事で省かれている部分です。Codexは設定値を次の順で解決します(上が最優先)。

順位備考
1CLIフラグ / --config-c)オーバーライドその場限りの上書き
2プロジェクト設定 .codex/config.toml信頼済みプロジェクトのみ。リポジトリルートからカレントディレクトリへ向かって読み、近い方が勝つ
3プロファイル ~/.codex/<プロファイル名>.config.toml--profile <名前> で選択
4ユーザー設定 ~/.codex/config.toml個人の既定値
5システム設定 /etc/codex/config.tomlUnix系で存在する場合
6組み込みデフォルトCodex本体の初期値

実務での使い分けは、共通の既定値をユーザー設定に置き、プロジェクト固有の差分だけをプロジェクト設定やプロファイルに書くのが基本です。全部をプロジェクト設定に書くと、リポジトリを増やすたびに同じ内容を複製することになります。

このとき、同じ名前のMCPサーバーを複数の層に書かないでください。 優先順位の高い層が勝つため、編集したつもりのない層の値で動き続ける、という状態になります。

「プロジェクト設定が効かない」の答え

優先順位の表で唯一、条件がついている層があります。2番目のプロジェクト設定です。

.codex/config.toml は、そのプロジェクトを信頼済みにしていないと読み込まれません。 未信頼のプロジェクトでは、Codexは .codex/ 配下の層をまるごとスキップします。これには設定ファイルだけでなく、hooks も rules も含まれます。このときユーザー設定とシステム設定は通常どおり読まれるため、「Codexは動いているのに、プロジェクトに書いたMCPサーバーだけが出てこない」という状態になります。

これはバグではなくセキュリティ上の仕様です。クローンしてきたリポジトリに .codex/config.toml が仕込まれていて、開いた瞬間に任意のコマンドがMCPサーバーとして起動する — という事故を防ぐための設計です。MCPサーバーのSTDIO設定は要するに「起動するコマンド」なので、信頼していないリポジトリの指示で勝手に実行されては困ります。

したがって、プロジェクト設定を使う場合は「そのリポジトリを信頼する」という手順が必ず一度必要になります。チームに配布する際は、この一手間を手順書に明記しておくと問い合わせが減ります。

プロファイルでMCP構成を切り替える

「普段は軽いサーバーだけ、レビューのときはブラウザ操作もログ参照も全部繋ぐ」といった使い分けをしたい場合、プロジェクト単位よりプロファイルのほうが適しています。

プロファイルは、~/.codex/config.toml の上に重ねる名前付きの設定レイヤーです。--profile <名前> を渡すと、ユーザー設定を読んだうえに ~/.codex/<名前>.config.toml が重なります。

# ~/.codex/deep-review.config.toml
[mcp_servers.chrome_devtools]
url = "http://localhost:3000/mcp"
default_tools_approval_mode = "writes"

[mcp_servers.sentry]
command = "npx"
args = ["-y", "@sentry/mcp-server"]
codex --profile deep-review
codex exec --profile deep-review "この変更をレビューして"

プロファイルを書くときの注意が1つあります。プロファイルファイルにはトップレベルの設定キーをそのまま書きます。 [profiles.deep-review] のような入れ子にしてはいけません。プロファイル名に使えるのは英数字・ハイフン・アンダースコアです。

プロファイルはユーザー設定の上、プロジェクト設定とCLIオーバーライドの下の層にあります。そのため、ベース設定との差分だけを書けば十分です。全サーバーを書き直す必要はありません。

なお、公式ドキュメントによると Codex 0.134.0 以降、--profileconfig.toml 内の [profiles.<名前>] テーブルを読まなくなり、トップレベルの profile = "<名前>" セレクタも廃止されました。古い記事の書き方をそのまま使っていて効かない場合は、設定を独立したプロファイルファイルへ移してください。

一時的に上書きする

「このサーバーだけ今回は止めたい」という場面では、設定ファイルを編集せずCLIから上書きできます。

codex --config mcp_servers.context7.enabled=false

-c / --config は任意のキーをドット記法で上書きします。公式ドキュメントがドット記法の例として挙げているのが、まさにこのMCPサーバーの enabled です。

1点だけ癖があります。--config の値はJSONではなくTOMLとして解釈されます。 そのため文字列を渡すときはクォートが二重に必要です。

codex --config mcp_servers.context7.startup_timeout_sec=30
codex --config mcp_servers.figma.bearer_token_env_var='"FIGMA_TOKEN"'

TOMLとして解釈できない値は、そのまま文字列として扱われます。切り分けの最中に設定を一時的に変えて試すときは、ファイルを書き換えるよりこちらのほうが安全です。元に戻し忘れる事故が起きません。

最短手順 — codex mcp add で繋ぐ

config.toml を直接開かなくても、CLIから追加できます。まずはこちらが速いです。Codex CLIそのもののインストールや基本操作はCodex CLIの使い方ガイドを前提とします。

ローカルで動くサーバー(STDIO)を追加する

STDIOサーバーは、Codexがローカルプロセスとして起動するタイプのMCPサーバーです。コマンドを指定して追加します。

codex mcp add <サーバー名> --env VAR1=VALUE1 --env VAR2=VALUE2 -- <サーバーを起動するコマンド>

-- より後ろが、実際に起動されるコマンドです。公式ドキュメントが例に挙げているContext7(開発者向けドキュメントを参照できる無料のMCPサーバー)なら、次の1行で追加できます。

codex mcp add context7 -- npx -y @upstash/context7-mcp

-- の位置がポイントです。これより前はCodex自身のオプション(--env など)、後ろは公式の書式どおり「サーバーを起動するコマンド」として扱われます。サーバー側にオプションを渡したいときも、-- より後ろにまとめて書きます。

リモートのHTTPサーバーを追加する

解説記事ではCLIでの追加をSTDIOの例だけで済ませているものが多いのですが、リモートのHTTPサーバーもCLIから追加できます--url を使います。

codex mcp add example --url https://mcp.example.com --oauth-client-id my-client

--oauth-client-id は、認可サーバー側で事前登録済みのOAuthクライアントIDを使う場合に指定します。事前登録が不要なサーバーであれば省略できます。

事前登録済みのクライアントIDを指定して追加した場合、この codex mcp add を実行した時点で、認可サーバーに登録すべきコールバックURLがターミナルに表示されます。

OAuth callback URL: http://127.0.0.1/callback

公式ドキュメントは「codex mcp add が表示したコールバックを、そのとおりに登録すること」を明記しています。自分で組み立てたURLを登録すると、Codexが実際に使うURLと登録したURLが一致せず、ログインできないことがあります。Codexは認可サーバーの対応状況によってコールバックにサーバー固有のIDを付け足すことがあり、実際に使われるポートも環境によって変わるためです。

CodexはクライアントIDと合わせてこのコールバックを config.toml に保存し、以降のログインで再利用します。

登録が済んだら、OAuthに対応したサーバーではログインを実行します。

codex mcp login <サーバー名>

追加できたか確認する

設定済みのサーバーを一覧するコマンドがあります。

codex mcp list

利用できるMCP関連のサブコマンドをすべて見るには、ヘルプを参照してください。

codex mcp --help

実際にセッション内で稼働しているサーバーを確認したいときは、codex のTUI(ターミナルUI)を起動して /mcp と入力します。ここに出てくるかどうかが、最終的な動作確認になります。

なお、codex mcp add はCLIから設定を書き込むための入口であり、書かれる先は結局 config.toml です。複雑な設定をしたくなったら、次章のようにファイルを直接編集する方が早くなります。

config.toml を直接書く — 設定キー全リファレンス

細かい制御をしたい場合は config.toml を直接編集します。サーバー1つにつき [mcp_servers.<サーバー名>] というテーブルを1つ書きます。

トランスポートは「キーの有無」で決まる

Codexには、Claude Codeの --transport に相当する明示的な指定がありません。どのキーを書いたかでトランスポートが決まります。 command を書けばSTDIO(ローカルプロセスとして起動)、url を書けばStreamable HTTP(アドレスに接続)です。

この暗黙のルールを知らないと、type = "stdio" のようなキーを足したくなりますが、Codexの設定にそのキーはありません。

STDIOサーバーのキー

キー必須内容
commandサーバーを起動するコマンド
argsコマンドに渡す引数(配列)
envサーバーに渡す環境変数(キーと値のマップ)
env_vars許可・転送する環境変数の名前リスト
cwdサーバープロセスの作業ディレクトリ
experimental_environmentlocal / remoteremote はリモート実行環境でSTDIOサーバーを起動する実験的設定

envenv_vars は役割が違います。env値をこちらで指定して渡すもの、env_varsCodex側の環境にある変数を許可して転送するものです。APIキーを config.toml に直書きしたくない場合は、シェルの環境変数に置いて env_vars で通すほうが安全です。

env_vars は変数名の文字列だけでなく、取得元を指定したオブジェクトも書けます。

env_vars = ["LOCAL_TOKEN", { name = "REMOTE_TOKEN", source = "remote" }]

文字列で書いた場合と source = "local" を指定した場合は、Codexのローカル環境から読みます。source = "remote" はリモート実行環境から読むもので、リモートMCP STDIOが利用できる状況でのみ機能します。

Streamable HTTPサーバーのキー

キー必須内容
urlサーバーのアドレス
authoauth(既定)/ chatgpt。設定済みのbearerトークンや認可ヘッダの後に試される認証方法
bearer_token_env_varAuthorization に載せるbearerトークンを保持する環境変数名
http_headers毎リクエストに付ける静的ヘッダ(マップ)
env_http_headers環境変数から値を取るヘッダ(ヘッダ名 → 環境変数名のマップ)
scopesOAuthログイン時に要求するスコープ
oauth_resourceOAuthログイン時に含めるリソースパラメータ
oauth.client_id事前登録済みのOAuthクライアントID
oauth.callback_urlこのサーバー専用のコールバックURL
oauth.callback_portこのサーバー専用のコールバック待受ポート

トークンの扱いには優先順位があります。まず設定済みのbearerトークンと認可ヘッダが使われ、それで解決しなければ auth の設定に従います。どの認証情報も解決しなかった場合、Codexは認証なしでサーバーに接続することがあります。認証必須のつもりのサーバーが、無認証で繋がって想定外の挙動をしていないか、初回は確認しておくと安全です。

サーバーが scopes_supported を広告している場合、Codexはそちらを優先します。広告がなければ config.toml に書いたスコープが使われます。

OAuthのクライアント登録については、事前登録が不要なケースが増えています。Codexは OAuth Client ID Metadata Documents(CIMD)動的クライアント登録(DCR) に対応しており、認可サーバーの広告内容に応じて既定では自動的に方式を選びます。事前登録済みのクライアントIDを oauth.client_id に設定した場合は、それが常に優先され、クライアント登録の工程自体が省略されます。

ログイン時に方式を明示したい場合は、codex mcp login にオプションを付けます。

codex mcp login <サーバー名> --oauth-client-registration cimd
codex mcp login <サーバー名> --oauth-client-registration dcr

既定は auto です。ここでの選択はそのログイン1回だけに適用され、config.toml には保存されません。

共通のオプション

キー既定値内容
startup_timeout_sec10秒サーバー起動を待つ秒数
startup_timeout_msstartup_timeout_secミリ秒エイリアス
tool_timeout_sec60秒ツール1回の実行を待つ秒数
enabledfalse で設定を消さずに無効化
requiredtrue にすると、このサーバーが初期化できないとき起動・再開自体を失敗させる
enabled_tools使用を許可するツール名のリスト
disabled_tools使用を禁止するツール名のリスト
default_tools_approval_modeこのサーバーのツール承認の既定動作
tools.<ツール名>.approval_modeツール単位での承認動作の上書き

サーバー単位ではないグローバル設定

[mcp_servers.<名前>] 配下のキーとは別に、OAuthのコールバックにはファイルのトップレベルに書く設定が2つあります。

mcp_oauth_callback_port = 5555
mcp_oauth_callback_url = "https://devbox.example.internal/callback"

mcp_oauth_callback_port は待受ポートを固定したいとき、mcp_oauth_callback_url はカスタムのコールバックパスやリモート環境のURLが必要なときに使います。サーバー単位で上書きしたい場合は、前掲の oauth.callback_port / oauth.callback_url を使います。

enabledrequired の使い分け

この2つは運用に効くわりに、解説されていることが少ないキーです。

enabled = false は、設定を残したままサーバーを止めるためのものです。切り分けの最中に「このサーバーが原因か確かめたい」場面で、設定ブロックを丸ごとコメントアウトする代わりに使えます。TOMLの複数行コメントアウトは面倒なので、1行足すだけで済むこちらのほうが実用的です。

required = true は逆で、このサーバーが初期化できなければ起動・再開そのものを失敗させるという宣言です。使いどころは限られます。

付けてよいのは、そのサーバー抜きでは作業が成立しない場合だけです。半端に動いて誤った結果を出すより、止まったほうが安全だからです。逆に「あると便利だが無くても進められる」サーバーや、検証中・導入直後のサーバーには付けません。落ちたときに作業全体が止まりますし、起動失敗の原因を切り分けにくくなります。

注意点として、required = true を複数のサーバーに付けると、そのうち1つが初期化に失敗しただけで起動・再開が止まります。付けるのは本当に不可欠な1〜2個に留めるのが現実的です。

タイムアウトの単位に注意する

startup_timeout_secstartup_timeout_ms同じ設定に対する別単位の入口です。前者が秒、後者がミリ秒で、後者は前者のエイリアスとして扱われます。

ここが事故になります。他ツールの設定を参考にしてミリ秒の感覚のまま、

startup_timeout_sec = 10000   # 10秒のつもり

と書くと、これは10,000 — 約2.8時間の起動タイムアウトになります。サーバーが起動に失敗しても延々と待ち続け、「Codexが固まった」ように見えます。秒のキーには秒を書いてください。

startup_timeout_sec = 20      # 20秒
startup_timeout_ms = 20000    # 同じ意味

古い解説記事には startup_timeout_ms しか載っていないものがあり、そこから単位の誤解が生まれやすくなっています。

公式の設定例

STDIOサーバーの例です。env_varsenv を併用しています。

[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]
env_vars = ["LOCAL_TOKEN"]

[mcp_servers.context7.env]
MY_ENV_VAR = "MY_ENV_VALUE"

HTTPサーバーの例です。トークンは環境変数から読み、静的ヘッダを付けています。

[mcp_servers.figma]
url = "https://mcp.figma.com/mcp"
bearer_token_env_var = "FIGMA_OAUTH_TOKEN"
http_headers = { "X-Figma-Region" = "us-east-1" }

タイムアウトと権限をまとめて指定した例です。

[mcp_servers.chrome_devtools]
url = "http://localhost:3000/mcp"
enabled_tools = ["open", "screenshot"]
disabled_tools = ["screenshot"]
default_tools_approval_mode = "prompt"
startup_timeout_sec = 20
tool_timeout_sec = 45
enabled = true

[mcp_servers.chrome_devtools.tools.open]
approval_mode = "approve"

この最後の例は、次章の内容を先取りしています。enabled_toolsscreenshot を入れているのに disabled_tools にも入れているため、結果として screenshot は使えません。理由は次章で説明します。

権限を設計する — 承認モードとツール許可リスト

MCPサーバーを繋ぐということは、Codexに外部への操作権限を渡すということです。読み取り専用のドキュメント検索サーバーと、リポジトリに書き込めるサーバーを、同じ扱いにすべきではありません。Codexにはこれを制御する仕組みが2段構えで用意されています。

許可リストと拒否リストの適用順

まず「どのツールを見せるか」を絞ります。

  • enabled_tools — 使用を許可するツール名のリスト
  • disabled_tools — 使用を禁止するツール名のリスト

重要なのは順番です。disabled_toolsenabled_tools の後に適用されます。 つまり両方に同じツール名が入っている場合、最終的に勝つのは disabled_tools です。

前章の公式例で screenshot が使えなくなるのはこのためです。enabled_tools = ["open", "screenshot"] でいったん2つに絞られ、そのあと disabled_tools = ["screenshot"] が適用されて screenshot が落ちます。残るのは open だけです。

この挙動は、普段は広めに許可しておき、一時的に特定のツールだけ止めるという運用に向いています。enabled_tools を書き換えずに disabled_tools へ1行足すだけで、そのツールを封じられます。

承認モードの4つの値

次に「実行時に確認を挟むか」を決めます。default_tools_approval_mode で、そのサーバーのツール全体の既定動作を指定します。

挙動向いている相手
auto確認せず自動で実行する読み取り専用で副作用のないサーバー
prompt毎回ユーザーに確認する導入直後で挙動を把握しきれていないサーバー
writesread-onlyとマークされていないツールだけ確認する読み書き両方を持つサーバー
approve承認を必須にする本番環境に触れるサーバー

この4値のうち、公式ドキュメントに挙動が明記されているのは writes だけです。残る3つは値名から読み取れる範囲の理解に留め、実際の確認の出方は導入時に手元で確かめてください。

実務でいちばん使いどころが多いのは writes です。読み取り系のツールは黙って実行させ、書き込み系だけ人間が止められる — MCPサーバーの多くが読み取りと書き込みを両方持つことを考えると、この粒度が現実的です。すべてを prompt にすると確認が多すぎて形骸化し、auto にすると事故ったときに気づけません。

ツール単位で上書きする

サーバー全体の既定を決めたうえで、個別のツールだけ厳しくすることもできます。

[mcp_servers.chrome_devtools.tools.open]
approval_mode = "approve"

tools.<ツール名>.approval_mode は、そのツールだけ既定を上書きします。取れる値は default_tools_approval_mode と同じ4つです。

設計としては、サーバー全体は writes にしておき、特に危険な数個だけ approve に上げるのが扱いやすい構成です。

権限設計のチェックリスト

MCPサーバーを本番の開発フローに載せる前に、次を確認してください。

  • このサーバーは読み取り専用か、書き込みもできるか把握している
  • enabled_tools で必要なツールだけに絞ったか
  • 書き込み系ツールの承認モードは auto になっていないか
  • APIキーを config.toml に直書きせず、env_varsbearer_token_env_var 経由にしたか
  • config.toml をリポジトリにコミットする場合、秘密情報が含まれていないか
  • このサーバーが落ちたとき、開発を止めてよいか(止めてよいなら required = true
  • 認証情報が解決しなかったとき、無認証で接続されても問題ないか

最後の2つはとくに見落とされがちです。どちらも「繋いだ後に気づく」種類の問題なので、繋ぐ前に一度考えておいてください。

権限を絞ることには、事故防止とは別の効果も期待できます。渡すツールが少ないほど選択肢が減るぶん、実務上はタスクに適したツールが選ばれやすくなるという感触があります。最小権限の設計は、安全のためだけでなく精度のためでもある、と考えると設計判断がしやすくなります。

Claude CodeとのMCP設定の違い

実務では、Claude CodeとCodexを併用しているチームが少なくありません。そこで起きるのが「Claude Codeで動いている設定をCodexに持っていきたい」という場面です。

結論から言うと、そのままコピーはできません。 設定形式から権限モデルまで、主要な設計が違います。両者の公式ドキュメントを突き合わせて、移植時に引っかかる差分を整理しました。

観点CodexClaude Code
設定ファイル形式TOMLJSON
ユーザー設定~/.codex/config.toml~/.claude.json
プロジェクト設定.codex/config.toml(信頼済みのみ).mcp.json(プロジェクトルート)
設定の単位[mcp_servers.<名前>] テーブルmcpServers オブジェクト内のエントリ
トランスポート指定キーの有無で暗黙決定command / url--transport で明示http / sse / stdio
追加コマンドcodex mcp add <名前> -- <コマンド>claude mcp add <名前> -- <コマンド>
適用範囲の考え方6層の優先順位(CLI → プロジェクト → プロファイル → ユーザー → システム → 既定)3つのスコープ(local → project → user の順に優先)を --scope で選択
重複時の解決値を優先順位順に解決する最上位のソースのエントリを丸ごと採用し、スコープ間でフィールドをマージしない
チーム共有プロジェクト設定をコミット(利用側で信頼が必要)--scope project.mcp.json をコミット。利用側で承認とワークスペース信頼が必要)
ツール実行タイムアウトtool_timeout_sec・既定60)/サーバー単位timeoutミリ秒)/サーバー単位
起動タイムアウトstartup_timeout_sec・既定10)/サーバー単位MCP_TIMEOUT 環境変数(ミリ秒・例 MCP_TIMEOUT=10000 で10秒)/全体
権限制御default_tools_approval_mode の4値+ツール単位上書き.mcp.json サーバーの承認・有効化設定

移植でとくに事故りやすい3点

1. タイムアウトの単位が逆。 Claude Codeの timeout はミリ秒です。10分なら 600000 と書きます。この感覚のままCodexの tool_timeout_sec600000 と書くと、約7日になります。Codexは秒、Claude Codeはミリ秒 — ここは機械的に変換してください。起動タイムアウトも同様で、Claude Codeの MCP_TIMEOUT はミリ秒指定です。

2. mcpServers のJSONブロックはそのまま貼れない。 MCPサーバーの導入手順は、Claude Desktopなど他のクライアント向けに mcpServers を含むJSONで書かれていることがよくあります。Claude CodeはこのJSONの形を読めますが、CodexはTOMLなので、構造ごと書き換える必要があります。JSONをそのまま config.toml に貼るとTOMLとして不正な構文になり、その設定ファイル全体の読み込みに失敗します。影響はMCPサーバーだけに留まりません。同じファイルに書いたモデル指定や承認ポリシーも巻き添えになります。

3. 重複したときの解決の仕方が違う。 どちらにも優先順位はあります。違うのは、同じ名前のサーバーが複数の場所にあったときの解決の仕方です。

Claude Codeの公式ドキュメントは、最上位のソースのエントリを丸ごと使い、スコープ間でフィールドはマージしないと明記しています。優先順位は local → project → user の順で、local が最上位です。つまり local スコープの定義が勝つ場合、project スコープにだけ書いてあった env の1項目は引き継がれません。定義がまるごと入れ替わります。

一方、Codexの公式ドキュメントは優先順位を「値をこの順で解決する」と説明しています。同名のMCPサーバーを複数の層に置いたときにキー単位で合成されるのかどうかまでは明示がないため、同じ名前のサーバーは1つの層にまとめておくのが安全です。移植の際に「片方の層に古い定義が残っていて、想定と違う設定で動く」という事故は、どちらのツールでも起こりえます。

実際に移植してみる

他クライアント向けの手順書によくある形のJSONを、Codexの config.toml に書き換えてみます。移植元がこの形だとします。

{
  "mcpServers": {
    "context7": {
      "command": "npx",
      "args": ["-y", "@upstash/context7-mcp"],
      "env": { "MY_ENV_VAR": "MY_ENV_VALUE" },
      "timeout": 45000
    }
  }
}

これをCodex向けに書き換えると次のようになります。

[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]
tool_timeout_sec = 45

[mcp_servers.context7.env]
MY_ENV_VAR = "MY_ENV_VALUE"

変換のポイントは4つです。

  1. mcpServers というラッパーは消える。 Codexでは [mcp_servers.<名前>] がそのままサーバー1つを表します
  2. env は入れ子のテーブルになる。 TOMLでは [mcp_servers.context7.env] という別テーブルとして書きます。env = { ... } のインライン記法でも書けますが、項目が増えると読みにくくなります
  3. timeout: 45000(ミリ秒)は tool_timeout_sec = 45(秒)になる。 ここで単位を変換し忘れると45,000秒=約12.5時間になります
  4. type に相当するキーは書かない。 command があるのでSTDIOと判定されます

逆方向(Codex → Claude Code)に移すときも、同じ4点を逆に適用します。とくに秒 → ミリ秒の変換忘れは、タイムアウトが短くなりすぎて「たまに失敗する」という再現性の低い不具合になるため厄介です。

どちらをどう使うか

設定の移植性という観点では、両者は独立した環境として扱い、それぞれに設定を持たせるのが結局いちばん早いです。共通で使いたいサーバー(ドキュメント検索など)は両方のユーザー設定に書き、プロジェクト固有のサーバーだけそれぞれのプロジェクト設定に置く、という運用に落ち着きます。

2つのツールを役割で使い分ける方法についてはClaude CodeとCodexを併用するワークフローで詳しく扱っています。Claude Code側のMCP設定手順そのものはClaude CodeのMCPサーバー導入ガイドを参照してください。

実務で何に使い、どこで線を引くか — 受託開発の現場でのMCP

設定できたとして、MCPは実際に何に効くのか。ツール名の列挙ではなく、開発の流れのどこが変わるかで整理します。

公式が挙げているMCPサーバー

OpenAIの公式ドキュメントは、よく使われるMCPサーバーとして次を挙げています。

サーバーできること
OpenAI Docs MCPOpenAIの開発者ドキュメントを検索・参照する
Context7最新の開発者ドキュメントを参照する
Figma(Local / Remote)Figmaのデザインにアクセスする
PlaywrightPlaywrightでブラウザを操作・検査する
Chrome DevToolsChromeを操作・検査する
SentrySentryのログにアクセスする
GitHubgit だけでは扱えないPull RequestやIssueを操作する

効き方は「調べる手間」の削減に出る

これらに共通するのは、Codexが自分で一次情報を取りに行けるようになるという点です。

AIコーディングエージェントが間違える典型的なパターンは、学習時点の古いAPI仕様で書いてしまうことです。ドキュメント参照系のMCPサーバーを繋いでおくと、Codexは推測ではなく現在のドキュメントを読んで実装できます。「そのライブラリのそのメソッドはもう存在しない」という手戻りが目に見えて減ります。

デザイン参照系も同じ構図です。Figmaを繋いでいなければ、実装の根拠は人間が転記した仕様の説明文になります。繋いでいれば、Codexはデザインそのものを見て実装できます。転記の過程で落ちる情報がなくなるのが本質的な効果です。

Sentryやブラウザ操作系は、調査フェーズに効きます。「エラーが出ている」という報告から、Codexがログを読み、再現し、原因箇所を特定するところまでを一続きで進められます。

受託開発の現場でどう変わるか

受託開発では、この「一次情報に自分で当たれる」性質が特に効く場面があります。

既存システムの改修案件では、着手時点で仕様書が現状と乖離していることが珍しくありません。ドキュメント参照系のサーバーに加えて、エラーログや実際の画面を参照できる状態にしておくと、Codexが「書かれている仕様」ではなく「動いている実物」を根拠に調査できます。仕様書の記述と実装の食い違いは、人間が読み比べるとかなりの工数になる作業です。

技術選定を伴う初期フェーズでは、ライブラリの最新仕様を確認しながら比較検討を進められます。学習時点の情報で「このライブラリはこの機能に対応していない」と判断されると、選定そのものを誤ります。ドキュメントを実際に読ませることで、この種の誤りが減ります。

レビュー工程では、変更差分に対してブラウザで実際の挙動を確認させる、といった使い方ができます。ただし前提として、レビューの最終判断は人間が持ちます。MCPで広がるのは調査の範囲であって、判断の責任ではありません。

段階的に増やす — 最初に繋ぐべき順番

いきなり全部繋ぐと、権限設計も切り分けも同時に破綻します。導入の順番として無理がないのは、副作用の小さいものから増やす進め方です。

段階繋ぐサーバーの性質承認モードの目安この段階で確認すること
1読み取り専用のドキュメント参照auto設定が読まれるか。/mcp に出るか
2読み取り中心の調査系(ログ・デザイン参照)auto または writes認証が通るか。応答が遅くないか
3ブラウザ操作など副作用のある実行系writes意図しないツールを呼んでいないか
4書き込み権限を持つ連携(リポジトリ操作など)writes + 危険なツールは approve承認が実際に止められているか

第1段階は、設定の仕組みそのものを検証する工程だと考えてください。ここでつまずいたら、それは設定の場所か優先順位の問題であって、サーバーの問題ではありません。読み取り専用のサーバーで一度成功させておくと、以降の切り分けが格段に楽になります。

何を繋がないかを決める

繋ぐ判断と同じくらい、繋がない判断が効きます。次に当てはまるサーバーは、慎重に扱ってください。

  • 本番環境に直接書き込めるもの — ステージング用の認証情報に差し替えられないか検討する。差し替えられないなら、承認モードを決めてから繋ぐ
  • 削除操作を持つものenabled_tools で削除系ツールを外せないか確認する
  • 課金が発生するもの — 想定外のループで呼ばれたときのコストを見積もっておく
  • 社外にデータを送るもの — 何がどこへ送られるかを、繋ぐ前に把握する

これらは技術的に接続できるかどうかの話ではなく、組織として許容できるかの話です。とくに受託開発では、顧客のデータをどこまでAIツールに触れさせてよいかが契約上の論点になります。繋げるから繋ぐ、ではなく、契約と運用ルールを先に確認するのが順序として正しくなります。

MCPサーバーを業務システム側から用意する視点についてはMCPサーバーのビジネス活用で扱っています。自社のデータやツールをAIから使える形で公開する場合の考え方です。

MCPで解決しないこと

期待値を正しく置くために、MCPが効かない領域も書いておきます。

レビュー体制の代わりにはなりません。 MCPはCodexが参照できる情報と操作できる範囲を広げますが、出力の正しさを保証する仕組みではありません。むしろ、外部システムに書き込めるツールを渡すほど、間違ったときの影響範囲は広がります。誰がどの粒度で結果を確認するかが決まっていない状態でGitHubへの書き込み権限を渡すのは、順序が逆です。

曖昧な仕様が明確になるわけでもありません。 ドキュメント参照系のサーバーは「公開されている情報」を取りに行く仕組みです。社内の暗黙知や、まだ誰も文章にしていない判断基準は、繋いでも出てきません。ここは人間が言語化するしかない領域です。

MCPは「調べる・触れる範囲を広げる」ための仕組みであって、判断を代行する仕組みではない — この線引きを持っておくと、導入後の期待外れが起きにくくなります。

繋がらないときの切り分け

ここまでが「何をどう繋ぐか」の話です。最後に、繋いだつもりで繋がっていないときの手順を整理します。

/mcp にサーバーが出てこない、あるいはツールが呼べない。原因は大きく4つのSTEPに切り分けられます。上から順に潰すのが最短です。

STEP 1 — 設定は読み込まれているか

まず「Codexがその設定を見ているか」を確認します。経験上、ここが原因であることが多く、確認コストも最も低いためです。

  • codex mcp list に出てくるか。出てこないなら、Codexはその設定を認識していません
  • プロジェクトの .codex/config.toml に書いた場合、そのプロジェクトを信頼済みにしましたか。未信頼なら読み込まれません
  • 同じ名前のサーバーを、ユーザー設定とプロジェクト設定の両方に書いていませんか。優先順位の高い層が勝つため、想定と違う定義が使われている可能性があります
  • プロファイルを使っている場合、意図したプロファイルで起動していますか

STEP 2 — TOMLとして壊れていないか

config.toml に構文エラーがあると、そのファイル全体の読み込みに失敗します。MCPサーバーが繋がらないだけでなく、同じファイルに書いた他の設定も効かなくなり、起動時にエラーが出ることがあります。他ツール向けのJSONを貼り付けた場合がこれに該当します。

設定を編集した直後におかしくなったら、まず直前の変更を戻してください。とくに次を確認します。

  • JSONの { "mcpServers": { ... } } をそのまま貼っていないか
  • テーブル名は [mcp_servers.<名前>] になっているか(mcpServers ではありません)
  • 配列は args = ["-y", "パッケージ名"] の形式か
  • 文字列がダブルクォートで囲まれているか

STEP 3 — サーバーは起動できているか

設定は読めていて構文も正しい場合、次はサーバープロセスそのものです。

  • command に指定したコマンドは、そのシェルで実際に実行できますか。ターミナルに直接打ち込んで確認してください
  • コマンドがPATH上にない場合、フルパスで指定すると解決することがあります。Windows環境で動かないときに一度は確認したい項目です
  • 起動に時間がかかるサーバーは、既定の10秒に間に合っていない可能性があります。startup_timeout_sec を延ばしてください(このとき単位に注意。秒です)
  • 依存パッケージをリモートから取得するタイプのサーバーは、初回起動が特に遅くなります
  • cwd の指定が必要なサーバーではないか確認してください

STEP 4 — 認証は通っているか

HTTPサーバーで、接続はするがツールが使えない場合は認証を疑います。

  • OAuth対応サーバーなら codex mcp login <サーバー名> を実行しましたか
  • 認可サーバーに登録したコールバックURLは、codex mcp add が表示したものと完全に一致していますか
  • bearer_token_env_var で指定した環境変数は、Codexを起動したシェルに実際に設定されていますか
  • ツールは見えるのに呼べない場合、disabled_tools で落ちていませんか(enabled_tools の後に適用される点に注意)
  • 承認モードが approveprompt になっていて、確認待ちで止まっていませんか

切り分けの早見表

症状疑うSTEP最初に見る場所
codex mcp list に出ないSTEP 1書いた場所と信頼設定
設定が一切反映されない/起動時にエラーが出るSTEP 2直前に編集した config.toml
一覧には出るが起動に失敗するSTEP 3command の実行可否とPATH
起動するがタイムアウトするSTEP 3startup_timeout_sec
繋がるがツールが呼べないSTEP 4認証と disabled_tools
毎回確認を求められるSTEP 4default_tools_approval_mode

切り分けの実例

「チームで共有しているプロジェクト設定に書いたMCPサーバーが、自分の環境だけ出てこない」というケースで、上の表がどう働くかを見ておきます。

同僚の環境では動いているのですから、設定ファイルの中身自体は正しいはずです。疑うべきは「読まれているかどうか」、つまり STEP 1 になります。クローンしたばかりのリポジトリは未信頼なので、まず信頼済みにしたかを確認します。

信頼済みにしても出てこないときに効くのが、いったんユーザー設定(~/.codex/config.toml)へ同じ内容をコピーして試すという手です。ユーザー設定には信頼の条件がかかりません。これで出てくるなら原因は設定の中身ではなく読み込み経路にあると確定し、出てこないならTOMLの構文か記述内容そのものに絞れます。1回の操作で STEP 1 と STEP 2 を分離できるのが、この方法の効きどころです。

こうして上のSTEPから順に潰すと、「サーバー側の問題だと思っていたら信頼設定だった」という遠回りを避けられます。

チームに配る場合

個人で動かすところまでは上記で足りますが、チームに展開するとつまずくポイントが変わります。

プロジェクト設定をリポジトリにコミットすれば設定自体は配れますが、受け取る側には信頼済みにする手順が必要です。ここを書いていない手順書だと、「READMEどおりにやったのに動かない」という問い合わせが人数分発生します。

配布時に決めておくとよいのは次の3点です。

  • 秘密情報を設定ファイルに入れない。 APIキーは env_varsbearer_token_env_var で環境変数から読む形にし、変数名だけをコミットします。値は各自が自分の環境に置きます
  • required を付けるサーバーを絞る。 全員の環境で確実に動くと言い切れるサーバーにだけ付けます
  • 承認モードの既定をチームで揃える。 個人ごとにバラバラだと、「自分の環境では確認が出たのに、他の人の環境では素通りした」という差が生まれます

よくある質問

まとめ

最後に、明日から動かすための順番だけまとめます。

  1. 読み取り専用のサーバーを1つだけ繋ぐ。 ドキュメント参照系が向いています。codex mcp add で追加し、codex mcp list と TUI の /mcp に出るところまでを確認します。ここが通れば、設定の仕組み自体は理解できています
  2. どの層に書くかを決める。 全プロジェクトで使うならユーザー設定、そのリポジトリ限定ならプロジェクト設定(信頼済みにする手順を忘れずに)、作業モードで切り替えたいならプロファイルです
  3. 繋ぐ前に権限を決める。 書き込み権限を持つサーバーは、enabled_tools で絞るか、最低でも default_tools_approval_mode = "writes" にしてから繋ぎます
  4. 段階的に増やす。 副作用の小さいものから順に足し、増やすたびに /mcp で確認します
  5. 繋がらなくなったら STEP 1 から下る。 設定が読まれているか → TOMLが壊れていないか → サーバーが起動するか → 認証が通るか の順です

この順で進めれば、「おすすめサーバー一覧」から入って繋がらずに詰まる、という回り道を避けられます。

なお、本記事の仕様はすべて2026年8月時点のOpenAI公式ドキュメントに基づいています。MCP周りは更新が速い領域なので、設定キーの挙動が想定と違うときは公式のMCPドキュメント設定リファレンスを確認してください。

接続先の選定と承認モードの設計は、そのまま社内の運用ルールの一部になります。衣株式会社では、AIコーディングエージェントを前提とした開発体制の構築を支援しています。MCPを含むツール選定から、レビュー体制の設計、社内への定着までを一気通貫でお手伝いします。

koromo からの提案

AIツールの導入判断は、突き詰めると「投資対効果が合うか」「リスクを管理できるか」「事業にどう効くか」の3点に帰着します。koromo では、この判断に必要な材料を整理するところからご支援しています。

以下のような状況にある方は、まず現状の整理だけでも前に進むきっかけになります。

  • AIで開発や業務を効率化したいが、自社に合う方法がわからない
  • 社内にエンジニアがいない / 少人数で、AI導入の進め方に見当がつかない
  • 外注先の開発会社にAI活用を提案したいが、何を求めればいいか整理できていない
  • 「AIを使えばコスト削減できるはず」と感じているが、具体的な試算ができていない

ツールを使った上で相談したい方はお問い合わせフォームから「AIコーディングツール導入の相談」とご記載ください。初回の壁打ち(30分)は無料で対応しています。

無料で相談する

関連記事