Claude Code の Notification hook は、Claude Code が通知を送るたびに実行されます。多くの場合、許可プロンプトが応答待ちになっているとき(permission_prompt)や、Claude の処理が終わってもまだ返信していないとき(idle_prompt)です。発火タイミングは、ユーザーが離席していると思われる時点に合わせてあります。permission_prompt はプロンプトがキー入力なしで約 6 秒待機した時点で、idle_prompt は Claude の完了から約 60 秒後に発火します。hook は通知テキストを JSON で受け取りますが、処理をブロックすることはできません。デスクトップ通知やスマートフォンへの push などの副作用のために使うものです。
01通知の種類
Notification hook の matcher には通知の種類を指定します。空にするとすべての種類で実行され、対象を絞りたい場合は | で区切って列挙します。よく使う種類は次のとおりです。
permission_promptClaude がツールの使用(またはサンドボックス内のコマンドのネットワークリクエスト)の承認を求めており、プロンプトが約 6 秒待機しているidle_promptClaude の応答が約 60 秒前に完了し、その後入力がないelicitation_dialogMCP サーバーがフォームを開き、約 6 秒間入力がないelicitation_url_dialogMCP サーバーが URL を開くよう求め、約 6 秒間入力がないauth_success認証が完了したほかにも、エージェントビューのバックグラウンドセッション向けの agent_needs_input や agent_completed、使用量制限による待機向けの quota_auto_resume_* 系の種類などがあります。最新の完全な一覧はhooks リファレンスを参照してください。
02タイミングのルール
ここがつまずきやすいポイントです。Notification hook は Claude Code 自身のデスクトップ通知と同じタイミングで動くため、terminal セッションでは画面から目を離しているときにしか発火しません。
permission_promptは、prompt が表示された時点で約 6 秒のタイマーを開始します。キー入力のたびにタイマーはリセットされるため、すぐに応答すれば発火することはありません。idle_promptは、Claude が処理を終えてから約 60 秒後、その間に入力がなく、バックグラウンドのエージェントも動いていない場合にのみ発火します。Claude Code が使用量制限のリセットを待っている間は発火しません。- 別のダイアログが開いている間に届いたリクエストは、届いた時点から計時されます。そのため、開いているダイアログの後ろでまだ待機している段階で通知が届くことがあります。
Claude Desktop や VS Code 拡張機能など、Agent SDK 経由で権限に応答するホストでは、permission_prompt のタイミングが異なります。リクエストから約 6 秒後に発火し、入力による延期はなく、あなたや PermissionRequest hook が先に応答した場合はスキップされます。
遅延なしで通知を受け取りたい場合は、別のイベントを使ってください。
PermissionRequestStopidle_prompt を指定した Notification03hook が受け取るデータ
Notification hook は、共通フィールド(session_id、transcript_path、cwd、hook_event_name)に加えて、通知の message、省略可能な title、そして notification_type を受け取ります。
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"hook_event_name": "Notification",
"message": "Claude needs your permission",
"title": "Permission needed",
"notification_type": "permission_prompt"
}
message は Claude Code 自身の文言なので、そのまま表示しても問題ありません。複数のセッションを実行していて、どのプロジェクトからの要求かを知りたい場合は cwd が便利です。
04hook にできること・できないこと
Notification hook は、通知をブロック・遅延・変更することはできません。終了コードと stderr は無視され、JSON 出力の systemMessage と continue も Claude Code によって破棄されます。用途は副作用を起こすことだけです。
使える出力フィールドが 1 つだけあります。terminalSequence です。hook は terminal なしで実行されるため自分でエスケープシーケンスを書き込めませんが、Claude Code に渡して出力してもらうことはできます。これにより、tmux 内であっても、iTerm2、Ghostty、Kitty、WezTerm、Windows Terminal などで terminal ネイティブの通知を表示できます。ただし、Claude Code の画面が表示されている対話セッションでのみ機能します。
preferredNotifChannel 設定でも hook は止まりません。組み込みの通知をオフにしても、Notification イベントは発火します。この設定が変えるのは Claude Code 自身の通知方法だけです。詳しくはterminal ベルのガイドを参照してください。
05例
タイプごとに別のハンドラーを使う
権限 prompt とアイドル時のリマインダーで、別々のスクリプトを実行します。
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [{ "type": "command", "command": "~/.claude/hooks/permission-alert.sh" }]
},
{
"matcher": "idle_prompt",
"hooks": [{ "type": "command", "command": "~/.claude/hooks/idle-alert.sh" }]
}
]
}
}
各スクリプトは chmod +x で実行可能にしてください。Mac、Windows、Linux 向けのデスクトップ通知コマンドはClaude Code の完了時に通知を受け取る方法で紹介しているので、ここでは省略します。
実際のメッセージとプロジェクトを表示する
このスクリプト(macOS と Linux 向け)は、固定の文字列ではなく Claude Code のメッセージとプロジェクトフォルダを通知に表示します。
#!/bin/bash
# ~/.claude/hooks/notify.sh
input=$(cat)
msg=$(jq -r '.message // "Claude Code needs your attention"' <<<"$input")
project=$(basename "$(jq -r '.cwd // "."' <<<"$input")")
if command -v osascript >/dev/null 2>&1; then
osascript -e 'on run argv' \
-e 'display notification (item 1 of argv) with title (item 2 of argv)' \
-e 'end run' "$msg" "Claude Code: $project"
elif command -v notify-send >/dev/null 2>&1; then
notify-send "Claude Code: $project" "$msg"
fi
exit 0
テキストを引数(on run argv)として渡すことで、メッセージに引用符が含まれていても AppleScript が壊れません。jq のインストールが必要です。
terminal ネイティブの通知
Anthropic 公式の例では、terminalSequence で OSC 777 を使っています。これは Ghostty、Warp、urxvt が対応しています。
#!/bin/bash
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}'
iTerm2、Windows Terminal、WezTerm では OSC 9 を、Kitty では OSC 99 を使ってください。許可されたシーケンス以外は無視されます。
06Claude Code Notifier の位置づけ
push サービスを呼び出す Notification hook を使えばスマートフォンに通知を届けられ、多くの人にはそれで十分です。その方法は ntfy ガイドで紹介しています。
足りないのは返信です。permission_prompt が発火した時点で、Claude は Notification hook では応答できないダイアログで待機しています。Claude Code Notifier は、応答が可能な hook でこれを解決します。PermissionRequest で判断を返し、AskUserQuestion に対する PreToolUse で回答を返します。無料のコマンドラインツール ccn は Mac、Windows、Linux で動作し、単体でもデスクトップ通知を表示します。iPhone または Android アプリとペアリングすれば、スマートフォンから「今回のみ許可」「セッション中は許可」「拒否」を選べます。直近 30 秒以内に入力していた場合はスマートフォンを待たず、通常どおり terminal で確認されます。本ツールは独立したもので、Anthropic 製ではありません。インストール方法は ccn のページにあります。
07よくある質問
Notification hook がまったく発火しないのはなぜですか?
多くの場合、まだキーボードの前にいるからです。キー入力のたびに permission_prompt は延期され、idle_prompt は Claude の完了後、約 1 分間入力がない場合にのみ発火します。テストするには、権限 prompt を発生させてから別のウィンドウに切り替え、6 秒以上待ってください。それでも発火しない場合は、/hooks に表示されているか確認し、トラブルシューティングのチェックリストを参照してください。
idle_prompt とは何ですか?
Claude が応答を終えてから約 60 秒経ち、その間に入力がない場合に Claude Code が送る通知タイプです。「完了した」ことを即座に知らせるものではなく、あなたの番であることを知らせるリマインダーです。即時の完了通知には Stop hook を使ってください。
Notification hook で権限を承認できますか?
できません。Notification hook には判断を制御する機能がないため、何を出力しても prompt には応答できません。許可・拒否を行うには、PermissionRequest ガイドで説明しているように PermissionRequest hook を使ってください。
preferredNotifChannel を notifications_disabled に設定しても Notification hook は実行されますか?
はい。この設定で変わるのは Claude Code 自身による通知方法だけです。Notification イベントと hook はそのまま実行されます。
通知が2回届くのはなぜですか?
Claude Code の組み込み通知と hook が並行して動作しているためです。iTerm2、Ghostty、Kitty では両方が表示されることがあります。preferredNotifChannel などでどちらかを無効にするか、hook だけを残してください。