Claude Codeの--mcp-configと--strict-mcp-configの使い分け
--mcp-configは追加読み込み、--strict-mcp-configは排他読み込みです。CI実行や検証環境、managed-mcp.jsonとの組み合わせでの挙動の違いをまとめます。
Claude Codeには、起動時にMCPサーバーの設定をJSONで読み込む--mcp-configと、その読み込みを排他的にする--strict-mcp-configという2つのフラグがあります。見た目がよく似ているうえに動作説明も短いため混同されがちですが、役割は別物です。--mcp-configは既存の設定に足す読み込み、--strict-mcp-configは既存の設定を無視して指定したものだけを使う排他読み込みです。
CIで不要なサーバーを読み込ませない、検証用のサーバー構成だけを一時的に試す、といった場面で迷わなくなります。取り違えると「足したつもりが既存の設定まで消えた」「絞ったつもりが他のサーバーも動いた」という事故になります。組織がmanaged-mcp.jsonを配布している端末では、さらに別の挙動になる点も扱います。
足すのか、ほかを切るのか — 2つのフラグの役割
v2.1.287のclaude --helpでは、2つのフラグは次のように説明されています。
claude --help
--mcp-config <configs...> Load MCP servers from JSON files or strings (space-separated)
--strict-mcp-config Only use MCP servers from --mcp-config, ignoring all other MCP configurations--mcp-configはJSONファイルまたはJSON文字列(スペース区切りで複数指定可)からサーバー定義を読み込みます。--strict-mcp-configの説明にある「他のすべてのMCP設定を無視する」は、ローカル・プロジェクト・ユーザーの各スコープや.mcp.jsonが対象です。managedMcpServersで配布されたサーバーも、managed-mcp.jsonがない環境では同じく除外されます。
読み込みの違い
--mcp-config
既存のスコープ設定や.mcp.jsonはそのまま残り、指定したサーバーが加わります。単独で使えます。
--strict-mcp-config
サーバーの供給元が--mcp-configだけになります。渡し忘れると、MCPサーバーなしの起動になる構成です。
どちらもclaude mcp addやclaude mcp add-jsonのようにスコープへ書き込むフラグではありません。変更履歴にはclaude --mcp-config <path-to-file>が「one-off」(その場限り)のMCPサーバーを動かす方法として載っています。チームで共有する恒常的な設定は.mcp.jsonをコミットする方法が向き、--mcp-configは検証やスクリプト実行向きです。不正なエントリがCIで黙ってスキップされるのを検知する方法はplugin_errorsとmcp_server_errorsをCIの失敗条件にするにあります。
どの場面でどちらを使うか
場面ごとの選び方
一時的にサーバーを足したい
--mcp-configのみ。既存の.mcp.jsonやユーザースコープを残したまま拡張できます。CI・バッチで構成を固定したい
--mcp-configと--strict-mcp-configの併用。プロジェクトやユーザーの設定に左右されず、毎回同じサーバー構成で動きます。バックグラウンドで承認待ちを避けたい
併用します。v2.1.246以降は、承認待ちで止まる不具合が解消されています。
Clineなど他のクライアント向けに書かれたmcpServersブロックは、claude mcp add-jsonで登録する前に--mcp-configで一度読み込めます。恒久的に移行する手順はClineからClaude CodeへMCP設定を移行する手順にあります。
--mcp-configでサーバーを一時的に追加する
--mcp-configにはJSONファイルのパスを渡します。中身は.mcp.jsonと同じmcpServers形式です。
{
"mcpServers": {
"weather-api": {
"type": "http",
"url": "https://api.weather.com/mcp"
},
"local-tool": {
"type": "stdio",
"command": "/path/to/tool-cli",
"args": ["--mode", "readonly"]
}
}
}claude --mcp-config ./mcp-servers.jsonファイルはスペース区切りで複数渡せ、それぞれのmcpServers定義が追加読み込みされます。複数ファイルに同じ名前のサーバーを書いたときの優先順位は、CLIリファレンスにもMCPのページにも書かれていません。衝突を避けるなら1つのJSONにまとめます。なおmanagedMcpServersで配布された同名のサーバーは、--mcp-configで渡した側がその実行に限って置き換えると、managed MCPのページに書かれています。
環境変数の${VAR}展開が公式ドキュメントに載っているのは.mcp.jsonの節で、--mcp-configのJSONで同じ展開が効くかはそこには書かれていません。CIで認証情報付きのサーバーを渡すなら、トークンを直書きせず、実行前にシェルで値を埋めたJSONを生成してから渡す形が確実です。
-p実行で読み込みの失敗を検知する
-p(--print)と組み合わせた非対話実行では、Claude Codeは接続待ちのサーバーが揃うまで最初のターンを待ちます。上限はMCP_TIMEOUT環境変数で、既定は30秒です。ツールリストがキャッシュ済みのサーバーは待機を飛ばし、最初にそのツールを呼ぶ時点で接続します(待機はv2.1.221以降)。
厄介なのは、設定の検証に失敗したエントリが黙ってスキップされ、実行は正常終了する点です。たとえばurlがあってtypeがないエントリは、stdioサーバーとして読まれるため設定エラー扱いになります。CIでは次の手順で、サーバーが読み込まれたかをジョブの成否に反映できます。
CIでMCPの読み込みを検証する
- 1
JSONを用意する
typeを明記したmcpServersのJSONを書きます。urlのエントリには"type": "http"などが必要です。 - 2
stream-jsonで実行する
claude -p "..." --mcp-config ./mcp-servers.json --output-format stream-json --verboseのように実行します。 - 3
initイベントを見る
最初の
system/initイベントのmcp_serversに各サーバーのnameとstatusが、mcp_server_errorsにスキップされたエントリのname・type・messageが入ります。後者はエラーがないとキーごと省かれるので、空でない配列を失敗条件にできます(v2.1.219以降)。
端末で手動実行する場合は、スキップしたエントリがWarning: 1 MCP server skipped due to invalid config:という警告で標準エラーに出ます。stderrをリダイレクトしたりCIランナーが取り込んだりすると警告は出ず、mcp_server_errorsだけが手がかりになります。
--strict-mcp-configで既存設定を無視して起動する
claude --strict-mcp-config --mcp-config ./mcp-servers.json./mcp-servers.jsonに書いたサーバー以外は読み込まれません。.mcp.jsonのプロジェクトスコープも、ユーザースコープの~/.claude.jsonも対象外です。
主な出番は、対話プロンプトを出せないセッションです。claude -p、Agent SDK、クラウドセッションでは、.mcp.jsonのプロジェクトスコープのサーバーを承認の確認なしで読み込みます。bypassPermissionsモードで起動し、ユーザー設定か管理設定にskipDangerousModePermissionPromptがある場合も、このプロンプトは省かれます。これを避けて「指定したサーバーだけ」にする手段は3つあります。
| 手段 | 効く範囲 | 向く場面 |
|---|---|---|
disabledMcpjsonServersに登録 | 効く範囲特定のサーバー。すべての権限モードで遮断 | 向く場面特定のサーバーを恒久的に封じる |
--setting-sources(user・project・localをコンマ区切り) | 効く範囲指定外のスコープの設定ファイル | 向く場面プロジェクト設定だけ外すなど、スコープ単位の除外 |
--strict-mcp-config | 効く範囲--mcp-config以外のMCP設定すべて | 向く場面その実行だけ構成を固定する |
v2.1.274では、空の--mcp-configと--strict-mcp-configを組み合わせたとき、無関係なMCPサーバーのせいで非対話の最初のターンがMCP_TIMEOUTまで止まる不具合も修正されています。
他の「MCPを切る」フラグとの違い
claude --helpには、MCPに触れるフラグがほかにもあります。--strict-mcp-configは「MCP設定の供給元を--mcp-configに限る」だけで、MCP以外には何も触りません。
--bare: フックやCLAUDE.mdなどの自動読み込みを切り、MCPは--mcp-configなどコマンドラインで渡したものだけが接続します。対話セッションでこの挙動になるのはv2.1.286以降で、それ以前の対話の--bareは通常のセッションと同じMCPサーバーに接続していました。--safe-mode: MCPサーバーを含むカスタマイズをまとめて無効にするトラブルシュート用のモードです。認証・モデル選択・組み込みツール・権限は通常どおり動きます。--restricted: ユーザー・プロジェクト・ローカルの設定ファイルを無視しますが、MCPは対象外です。ヘルプには「MCPサーバーも飛ばすには--strict-mcp-configを足す」とあります。
読み込むサーバーを絞ると、コンテキストに載るツール定義も減ります。サーバーが増えるほどツール定義がコンテキストを圧迫する仕組みはMCPのツール定義はなぜコンテキストを圧迫するのかで扱っています。
managed-mcp.jsonがある環境では両方の挙動が変わる
managed-mcp.jsonは組織がMCPサーバーを排他的に管理するためのファイルです。配置された端末で読み込まれるのは、このファイルのサーバー、managedMcpServersで配布されたサーバー、アプリが登録するインプロセスのサーバー(VS Code拡張自身のサーバーやデスクトップアプリのコネクタなど)、許可された場合の組み込みClaude in Chromeサーバーです。プラグイン提供のサーバーや--mcp-configで渡すサーバーも使えません。この動作は、Claude Codeが読めて解釈できるmanaged-mcp.jsonが配備されているときのものです。
| 実行環境 | --mcp-configを渡した場合 | --strict-mcp-configを渡した場合 |
|---|---|---|
| 通常のワークステーション | --mcp-configを渡した場合起動時にエラーで終了する | --strict-mcp-configを渡した場合起動時にエラーで終了する |
| セルフホストランナー上のクラウドセッション | --mcp-configを渡した場合managed setのサーバーだけで起動し、--mcp-configで渡したサーバーやclaude.aiコネクタはスキップされる | --strict-mcp-configを渡した場合起動時にエラーで終了する |
ワークステーションではYou cannot dynamically configure MCP servers when an enterprise MCP config is presentと表示して終了します。クラウドセッションでは終了せず、除外されたサーバー名は標準エラーへの警告として出るだけで、セッション内には表示されません。セルフホストランナーではdebugログレベルで記録されます。
--strict-mcp-configは「managed setを置き換えたい」という要求にあたるため、ワークステーションでもクラウドセッションでも常に起動時に終了します。managed-mcp.jsonのない環境でも、--strict-mcp-configはallowedMcpServersとdeniedMcpServersの許可・拒否リストを回避しません。リストは--mcp-configで渡したサーバーにも効きます。ただしtype: "sdk"のインプロセス項目は対象外で、リストを迂回する手段としては使えません。
よくあるつまずき
- JSON文字列を直接渡して崩れる: シェルのクォート処理でエスケープが崩れることがあります。複雑な設定はファイルに書いてパスを渡します。
- 予約済みの名前を使って読み込まれない:
workspace・claude-in-chrome・computer-use・Claude Preview・Claude Browserは組み込みサーバー用に予約されており、同名の定義は読み込み時にスキップされて警告が出ます。stream-jsonではmcp_server_errorsのtypeがreserved_nameになります。読み込み状況はセッション内の/mcpか、stream-jsonのmcp_server_errorsで見られます。 urlだけでtypeがない:MCP server "<name>" has a "url" but no "type"; add "type": "http" (or "sse" / "ws") to this entryという設定エラーでスキップされます。v2.1.202より前はcommand: expected string, received undefinedと報告されていました。- Claude Desktopの設定と混同する:
--mcp-configはCLIの起動フラグで、Claude Desktopのclaude_desktop_config.jsonとは別の仕組みです。Desktop側はClaude Desktop MCP設定ガイドを参照してください。
まとめ
CIでは、サーバーが読み込まれたかをmcp_server_errorsで検査する工程を入れておくと、黙ってスキップされた設定に気づけます。managed-mcp.jsonが配布された端末では両フラグとも起動時エラーになるので、その前提でジョブを設計します。