Claude Code → phone push notifications via ntfy.sh (free, no account).
One ping per prompt-cycle. You receive at most one push per prompt-cycle, with a message that says what happened:
- Claude has a question — it called the
AskUserQuestiontool. - Claude is waiting — it went idle waiting on you (
Notification/idle_prompt). - Claude is done — it finished a turn (
Stop).
Only interactive Desktop sessions ping. Headless / scheduled / SDK runs (claude -p, cron jobs, background scheduled tasks) are gated out, so automation never notifies your phone. A global on/off flag (~/.claude/ping_enabled) is the kill switch.
Topic security: ntfy.sh topics are a public namespace — anyone who knows your topic name can read and post to it. Use a random, unguessable string (e.g.
my-claude-f3a8) and never commit the literal topic to a public repo. The notification body also includes your working-directory's folder name; if that could be sensitive, replace$projinping_notify.ps1with a fixed string.
- No end-to-end privacy. ntfy.sh topics are unauthenticated (see above) — treat every pushed message body as readable by anyone who guesses or leaks the topic name.
- No automated tests or CI. Verification is the manual
ping_check.ps1diagnostic (see Install step 6), which confirms the hook wiring and that ntfy accepted the POST — it does not prove the push reached your phone. - Windows / PowerShell only. No macOS or Linux script is shipped (see Extension points in workflow.md for a porting sketch).
Windows, PowerShell 5.1+, curl.exe (bundled since Windows 10 1803). No PS7-only syntax is used.
- Copy the scripts into place:
Copy-Item ping_notify.ps1 "$env:USERPROFILE\.claude\hooks\ping_notify.ps1" Copy-Item ping_check.ps1 "$env:USERPROFILE\.claude\ping_check.ps1" Copy-Item toggle_ping.ps1 "$env:USERPROFILE\.claude\toggle_ping.ps1"
- Edit
~/.claude/hooks/ping_notify.ps1and replace the$topic = '<YOUR-TOPIC>'placeholder with your own random, unguessable ntfy topic name. - Merge the four hook entries from
settings.snippet.jsoninto~/.claude/settings.jsonunderhooks(replace<USER>with your Windows username; if you already have otherPreToolUse/UserPromptSubmit/Stopentries, add these as extra array items, don't overwrite them). - Turn notifications on:
powershell -NoProfile -File "$env:USERPROFILE\.claude\toggle_ping.ps1"
- In the ntfy mobile app, subscribe to your topic name.
- Start a new Claude Code session (hook wiring only takes effect on new sessions), then verify:
Expect 3 phone notifications: "Claude has a question", "Claude is waiting", "Claude is done".
powershell -NoProfile -File "$env:USERPROFILE\.claude\ping_check.ps1"
| File | Purpose |
|---|---|
ping_notify.ps1 |
The hook script. One entry point for all four events; dispatches on hook_event_name, gates out background/headless runs, sends at most one ping per prompt-cycle, then POSTs to ntfy.sh via curl.exe. Messages are defined inline in its $msg map. |
ping_check.ps1 |
Diagnostic — verifies the flag, the script, the four-hook wiring, and POSTs the three tailored test pings directly to ntfy. Also purges stale per-session state (>7 days). |
settings.snippet.json |
The four hook entries to merge into ~/.claude/settings.json. |
toggle_ping.ps1 |
Flip the on/off kill-switch flag in one command. |
ping_messages.json |
Legacy — an earlier config-driven message file. The current ping_notify.ps1 defines messages inline and does not read this; kept for reference. |
MIT (LICENSE).