MCPセキュリティガイド — サーバーごとに許可する範囲をどう決めるか
MCPサーバーの許可判断は接続前の信頼確認・権限ルール・組織管理の3層で決まります。allowとdenyのglob構文からmanaged-mcp.jsonまで、実装できる基準を示します。
MCPサーバーは、外部のツールやデータベースにClaude Codeから直接アクセスさせる接続口です。接続したサーバーの数だけ、Claudeが触れる範囲と資格情報の置き場所が増えます。判断は、どの段階で何を止めるかに分けると見通せます。どれか1つだけを固めても抜け道が残るため、3層それぞれで設定できる項目を示します。サンドボックスや権限モード全体、データの学習利用を含む設計はClaude Codeセキュリティ・権限ガイドにあります。本番のKubernetesクラスタに接続する場合の権限設計はKubernetes MCPサーバーの権限設計にあります。
許可判断の3層
接続前
.mcp.jsonのサーバーは、対話セッションでは承認されるまで接続されません。サーバーの提供元と、資格情報の渡し方もここで決まります。権限ルール
mcp__<サーバー名>__<ツール名>の名前空間で、allowとdenyを書き分けます。組織の管理設定
managed-mcp.jsonと許可・拒否リストで、利用者が足せるサーバーの範囲を決めます。
クローンしたリポジトリの.mcp.jsonは、承認するまでどう扱われるか
リポジトリに同梱された.mcp.jsonのサーバーは、Claude Codeを対話的に起動し、ワークスペースの信頼ダイアログを受け入れるまで接続されません。クローンしただけのリポジトリが、自分自身のサーバーを承認する経路は閉じられています。.claude/settings.jsonにコミットされた承認設定も、信頼していないフォルダーでは無視されます。対象はenableAllProjectMcpServersとenabledMcpjsonServersです(v2.1.196以降)。
claude -p、Agent SDK、クラウドセッションは承認ダイアログを出せないため、プロジェクトスコープのサーバーを確認なしで読み込みます。bypassPermissionsモードで起動し、ユーザー設定か管理設定にskipDangerousModePermissionPromptを置いた場合も、ダイアログは出ません。止めたいサーバーは次の3つで外します。disabledMcpjsonServers、--setting-sources(SDKではsettingSourcesオプション)、--strict-mcp-configです。
自分の~/.claude/settings.json、管理設定、--settingsで渡した設定による承認は、未信頼のフォルダーでも有効です。git管理外の.claude/settings.local.jsonの承認は、v2.1.207以降は信頼ダイアログの後にだけ適用されます。ホームディレクトリとCLAUDE_CONFIG_DIRに指定したディレクトリは例外で、信頼前でも適用されます。disabledMcpjsonServersに載せたサーバーは、どの設定ファイルに書いても拒否されます。
v2.1.287で、空のホームディレクトリに作った一時プロジェクトに.mcp.jsonを置いて確かめました。headersHelper付きのHTTPサーバーと、stdioサーバー(echo)を1つずつ定義しています。
claude mcp listChecking MCP server health…
demo-docs: https://example.invalid/mcp (HTTP) - ⏸ Pending approval (run `claude` to approve)
demo-local: echo hello - ⏸ Pending approval (run `claude` to approve)どちらも⏸ Pending approvalのままで、接続もヘルスチェックも行われていません。claude mcp get demo-docsも同じ状態を返し、Scope: Project config (shared via .mcp.json)と表示します。--helpの説明では、承認済みのサーバーは無効化されていなければヘルスチェックの対象です。承認した後は、claude mcp listを打つだけで登録されたコマンドやURLへの接続が走ります。
プロジェクトスコープのサーバーが動くまで
- 1
対話起動して承認
claudeを起動してワークスペースの信頼ダイアログを受け入れ、サーバーごとに承認または拒否します。すべて承認を選ぶと、enableAllProjectMcpServersが.claude/settings.local.jsonに書かれます。拒否したサーバーは.claude/settings.local.jsonのdisabledMcpjsonServersに書かれます。claude mcp get <サーバー名>では✘ Rejected (see disabledMcpjsonServers in settings)と表示されます。 - 2
見直したいとき
claude mcp reset-project-choicesで承認と拒否をすべて戻します。消える範囲と残る承認はreset-project-choicesの解説にあります。
claude mcp reset-project-choicesProject-scoped (.mcp.json) server approvals and rejections stored for this project have been reset.
You will be prompted for approval next time you start Claude Code.外部コンテンツを読むサーバーと提供元をどう見極めるか
外部コンテンツを取得するMCPサーバーは、プロンプトインジェクションのリスクを持ち込みます。Web検索結果を返すBrave Search MCPサーバーのように、取得した本文をそのまま返すサーバーが該当します。Claude Codeのドキュメントは、接続前にサーバーを信頼できるかを確かめるよう警告しています。
もう1つのリスクは提供元の不透明さです。Anthropic Directoryに掲載されたコネクタは掲載基準による審査を受けていますが、Anthropicがセキュリティ監査やサーバーの管理をするわけではありません。claude mcp addや.mcp.jsonへの直書きは、審査も経由しません。管理設定でこの追加が止められる場合は、claude mcp addが失敗する: プラグイン以外のMCP追加を管理設定が止めるで対処を確認できます。「配布元らしく見えるか」ではなく「自分がコードまたは提供元を検証できたか」を基準にします。この検証可能性は、MCPサーバーを自作して配布する側にも同じ基準で跳ね返ります。
判断に使う4つの要因を並べます。
| 観点 | リスク | 判断の目安 |
|---|---|---|
| 提供元 | リスク提供元が未確認の自作・第三者サーバー | 判断の目安Anthropic Directoryへの掲載の有無と、コードや提供元を自分で検証できたかを見る |
| 認証方式 | リスクheadersHelperは任意のシェルコマンドを実行する | 判断の目安OAuthとoauth.scopesを優先し、静的ヘッダーは環境変数展開で扱う |
| 外部コンテンツの取得 | リスク取得した文面がプロンプトインジェクションの経路になる | 判断の目安書き込み系ツールはallowに入れず、毎回確認が出る状態にする |
| スコープ | リスクプロジェクトスコープはリポジトリ経由で全員に届く | 判断の目安個人の資格情報が要るサーバーはローカルかユーザースコープに置く |
外部コンテンツを取得するサーバーに書き込み系ツールを許可すると、取得した文面から書き込みが誘導される経路ができます。読み取り専用のツールと、ファイル書き込みやコマンド実行を伴うツールは、同じ扱いにしません。
資格情報はどの経路で渡り、どこで止まるか
MCPサーバーの認証方式は、資格情報の置き場所と漏えい経路が異なります。
- OAuth 2.0: トークンはシステムキーチェーンなど安全な場所に保存されます。
oauth.scopesにスペース区切りの文字列を設定すると、要求するスコープをその範囲に固定できます。セキュリティチームが承認した範囲に絞るための、サポート済みの手段です。未設定のときは、サーバーのWWW-Authenticateヘッダーかリソースメタデータが示すスコープを要求し、どちらも無ければscopeパラメーターを送りません(v2.1.196以降) - 静的ヘッダー(
headers): プロジェクトスコープの.mcp.jsonに直書きすると、リポジトリにトークンが残ります。${VAR}や${VAR:-default}の環境変数展開で参照する形にします。展開できるのはcommand・args・env・url・headersです headersHelper: 短命トークンや社内SSOなど、OAuth以外の認証に使います。任意のシェルコマンドを実行するため、次の注意書きの条件が付きます
環境変数展開には、リモートサーバー向けの歯止めがあります。urlとheadersの中では、資格情報の変数は設定済みでも空として読まれます。対象はANTHROPIC_API_KEY、ANTHROPIC_AUTH_TOKEN、クラウドの認証情報、NPM_TOKENなどです。Bearer ${ANTHROPIC_AUTH_TOKEN}と書いたサーバーにはBearer だけが届き、通常は401で拒否されます。他人のリポジトリの.mcp.jsonが、手元のClaude Codeやクラウドの資格情報を、指定したサーバーへ送れない設計です。API_KEYのようにリスト外の名前は、書いたとおりに展開されます。
stdio型のサーバーには別の経路があります。既定では、起動したサーバーがシェルの環境変数を引き継ぎます。CLAUDE_CODE_MCP_ALLOWLIST_ENV=1を設定すると、安全な基本環境とサーバー設定のenvだけで起動します。
リポジトリやプラグインが持ち込んだheadersHelperは、自分で書いたコマンドではありません。そのため、TOKEN・SECRET・PASSWORD・KEY・AUTHを名前に含む環境変数を取り除いたうえで実行されます。ユーザースコープ、ローカルスコープ、管理設定のサーバーでは取り除かれません。ヘルパー内で資格情報が要るときは、ファイルや資格情報ストアから読む形にします。
スコープの違いもリスクの層になります。ローカルスコープ(既定)は~/.claude.jsonに自分専用で保存され、チームには共有されません。プロジェクトスコープは.mcp.jsonをバージョン管理に載せるため全員に届きます。同じサーバーの定義が複数あると、ローカル、プロジェクト、ユーザー、プラグイン、claude.aiコネクタの順で最初に見つかった定義だけが使われます。3つのスコープは名前で、プラグインとコネクタは接続先で重複を判定します。フィールドはマージされず、managedMcpServersはこれらすべてより優先されます。サーバーの追加方法とスコープ指定の構文はClaude Code MCP設定ガイドにあります。
権限ルールでMCPツールをどこまで許可するか
MCPツールの権限ルールは、mcp__<サーバー名>__<ツール名>という名前空間で管理します。粒度は3段階です。
| 書き方 | 対象範囲 |
|---|---|
mcp__puppeteer | 対象範囲puppeteerサーバーの全ツール |
mcp__puppeteer__* | 対象範囲同上(ワイルドカード表記) |
mcp__puppeteer__puppeteer_navigate | 対象範囲特定の1ツールのみ |
グロブの扱いは、denyとallowで非対称です。
グロブの使える範囲
deny(拒否)
ツール名の位置にグロブを置けます。"mcp__*"と書けば、サーバーをまたいで全MCPツールを一括で拒否します。裸のグロブでdenyされたツールは、Claudeの文脈からも取り除かれます。
allow(許可)
mcp__<サーバー名>__の接頭辞が必須で、サーバー名の部分にグロブは使えません。mcp__github__get_*のように、接頭辞の後ろだけが書けます。"*"や"mcp__*"は警告付きでスキップされ、何も自動承認しません。
書き方でつまずきやすい構文はClaude Code MCP権限ルール — server:tool単位の書き方にまとめています。設定ファイルでは、mcp__で始まる括弧付きのルールはスキップされ、無効な設定として報告されます。ツールの引数で絞りたいときのdenyは、--disallowedToolsで渡します。
権限モードとの組み合わせにも注意が必要です。dontAskモードは事前承認済みのツール以外を自動拒否します。ただしMCPサーバー側が_metaでanthropic/requiresUserInteractionをtrueに設定したツールは別扱いです(v2.1.199以降)。acceptEdits・auto・bypassPermissionsでも毎回プロンプトが出ます。v2.1.246以降は「今後は確認しない」の選択肢も出ません。allowルールでも省略できず、dontAskでは拒否されます。同意そのものが目的のツールを自動承認すると、誰も同意していないのに処理が進むためです。
組織がclaude.aiコネクタのツールをaskに設定した場合も、同じ扱いになります。プロンプトの理由はYour organization requires approval for this toolと表示されます。
読み取り系と書き込み系が混在するサーバーでは、mcp__<サーバー>__*で丸ごと許可せず、個別ツール名のallowルールを積み上げます。丸ごと許可は、そのサーバーの全ツールが同じ信頼度を持つときに限ります。
組織で統制するとき、目的別にどの設定を選ぶか
管理設定(managed settings)の設計は、利用者に何を許すかで選びます。ここではどの層で止めるかの判断だけを扱います。8つのパターンごとの書き方、v2.1.259での免除、利用者に出るメッセージは管理設定でMCPサーバーを許可・拒否する手順にまとめています。
| 目的 | 利用者ができること | 使う設定 |
|---|---|---|
| MCPを無効化 | 利用者ができること例外を除き、サーバーを読み込まない | 使う設定空のサーバーマップを持つmanaged-mcp.json |
| 固定配布 | 利用者ができること配られたサーバーだけを使い、他は足せない | 使う設定managed-mcp.json |
| 承認済みカタログ | 利用者ができること一覧にあるものだけを自分で追加できる | 使う設定allowedMcpServersとallowManagedMcpServersOnly: true |
| プラグインのみ | 利用者ができることプラグイン経由のサーバーだけ | 使う設定strictPluginOnlyCustomizationにmcpを含める |
| ゆるい許可リスト | 利用者ができること自分の設定で許可範囲を広げられる | 使う設定allowManagedMcpServersOnlyなしのallowedMcpServers |
| 提供サーバー | 利用者ができること利用者は自分のサーバーを残したまま、組織のサーバーを受け取る | 使う設定managedMcpServers(v2.1.259以降) |
| 拒否リストのみ | 利用者ができること既知の危険なサーバー以外は自由 | 使う設定deniedMcpServers |
managed-mcp.jsonは、OSごとに決まったパスに置きます。パスは、macOSが/Library/Application Support/ClaudeCode/managed-mcp.jsonです。Linux/WSLは/etc/claude-code/managed-mcp.json、WindowsはC:\Program Files\ClaudeCode\managed-mcp.jsonです。
置くと、ファイルのサーバーに加えて、managedMcpServersで配ったサーバーと、アプリが登録する組み込みのサーバーだけが読み込まれます。プラグイン提供のサーバーと--mcp-configのサーバーは使えません。claude mcp addは、次のメッセージで失敗します。
Cannot add MCP server: enterprise MCP configuration is active and has exclusive control over MCP servers
このファイルは、サーバー管理設定では配布できません。デバイス管理ツールで配ります。
この方式はclaude.aiコネクタも既定で抑制します。管理設定側でallowAllClaudeAiMcpsをtrueにした場合だけ、コネクタが元どおり読み込まれます。この設定は管理者が制御する層からしか読まれず、ユーザー設定やプロジェクト設定に書いても効きません。端末で動く組み込みのClaude in Chromeサーバーも既定でブロックされ、allowClaudeInChromeWithManagedMcpで許可できます(v2.1.282以降)。
allowedMcpServersとdeniedMcpServersは、サーバーを名前・コマンド・URLで許可または拒否します。allowManagedMcpServersOnlyをtrueにすると管理設定の許可リストだけが有効になり、ユーザーの設定にある許可リストはマージされません。これが無いと、利用者が自分の~/.claude/settings.jsonで許可範囲を広げられます。deniedMcpServersはどのスコープからでもマージされ、allowManagedMcpServersOnlyでも変わりません。
allowedMcpServersはmanaged-mcp.jsonのサーバーには適用されません(v2.1.259以降)。例外は、定義に${VAR}展開を使うサーバーだけです。許可リストで一部の管理サーバーを読み込ませないようにしていた場合、v2.1.259以降へのアップグレード時にそのサーバーが通知なしに読み込まれ始めます。止めたいサーバーはdeniedMcpServersに書くか、グループごとに別のmanaged-mcp.jsonを配ります。
disableSideloadFlagsは、次の4つのフラグを起動時に拒否します(v2.1.193以降)。--plugin-dir、--plugin-url、--agents、--mcp-configです。これらのフラグは、単発の実行で組織のマーケットプレイス制限を迂回できてしまうためです。ただしclaude mcp addや.mcp.jsonでのサーバー追加は止まらないので、サーバー単位の制御はallowedMcpServersと組み合わせます。
strictPluginOnlyCustomizationは、skills / agents / hooks / MCPサーバーを、プラグインまたは管理設定由来のものだけに限定します。trueで4種すべてを、["skills", "hooks"]のような配列で特定の種類だけをロックできます。mcpをロックしても、プラグインのサーバー、managed-mcp.json、managedMcpServersは読み込まれ続けます。
claude.aiコネクタは、組織が各ツールにaskかblockedを設定できます。blockedのツールは、Claudeの目に触れる前にツール一覧から除外されます。デスクトップアプリのローカルセッションではaskがClaude Codeに届かず、通常の権限ルールが適用されます。個別のコネクタを止めるときは、deniedMcpServersに{ "serverName": "claude.ai Slack" }のように書きます。サーバー名の変更に強くするならserverUrlのエントリが堅牢です。
許可リストの運用では、組織の統制と個人の生産性が衝突します。Coworkのデータ共有は、この管理設定とは別の権限モデルで制御されます(Coworkセキュリティ)。
よくある質問
claude mcp serveでClaude Codeを公開したときの責任範囲は
Claude Code自身をMCPサーバーとして公開すると、ファイル編集などのツールがそのまま外部のMCPクライアントに露出します。個々のツール呼び出しをユーザーに確認させる実装は、接続先のクライアント側の責任です。
全コネクタを止めるには
disableClaudeAiConnectorsをtrueにします。どの設定ファイルでtrueにしても有効で、プロジェクトのfalseで管理側のtrueを戻すことはできません。シェルセッション単位ならENABLE_CLAUDEAI_MCP_SERVERS=falseです。どちらもClaude Codeが自分で取得するコネクタだけが対象で、デスクトップアプリやクラウドセッションが届けるコネクタには効きません。
まとめ
固める順は、接続前の.mcp.jsonとheadersHelperの信頼確認、権限ルール、組織の管理設定です。組織では、固定配布ならmanaged-mcp.json、利用者の追加を残すなら許可リストとallowManagedMcpServersOnlyの組み合わせを選びます。業務SaaSで読み取り専用から始める理由は業務SaaS連携は読み取り専用アクセスから始める理由にあります。本番DBでサーバー側のフラグも重ねる例はMongoDB MCPを本番で使うときの読み取り専用設定にあります。MCP全体はMCPのページから辿れます。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。