Managed MCPで許可リスト・拒否リストを組織管理する
Managed MCPはmanaged-mcp.jsonの固定配布と許可リスト・拒否リストの2系統で、組織が使えるMCPサーバーを絞り込みます。評価順序と設定の落とし穴をまとめました。
Managed MCPで組織のMCP利用をどこまで絞れるか
Claude Codeは既定では、ユーザーが任意のMCPサーバーを自由に接続できます。Anthropicはディレクトリに載せる前にコネクタを掲載基準で審査しますが、個々のMCPサーバーそのものをセキュリティ監査したり運用管理したりはしません。つまり社内の誰かがclaude mcp addで怪しいサーバーを追加しても、Claude Code自体はそれを止めません。
Managed MCPは、この状態を管理者の意図した範囲に絞り込むための仕組みです。固定のサーバーセットだけを配布するmanaged-mcp.jsonと、ユーザーが追加したサーバーを許可・拒否リストでフィルタするallowedMcpServers/deniedMcpServersの2系統があり、MCPを全面無効化することもできます。
パターンで選ぶ — 7段階の絞り込み
どこまで絞るかは組織のポリシー次第です。公式ドキュメントは次の7パターンを挙げています。
| パターン | できること | 設定 |
|---|---|---|
| MCP全面無効化 | できることVS Code拡張の内蔵サーバー以外、一切ロードしない | 設定managed-mcp.jsonを空のサーバーマップで配置 |
| 固定配布 | できること全員が同じサーバーセットを使い、自分では追加できない | 設定managed-mcp.jsonにサーバーを列挙 |
| 承認カタログ | できること承認済みリストを公開し、ユーザーはその中から選んで追加 | 設定allowedMcpServers + allowManagedMcpServersOnly: true |
| プラグイン経由のみ | できることプラグインが提供するサーバーだけ許可 | 設定strictPluginOnlyCustomizationにmcpを含める |
| ソフト許可リスト | できること許可リストを敷くが、ユーザー自身の設定で広げられる | 設定allowManagedMcpServersOnlyなしのallowedMcpServers |
| 拒否リストのみ | できること既知の危険なサーバーだけ止め、他は自由 | 設定deniedMcpServers |
| 制限なし | できることユーザーが何でも追加できる(既定) | 設定Managed MCP設定を配置しない |
承認カタログを選ぶ場合、Claude Codeにはユーザーがブラウズして選べるMCPサーバーレジストリはありません。承認リストとclaude mcp addコマンドを社内wikiで共有するか、マネージドプラグインマーケットプレイス経由でプラグインとして配布し、/pluginから選ばせる形にします。
managed-mcp.jsonで固定セットに絞る(排他制御)
managed-mcp.jsonを配置すると、Claude Codeはそのファイルが定義したサーバーと、VS Code拡張が起動するセッションに限りその拡張自身の内蔵サーバーだけをロードします。ユーザーはプラグイン提供のサーバーや--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で接続時に動的生成する、のいずれかに逃がします。
配置後は2つのコマンドで反映を確認できます。
claude mcp listmanaged-mcp.jsonに列挙したサーバーだけが表示されれば反映されています。ユーザー自身のサーバーがまだ見えるなら、パスか権限を疑います。追加を試みるコマンドはこうなります。
claude mcp add --transport http test https://example.com/mcp排他制御が効いていればCannot add MCP server: enterprise MCP configuration is active and has exclusive control over MCP serversで失敗します。URLは実在しなくても、ポリシーチェックが接続前にコマンドを拒否するのでこのテストで十分です。
MCPを全面無効化したい場合は、空のサーバーマップを配置します。
{
"mcpServers": {}
}claude mcp addは同じエンタープライズポリシーエラーで失敗し、ユーザーが以前設定していたサーバーは次回セッション開始時から警告なく読み込まれなくなります。
ワークステーションとクラウドセッションでは、--mcp-config経由でサーバーが渡されたときの挙動が違います。ワークステーションは起動時に前述のエラーで終了します。クラウドセッションはclaude.aiコネクタなどをサーバー側から--mcp-configで受け取ります。v2.1.229以降は管理対象サーバーだけで起動を続け、除外されたサーバー名はstderrの警告に記録されます(セルフホストランナーではdebugログレベルで記録)。v2.1.229より前は、クラウドセッションもワークステーションと同じエラーで終了していました。
ユーザーが--strict-mcp-configを付けた場合は、管理対象セットの置き換えを要求する操作です。そのためワークステーション・クラウドセッションのどちらでも起動時に終了します。
claude.aiコネクタを管理対象セットと併用したい場合は、allowAllClaudeAiMcps: trueを管理設定ソースに設定します(v2.1.149以降)。この設定はClaude Code自身が取得するコネクタにだけ効きます。クラウドセッションがサーバー側から--mcp-configで受け取るコネクタは、managed-mcp.json配置中は常に抑制されたままです。また、サーバー管理設定・MDM配布のplistやレジストリ・システムのmanaged-settings.jsonのいずれかでしか読み込まれません。そのためユーザー自身の設定でこの抑制を解除することはできません。
allowedMcpServers / deniedMcpServersでポリシー制御する
managed-mcp.jsonが「これだけを配る」仕組みなのに対し、許可リストと拒否リストは「既に設定されたサーバーのうち何を通すか」を絞ります。サーバーはユーザー・プラグイン・managed-mcp.jsonのいずれかが追加した後でなければフィルタの対象になりません。両リストとも--mcp-configフラグで渡されたサーバーにも効き、--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コネクタを表示名でブロックできます。ただし表示名は変わりうるので、リネームに強くしたいならserverUrlを優先します。許可リストのserverNameは英数字・ハイフン・アンダースコアに限られ、claude.aiコネクタを許可リストに載せるならserverUrlを使う必要があります。
allowedMcpServersは「未設定」と「空配列」で意味が異なります。
| 設定 | 未設定(既定) | 空配列[] | 値あり |
|---|---|---|---|
allowedMcpServers | 未設定(既定)全サーバーを許可 | 空配列[]全サーバーを拒否 | 値あり一致したサーバーのみ許可 |
deniedMcpServers | 未設定(既定)ブロックなし | 空配列[]ブロックなし | 値あり一致したサーバーをブロック |
許可リストを唯一の正としたい場合は、管理設定ソース(サーバー管理設定や配置済みのmanaged-settings.json)でallowedMcpServersとallowManagedMcpServersOnly: trueを同時に設定します。これを付けないと、ユーザー自身の~/.claude/settings.jsonにある許可リストもマージされ、管理者の意図より広い範囲を通してしまいます。拒否リストはこの設定に関わらず、常にすべてのソースからマージされます。allowManagedMcpServersOnlyは権限ルールを固定するallowManagedPermissionRulesOnlyとは別物で、後者を設定してもMCPの許可リストは強制されません。
評価順序 — 拒否リストが常に勝つ
managed-mcp.json由来のサーバーを含め、ロード前に3段階のチェックが順番に走ります。
- リストの合流: 全設定ソースの許可・拒否リストを1つの許可リストと1つの拒否リストにまとめます。
allowManagedMcpServersOnlyが有効なら管理対象の許可リストだけが残りますが、拒否リストは常に全ソースから合流します。 - 拒否リストの確認: URL・コマンド・名前のいずれかで拒否リストに一致したサーバーはブロックされます。これを上書きする設定はありません。
- 許可リストの確認:
allowedMcpServersがどこにも設定されていなければ、拒否リストを通過した全サーバーがロードされます。設定されている場合、サーバー種別ごとに一致すべき対象が変わります。
| サーバー種別 | 許可される条件 |
|---|---|
| リモート(HTTP/SSE) | 許可される条件serverUrlエントリに一致。許可リストにserverUrlエントリが1つもないときだけserverName一致でも通る |
| stdio | 許可される条件serverCommandエントリに一致。許可リストにserverCommandエントリが1つもないときだけserverName一致でも通る |
コマンドは引数まで完全一致で照合されるため、["npx", "-y", "server"]は["npx", "server"]にも["npx", "-y", "server", "--flag"]にも一致しません。URLの*ワイルドカードはスキームを含めどこにでも書け、ホスト名は大文字小文字を区別せず末尾のドットも無視しますが、パス部分は大文字小文字を区別します。
| パターン | 許可する範囲 |
|---|---|
https://mcp.example.com/* | 許可する範囲特定ドメインの全パス |
https://*.example.com/* | 許可する範囲example.comの任意のサブドメイン |
http://localhost:*/* | 許可する範囲localhostの任意のポート |
次の設定は、リモート・stdioの両方に許可リストの起点を作り、危険な名前のサーバーだけ拒否リストで確実に止める例です。
{
"allowedMcpServers": [
{ "serverUrl": "https://api.githubcopilot.com/*" },
{ "serverCommand": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."] }
],
"deniedMcpServers": [
{ "serverName": "dangerous-server" },
{ "serverUrl": "https://*.untrusted.example.com/*" }
]
}serverUrlエントリが1つでも存在すると、それ以降はリモートサーバー全てがURLパターンに一致しない限り通りません。名前だけを許可リストに入れても、この例では意味を持ちません。両方のリストに一致した場合は拒否リストが勝ちます。https://staging.example.com/*のように許可パターンにも拒否パターンにも一致するサーバーは、ブロックされる側です。
設定ミスでハマりやすいポイント
allowManagedMcpServersOnlyの付け忘れ: 許可リストだけ管理設定に書いても、このフラグがなければユーザー自身の設定にある許可リストがマージされ、管理者の想定より広い範囲を通してしまいます。managed-mcp.jsonはサーバー管理設定から配布できない: サーバー管理設定はclaude.ai管理コンソールから配布できますが、managed-mcp.jsonはスタンドアロンファイルのため対象外です。MDM・GPO・フリート管理ツールなど、システムパスに書き込める管理者権限のあるプロセスで配置する必要があります。一方allowedMcpServers/deniedMcpServers/allowManagedMcpServersOnly/allowAllClaudeAiMcpsはサーバー管理設定からも配布できます。配布経路が2系統に分かれる点を混同しないようにします。サーバー管理設定はClaude for TeamsとClaude for Enterpriseで利用でき、組織のOAuthログインか直接設定したAPIキーでの認証が必要です。- 不正な値の扱いが項目ごとに違う:
allowedMcpServersに無効な値が残ると、直るまで空の許可リストとして扱われ、フィルタが厳しくなる方向(fail-closed)に倒れます。一方deniedMcpServersは個々の不正エントリだけが取り除かれます。値全体が不正な場合は警告付きで無視されます(全拒否にすると無関係なサーバーまで巻き込むため)。allowManagedMcpServersOnlyが不正な場合はtrueとして扱われます。claude doctorを実行すると、取り除かれたエントリを出所とフィールド付きで確認できます。ポリシー変更後はテスト機で先に走らせておくと安全です。 - 管理対象からユーザーが黙って外れる: 以前は使えていたサーバーが拒否リストや許可リストの変更でブロックされても、
/mcpやclaude mcp listから警告なく消えるだけです。ロールアウト前に、影響を受けるユーザーへどのサーバーが対象かを伝えておかないと、原因不明の障害報告が増えます。 - クライアント側の制御であってセキュリティ境界ではない: サーバー管理設定は集中管理を提供しますが、管理外の端末ではユーザーが管理者権限なしに回避できます。MDMで端末を管理していない組織では、この前提で運用設計する必要があります。
使われ方を把握する
OpenTelemetryのエクスポートを設定していれば、Claude Codeはユーザーがどのサーバー・ツールを呼び出したか記録できます。OTEL_LOG_TOOL_DETAILS=1を設定してツールイベントにMCPサーバー名とツール名を含め、コレクター側で集計すると、実際にどのサーバーが使われているかが見えてきます。承認カタログのように「使っていいものを配る」パターンでも、実測がないと過不足の判断がつきません。
まとめ
MCPサーバーの利用範囲を絞りたいなら、まず7パターンの表から組織の許容度に合うものを選びます。全員に同じセットだけを使わせたいならmanaged-mcp.json、ユーザーの自由度を残しつつ危険なものだけ止めたいならdeniedMcpServers、承認済みだけに絞りたいならallowedMcpServersとallowManagedMcpServersOnlyの組み合わせです。managed-mcp.jsonはMDM経由、許可・拒否リストはサーバー管理設定経由という配布経路の違いを押さえておくと、ロールアウト時の手戻りを避けられます。設定後はclaude doctorとclaude mcp listで反映を確認し、ブロックされたサーバーがある場合は対象ユーザーに個別に伝えます。
よくある質問
個々のMCPサーバーはAnthropicが安全性を審査していますか
Directoryへの掲載前に掲載基準でレビューされますが、個別サーバーのセキュリティ監査や継続的な管理はAnthropicの範囲外です。接続前の評価は組織側の責任になります。MCP自体の脅威モデルと評価基準はMCPセキュリティガイドにまとめています。
ユーザーが自分で追加したサーバーを後から拒否リストに入れるとどうなりますか
次回セッション開始時から読み込まれなくなりますが、/mcpやclaude mcp listからは警告なく消えるだけです。ポリシー変更を伝える運用側の告知が必要です。
allowManagedMcpServersOnlyとallowManagedPermissionRulesOnlyは同じ効果ですか
別物です。前者はMCPの許可リストだけを、後者は権限ルールだけを管理対象ソースに固定します。どちらか一方を設定してももう一方には影響しません。
managed-mcp.jsonをclaude.ai管理コンソールから配布できますか
できません。スタンドアロンファイルなのでMDM・GPO・フリート管理など、システムパスに書き込める手段でのみ配置します。allowedMcpServers/deniedMcpServersはコンソール経由のサーバー管理設定からも配布できるので、この非対称を踏まえて配布計画を立てます。
ユーザーが自分の設定で管理対象サーバーをブロックできますか
できます。managed-mcp.jsonが配布したサーバーであっても、ユーザー自身のdeniedMcpServersは他の全ソースの拒否リストと合流するため、自分だけそのサーバーを使わないという選択が可能です。逆に許可リストを個人設定で広げることは、allowManagedMcpServersOnlyが有効な限りできません。