claude-code-notifier
how it works guides faq
◐English
English العربية Deutsch Español Français עברית Italiano 日本語 한국어 Nederlands Polski Português (Brasil) Русский Türkçe Tiếng Việt 简体中文 繁體中文
Get started
All guides

Claude Code push notifications with ntfy (do it yourself)

Updated 31 October 2026 · 6 min read
on this page 01Step 1: pick a topic and subscribe 02Step 2: a hook script (Mac and Linux) 03Step 3: wire it into settings.json 04Windows (PowerShell) 05Keeping it private 06Where Claude Code Notifier fits 07FAQ

To get Claude Code push notifications with ntfy, install the ntfy app on your phone, subscribe to a topic with a hard-to-guess name, and add a Claude Code hook that runs curl -d "message" https://ntfy.sh/your-topic. A Notification hook tells you when Claude needs a permission or is waiting for you, and a Stop hook tells you the moment a turn ends. It is free, takes about ten minutes, and works on Mac, Windows and Linux.

01Step 1: pick a topic and subscribe

ntfy has no sign-up. A topic is created the first time someone publishes or subscribes to it, and anyone who knows the name can read it. ntfy's own documentation says the topic is essentially a password, so make it long and random, for example claude-7f3k9q2xw4mz. Topic names can use letters, numbers, underscores and dashes, up to 64 characters.

Install the ntfy app (App Store, Google Play or F-Droid), tap +, and subscribe to your topic on ntfy.sh.

Check it works from a terminal:

curl -H "Title: Test" -d "Hello from my computer" https://ntfy.sh/claude-7f3k9q2xw4mz

The phone should buzz within a second or two. On Windows, curl.exe ships with Windows 10 and 11 and accepts the same line.

02Step 2: a hook script (Mac and Linux)

Claude Code passes each hook a JSON object on standard input. Both events share fields such as cwd and hook_event_name. Notification adds message and notification_type, and Stop adds last_assistant_message, the text of Claude's final reply. This script turns either into a readable push. It needs jq (brew install jq, or apt install jq on Debian and Ubuntu).

Save it as ~/.claude/ntfy-notify.sh and run chmod +x ~/.claude/ntfy-notify.sh:

#!/bin/sh
TOPIC_URL="https://ntfy.sh/claude-7f3k9q2xw4mz"

input=$(cat)
event=$(printf '%s' "$input" | jq -r '.hook_event_name')
project=$(basename "$(printf '%s' "$input" | jq -r '.cwd')")

if [ "$event" = "Stop" ]; then
  title="Claude finished: $project"
  body=$(printf '%s' "$input" | jq -r '(.last_assistant_message // "Done") | .[0:300]')
  priority=3
else
  title="Claude needs you: $project"
  body=$(printf '%s' "$input" | jq -r '.message // "Needs your attention"')
  priority=4
fi

curl -s -H "Title: $title" -H "Priority: $priority" -H "Tags: robot" \
  -d "$body" "$TOPIC_URL" > /dev/null
exit 0

Priority runs from 1 (min) to 5 (urgent). Tags adds an emoji to the notification; robot shows a robot face.

03Step 3: wire it into settings.json

Add the hooks to ~/.claude/settings.json. If the file already has a hooks object, add these events inside it rather than replacing it.

{
  "hooks": {
    "Notification": [
      {
        "matcher": "permission_prompt",
        "hooks": [
          { "type": "command", "command": "~/.claude/ntfy-notify.sh" }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          { "type": "command", "command": "~/.claude/ntfy-notify.sh", "async": true }
        ]
      }
    ]
  }
}

"async": true lets the Stop hook send in the background, so a slow network never delays Claude. Start a new Claude Code session, because hooks load when a session starts.

Stop or idle_prompt?

Stop fires the moment Claude finishes, even if you are sitting at the keyboard. If that is too much, drop the Stop block and use the matcher permission_prompt|idle_prompt instead. Anthropic's documentation says idle_prompt fires about 60 seconds after Claude finishes, only if you have not typed since, and permission_prompt fires once a permission prompt has waited about six seconds without a keystroke. That gives you a rough "only when I am away" filter for free. The Notification hook guide and the Stop hook guide cover every field and timing.

04Windows (PowerShell)

On Windows, save this as %USERPROFILE%\.claude\ntfy-notify.ps1. It needs nothing extra installed:

$in = [Console]::In.ReadToEnd() | ConvertFrom-Json
$project = Split-Path $in.cwd -Leaf

if ($in.hook_event_name -eq 'Stop') {
  $title = "Claude finished: $project"
  $body = [string]$in.last_assistant_message
  if ($body.Length -gt 300) { $body = $body.Substring(0, 300) }
  $priority = '3'
} else {
  $title = "Claude needs you: $project"
  $body = [string]$in.message
  $priority = '4'
}

