Get native macOS notifications from Claude Code so you know when it needs your attention — without staring at the terminal.
Token anxiety is real. You've got Claude working on something important, you switch tabs for 30 seconds, and now you have no idea if it finished, crashed, or is waiting on you.
When running Claude Code, you context-switch to other work while Claude is thinking. There's no way to know when Claude needs your attention without constantly checking back.
macOS Terminal.app doesn't support Claude Code's built-in notification escape sequences (only Kitty, Ghostty, and iTerm2 do). This repo is the fix.
Two independent notification hooks cover different scenarios:
Fires when Claude Code sends a notification event: permission prompts, idle waiting, auth dialogs. Shows the working directory as the subtitle so you know which session it's from.
Fires when Claude finishes a response — but only if it took 15+ seconds. Quick replies are silent. Long tasks (code generation, debugging, multi-step work) get a notification.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Aman-Kothari7/claude-code-macos-notifications/main/install.sh)"Or clone and run locally:
git clone https://github.com/Aman-Kothari7/claude-code-macos-notifications
cd claude-code-macos-notifications
./install.shbrew install terminal-notifiermkdir -p ~/.claude/hooks
cp hooks/stamp-prompt.sh ~/.claude/hooks/
cp hooks/notify-on-stop.sh ~/.claude/hooks/
chmod +x ~/.claude/hooks/stamp-prompt.sh ~/.claude/hooks/notify-on-stop.shFor the Notification hook only (recommended starting point):
{
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "jq -r '\"\\(.cwd // \"unknown\")\"' | xargs -I{} /opt/homebrew/bin/terminal-notifier -title 'Claude Code' -subtitle '{}' -message 'Waiting for your input' -sound Glass"
}
]
}
]
}
}To also enable the Stop hook (notify after 15+ second tasks):
{
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "jq -r '\"\\(.cwd // \"unknown\")\"' | xargs -I{} /opt/homebrew/bin/terminal-notifier -title 'Claude Code' -subtitle '{}' -message 'Waiting for your input' -sound Glass"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/stamp-prompt.sh"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/notify-on-stop.sh"
}
]
}
]
}
}After the first notification fires, go to System Settings > Notifications > terminal-notifier and set:
- Alert style: Banners or Alerts
- Play sound for notifications: On
- Allow notifications: On
Change the notification sound: Replace Glass with any macOS system sound name (e.g. Ping, Funk, Blow, Pop). See /System/Library/Sounds/ for options.
Change the Stop hook threshold: Edit ~/.claude/hooks/notify-on-stop.sh and change the 15 in -ge 15 to your preferred number of seconds.
Change notification messages: Edit the -message values in settings.json.
Why terminal-notifier over osascript?
osascript -e 'display notification ...' requires the calling app (Terminal.app) to have notification permissions. Terminal.app doesn't register in macOS notification settings until it successfully sends one — a chicken-and-egg problem. terminal-notifier is its own app and registers immediately.
Why absolute paths in settings.json?
Hooks run in a minimal shell that may not load your full shell profile. /opt/homebrew/bin/terminal-notifier works reliably; bare terminal-notifier may not be found in PATH.
Why per-session stamp files?
Multiple Claude Code sessions run concurrently. Using the session ID in the temp file path (/tmp/claude-prompt-stamp-${SESSION_ID}) prevents sessions from overwriting each other's timestamps.
Why 15 seconds for the Stop threshold?
- < 15s: quick answers, confirmations, short responses — you're likely still at the terminal
- ≥ 15s: multi-step work, code generation, debugging — you've probably switched away
- macOS
- Claude Code
- Homebrew
jq(usually already installed;brew install jqif not)
Issues and PRs welcome. Common areas for improvement:
- Support for non-Homebrew terminal-notifier paths (Intel Macs use
/usr/local/bin/) - Linux support via
notify-send - Different notification styles or sounds per hook type
MIT