CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKSで通知を止める
Claude DesktopやVS Code拡張機能がcanUseTool経由でホストするセッションで、Notification hookのpermission_prompt通知だけを止める環境変数を解説します。
Claude DesktopやVS Code拡張機能でClaude Codeを動かしていると、権限確認のたびにNotification hookのpermission_promptが発火します。すでに自作スクリプトで外部サービスへ通知を転送している場合、ホスト側の確認ダイアログと合わせて二重に鳴ることがあります。CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKSを1に設定すると、この特定のセッション形態でだけpermission_prompt通知を止められます。
CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKSとは
CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKSとは、Claude Codeが権限確認をAgent SDKのcanUseToolコールバックへ送るセッションで、Notification hookのpermission_prompt通知だけを止める環境変数です。Claude DesktopとVS Code拡張機能は、このcanUseTool経由でClaude Codeをホストしています。
1に設定すると、これらのホストが動かすセッションだけでpermission_promptが発火しなくなります。ターミナルから直接claudeを起動するセッションには影響しません。Claude Code v2.1.233以降が必要です。
permission_prompt通知はv2.1.233から動くようになった
この環境変数が意味を持つ背景には、permission_prompt自体の挙動変更があります。Claude Code v2.1.233より前は、Claude DesktopやVS Code拡張機能がホストするセッションで、Notification hookのpermission_promptがそもそも発火しませんでした。公式changelogのv2.1.233には、この不具合の修正が記載されています。
同じv2.1.233でpermission_promptは発火するようになりましたが、タイミングはターミナルセッションと異なります。通常のターミナルセッションでは、プロンプトが表示されてから約6秒間キー入力が無い場合に発火し、キー入力のたびにタイマーが延びます。canUseTool経由のセッションでは、キー入力による延長がなく、権限確認が表示されてから一律で約6秒後に発火します。ユーザーかPermissionRequest hookが先に応答すれば、permission_prompt自体が発火しません。
つまりv2.1.233は、以前は鳴らなかった通知を新しく鳴るようにした変更です。CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKSは、その新しい挙動を選んで元に戻すための設定です。
設定方法
シェルの環境変数として設定するか、チームで揃えたいならsettings.jsonのenvブロックに書きます。
export CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS=1
claudeプロジェクト共有の設定にする場合は、.claude/settings.jsonに次のブロックを追加します。
{
"env": {
"CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS": "1"
}
}環境変数は起動時に一度だけ読み込まれます。設定を変えても、すでに起動しているセッションには反映されないため、claudeを再起動してください。
シェルのexportとsettings.jsonのenvブロックの両方で同じ変数を設定した場合は、envブロック側の値が優先されます。ユーザー設定・プロジェクト設定・管理者設定のように複数の設定ファイルが同じ変数を設定しているときも、優先順位の高い設定ファイルの値が採用されます。この変数はモデル選択やタイムアウトと同じ「安全な機能トグル」に分類されており、プロジェクト・ローカル設定のenvブロックからでも起動時に読み込まれます。
Notification hookが受け取る入力
Notificationのhookは、session_id・cwd・hook_event_nameなど全hook共通のフィールドに加えて、message(通知本文)・title(任意の見出し)・notification_type(発火した通知の種類)を受け取ります。permission_promptを止めたいときは、notification_typeがpermission_promptのケースだけをmatcherで絞り込むか、この環境変数でセッション単位に止めます。
{
"session_id": "abc123",
"cwd": "/Users/.../my-project",
"hook_event_name": "Notification",
"message": "Claude needs your permission",
"title": "Permission needed",
"notification_type": "permission_prompt"
}Notification hookは通知を止めたり内容を書き換えたりはできません。systemMessageやcontinueフィールドを返しても無視されます。外部サービスへの転送やログ保存のような副作用のためのhookです。
似た設定・hookとの違い
permission_promptとその周辺には、名前や役割が紛らわしい設定がいくつかあります。
| 設定 / hook | 効果 | この環境変数との違い |
|---|---|---|
disableAllHooks | 効果すべてのhookの実行を止める | この環境変数との違いpermission_promptだけでなく全hookが止まる。個別のhookだけを選んで無効化する方法は無い |
PermissionRequest hook | 効果権限確認が出た瞬間に発火する専用のhook event | この環境変数との違いpermission_promptは約6秒待ってから発火する通知用。即座に判定したいならこちらを使う |
preferredNotifChannel | 効果デスクトップ通知かターミナルベルか、通知の届け方を選ぶ設定 | この環境変数との違いhookが動くかどうかには関与しない。設定を変えてもhook自体は変わらず発火する |
CLAUDE_CODE_DISABLE_NOTIFICATION_PRESENCE_CHECK | 効果PushNotificationツールの在席判定を無効化する | この環境変数との違い対象がNotification hookではなくPushNotificationツール。別の通知経路を制御する |
disableAllHooksはhookの設定自体を丸ごと止めるため、他のNotification hookやPreToolUse hookも道連れになります。permission_promptだけを狙って止めたいなら、CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKSのほうが影響範囲を絞れます。
PermissionRequest hookは、通知を出すだけのNotification hookと違い、権限確認そのものに答えられます。behaviorに"allow"か"deny"を返すことで、ユーザーに代わって許可・拒否を決められ、"allow"のときはupdatedInputでツールの入力を書き換えたり、updatedPermissionsで許可ルールを追加したりもできます。"deny"のときはmessageで理由をClaudeへ伝え、interruptをtrueにすればClaudeの処理自体を止められます。ここで先に応答が返れば、permission_promptのNotification hook自体が発火しません。
ただしPermissionRequest hookが代われるのはツール使用の許可確認だけです。サンドボックス化されたコマンドがネットワークへアクセスしようとしたときの確認はPermissionRequest hookの対象外で、シグナルを取りたければpermission_promptのNotification hookを使うしかありません。ターミナルセッションでこのネットワークアクセス確認にpermission_promptが発火するにはClaude Code v2.1.246以降が必要で、ツール使用の確認自体はそれより前のバージョンから対象でした。
canUseToolセッションで通知が二重になりやすい理由
Claude DesktopとVS Code拡張機能は、権限確認のダイアログを自前のUIで表示します。canUseToolコールバックが呼ばれた時点で、ユーザーはすでにそのホストの画面上で承認・拒否を選べる状態です。
そこへNotification hookのpermission_promptが約6秒後に追加で発火します。hook側で外部サービスへ転送する設定をしていれば、同じ権限確認について二重の通知が届くことになります。ターミナルセッションでは「席を外している間だけ」鳴る設計だったpermission_promptが、canUseToolセッションではキー入力に関係なく一律で鳴るようになったぶん、この重複は目につきやすくなります。
外部サービスへの転送自体をやめたくない場合は、Notification hookのmatcherにpermission_promptを残したままにします。ターミナルセッションでは転送を続けつつ、canUseTool経由のセッション(Claude DesktopやVS Code拡張機能)でだけ、この環境変数でpermission_promptだけを個別に止められます。
Notification hookの設定は、どこに書くかで有効範囲が変わります。~/.claude/settings.jsonに書けば自分の全プロジェクトに適用され、.claude/settings.jsonに書けばプロジェクト単位でチームに共有できます。転送先が個人のSlack宛先のようにマシン固有の値なら~/.claude/settings.jsonか.claude/settings.local.json(gitignore対象)に置き、リポジトリへコミットしないようにします。
デスクトップ通知を出すNotification hookの例
公式ドキュメントに掲載されているNotification hookの例では、messageフィールドをデスクトップ通知として表示します。
#!/bin/bash
# Notification hook: ping the desktop when Claude Code needs attention.
input=$(cat)
title="Claude Code"
body=$(jq -r '.message // "Needs your attention"' <<<"$input")
seq=$(printf '\033]777;notify;%s;%s\007' "$title" "$body")
jq -nc --arg seq "$seq" '{terminalSequence: $seq}'このスクリプトをNotificationのmatcherにpermission_promptを指定して登録している場合、canUseToolセッションではCLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS=1を設定するだけでこの経路が止まります。hookの登録自体を書き換える必要はありません。TaskCreated/TaskCompletedフックで進捗を外部通知するように、Notification hook以外の経路で外部通知を組んでいる場合は、そちらへは影響しません。
つまずきやすい点
設定したのにpermission_promptがまだ鳴る: 主な原因は3つです。ターミナルセッションでclaudeを起動している(この環境変数はcanUseTool経由のセッションにしか効きません)、設定を変えた後にセッションを再起動していない、あるいはenvを書いた設定ファイルより優先度の高い設定ファイルが同じ変数を上書きしている、のいずれかを順に確認します。
変数を設定しても何も変わらない: claude --versionでv2.1.233以上か確認します。それより前のバージョンではcanUseToolセッションでpermission_prompt自体が発火しないため、この環境変数を設定しても効果はありません。
すでに起動中のセッションで反映されない: 環境変数は起動時に一度だけ読み込まれます。設定を変えたら、そのセッションを一度終了してclaudeを起動し直します。
ターミナルセッションでも止まると思っていた: この環境変数が対象にしているのはcanUseTool経由のセッションだけです。ターミナルセッションのpermission_prompt(約6秒間キー入力が無いと発火する通知)を止めたい場合は、Notification hookの設定自体をpermission_promptにマッチしないよう変えるか、disableAllHooksで全hookを止める必要があります。
disableAllHooksで代用しようとして他のhookも止まった: disableAllHooksは個別のhookを選んで無効化する仕組みではありません。permission_promptだけを狙うなら、この環境変数のほうが影響範囲を絞れます。
他の通知タイプも止まると思っていた: Notificationのhookをmatcher無しで登録していると、idle_promptやelicitation_dialogなど他の通知タイプは引き続き発火します。この環境変数が止めるのはpermission_promptだけで、他のタイプを止めたい場合は個別にmatcherを外すか設定を変える必要があります。
まとめ
CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS=1は、Claude DesktopやVS Code拡張機能がcanUseTool経由でホストするセッションだけで、Notification hookのpermission_prompt通知を止めます。ターミナルセッションには効果がなく、Claude Code v2.1.233以降が必要です。
すべてのhookを止めたいならdisableAllHooks、権限確認の瞬間に反応させたいならPermissionRequest hook、通知の届け方だけを変えたいならpreferredNotifChannelを使います。目的が「canUseToolセッションのpermission_promptだけを消したい」であれば、この環境変数がもっとも狙いを絞った選択肢です。設定後にまだ挙動が変わらないと感じたら、まずclaude --versionでv2.1.233以上か、そしてセッションを再起動したかの2点から切り分けてください。