Invoke-RestMethod -Method Post -Uri 'https://ntfy.sh/claude-7f3k9q2xw4mz' `
  -Headers @{ Title = $title; Priority = $priority } `
  -Body ([Text.Encoding]::UTF8.GetBytes($body)) | Out-Null

Then use this hook entry in place of the command lines above:

{
  "type": "command",
  "shell": "powershell",
  "command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"$HOME\\.claude\\ntfy-notify.ps1\""
}

If you run Claude Code inside WSL, use the Mac and Linux script instead; WSL is Linux as far as the hook is concerned.

05Keeping it private

Everything in the push goes through the ntfy server, and on ntfy.sh anyone with the topic name can read it. The Stop message above includes the start of Claude's reply, which can contain code or file names. Three ways to tighten this:

  1. Send less. Replace the Stop body with a fixed string such as "Done" and keep only the project name in the title.
  2. Use an access token. ntfy accepts -H "Authorization: Bearer tk_..." on any publish. On your own server, set auth-default-access: "deny-all", create a user with ntfy user add, and create a token with ntfy token add.
  3. Host your own server. ntfy is self-hostable. For instant delivery to the iPhone app, ntfy's docs say to set upstream-base-url: "https://ntfy.sh", which forwards only a message ID and a topic hash to ntfy.sh so it can wake the phone; the app then fetches the message from your server.

If Claude Code runs on a remote server, the same hook works there unchanged, which makes ntfy a good fit for notifications over SSH.

06Where Claude Code Notifier fits

For one-way alerts, the setup above is a complete answer and we would not talk you out of it. It stops at telling you. When the push says Claude needs a permission, the session still waits until you get back to the keyboard.

ntfy does support action buttons that make an HTTP request, so you could build a reply path yourself: a PermissionRequest hook that publishes the request, waits for a response on a second topic, and returns a decision. Some open source projects do exactly that (see the comparison).

Claude Code Notifier packages that path. With a phone paired, you can allow once, allow for the session or deny a permission, pick an answer when Claude asks a question, and send the next instruction after Claude finishes, all from the phone. It also checks presence: if you typed in the last 30 seconds, the terminal asks as usual and nothing waits on the phone. If you are away, the terminal waits for your answer up to a ceiling you set, and stops waiting the moment you touch the keyboard. ccn runs on Mac, Windows and Linux; see the ccn page and pricing for the phone apps.

07FAQ

Is ntfy free for Claude Code notifications?

Publishing to and subscribing on ntfy.sh needs no account, and the server is open to anyone. ntfy also offers a paid tier and can be self-hosted. Check ntfy's own site for current limits.

Why does my ntfy hook not fire?

Start a new Claude Code session after editing settings.json, since hooks load at startup. Then run the curl test line by hand, and pipe sample JSON into the script, for example echo '{"hook_event_name":"Stop","cwd":"/tmp/x"}' | ~/.claude/ntfy-notify.sh. The troubleshooting checklist covers the rest.

Can I reply to Claude Code from an ntfy notification?

Not with a plain publish. ntfy's HTTP action buttons can send a request, but you need a hook that waits for the answer and turns it into a decision Claude Code understands.

Do I get a push for every notification type?

Only for the matchers you list. Omit matcher on the Notification entry to receive every type, including authentication and MCP dialogs.

Claude Code Notifier Get a push on your phone when Claude Code finishes or needs you, then approve, deny or answer from there. The ccn command line tool is free on Mac, Windows and Linux.
Download for iOS Download for Android Install ccn

Related guides

  • Every way to get Claude Code notifications, comparedBuilt-in alerts, your own hooks, ntfy and chat webhooks, Anthropic's Remote Control and notifier apps, compared on what each can and cannot do.
  • Send Claude Code notifications to Telegram, Slack or DiscordOne hook script that posts Claude Code alerts to a Telegram bot, a Slack incoming webhook or a Discord webhook, on Mac, Windows and Linux.
  • The Claude Code Notification hook: when it fires and how to use itWhen Claude Code's Notification hook fires, what permission_prompt and idle_prompt mean, the input it gets, and why it waits before firing.
  • The Claude Code Stop hook: run something when Claude finishesHow Claude Code's Stop hook works, what input it gets, how to run a command when Claude finishes, and how to make Claude keep going safely.
claude-code-notifier

Claude Code Notifier is an independent third-party application. It is not affiliated with, endorsed by, or sponsored by Anthropic, PBC. "Claude" and "Claude Code" are trademarks of Anthropic, PBC.

apps iOS App Android App ccn for macOS, Windows & Linux All guides
legal Privacy Policy Terms of Service Other languages © 2026 touchtap. All rights reserved. TouchTap Ltd is registered in England and Wales, company number 13942589.