Claude Code desktop notifications for macOS
Desktop notifications when Claude Code needs your input (permission prompts, questions).
- Notification fires after a configurable delay (default 10s)
- Each Claude session gets independent notifications - works with multiple instances in tmux/zellij
- Notifications clear automatically when you respond (approve, reject, or send a message)
| Environment Variable | Default | Description |
|---|---|---|
CLAUDE_NOTIFY_DELAY |
10 |
Seconds to wait before showing notification |
CLAUDE_NOTIFY_DEBUG |
0 |
Set to 1 to enable logging to /tmp/claude-notify-debug.log |
Tip: Set notification style to "Alerts" in macOS Settings > Notifications > terminal-notifier for persistent notifications that don't auto-dismiss.
- macOS
terminal-notifier(brew install terminal-notifier)jq(brew install jq)
Create ~/.claude/hooks/ directory with these two files:
#!/bin/bash
DELAY="${CLAUDE_NOTIFY_DELAY:-10}"
INPUT=$(cat)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id' | grep -E '^[a-f0-9-]{36}$')
[ -z "$SESSION_ID" ] && exit 1
PIDFILE="/tmp/claude-notify-${SESSION_ID}.pid"
[ -f "$PIDFILE" ] && kill "$(cat "$PIDFILE")" 2>/dev/null
(
sleep "$DELAY"
terminal-notifier -title "Claude Code" -message "Waiting for input" -group "claude-$SESSION_ID" -sound default
rm "$PIDFILE" 2>/dev/null
) &
echo $! > "$PIDFILE"#!/bin/bash
INPUT=$(cat)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id' | grep -E '^[a-f0-9-]{36}$')
[ -z "$SESSION_ID" ] && exit 1
PIDFILE="/tmp/claude-notify-${SESSION_ID}.pid"
[ -f "$PIDFILE" ] && kill "$(cat "$PIDFILE")" 2>/dev/null && rm "$PIDFILE"
terminal-notifier -remove "claude-$SESSION_ID"Make both scripts executable: chmod +x ~/.claude/hooks/notify-*.sh
Merge this into the existing settings (or create the file if it doesn't exist):
{
"hooks": {
"Notification": [
{ "matcher": "permission_prompt", "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify-start.sh" }] },
{ "matcher": "elicitation_dialog", "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify-start.sh" }] }
],
"UserPromptSubmit": [
{ "matcher": "*", "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify-cancel.sh" }] }
],
"PostToolUse": [
{ "matcher": "*", "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify-cancel.sh" }] }
],
"Stop": [
{ "matcher": "*", "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify-cancel.sh" }] }
]
}
}