Claude Code MCP権限ルール — server:tool単位の書き方
MCP権限ルールのmcp__サーバー名__ツール名記法を、allow/denyの非対称な粒度・評価順・Cowork環境での対応関係まで、設定の書き方に絞ってまとめています。
MCPサーバーのツールを許可する、あるいは止めるルールは、mcp__サーバー名__ツール名という名前空間に対して書きます。ところが同じ名前でも、権限ルール・フックのmatcher・サブエージェントのtoolsでは、使えるワイルドカードの文法が違います。サーバー全体を許可したつもりで何も許可されていない、という事故はこの差から起きます。
どのサーバーをどこまで信用するかという判断基準はMCPセキュリティガイドにまとめています。本記事はルールそのものの書き方と、書いたルールが効いているかの確かめ方に絞ります。確認はClaude Code v2.1.285のヘルプ出力と公式ドキュメントで行いました。
MCP権限ルールの基本構文
MCPのツール名はmcp__<サーバー名>__<ツール名>という形式で公開されます。権限ルールはこの名前空間に対して3段階の粒度で書けます。
| 書き方 | 対象範囲 |
|---|---|
mcp__puppeteer | 対象範囲puppeteerサーバーが提供する全ツール |
mcp__puppeteer__* | 対象範囲同上(ワイルドカード表記。挙動は上と同じ) |
mcp__puppeteer__puppeteer_navigate | 対象範囲puppeteerサーバーのpuppeteer_navigateツールのみ |
settings.jsonのpermissions.allowまたはpermissions.deny配列に、この形式の文字列をそのまま入れます。
{
"permissions": {
"deny": ["mcp__github__delete_repository"],
"allow": ["mcp__github__list_pull_requests", "mcp__github__get_pull_request"]
}
}サーバー名はClaude Codeに登録した名前がそのまま入ります。claude.aiのコネクタをClaude Codeが自分で取得した場合は、mcp__claude_ai_<サーバー名>__<ツール名>という名前で現れます。
allowにmcp__*を書いても何も許可されない理由
「危険なものを広く止める」側と「安全なものを広く許可する」側で、書ける形が違います。
denyとallowで書ける形の違い
deny(と ask)
ツール名の位置にグロブを置けます。mcp__*と書けば、サーバーをまたいで全MCPツールを一括で拒否できます。
allow
mcp__<サーバー名>__というリテラルな接頭辞が必須で、サーバー名の部分はグロブにできません。*やmcp__*は警告付きでスキップされ、何も自動承認しません。
接頭辞を具体的なサーバー名で固定していれば、その後ろのツール名はグロブにできます。mcp__github__get_*ならget_で始まるツールだけ、mcp__puppeteer__*ならサーバー全体です。制限されるのはサーバー名の部分だけです。
この非対称は公式が理由を書いていないので、設計意図は推測になります。ただ、allowのグロブ側に「設定済みの特定サーバーを名指しする」という条件が付いている点は、公式の説明に明記されています。
存在しないツール名をdenyやaskに書くと、起動時にタイポを知らせる警告が出ます。ただし名前に_や*を含むものはこの警告の対象外なので、MCPツール名のタイポは警告に頼れません。個別ツールを積み上げて許可し、拒否だけ大きな網で掛けるのが、この非対称に沿った運用です。
裸のルールはコンテキストごとツールを消す
権限ルールには、Bashのように名前だけを書く裸のルールと、Bash(rm *)のように括弧で引数パターンまで絞るスコープ付きルールがあります。裸の名前をdenyすると、そのツールはClaudeのコンテキストから完全に除去され、Claudeはツールの存在を知りません。スコープ付きのdenyはツールを残したまま、一致する呼び出しだけを拒否します。
MCPツールにはスコープ付き記法が使えません。括弧付きのmcp__ルールは、settings.jsonの読み込み時にすべてスキップされます。スキップされたルールは、対話セッションの起動時に出るinvalid-settingsダイアログと、claude doctorの出力に列挙されます。引数の値まで絞りたいときは、denyルールを--disallowedToolsに渡す方法が公式に示されています。
次は引数を付けず、ツール全体を拒否する書き方の例です(v2.1.285)。
claude --disallowedTools "mcp__github__delete_repository"claude --helpの該当箇所は次のとおりです。
--disallowedTools, --disallowed-tools <tools...>
Comma or space-separated list of tool names to deny (e.g. "Bash(git *)
Edit")MCPツールではmcp__github__delete_repositoryのようにツール名まで書いた形も、mcp__githubのようにサーバー名だけの形も、括弧のない裸の名前です。denyに書けば粒度を問わず、対象はコンテキストから消えます。settings.jsonのdenyでは、ツールを残したまま呼び出し時だけ止める運用はMCPツールで取れません。引数の値で止めたいときは、--disallowedToolsに引数付きのdenyルールを渡します。
読み取り系と書き込み系が混在するサーバーでは、危険なツール名だけを個別にdenyへ列挙します。そのツールだけが消え、他のツールは通常どおり残ります。サーバー全体を隠したいときはmcp__githubかmcp__github__*と書きます。
評価順は他のツールと同じくdeny → ask → allowで、最初に一致したものが採用されます。範囲の広いdenyは、範囲の狭いallowが同時にあっても優先されます。
書いたルールが効いているかを確かめる手順
ルールは書いた時点では、効いているか分かりません。次の順で確かめます。
MCPルールの書き込みから確認まで
- 1
正規名を確認する
/mcpで接続済みサーバーとツールを確認します。画面の表示名と、権限ルールが照合する正規名が違うツールがあります(組み込みツールでは、画面でStop Taskと表示されるものの正規名がTaskStopです)。 - 2
settings.jsonに書く
permissions.denyかpermissions.allowに入れます。denyは広く、allowはサーバー名まで書きます。 - 3
スキップされたルールを見る
claude doctorを実行すると、括弧付きのmcp__ルールのようにスキップされたものが出ます。allowのmcp__*は、警告付きでスキップされます。 - 4
起動時の警告を読む
denyとaskのタイポは起動時の警告で分かります。ただしMCPツール名は
_を含むので、この警告は当てにできません。/mcpの一覧との突き合わせが確実です。
許可ルールを書いても毎回確認になるケース
allowを書いたのに毎回プロンプトが出る場合、原因は自分の設定の外にあることがあります。決めているのは、組織の管理者かMCPサーバーの実装者です。
毎回確認を強制する2つの出どころ
組織のコネクタ設定
組織がclaude.aiコネクタの特定ツールをaskにして、その設定がセッションに届いている場合です。プロンプトの理由はYour organization requires approval for this toolと表示され、「今後は確認しない」の選択肢は出ません。
requiresUserInteraction
ツール定義の_metaにanthropic/requiresUserInteractionをtrueと書いたツールです。同じサーバーの他のツールは、通常の権限判定のままです。
どちらも、allowルールがあってもプロンプトが出ます。acceptEdits auto bypassPermissionsの各モードでも同じです。dontAskモード(そもそもプロンプトを出さないモード)では、プロンプトの代わりに拒否されます。
組織設定のaskが届かない環境もあります。Claude Desktopアプリのローカル・SSHセッションではaskがClaude Codeに届かず、セッション自体の通常の権限ルールが適用されます。組織がblockedにしたツールは、Desktopのローカル・SSHセッションではアプリが渡す前に取り除きます。それ以外ではClaude Codeが、Claudeに見せる前に取り除きます。
requiresUserInteractionのマークは、同意そのものがツールの目的であるときのためのものです。アクセス権限の付与で、誰も同意していないのに処理が進む事態を防ぎます。サーバー側は次のように付けます。この指定はv2.1.199以降で効き、それ以前のバージョンは無視して通常の権限判定に戻ります。値はJSONの真偽値trueに限られ、それ以外は無視されます。
{
"name": "grant_repository_access",
"_meta": {
"anthropic/requiresUserInteraction": true
}
}自分のallowルールやpermissionModeでは、このマークを外せません。信頼できないサーバーの該当ツールを拒否したいなら、通常どおり個別のdenyルールを書きます。
非対話モードとRemote Controlでの扱い
このマークは、人にプロンプトが届く前提で作られています。非対話モードで--permission-prompt-toolを使うと、マーク付きのツールへのallow判定はMCP tool requires user interaction; not supported via --permission-prompt-toolというメッセージ付きでdenyに変換されます。一方、Agent SDKのcanUseToolコールバックは、この呼び出しを受け取って承認できます。SDKを使うアプリケーション側が、人に見せて承認を得ることが前提になっているからです。
v2.1.285のclaude --helpには、-p実行時にプロンプトへ誰が答えるかを決める--permission-promptsが出ています。
--permission-prompts <target>
Who answers permission prompts with --print: "host" (the SDK host or
--permission-prompt-tool) or "none" (nobody: anything that would prompt
is denied automatically; the permission mode still decides everything
else) (choices: "host", "none", default: "host")noneにすると、プロンプトが要る呼び出しはすべて自動で拒否されます。マーク付きツールに人の承認が付かない環境では、拒否になると考えて設計します。
Remote ControlやAgent SDKアプリのように1タップで承認できる面でも、マーク付きツールにはワンタップの承認を出さず、完全な確認プロンプトを表示します。このプロンプトには「今後は確認しない」の選択肢もありません。v2.1.214以降は、安全警告付きの要求など端末ダイアログでしか完全に表示できない要求も同じ扱いで、端末側で答えます。
Cowork環境ではBash/WebFetchのdenyがMCPツールに波及する
Claude DesktopアプリのCoworkセッションでは、ClaudeはビルトインのBashではなく、Coworkのmcp__workspace__bashというMCPツールでシェルコマンドを実行します。Web取得も同様にmcp__workspace__web_fetchが担います。
BashやWebFetchというツール名全体を対象にしたdenyルールは、これらのCoworkツールにも適用されます。管理設定でBashをdenyしていれば、Coworkでのシェル実行も止まります。ただし波及はdeny方向だけです。Bashのallowルールがmcp__workspace__bashに適用されることはありません。ブロック時のメッセージには、Coworkツールの名前が出ます(Permission to use mcp__workspace__bash has been denied.)。
「Bashは全環境で禁止」というポリシーをCoworkにも効かせたいなら、この波及が使えます。逆に「Coworkだけは許可したい」なら、Bashのallowでは足りないので、mcp__workspace__bashを名指しでallowに加えます。
同じ名前でも場所によって文法が違う
mcp__<サーバー名>__<ツール名>という名前は、権限ルールのほかにも複数の場所で使えます。ただしワイルドカードの文法は場所ごとに違い、コピーして貼ると効かなくなります。
| 書く場所 | サーバー全体の書き方 | 注意点 |
|---|---|---|
| 権限ルール | サーバー全体の書き方mcp__github または mcp__github__* | 注意点グロブ。allowはサーバー名まで具体化 |
サブエージェントのtools / disallowedTools | サーバー全体の書き方mcp__github または mcp__github__* | 注意点disallowedToolsではmcp__*も使える |
| フックのmatcher | サーバー全体の書き方mcp__github__.* | 注意点正規表現。mcp__githubだけでは何にも一致しない |
サブエージェントの権限設計はサブエージェントの権限設計で扱っています。ここではdisallowedTools: mcp__githubと書くと、そのサブエージェントだけgithubサーバーの全ツールが外れ、他のサーバーと組み込みツールは残る点だけを押さえます。
フックのmatcherは英数字だけだと完全一致になる
PreToolUseなどのフックのmatcherは、書かれた文字で解釈が変わります。英数字・_・-・空白・,・|だけなら完全一致、それ以外の文字を含めば正規表現(非アンカー)です。
mcp__memoryのようにサーバー名までしか書かないmatcherは、完全一致の文字列として比べられるので、どのツールにも一致しません。サーバー全体を狙うにはmcp__memory__.*と書きます。ハイフンを含むサーバー名は、mcp__brave-search__.*のように書きます。
プラグイン同梱のサーバーは名前が変わる
プラグインが同梱するMCPサーバーのツールは、サーバー部分にプラグイン名が入ります。my-pluginがdbというキーでサーバーを同梱していれば、queryツールはmcp__plugin_my-plugin_db__queryという名前になります。この場合、サーバー全体を狙うmatcherはmcp__plugin_my-plugin_db__.*です。素のサーバー名で書いたmatcherは、プラグイン同梱のサーバーに一致しません。
Skillのallowed-toolsは次のメッセージで切れる
スキルのallowed-toolsに書いたツールは、そのスキルを呼び出したターンの間だけ、確認なしで使えます。付与は次にメッセージを送った時点で消えます。恒久的な許可はpermissions.allowに書くもので、スキル側の指定とは役割が違います。
用途別の設定レシピ
| 用途 | 書き方 | 補足 |
|---|---|---|
| 読み取り専用のDB接続だけ許可 | 書き方allowにmcp__postgres__queryを個別列挙、denyにmcp__postgres__execute | 補足書き込み系ツール名を確認してから個別denyを積む |
| Puppeteerサーバーを全面的に信頼 | 書き方allowにmcp__puppeteer(またはmcp__puppeteer__*) | 補足サーバー内の全ツールが同じ信頼度のときだけ使う |
| GitHubサーバーで削除系だけ止める | 書き方denyにmcp__github__delete_repositoryなど個別ツール名 | 補足他のツールはコンテキストに残る |
| 全MCPサーバーを一括で無効化 | 書き方denyにmcp__* | 補足allow側では同じ書き方はできない |
| Coworkのシェル実行だけ会社ポリシーで禁止 | 書き方denyにBash | 補足mcp__workspace__bashにも波及する |
よくあるつまずき
mcp__*をallowに書いたのに何も許可されない: サーバー名部分のグロブは無効で、警告付きでスキップされます。サーバー名まで書き直します- サーバーの一部ツールだけをdenyしたつもりが、サーバー全体が消えた: ツール名まで書いた個別指定も裸の名前として扱われ、そのツールがコンテキストごと消えます。全体が消えたなら、
mcp__<サーバー名>とサーバー名だけで書いていないか見直します BashのallowルールをCoworkにも効かせたいのに反映されない: allow方向の波及は起きません。mcp__workspace__bashを明示的にallowへ追加します- 個人のallowルールで、組織が
askにしたツールが自動承認されると思っていた: 組織側のaskが優先されます。個人設定では上書きできません - フックのmatcherに
mcp__memoryと書いたのに発火しない: 完全一致になっています。mcp__memory__.*と書きます
まとめ
MCP権限ルールで迷うのは、denyの広さとallowの狭さ、そして場所ごとに違うワイルドカードの文法です。ルールを書いたら/mcpの正規名と突き合わせ、claude doctorでスキップされたルールを確かめてください。毎回確認になるツールがあるときは、自分のルールではなく、組織の設定かサーバー側のマークを疑います。
サーバーの追加方法とスコープ指定はClaude Code MCP設定ガイド、権限ルール全体の管理は/permissionsコマンドで扱っています。
関連する記事
Claude Code をもっと見る →Claude Codeとは — できること・料金・始め方と使い方の全体像
MCP tool not foundエラー — --permission-prompt-toolの原因と対処
mcp-grafanaでダッシュボードを読む — summaryとJSONPathの使い分け
ListMcpResourcesToolとReadMcpResourceToolでMCPのresourcesを読む
Not ready after 60 secondsエラー — Claude DesktopのMCP起動失敗
CLAUDE_CODE_MCP_ALLOWLIST_ENVとは — stdio MCPサーバーへの環境変数漏えいを防ぐ