Managed MCPで許可リスト・拒否リストを組織管理する
Managed MCPはmanaged-mcp.jsonの固定配布、managedMcpServersの提供、許可・拒否リストの3系統で組織のMCPを絞ります。評価順序と落とし穴を示します。
Managed MCPで組織のMCP利用をどこまで絞れるか
Claude Codeは既定では、ユーザーが任意のMCPサーバーを自由に接続できます。Anthropicはディレクトリに載せる前にコネクタを掲載基準で審査しますが、個々のMCPサーバーそのものをセキュリティ監査したり運用管理したりはしません。社内の誰かがclaude mcp addで怪しいサーバーを追加しても、Claude Code自体はそれを止めません。接続前の評価は組織側の仕事で、MCP自体の脅威モデルはMCPセキュリティガイドにあります。
Managed MCPは、この状態を管理者の意図した範囲に絞る仕組みです。使う部品は3つあります。
Managed MCPの3つの部品
managed-mcp.json
固定のサーバーセットだけを配り、他は追加させません。ファイルを端末のシステムパスに置く方式です。
managedMcpServers
組織のリモートサーバーを全員に配りつつ、ユーザー自身のサーバーも残します。v2.1.259以降です。
allowedMcpServers / deniedMcpServers
ユーザー・プラグインなどが追加済みのサーバーを、許可・拒否リストでふるいにかけます。
導入前に決めること — 目的から選ぶ8つのパターン
どこまで絞るかは組織のポリシー次第です。公式ドキュメントは次の8パターンを挙げています。
| パターン | できること | 設定 |
|---|---|---|
| MCP全面無効化 | できること例外を除き、一切ロードしない | 設定managed-mcp.jsonを空のサーバーマップで配置 |
| 固定配布 | できること全員が同じサーバーセットを使い、自分では追加できない | 設定managed-mcp.jsonにサーバーを列挙 |
| 提供サーバー | できること組織のリモートサーバーを配り、ユーザーは自分のものも使える | 設定管理設定のmanagedMcpServers |
| 承認カタログ | できること承認済みリストを公開し、ユーザーはその中から選んで追加 | 設定allowedMcpServers + allowManagedMcpServersOnly: true |
| プラグイン経由のみ | できること~/.claude.jsonや.mcp.jsonからの追加を止め、プラグインのサーバーは通す | 設定strictPluginOnlyCustomizationにmcpを含める |
| ソフト許可リスト | できること許可リストを敷くが、ユーザー自身の設定で広げられる | 設定allowManagedMcpServersOnlyなしのallowedMcpServers |
| 拒否リストのみ | できること既知の危険なサーバーだけ止め、他は自由 | 設定deniedMcpServers |
| 制限なし | できることユーザーが何でも追加できる(既定) | 設定Managed MCP設定を配置しない |
承認カタログを選ぶ場合、Claude Codeにはユーザーがブラウズして選べるMCPサーバーレジストリはありません。承認リストとclaude mcp addコマンドを社内wikiで共有するか、マネージドプラグインマーケットプレイス経由でプラグインとして配布し、/pluginから選ばせる形にします。
配布経路は2系統に分かれる
どの設定をどこから配るかを混同すると手戻りになります。
どの設定をどこから配るか
managed-mcp.json
スタンドアロンファイルなので、サーバー管理設定からは配れません。MDM・GPO・フリート管理ツールなど、システムパスに書き込める管理者権限のあるプロセスで置きます。
管理設定のキー
次の5つはサーバー管理設定からも配れます。managedMcpServers、allowedMcpServers、deniedMcpServers、allowManagedMcpServersOnly、allowAllClaudeAiMcpsです。
サーバー管理設定はClaude for TeamsとClaude for Enterpriseで使えます。配信にはTeams / EnterpriseのOAuthログイン、CLAUDE_CODE_OAUTH_TOKENのOAuthトークン、直接設定したAPIキーなどの認証が必要です。
固定セットだけ使わせる — managed-mcp.json
managed-mcp.jsonを配置すると、Claude Codeが読み込むのは次の4種類だけになります。
- ファイルが定義したサーバー
managedMcpServersで提供したサーバー- セッションを起動したアプリが登録するプロセス内サーバー(VS Code拡張の内蔵サーバー、デスクトップアプリが届けるコネクタなど)
- 許可設定を入れた場合の、内蔵のClaude in Chromeサーバー
プラグイン提供のサーバーや--mcp-configフラグで渡されたサーバーを含め、それ以外をユーザーは追加・変更・使用できません。claude.aiコネクタも、後述のallowAllClaudeAiMcpsを有効にしない限り抑制されます。
配置先は3プラットフォームで固定です。
| プラットフォーム | パス |
|---|---|
| macOS | パス/Library/Application Support/ClaudeCode/managed-mcp.json |
| Linux / WSL | パス/etc/claude-code/managed-mcp.json |
| Windows | パスC:\Program Files\ClaudeCode\managed-mcp.json |
ファイルの書式はプロジェクトの.mcp.jsonと同じです。
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/"
},
"sentry": {
"type": "http",
"url": "https://mcp.sentry.dev/mcp"
},
"company-internal": {
"type": "stdio",
"command": "/usr/local/bin/company-mcp-server",
"args": ["--config", "/etc/company/mcp-config.json"],
"env": {
"COMPANY_API_URL": "https://internal.example.com"
}
}
}
}このファイルはマシン上の誰でも読めます。envブロックにAPIキーなどの認証情報を直書きしないでください。個人ごとの資格情報が必要なら、${VAR}展開で各ユーザーの環境変数から読ませる・OAuthやユーザーごとのヘッダーで本人として認証させる・headersHelperで接続時に動的生成する、のいずれかで渡します。
配置後はclaude mcp listで確認します。
claude mcp listmanaged-mcp.jsonのサーバー(とmanagedMcpServersで配ったサーバー)だけが表示されれば反映されています。結果が違うときの読み方は2通りです。
- ユーザー自身のサーバーが見える: ファイルを読めていません。パスと親ディレクトリの権限を疑います
- 配ったサーバーが出ず、出力の
MCP config diagnostics欄に解析失敗と出る: ファイルが読めないか壊れています。欄が示すエラーを直し、ユーザーにClaude Codeを再起動してもらいます
claude mcp listとclaude mcp getは、承認済みのサーバーにヘルスチェックの接続をします。claude mcp list --help(v2.1.287)にも、こうあります。「approved servers are health-checked unless disabled for this project」。試すとサーバーへ実際にアクセスが飛びます。次の追加テストは、ポリシーが効いていれば接続の前に拒否されます。
claude mcp add --transport http test https://example.com/mcp排他制御が効いていれば、後述のメッセージ表の1行目のエラーで失敗します。URLは実在しなくても、ポリシーチェックが接続前にコマンドを拒否するのでこのテストで十分です。
MCPを全面的に無効にするなら、空のサーバーマップを配置します。
{
"mcpServers": {}
}claude mcp addは同じエンタープライズポリシーエラーで失敗し、ユーザーが以前設定していたサーバーは次回セッション開始時から警告なく読み込まれなくなります。ただしmanagedMcpServersで提供したサーバーや、アプリが登録するプロセス内サーバーは空のマップでも読み込まれます。完全に止めたいならmanagedMcpServersなどのキーも未設定にします。
--mcp-configとクラウドセッション
ワークステーションで--mcp-config付きに起動すると、メッセージ表の2行目の文言で終了します。claude mcp addのエラーとは別の文言です。
クラウドセッションはclaude.aiコネクタなどをサーバー側から--mcp-configで受け取ります。ファイルを配置したホストでは、v2.1.229以降は管理対象サーバーだけで起動を続け、除外されたサーバーはstderrの警告に出ます(セルフホストランナーではdebugログレベルで記録)。セッション内にはどのサーバーが外れたかの表示が出ません。v2.1.229より前は、起動時に終了していました。
--strict-mcp-configは管理対象セットの置き換えを要求する操作なので、ファイルが配置されていると、ワークステーションでもクラウドセッションでも起動時に終了します。
claude.aiコネクタとClaude in Chrome
claude.aiコネクタを管理対象セットと併用したいときは、allowAllClaudeAiMcps: trueを管理設定ソースに置きます(v2.1.149以降)。効くのはClaude Code自身が取得するコネクタだけです。クラウドセッションがサーバー側から--mcp-configで受け取るコネクタは、ファイルがあるホストでは常に抑制されます。この設定はサーバー管理設定・MDM配布のplistやレジストリ・システムのmanaged-settings.jsonからしか読まれず、ユーザー設定やプロジェクト設定では効きません。拒否リストはコネクタにも効くので、一部だけ止めることもできます。
組み込みのClaude in Chromeサーバーも、ファイルを置くとターミナルのセッションで既定でブロックされます。ブラウザ拡張のインストール案内は出ず、Chromeを既定で有効にしているセッションは警告なしにChromeなしで起動します。claude --chromeかCLAUDE_CODE_ENABLE_CFC=1で明示的に起動した場合は、設定名を挙げたエラーで終了します。許可するには、端末側の管理設定にallowClaudeInChromeWithManagedMcp: trueを書きます(v2.1.282以降)。置き場所はMDMのplist、HKLMレジストリ、システムのmanaged-settings.jsonのいずれかです。サーバー管理設定やHKCUに書いても無視されます。claude-in-chromeを拒否リストに入れれば、設定が有効でもブロックされます。
自分のサーバーも残して配る — managedMcpServers
排他制御にせず、組織のサーバーを全員に追加で届けたいときは、管理設定にmanagedMcpServersを書きます(v2.1.259以降。古いクライアントはキーを無視します)。HTTPまたはSSEのリモートサーバーだけが対象です。
{
"managedMcpServers": {
"search": {
"type": "http",
"url": "https://search.example.com/mcp"
},
"records": {
"type": "http",
"url": "https://records.example.com/mcp",
"headers": {
"X-Records-Key": "key-issued-for-all-claude-code-users"
}
}
}
}管理設定を読める人は、ユーザー本人も含めてヘッダーの値を読めます。全員向けに発行した資格情報だけを置くか、headersを省いてOAuthでサインインさせます。
エントリは次の条件を全部満たしたときだけ読み込まれます。1つでも外れたエントリは捨てられ、/statusに通知が残り、他のエントリは読み込まれます。
typeがhttpかsse(streamable-httpはhttpの別名として通る)urlがhttps://で始まる。localhost向けでもhttp://は拒否されるcommand・args・env・headersHelperを持たない。管理設定が利用者の端末で実行するプログラムを指名しないため- どの値にも
${VAR}参照がない。このキーでは環境変数が展開されないので、値は直書きにする - サーバー名が英数字・ハイフン・アンダースコアだけで、制御文字や不可視の書式文字がない
Claude Desktopにも同名の管理設定がありますが、値は別の形の配列です。Claude Codeは配列形式を受け付けず、通知だけ残して読み込みません。
読み込みの優先関係は次のとおりです。
- 同名なら、ローカル・プロジェクト・ユーザーのサーバー、および同じURLを指すプラグインやclaude.aiコネクタより優先される
managed-mcp.jsonも置くと両方が読み込まれ、同名ならファイルのエントリが勝つstrictPluginOnlyCustomizationでmcpをロックしても読み込まれ続けるallowedMcpServersのエントリは不要。deniedMcpServersは効くので、ユーザーは自分の設定で提供サーバーをブロックできる
ユーザー側の見え方にも特徴があります。claude mcp removeは「組織が提供しているので削除できない」と返します。managed-mcp.jsonを置いていなければ、同名で自分が追加したエントリは保存されても使われません。/mcpのManaged MCPs欄から、自分だけ無効にすることはできます。claude mcp getと/mcpはURLをホスト名までしか表示せず、ヘッダーは名前だけを出します。
サーバー管理設定経由で届けると、タイミングに注意点があります。キャッシュ済みの端末では、サーバーが設定を確認するまでキャッシュ済みのこのキーを保留し、確認後にMCPサーバーを読み込みます。MCPサーバーに接続する前に、この確認を最大30秒待ちます。確認に失敗するとセッションは提供サーバーなしで続き、/statusが保留を知らせます。初回起動でキャッシュがない端末では、設定の到着前に始まった対話セッションは到着後に接続しますが、すでに動き出したclaude -pは提供サーバーなしで終わることがあります。実行中の対話セッションでは、追加は再起動なしで接続され、変更は再接続され、削除は設定を読んだ時点で切断されます。-pの実行は終了まで残します。
許可・拒否リストを書く
許可リストと拒否リストでふるいにかける
managed-mcp.jsonとmanagedMcpServersが「これを配る」仕組みなのに対し、許可リストと拒否リストは「既に設定されたサーバーのうち何を通すか」を絞ります。サーバーはユーザー・プラグイン・組織のいずれかが追加した後でなければ対象になりません。--strict-mcp-configを付けても、どちらのリストも迂回できません。
各エントリはURL・コマンド・名前のいずれか1つのキーを持つオブジェクトです。
| キー | 照合対象 | 向いている用途 |
|---|---|---|
serverUrl | 照合対象リモートサーバーのURL(完全一致または*ワイルドカード) | 向いている用途HTTP・SSEサーバー |
serverCommand | 照合対象stdioサーバーを起動する正確なコマンドと引数 | 向いている用途stdioサーバー |
serverName | 照合対象ユーザーが付けたラベル(完全一致のみ、ワイルドカード不可) | 向いている用途補助的に。下記の注意を参照 |
serverNameはセキュリティ制御になりません。名前はclaude mcp addを実行した本人やプラグイン設定側が自由に付けるラベルであり、実体のサーバーを指すものではないため、誰でも自分のサーバーにgithubと名付けられます。claude.aiコネクタの場合、名前はclaude.ai側が返す表示名で変わることもあります。実際に動くサーバーを確実に絞りたいならserverCommandかserverUrlを使います。
serverNameの扱いは許可リストと拒否リストで違います。拒否リストでは前後に空白のない任意の空でない文字列を受け付けるので、{ "serverName": "claude.ai Slack" }のようにclaude.aiコネクタを表示名でブロックできます。ただし同名が衝突すると (N)の接尾辞が付くので、serverUrlを優先します。許可リストのserverNameは英数字・ハイフン・アンダースコアに限られ、claude.aiコネクタを許可リストに載せるならserverUrlを使う必要があります。
allowedMcpServersは「未設定」と「空配列」で意味が異なります。
| 設定 | 未設定(既定) | 空配列[] | 値あり |
|---|---|---|---|
allowedMcpServers | 未設定(既定)全サーバーを許可 | 空配列[]許可リスト検査を免れるもの以外すべて拒否 | 値あり一致したサーバーのみ許可(免除対象を除く) |
deniedMcpServers | 未設定(既定)ブロックなし | 空配列[]ブロックなし | 値あり一致したサーバーをブロック |
許可リストを唯一の正としたい場合は、allowedMcpServersとallowManagedMcpServersOnly: trueを同時に設定します。置き場所は管理設定ソース(サーバー管理設定や配置済みのmanaged-settings.json)です。
{
"allowManagedMcpServersOnly": true,
"allowedMcpServers": [
{ "serverUrl": "https://api.githubcopilot.com/*" },
{ "serverUrl": "https://*.internal.example.com/*" }
]
}これを付けないと、ユーザー自身の~/.claude/settings.jsonにある許可リストもマージされ、管理者の意図より広い範囲を通してしまいます。拒否リストはこの設定に関わらず、常にすべてのソースからマージされます。allowManagedMcpServersOnlyは権限ルールを固定するallowManagedPermissionRulesOnlyとは別物で、後者を設定してもMCPの許可リストは強制されません。
管理ソースが複数あるときは、ロックが入っていれば最上位の管理ソースの許可リストが丸ごと採用され、下位ソースの項目とは混ざりません。拒否リストはどの管理ソースのものも合流します。この読み方はv2.1.273以降です。ロックがない場合は、適用された管理ソースのallowedMcpServersだけが読まれ、既定の"first-wins"では選ばれなかった管理ソースのリストは無視されます。managedSourcesBehaviorを"merge"にするとmanagedMcpServersは全管理ソースから提供され、同名なら上位ソースのエントリが丸ごと適用されます。
評価順序 — 拒否リストが常に勝つ
ロードの前に3段階のチェックが順番に走ります。ユーザーが/mcpでサーバーを再接続したり、無効にしていたサーバーを戻したりするたびに、同じチェックがもう一度走ります。
サーバーがロードされるまでの3段階
- 1
リストを合流させる
全設定ソースの許可・拒否リストを、許可リスト1つと拒否リスト1つにまとめます。
allowManagedMcpServersOnlyが有効なら管理対象の許可リストだけが残ります。 - 2
拒否リストを確認する
URL・コマンド・名前のいずれかで一致したサーバーはブロックされます。これを上書きする設定はありません。
- 3
許可リストを確認する
allowedMcpServersがどこにもなければ、拒否を通過した全サーバーがロードされます。あれば、サーバー種別ごとの一致条件を満たす必要があります。ただし組織自身のサーバーなど、このチェックを免れるグループがあります(v2.1.259の節)。
種別ごとの一致条件
| サーバー種別 | 許可される条件 |
|---|---|
| リモート(HTTP/SSE) | 許可される条件serverUrlエントリに一致。許可リストにserverUrlエントリが1つもないときだけserverName一致でも通る |
| stdio | 許可される条件serverCommandエントリに一致。許可リストにserverCommandエントリが1つもないときだけserverName一致でも通る |
この規則は種別ごとに独立に働くので、名前とコマンドを混ぜた許可リストは意外な結果になります。serverName: "github"とserverCommand: ["npx", "-y", "approved-package"]を並べた許可リストでは、次のように振り分けられます。
| サーバー | 結果 |
|---|---|
githubという名前のHTTPサーバー | 結果通る(serverUrlエントリがないので名前一致が効く) |
other-apiという名前のHTTPサーバー | 結果通らない(名前が違う) |
["npx", "-y", "approved-package"]で起動するstdio | 結果通る(コマンド一致) |
githubという名前で["node", "server.js"]のstdio | 結果通らない(コマンドエントリがあるので名前は効かない) |
マッチの細則は3つあります。
- コマンドは引数まで順序どおり完全一致で照合されます。
["npx", "-y", "server"]は["npx", "server"]にも["npx", "-y", "server", "--flag"]にも一致しません - URLの
*ワイルドカードはスキームを含めどこにでも書けます。ホスト名は大文字小文字を区別せず末尾のドットも無視しますが、パス部分は区別します。パスのないパターンは任意のパスに一致します serverCommandとserverUrlは、ポリシー側と設定側の両方で${VAR}と${VAR:-default}が展開されてから照合されます。Windowsでは${HOME}でなく${USERPROFILE}のように、そこで設定された変数を使います。serverNameは展開されません
| パターン | 許可する範囲 |
|---|---|
https://mcp.example.com/* | 許可する範囲特定ドメインの全パス |
https://*.example.com/* | 許可する範囲example.comの任意のサブドメイン |
http://localhost:*/* | 許可する範囲localhostの任意のポート |
*://mcp.example.com/* | 許可する範囲任意のスキームで特定ドメイン |
ポリシー側のエントリは、固定された環境から展開されます。プロジェクトやユーザーの設定ファイルが置いた変数で、許可リストのエントリの意味が変わらないようにするためです。許可リストのURLエントリは、展開によってスキーム・ホスト・パスの範囲が変わる場合、エントリごと無視されます。拒否リストは一致のまま残ります。展開の結果は起動したシェルの環境にも左右されるので、強制に頼るエントリはURLもコマンドも直書きにします(v2.1.219以降)。
次の設定は、リモート・stdioの両方に許可リストの起点を作り、危険な名前のサーバーだけ拒否リストで確実に止める例です。
{
"allowedMcpServers": [
{ "serverUrl": "https://api.githubcopilot.com/*" },
{ "serverCommand": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."] }
],
"deniedMcpServers": [
{ "serverName": "dangerous-server" },
{ "serverUrl": "https://*.untrusted.example.com/*" }
]
}この例に名前だけの許可エントリを足しても、何にも一致しません。
手元で確かめる — ユーザー設定の許可・拒否リスト
許可・拒否リストはユーザー設定にも書けます。allowManagedMcpServersOnlyを付けないソフト許可リストの動きは、手元で再現できます。空の一時ディレクトリをHOMEとCLAUDE_CONFIG_DIRに指定すれば、自分の環境に触れません。ユーザー設定のsettings.jsonには次の内容を置きました。
{
"allowedMcpServers": [
{ "serverUrl": "https://api.githubcopilot.com/*" }
],
"deniedMcpServers": [
{ "serverUrl": "https://*.untrusted.example.com/*" }
]
}この設定のままv2.1.287でclaude mcp addを実行した結果です。ポリシーチェックは接続の前に走るので、実在しないURLでも判定が出ます。
claude mcp add --transport http bad https://x.untrusted.example.com/mcp
# Cannot add MCP server "bad": server is explicitly blocked by enterprise policy
claude mcp add --transport http other https://example.com/mcp
# Cannot add MCP server "other": not allowed by enterprise policy
claude mcp add --transport http gh https://api.githubcopilot.com/mcp/
# Added HTTP MCP server gh with URL: https://api.githubcopilot.com/mcp to local config
# (この後に設定ファイルの書き込み先が出ますが、ここでは省略)管理設定を1つも置かなくても、ユーザー自身の許可・拒否リストはこのように効きます。許可リストに載るURLだけが追加でき、拒否リストに一致したURLはnot allowedではなくexplicitly blockedという別の文言で止まります。
v2.1.259へ上げる前の確認 — 許可リストの免除対象
許可リストの検査(評価順序の3段目)を素通りするグループがあります。
- 組織自身のサーバー: すべての
managedMcpServersエントリと、${VAR}展開を使わないmanaged-mcp.jsonのエントリ - 内蔵サーバー: Claude in Chrome、起動中のVS CodeやJetBrains IDEにつなぐ
ideサーバー、CLI自身が設定するサーバー - Claude TagセッションのSlackツール(スレッドの読み取りと返信に使うサーバー)
逆に検査を受けるのは、次のサーバーです。
${VAR}展開をコマンド・引数・env・URL・ヘッダーのどこかに使うmanaged-mcp.jsonのサーバー- ユーザー・プラグイン・claude.aiが追加したサーバー
--mcp-configで渡されたサーバー
環境変数の中身は利用者ごとに違い、ファイルだけでは実体が決まらないからです。
この扱いはv2.1.259で変わりました。それ以前は、許可リストがあればmanaged-mcp.jsonのサーバーもすべて通過が必要でした。許可リストで自前のサーバーの一部を読み込ませないようにしていた組織では、利用者がv2.1.259以降で最初に起動した時点で、${VAR}展開のないサーバーが通知なしに読み込まれ始めます。以降も引き算できるのはdeniedMcpServersだけです。アップグレード前に、止めたいサーバーを拒否リストへ移すか、グループごとに別のmanaged-mcp.jsonを配ります。
ロールアウト後の問い合わせ対応
利用者に見えるメッセージ
ロールアウト前に、利用者が目にする文言を把握しておくと問い合わせに答えやすくなります。
| 状況 | 利用者に見えるもの |
|---|---|
managed-mcp.jsonがあり、claude mcp addを実行 | 利用者に見えるものCannot add MCP server: enterprise MCP configuration is active and has exclusive control over MCP servers |
managed-mcp.jsonがあり、--mcp-config付きで起動(ワークステーション) | 利用者に見えるものYou cannot dynamically configure MCP servers when an enterprise MCP config is presentで終了 |
managed-mcp.jsonがあり、claude --chromeを実行 | 利用者に見えるものClaude in Chrome is blocked by your organization's managed MCP configuration (managed-mcp.json). An administrator can allow it with allowClaudeInChromeWithManagedMcp in device policy.で終了 |
拒否リストに載るサーバーをclaude mcp add | 利用者に見えるものCannot add MCP server "<name>": server is explicitly blocked by enterprise policy |
許可リストにないサーバーをclaude mcp add | 利用者に見えるものCannot add MCP server "<name>": not allowed by enterprise policy |
strictPluginOnlyCustomizationがtrueかmcpを含む状態でclaude mcp add | 利用者に見えるものCannot add MCP server: your organization's managed settings allow only MCP servers that plugins provide. Install a plugin that provides this server, or ask your administrator to make it available. |
managedMcpServersのサーバーをclaude mcp remove | 利用者に見えるものMCP server "<name>" is provided by your organization (managed settings) and cannot be removed locally. |
実行中にブロック対象になったサーバーを、/mcpで再接続・再有効化 | 利用者に見えるものMCP server <name> is blocked by enterprise managed policy |
| 設定済みだったサーバーが新しいポリシーでブロックされる | 利用者に見えるもの/mcpとclaude mcp listから、警告なしに消える |
最後の行が最も問い合わせにつながります。追加時にはエラーが出るのに、すでに設定済みのサーバーは何も言わずに消えるからです。影響を受けるユーザーに、どのサーバーが対象になるかを先に伝えておくと問い合わせを減らせます。
設定の不備はどう見えるか
- 不正な値の扱いが項目ごとに違う:
allowedMcpServersに無効な値があると、直るまで空の許可リストとして扱われ、ユーザーが追加するサーバーが全部通らなくなります。managedMcpServersの提供サーバーは読み込まれ、managed-mcp.jsonはv2.1.259の節の規則で扱われます。個々の不正エントリは取り除かれ、残りが強制されます。deniedMcpServersは個々の不正エントリだけ取り除き、値全体が不正なら警告付きで無視します(全拒否にすると、ポリシーが名指ししていないサーバーまで止まるため)。claude doctorで、取り除かれたエントリを出所とフィールド付きで確認できます。 - ファイルが読めないとき: 読み取りや解析に失敗した
managed-mcp.jsonは無視されず、排他制御を維持してユーザー・プロジェクト・プラグインのサーバーを読み込まないまま起動時に警告します(v2.1.271の修正)。
強制の範囲
サーバー管理設定はクライアント側の制御で、セキュリティ境界ではありません。管理外の端末では管理者権限なしに回避でき、CLAUDE_CODE_USE_BEDROCKやANTHROPIC_BASE_URLの変更など、サードパーティのモデルプロバイダーを設定した場合も届きません。MDMで端末を管理していない組織では、この前提で運用を設計します。起動時のフラグによる迂回を塞ぎたいならdisableSideloadFlagsを併用できます。
使われ方を把握する
OpenTelemetryのエクスポートを設定していれば、Claude Codeはユーザーがどのサーバー・ツールを呼び出したか記録できます。OTEL_LOG_TOOL_DETAILS=1を設定してツールイベントにMCPサーバー名とツール名を含め、コレクター側で集計すると、実際にどのサーバーが使われているかが見えてきます。承認カタログのように「使っていいものを配る」パターンでも、実測がないと過不足の判断がつきません。
まとめ
組織のサーバーを足したいだけなら、managedMcpServersは既存のサーバーを消さないので、無言で消える問い合わせを生みません。消える側に回るのはmanaged-mcp.json・許可リスト・拒否リストで、どれを選ぶかで事前に告知する範囲が決まります。権限ルールを管理設定に固定する話は権限と設定の完全ガイドにあります。