To get a notification when Claude Code finishes, add a Stop hook to ~/.claude/settings.json that runs your system's notification command. Stop fires the moment Claude finishes responding. For "Claude needs my input", add a Notification hook as well: it fires when a permission prompt has waited about six seconds, or when Claude has been idle for about a minute. Both work on Mac, Windows and Linux, and a tool such as Claude Code Notifier can send the same alerts to your phone.
01What Claude Code does on its own
Claude Code already tries to alert you when you seem to be away from the terminal. By default it sends a desktop notification in iTerm2, Ghostty and Kitty, may send a bell character in Apple Terminal, and does nothing in other terminals. iTerm2 also needs its alert settings switched on before anything shows.
So if you use VS Code's terminal, Warp, Windows Terminal or most Linux terminals, you will usually get nothing. You can force a terminal bell with the preferredNotifChannel setting, covered in the terminal bell guide. For a real desktop notification in any terminal, you need a hook.
02The two hooks you need
Hooks are commands that Claude Code runs at fixed points in a session. Two of them matter here:
StopWhen Claude finishes responding (not when you interrupt it)"Claude has finished"Notification with matcher permission_promptA permission prompt has waited about six seconds while you haven't typed"Claude needs approval"Notification with matcher idle_promptAbout 60 seconds after Claude finished, if you haven't typed sinceA reminder that it's your turnStop is the fast one. It runs at the end of every turn, straight away. The Notification types are gated on you looking away: each keystroke defers them, so you don't get pinged while you're watching. If you want a signal the instant Claude asks for permission, use the PermissionRequest hook instead, described in the PermissionRequest guide.
For how hooks work in general (events, matchers, settings files, exit codes), see Claude Code hooks explained.
03A working setup on macOS
Open ~/.claude/settings.json (create it if it doesn't exist) and add this. If the file already has a hooks object, add Stop and Notification as keys inside it rather than replacing it.
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude has finished\" with title \"Claude Code\"'"
}
]
}
],
"Notification": [
{
"matcher": "permission_prompt|idle_prompt",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}
Stop has no matcher, so it fires on every turn. The Notification matcher limits it to the two types that mean "come back".
If nothing appears, macOS may be blocking Script Editor, which osascript uses to show notifications. Run osascript -e 'display notification "test"' once in Terminal, then open System Settings > Notifications, find Script Editor and turn on Allow Notifications.
04The same setup on Linux and Windows
Keep the JSON shape above and swap the command strings.
Linux (needs a desktop notification daemon, so not on a headless server):
"command": "notify-send 'Claude Code' 'Claude has finished'"
If notify-send is missing, install libnotify-bin on Debian and Ubuntu, or your distribution's equivalent. For SSH and server setups, see notifications over SSH.
Windows (PowerShell). Anthropic's own example opens a message box rather than a corner toast:
"command": "powershell.exe -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude has finished', 'Claude Code')\""
The box can open behind your terminal window, so test the command in PowerShell first. Under WSL, powershell.exe must be reachable through Windows interop. The Windows guide covers other options.
05Check that it works
- Type
/hooksin Claude Code. Your hooks should be listed underStopandNotification. - Ask Claude something short. When it replies, the
Stopnotification should appear. - Ask for something that needs permission, switch to another window and wait. The
permission_promptnotification arrives after about six seconds.
Edits to settings.json are normally picked up straight away. If a hook doesn't show in /hooks, check the file is valid JSON (no trailing commas, no comments). Start Claude Code with claude --debug to see what each hook did. More fixes are in the troubleshooting checklist.
06Getting the alert on your phone
A desktop notification only helps if you're at the desk. Once you walk away, you need the alert somewhere else. There are three common routes:
- A push service you run yourself, such as ntfy, called with
curlfrom the same hooks. Cheap and flexible. See the ntfy guide. - A chat webhook for Telegram, Slack or Discord. Good if you live in chat already. See the chat webhooks guide.
- Claude Code Notifier, which does the hooks for you and lets you answer from the phone.
The DIY routes are a fine answer if all you want is a ping. Their limit is that they are one-way. You find out Claude is waiting, then you still have to get back to the keyboard to approve anything.
Claude Code Notifier is an independent tool (not made by Anthropic) with two parts: ccn, a free command line tool for Mac, Windows and Linux, and apps for iPhone and Android. Install it with one line:
curl -fsSL https://claudecodenotifier.com/install.sh | sh
On Windows, use irm https://claudecodenotifier.com/install.ps1 | iex in PowerShell (Windows support is in beta). Other options, including Homebrew, npx @touchtap/ccn and the Claude Code plugin, are on the ccn page.
Installing adds seven hook entries that each run ccn hook, keeps the rest of your settings.json as it was, and saves a one-time backup beside it. With no phone at all, ccn shows a desktop notification on your computer when Claude finishes, needs a permission or asks a question. That part is free and works without a network.
Pair a phone with ccn pair and you also get:
- a "Claude has finished" push the moment a turn ends;
- permission requests you can allow once, allow for the session, or deny;
- Claude's multiple-choice questions, answered from the phone;
- a follow-up box to send Claude its next instruction right after it finishes.
If you typed in the last 30 seconds, nothing waits for the phone and the terminal asks as usual. The apps need a subscription or lifetime purchase; see pricing. Pairing a phone walks through the setup.
07FAQ
Why does my Notification hook take so long to fire?
The permission_prompt type waits until the prompt has been on screen for about six seconds without you typing, and idle_prompt waits about 60 seconds after Claude finishes. That delay is by design, so you are not pinged while watching. Use a Stop hook for an instant "finished" alert, and a PermissionRequest hook for an instant "needs approval" alert.
Does the Stop hook fire if I press Esc to interrupt Claude?
No. Stop does not run when the turn ends because you interrupted it. It also does not run when the turn ends with an API error such as a rate limit. Claude Code fires a separate StopFailure event for that, which you can hook in the same way.
Will a Stop hook fire after every message, or only when the whole task is done?
After every turn. Claude Code has no idea when your overall task is finished, only when it has stopped responding. If you have a long back-and-forth, you get one alert per reply. If that is too many, use the idle_prompt notification instead, which only fires once you have been away for about a minute.
Does this work in the VS Code or JetBrains terminal?
Yes. Hooks run from Claude Code itself, not from the terminal, so they work in any terminal, including IDE terminals. The built-in notifications are what depend on the terminal. See the IDE terminals guide.
Can I get notified on my phone without installing anything on it?
Partly. A hook that posts to ntfy or a chat webhook can reach an app you already have. It can only tell you something happened. To approve or answer from the phone, you need something that sends your reply back to the hook, which is what Claude Code Notifier's apps do.