Claude Code の通知が届かなくなる原因は、ほぼ次の 4 つのいずれかです。hook が読み込まれていない、hook は実行されているが失敗している、頼りにしているイベントが想定したタイミングで発火していない、OS が通知を表示していない。まず Claude Code 内で /hooks を実行して読み込まれている hook を確認し、次に claude --debug でセッションを開始して各 hook が実際にどう動いたかを確認します。最後に、コンピューターやスマートフォンの通知設定をチェックしてください。Claude Code Notifier を使っている場合は、ccn doctor と ccn test の 2 つのコマンドでこの大部分を確認できます。
以下のチェックリストは、よくある原因から順に並べています。Mac、Windows、Linux のいずれでも使えます。
011. Claude Code が hook を読み込んでいるか確認する
Claude Code の prompt で /hooks と入力します。これは Claude Code が読み込んだすべての hook を一覧できる読み取り専用のブラウザーで、それぞれの出どころ(ユーザー設定、プロジェクト設定、ローカル設定、プラグイン、現在のセッション)が表示されます。hook を選択すると、実行されるコマンドと定義元のファイルを確認できます。
一覧に hook が表示されない場合:
- JSON が不正です。設定ファイルは厳密な JSON です。末尾のカンマや
//コメントがあるとファイルが壊れ、次回起動時に Claude Code が Settings Error を表示します。claude doctorを実行すると、Claude Code が受け付けなかった項目を確認できます。 - ファイルの場所が違います。個人用の hook は
~/.claude/settings.json(Windows では%USERPROFILE%\.claude\settings.json)に、プロジェクト用の hook はプロジェクト内の.claude/settings.jsonに置きます。/statusを実行し、Setting sourcesの行で読み込まれたファイルを確認してください。 - イベント名が間違っています。イベント名は大文字と小文字を区別します(
Notification、Stop、PermissionRequest)。不明なイベント名は Settings Warning として表示され、スキップされます。 - hook が無効化されています。いずれかの設定ファイルに
"disableAllHooks": trueがあると、すべての hook が無効になります。/hooksにOnly hooks from managed settings run hereと表示される場合は、組織がallowManagedHooksOnlyを設定しているため、自分で追加した hook は実行されません。 - 編集が反映されていません。Claude Code は通常、設定を自動で再読み込みします。数秒経っても hook が表示されない場合は、セッションを再起動してください。
022. ワークスペースの信頼を承認する
対話セッションでは、フォルダーのワークスペース信頼ダイアログを承認するまで、Claude Code はすべての設定ファイル(自分の ~/.claude/settings.json も含む)の hook を保留します。このダイアログを閉じてしまった場合や、一度も Claude Code を開いたことのないフォルダーでは、hook は実行されません。そのフォルダーで claude を起動し、ダイアログを承認してください。
033. イベントが想定どおりのタイミングで発火しているか確認する
「通知が壊れている」ように見えるケースの多くは、実はタイミングの問題です。Anthropic の hooks リファレンスによると:
Notification(permission_prompt)許可を求める prompt が表示されてから、入力がないまま約 6 秒経過したとき。キー入力のたびにタイマーはリセットされます。idle_prompt を指定した NotificationClaude の処理完了から約 60 秒後。ただし入力がなく、バックグラウンドのエージェントも動いていない場合に限ります。StopClaude が応答を終えるたび。中断時は発火しません。API エラー時は代わりに StopFailure が発火します。PermissionRequestClaude Code が許可を求めようとした瞬間。そのため、terminal で入力しながら Notification hook をテストすると、いつまでも発火しないことがあります。別のウィンドウに切り替えて待ってみてください。ターンが終わった瞬間に通知したい場合は Stop を使います。詳しくは Stop hook ガイドを参照してください。
パーミッションモードも確認しましょう。最近の Claude Code では、対話セッションが auto モードで開始され、分類器がほとんどの操作を確認なしで承認します。prompt が出なければ、permission_prompt の通知も PermissionRequest hook も発生しません。許可の通知をテストするには、ステータスバーに manual モードと表示されるまで Shift+Tab を押し、承認が必要な操作を Claude に依頼してください。詳しくはパーミッションモードの解説をご覧ください。
matcher も大文字と小文字を区別します。PermissionRequest の matcher を bash にすると、Bash ツールにはマッチしません。
044. hook のコマンドを自分で実行してみる
/hooks からコマンドをコピーし、サンプル入力を渡して terminal で実行します:
echo '{"hook_event_name":"Stop","cwd":"/tmp","last_assistant_message":"done"}' | ./my-hook.sh
echo $?
よくある失敗:
command not found:スクリプトを絶対パスで指定するか、プロジェクト内のスクリプトなら${CLAUDE_PROJECT_DIR}を使ってください。- スクリプトがまったく動かない:
chmod +x ./my-hook.shで実行権限を付けてください。 jq: command not found:jqをインストールするか、Python や Node.js で JSON をパースしてください。
055. デバッグログを確認する
claude --debug で Claude Code を起動します。terminal には何も追加表示されず、ログは ~/.claude/debug/<session-id>.txt に出力されます。出力先を指定したい場合は claude --debug-file /tmp/claude.log を使い、別の terminal で tail -f /tmp/claude.log を実行します。すでにセッションが動いている場合は、/debug でログを有効にでき、ログの場所も表示されます。
Hooks: で始まる行を探してください。各行にはイベント、コマンド、終了状態(finished with status 0、timed out、failed to start)、所要時間が記録されています。マッチングをさらに詳しく見たい場合は、CLAUDE_CODE_DEBUG_LOG_LEVEL=verbose を設定します。
次の 2 つの問題は、ここでしか確認できません:
- シェルのプロファイルが何かを出力している。
~/.bashrcや~/.zshrcでechoを実行していて、シェルがそれを読み込むと、その文字列が hook の JSON 出力の前に入り込み、Claude Code は出力をプレーンテキストとして扱います。ログでHook output does not start with {を検索してください。プロファイルの出力はif [[ $- == *i* ]]; then ... fiで囲み、対話シェルでのみ実行されるようにします。 - 書き込み先の terminal がない。Mac と Linux では、コマンド hook は制御端末なしで実行されます。ベルを鳴らしたり
/dev/ttyにエスケープコードを書き込もうとする hook は、何も言わずに失敗します。代わりにデスクトップ通知のコマンドを使うか、Claude Code 自体のpreferredNotifChannel設定を使ってください。詳しくはterminal ベルのガイドで解説しています。
066. OS の設定を確認する
デバッグログで hook がステータス 0 で終了しているのに何も表示されない場合は、OS が通知を非表示にしています。通知を出しているアプリに通知の表示が許可されているか、また集中モード(Mac)、応答不可(Windows)、Linux デスクトップのおやすみモードがオフになっているかを確認してください。Linux では通知デーモンが起動している必要があります。
07Claude Code Notifier を使っている場合
Claude Code Notifier は独立したツール(Anthropic 製ではありません)で、ccn という小さなプログラムを Claude Code の hook としてインストールします。ccn も他と同じ hook なので、ここまでの内容はすべて当てはまります。まずは専用のチェックから始めてください。
ccn doctorは hook、認証情報、サーバーへの接続、在席検知をチェックします。何か報告されたら、まずそれを修正してください。ccn testはテスト通知を送信します。届くなら、問題はパイプラインではなくイベントか設定にあります。ccn devicesはこのコンピューターとペアリングされたスマートフォンを一覧表示します。何も表示されない場合はccn pairで再度ペアリングしてください。手順はペアリングガイドで説明しています。ccn config showは有効な設定を表示します。notify_on_done、notify_on_permission、notify_on_questionがオンになっているか、quiet_hoursが現在時刻にかかっていないかを確認してください。スマートフォンで変更した設定はccn syncでコンピューターに反映されます。
不具合のように見えても、仕様どおりの動作がいくつかあります。
- キーボードの前にいる場合。直近 30 秒以内に入力していれば、スマートフォンを待たずにいつもどおり terminal で確認されます。
quiet_when_presentがオン(デフォルト)の場合、Claude が動いている terminal を使っている間はスマートフォンに何も送られず、別のアプリを操作中なら情報カードが届きます。 - Mac で通知が重複する・届かない。旧 Mac メニューバーアプリと
ccnを同じ Mac で併用しないでください。 - 長期間使っていない場合。スマートフォンやコンピューターを 60 日間使わないと、サーバーがそのペアリングを削除するため、再度ペアリングが必要です。
スマートフォン側では、アプリの通知が許可されているか、集中モード(iPhone)やサイレントモード(Android)で通知が消音されていないかを確認してください。Android では、バッテリーの最適化によって一部のアプリの通知が遅れることがあります。通知が遅れて届く場合は、アプリのバッテリー設定で制限なしに設定してください。settings.json を手動で編集した場合は、ccn doctor で hook が残っているか確認できます。ccn upgrade で最新リリースに更新できます。
08よくある質問
Notification hook がときどきしか発火しないのはなぜですか?
permission_prompt と idle_prompt は、ユーザーが離席していると判断されたタイミングで発火します。permission_prompt は入力がない状態で約 6 秒、idle_prompt は Claude の完了から約 60 秒待ちます。入力中は先送りされます。すぐに通知したい場合は PermissionRequest または Stop を使ってください。
Claude Code のデバッグログはどこにありますか?
claude --debug を実行すると、ログが ~/.claude/debug/<session-id>.txt に書き出されます。保存先を指定するには claude --debug-file <path> を、実行中のセッション内では /debug を使います。
ccn test は動くのに、実際の通知が届かないのはなぜですか?
パイプラインは正常なので、設定とタイミングを確認します。ccn config show で notify_on_* と quiet_hours を確認してください。quiet_when_present がオンだと terminal の前にいる間は何も送信されない点にも注意し、Claude Code の権限モードも確認してください。