はじめに / 対象と前提
Claude Code で作業していると、npm install や git status を叩くたびに「このツールを許可しますか?」というプロンプトが出てきて、フローが切れることがある。毎回エンターを押すのが地味にストレスで、長いセッションだと体感で 1 割くらい時間を奪われてる気がした。
この記事は そのプロンプトを 9 割減らすための settings.json の書き方 をまとめたメモ。同じところでハマった人向けに、自分が試した allowlist パターンと、引っかかったポイントを残しておく。
対象読者
- Claude Code を日常的に使っているエンジニア
- ツール許可プロンプトに疲弊している人
-
.claude/settings.jsonの挙動を一度ちゃんと整理したい人
前提環境
- macOS 14.x(Darwin 24.6.0)
- Claude Code(
/permissionsコマンドが使える版) - Node.js 22.x / Python 3.13
- シェル: zsh
TL;DR
-
~/.claude/settings.jsonのpermissions.allowに Bash・MCP の安全な定型を列挙 - プロジェクト固有のものは
.claude/settings.jsonに分けて書く - Bash は
Bash(npm install:*)のように コロン + ワイルドカード が必須(これを知らないとマッチしない) -
denyはallowより強い(ここでハマりやすい) - 危険系(
rm -rf、git push --force)は明示的にdenyに入れて事故防止
これで npm / git status / gh pr / Read / Grep あたりのプロンプトはほぼ消える。
手順 / 動かし方
1. 現状確認 — 何で詰まっているかを集計
まず今出てるプロンプトの内訳を見たい。直近セッションのログを集計して、頻出ツールを並べてくれる /fewer-permission-prompts というスキルが同梱されてる。
/fewer-permission-prompts
出力イメージ(自分の環境の例):
[summary] 直近 200 セッションで許可プロンプトが出たツール上位
- Bash(npm install:*) 42 回
- Bash(git status:*) 35 回
- Bash(gh pr view:*) 18 回
- mcp__notion__fetch 12 回
- Bash(python3 -m pytest:*) 9 回
これを元に settings.json に足す候補が決まる。自分が日常的に何度も許可してるものを優先して allowlist に入れていくのが正解。最初から全部書こうとすると粒度がぶれる。
2. グローバル設定を書く
~/.claude/settings.json(全プロジェクト共通)を編集する。読み取り系・調査系は基本的に allow に入れて問題ない。
{
"permissions": {
"allow": [
"Bash(npm install:*)",
"Bash(npm run *:*)",
"Bash(git status:*)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(git show:*)",
"Bash(gh pr view:*)",
"Bash(gh pr list:*)",
"Bash(gh issue list:*)",
"Read",
"Grep",
"Glob"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force*)",
"Bash(git reset --hard*)",
"Bash(git checkout --:*)"
]
}
}
Read・Grep・Glob のような 読み取り専用ツール は丸ごと allow にして問題ない。これだけでもプロンプト数はガクッと減る。
3. プロジェクト固有を分けて書く
リポジトリ直下の .claude/settings.json にプロジェクト固有のコマンドを書く。例えば Next.js プロジェクトなら:
{
"permissions": {
"allow": [
"Bash(pnpm dev:*)",
"Bash(pnpm build:*)",
"Bash(pnpm test:*)",
"Bash(pnpm lint:*)",
"mcp__playwright__browser_snapshot",
"mcp__playwright__browser_navigate"
]
}
}
pnpm と npm のような パッケージマネージャの違い は、プロジェクト側に分離するのが運用上スッキリする。グローバルに pnpm を書いてしまうと npm プロジェクトに不要な許可が紛れ込む。
4. 再起動して確認
Claude Code を一度終了して再起動するか、/config reload で設定を再読込する。あとは普段通りに作業して、npm install や git status でプロンプトが出なくなれば成功。
確認用にわざと deny に入れたコマンド を叩いてみる:
> git push --force origin main
ここで「許可しますか?」プロンプトが出ることを確認する。これが出ないと deny が効いていない(後述のハマりどころ参照)。
ハマりどころ
(1) Bash パターンは :* がないとマッチしない
最初これに気づかなくて 1 時間溶かした。
NG な例:
"allow": ["Bash(npm install)"]
これだと 完全一致 扱いになり、npm install --save react のように引数があるとマッチしない。プロンプトが出続けて「allow に書いたのになぜ?」となる。
OK な例:
"allow": ["Bash(npm install:*)"]
:* が「以降の引数は何でもいい」のワイルドカード。Bash ツール特有の記法で、コロンが境界記号になっている点に注意。Bash(npm install*) のようにアスタリスクだけ付けても効かない。
サブコマンドが可変な場合は Bash(npm run *:*) のように コマンド側にも * を入れる。これで npm run dev・npm run build・npm run test 全部に効く。
(2) deny は allow より優先される
allow に Bash(git push:*) と書いて、deny に Bash(git push --force*) と書くと、git push --force は deny が勝つので ちゃんとプロンプトが出る。
ここで「allow に書いたんだから素通りするはず」と勘違いするとセキュリティ事故につながる。禁止したい操作は明示的に deny へ書く。allow と deny で同じパターンが衝突したら deny が勝つ、と覚えておく。
(3) グローバルとプロジェクトの優先度
優先順位は ~/.claude/settings.local.json(ローカル個人)→ .claude/settings.json(プロジェクト)→ ~/.claude/settings.json(ユーザー)の順で、より具体的な層が後勝ち。
ただし deny はどのレイヤでも有効(ユーザー層で deny したものを、プロジェクト層の allow で覆せない)。これでセキュリティを担保している。
「プロジェクトで一時的に許可したい」場合は、グローバル側を緩めるのではなく、.claude/settings.local.json に個人用 allow を追加するのが正解。
(4) MCP ツール名はフル修飾
MCP サーバーのツールを許可するときは mcp__<server>__<tool> の形式で書く。
"allow": ["mcp__notion__notion-fetch"]
ポイントは:
- サーバー名と「mcp」の区切りが アンダースコア 2 つ
- ツール名側は実際の登録名そのまま(ハイフン区切りの場合はそのまま)
これを知らないと、Notion 公式 MCP のように notion-fetch という名前のツールを許可するときに、mcp__notion__notion_fetch と打ち間違えて永遠にマッチしない、という事故が起きる。
設定後に /permissions を叩くと、実際にマッチしているルールの一覧が見えるので、書いた直後に必ず確認する。
(5) settings.local.json は git にコミットしない
.claude/settings.local.json は個人の追加 allowlist 用。.gitignore に入れておかないと、チームメンバーの設定を上書きしたり、自分の個人許可が漏れたりする。
確認方法:
grep settings.local.json .gitignore
ヒットしなかったら追加する:
echo ".claude/settings.local.json" >> .gitignore
Claude Code は初回 init で .gitignore に自動で追加してくれることが多いが、古いリポジトリだと入っていないことがあるので一度確認しておく。
背景・補足
なぜプロンプトが出る設計になっているか。Claude Code は エージェント なので、人間が監視していなくてもコマンドを実行する設計になっている。これを無制限に許すと rm -rf / のような事故が起きうる。だから「読み取り系はデフォルト許可、書き込み・実行系は確認」という基本路線が取られている。
allowlist は「自分が安全と判断したものだけ自動許可する」という権限管理の仕組みで、OS の sudoers に近い発想。自動許可するということは、自分でその安全性に責任を負うということでもある。
実運用では「読み取り系は丸ごと allow、書き込み系は個別 allow、破壊系は明示 deny」の 3 段構えにすると、楽さと安全性のバランスが取れる。
まとめ
-
/fewer-permission-promptsで頻出ツールを集計し、上から潰す - グローバル(
~/.claude/settings.json)とプロジェクト(.claude/settings.json)を使い分ける - Bash パターンは
Bash(コマンド:*)の形でワイルドカードを付ける -
denyはallowより強い、危険系は明示 deny -
.claude/settings.local.jsonは.gitignoreに入れる
これだけでプロンプト疲れは 9 割消える。フローが切れずに走り続けられるのは、長い作業ほど効いてくる。