月曜の朝、settings.json を開いたまま、しばらく手が止まりました。許可の欄に mcp__figma とだけ書かれた行があったのです。
いつ書いたのかも覚えていません。ただ、その行が「figma という MCP サーバーのツールをまとめて許可する」つもりで置かれていたことだけは、はっきり思い出せました。
公式の変更履歴を読み返すと、v2.1.299(10 月 14 日)にこの書き方へ直接かかわる項目がありました。最初にお伝えしたいのは、慌てて全部を書き換える必要はない、ということです。まず「どの行が対象か」を数えるところから始めれば足ります。
何が変わったのか
変更履歴の記述は短いものです。MCP の allow ルールが、名指ししたサーバーだけに届くようになりました。たとえば mcp__a は、a__b や a_ という名前のサーバーを許可しなくなります。サーバーの正規化された名前の全体を使い、mcp__<server>__* と書くよう案内されています。
つまり、サーバー名の「前方一致」に頼った書き方が、これまでより狭く解釈されるということです。許可が広がる方向ではなく、狭まる方向の変更だという点が、見直しの順番を決めます。
狭まると何が起きるか。許可されていたはずのツールが、また承認待ちに戻ります。無人で動かしている作業では、そこで止まります。
なお、同じ日の v2.1.300 には関連する不具合修正があります。サーバーの正規化後の名前に二重アンダースコアが含まれるとき、mcp__<server> の deny と ask が効かなかった問題です。こちらは deny 側の話なので、別の機会に切り分けます。
止まるのは、人がいないときです
個人開発でアプリの運用を続けていると、確認の画面が出ても誰も押せない時間帯があります。深夜に回す定期作業や、席を外しているあいだに走らせるスクリプトがそうです。
承認待ちは、画面の前にいれば数秒の手間で済みます。しかし無人の実行では、その一回で作業全体が止まったままになります。許可の範囲が狭まる変更は、日中に使っているだけなら気づきにくく、夜の実行でようやく表に出てきます。
だからこそ、症状が出る前に、設定ファイルのほうを先に点検しておく価値があるのです。
点検するのは三つの形だけ
私は settings.json の MCP 行を、次の三つに分けて見ることにしました。
| 書き方 | 意味 | v2.1.299 以降の扱い |
|---|---|---|
| `mcp__github__*` | github サーバーの全ツール | そのまま使えます |
| `mcp__figma__get_screenshot` | 特定ツールだけ | そのまま使えます |
| `mcp__figma` | サーバー名だけ | 要確認。`mcp__figma__*` に直す候補です |
三行目の形が、私の settings.json にあった書き方でした。
点検スクリプト
目で追うと見落とすので、短いスクリプトにしました。設定ファイルを読み、MCP の allow だけを三つの形に振り分けます。
#!/usr/bin/env python3
"""settings.json の MCP allow ルールを、サーバー名全体一致の基準で点検する。"""
import json, re, sys
from pathlib import Path
def rules(path):
try:
data = json.loads(Path(path).read_text(encoding="utf-8"))
except FileNotFoundError:
return [] # 無いファイルは黙って飛ばす
return data.get("permissions", {}).get("allow", [])
def check(rule):
m = re.fullmatch(r"mcp__(.+)", rule)
if not m:
return None # MCP 以外のルールは対象外
rest = m.group(1)
if rest.endswith("__*"):
return ("OK", f"サーバー名「{rest[:-3]}」の全ツール")
if "__" not in rest:
return ("要確認", f"サーバー名だけ。mcp__{rest}__* に書き直す候補")
return ("OK", "ツール名まで指定")
for p in sys.argv[1:]:
for r in rules(p):
res = check(r)
if res:
print(f"{res[0]:6} {r:40} {res[1]} ({p})")使い方は、確認したい設定ファイルを引数に並べるだけです。
python3 audit_mcp_allow.py ~/.claude/settings.json .claude/settings.json .claude/settings.local.json手元で mcp__notion、mcp__github__*、mcp__figma__get_screenshot を並べた検証用ファイルに通したところ、要確認と出たのは mcp__notion の 1 行だけでした。存在しないファイルを混ぜても止まらないのは、プロジェクトごとに設定ファイルの有無が違うためです。
書き直す前に、サーバー名を確かめる
ここで私は一つ失敗しかけました。mcp__figma を機械的に mcp__figma__* へ置き換えようとしたのです。
変更履歴が求めているのは「サーバーの正規化された名前の全体」です。設定に書いた名前と、実際にツール名へ現れる名前が同じとは限りません。書き直す前に、承認の画面や /mcp の表示に出るツール名を一度見て、mcp__ と __ のあいだの部分を写すことにしています。
- 承認画面に出たツール名から、サーバー名の部分をそのまま写します
- 推測で補わず、一行ずつ確かめます
- 直したあとは、そのツールを一度だけ呼んで、承認待ちが出ないことを確かめます
広げすぎないための線引き
mcp__<server>__* は便利ですが、そのサーバーの全ツールを許可する書き方でもあります。読み取りだけで足りるサーバーまで全許可にしてしまうと、今回の見直しの意味が薄れます。
無人で動かす作業では、権限の置き場所を別の面から考えた記事もあります。あわせてご覧ください。
- 無人で動くエージェントに渡す MCP ツールを絞り込む — ポリシー強制で deny-by-default にする
- allow を足したのに承認画面が消えない — 「どの層が決めたか」を 6 段で読む
書く範囲はサーバーで決め、広げる範囲はツールで決めます。 この線引きだけは、行を足すたびに思い出すようにしています。
まずは上のスクリプトを一度だけ走らせて、要確認が何行出るかを数えてみていただければと思います。ゼロなら、今日はそれで終わりです。