6.7 KiB
Desktop Notifications Guide [Claude Code only]
Never miss important Claude Code events with native desktop notifications on all platforms.
🔔 Overview
The notification system keeps you in flow by alerting you when:
- Claude Code needs permission to proceed
- Tasks complete successfully
- Errors require your attention
- Long-running operations finish
- Custom events you define occur
🖥️ Platform Support
macOS
- Native Notification Center
- Supports title, subtitle, and message
- Respects Do Not Disturb settings
- Sound alerts optional
Linux
- Uses
notify-send
(libnotify) - Full desktop environment support
- Works with GNOME, KDE, XFCE, etc.
- Custom icons supported
Windows
- Native Windows toast notifications
- Action Center integration
- Works in PowerShell/WSL
- Supports notification grouping
WSL (Windows Subsystem for Linux)
- Automatically detects WSL environment
- Routes to Windows notifications
- Full feature support
- No additional setup needed
🚀 Quick Start
Notifications work out of the box! The system automatically:
- Detects your platform
- Uses the best notification method
- Falls back to console output if needed
🛠️ How It Works
Notification Flow
Claude Code Event
↓
Notification Hook Triggered
↓
notify.sh Receives JSON
↓
Platform Detection
↓
Native Notification Sent
↓
You Stay In Flow ✨
JSON Input Format
The notification script receives:
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.jsonl",
"cwd": "/path/to/project",
"hook_event_name": "Notification",
"message": "Task completed successfully"
}
Smart Context Detection
Notifications include:
- Project Name: From git repo or directory name
- Session ID: Last 6 characters for multi-window users
- Message: The actual notification content
Example: MyProject (abc123): Build completed successfully
🎨 Customization
Custom Messages
Edit .claude/settings.json
to customize when notifications appear:
{
"hooks": {
"Notification": [
{
"matcher": ".*error.*",
"hooks": [
{
"type": "command",
"command": ".claude/tools/notify-error.sh"
}
]
}
]
}
}
Adding Sounds
macOS - Add to notify.sh
:
# Play sound with notification
osascript -e 'display notification "..." sound name "Glass"'
Linux - Add to notify.sh
:
# Play sound after notification
paplay /usr/share/sounds/freedesktop/stereo/complete.oga &
Windows/WSL - Add to PowerShell section:
# System sounds
[System.Media.SystemSounds]::Exclamation.Play()
Custom Icons
Linux:
notify-send -i "/path/to/icon.png" "Title" "Message"
macOS (using terminal-notifier):
terminal-notifier -title "Claude Code" -message "Done!" -appIcon "/path/to/icon.png"
Notification Categories
Add urgency levels:
# In notify.sh
case "$MESSAGE" in
*"error"*|*"failed"*)
URGENCY="critical"
TIMEOUT=0 # Don't auto-dismiss
;;
*"warning"*)
URGENCY="normal"
TIMEOUT=10000
;;
*)
URGENCY="low"
TIMEOUT=5000
;;
esac
# Linux
notify-send -u "$URGENCY" -t "$TIMEOUT" "$TITLE" "$MESSAGE"
🔧 Troubleshooting
No Notifications Appearing
-
Check permissions:
# Make script executable chmod +x .claude/tools/notify.sh
-
Test manually:
echo '{"message": "Test notification", "cwd": "'$(pwd)'"}' | .claude/tools/notify.sh
-
Enable debug mode:
echo '{"message": "Test"}' | .claude/tools/notify.sh --debug # Check /tmp/claude-code-notify-*.log
Platform-Specific Issues
macOS:
- Check System Preferences → Notifications → Terminal/Claude Code
- Ensure notifications are allowed
- Try:
osascript -e 'display notification "Test"'
Linux:
- Install libnotify:
sudo apt install libnotify-bin
- Test:
notify-send "Test"
- Check if notification daemon is running
Windows/WSL:
- Ensure Windows notifications are enabled
- Check Focus Assist settings
- Test PowerShell directly
Silent Failures
Enable verbose logging:
# Add to notify.sh
set -x # Enable command printing
exec 2>/tmp/notify-debug.log # Redirect errors
📊 Advanced Usage
Notification History
Track all notifications:
# Add to notify.sh
echo "$(date): $MESSAGE" >> ~/.claude-notifications.log
Conditional Notifications
Only notify for important events:
# Skip trivial notifications
if [[ "$MESSAGE" =~ ^(Saved|Loaded|Reading) ]]; then
exit 0
fi
Remote Notifications
Send to your phone via Pushover/Pushbullet:
# Add to notify.sh for critical errors
if [[ "$MESSAGE" =~ "critical error" ]]; then
curl -s -F "token=YOUR_APP_TOKEN" \
-F "user=YOUR_USER_KEY" \
-F "message=$MESSAGE" \
https://api.pushover.net/1/messages.json
fi
Notification Groups
Group related notifications:
# macOS - Group by project
osascript -e "display notification \"$MESSAGE\" with title \"$PROJECT\" group \"$PROJECT\""
🎯 Best Practices
- Be Selective: Too many notifications reduce their value
- Add Context: Include project and session info
- Use Urgency: Critical errors should stand out
- Test Regularly: Ensure notifications work after updates
- Provide Fallbacks: Always output to console too
🔌 Integration Examples
Build Status
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash.*make.*build",
"hooks": [
{
"type": "command",
"command": ".claude/tools/notify-build.sh"
}
]
}
]
}
}
Test Results
# In notify-build.sh
if grep -q "FAILED" <<< "$TOOL_OUTPUT"; then
MESSAGE="❌ Build failed! Check errors."
else
MESSAGE="✅ Build successful!"
fi
Long Task Completion
# Track task duration
START_TIME=$(date +%s)
# ... task runs ...
DURATION=$(($(date +%s) - START_TIME))
MESSAGE="Task completed in ${DURATION}s"
🌟 Tips & Tricks
-
Use Emojis: They make notifications scannable
- ✅ Success
- ❌ Error
- ⚠️ Warning
- 🔄 In Progress
- 🎉 Major Success
-
Keep It Short: Notifications should be glanceable
-
Action Words: Start with verbs
- "Completed build"
- "Fixed 3 errors"
- "Need input for..."
-
Session Context: Include session ID for multiple windows
-
Project Context: Always show which project
🔗 Related Documentation
- Automation Guide - Hook system
- Command Reference - Triggering notifications