Get macOS desktop notifications when Claude Code finishes working using the official Claude Code hooks feature.
This setup configures Claude Code hooks to send native macOS notifications when Claude Code completes any task. No wrapper scripts, no complexityβjust proper integration with Claude Code's official hooks system.
- π Native macOS notifications when Claude Code stops
- π Project context included in notifications
- π΅ Customizable sounds (default, Glass, Basso, etc.)
- π Global setup works across all projects
- π― Per-project customization available
- π¦ Simple one-script setup
- macOS with Homebrew installed
- Claude Code CLI tool
- Terminal access
-
Clone this repository:
git clone https://github.com/centminmod/terminal-notifier-setup.git cd terminal-notifier-setup
-
Run the setup script:
chmod +x terminal_notifier_setup.sh ./terminal_notifier_setup.sh
That's it! π
- Installs terminal-notifier via Homebrew (if not already installed)
- Creates/updates
~/.claude/settings.json
with hooks configuration - Backs up your existing settings
- Tests the notification system
- Provides customization guidance
The setup configures a Stop event hook in ~/.claude/settings.json
:
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "terminal-notifier -title \"Claude Code\" -subtitle \"Session Complete\" -message \"Finished working in $(basename \"$PWD\")\" -sound default -timeout 10"
}
]
}
]
}
}
This hook:
- Triggers when any Claude Code session completes
- Shows the project name (current directory) in the notification
- Plays the default system sound
- Works in all projects automatically
Edit ~/.claude/settings.json
and modify the sound
parameter:
"command": "terminal-notifier -title \"Claude Code\" -subtitle \"Session Complete\" -message \"Finished working in $(basename \"$PWD\")\" -sound Glass -timeout 10"
Available sounds: default, Basso, Blow, Bottle, Frog, Funk, Glass, Hero, Morse, Ping, Pop, Purr, Sosumi, Submarine, Tink
Customize the title, subtitle, and message:
"command": "terminal-notifier -title \"π€ Claude\" -subtitle \"Task Done\" -message \"Completed work in $(basename \"$PWD\")\" -sound Glass -timeout 10"
Make notifications disappear after a specific time:
"command": "terminal-notifier -title \"Claude Code\" -subtitle \"Session Complete\" -message \"Finished working in $(basename \"$PWD\")\" -sound default -timeout 10"
For project-specific notifications, create .claude/settings.json
in your project directory:
# In your project directory
mkdir -p .claude
cat > .claude/settings.json << 'EOF'
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "terminal-notifier -title \"My Project\" -subtitle \"Build Complete\" -message \"Finished working on $(basename \"$PWD\")\" -sound Glass -timeout 10"
}
]
}
]
}
}
EOF
Project-level hooks override user-level hooks for that specific project.
You can set up hooks for different Claude Code events:
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "terminal-notifier -title \"Claude Code\" -subtitle \"Session Complete\" -message \"Finished working in $(basename \"$PWD\")\" -sound default -timeout 10"
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "terminal-notifier -title \"Claude Code\" -subtitle \"Running Command\" -message \"Executing bash command...\" -sound Purr -timeout 3"
}
]
}
]
}
}
Use shell conditionals for smarter notifications:
{
"type": "command",
"command": "if [ -f package.json ]; then terminal-notifier -title \"Node.js Project\" -message \"Claude finished working on $(basename \"$PWD\")\" -sound Glass -timeout 10; else terminal-notifier -title \"Claude Code\" -message \"Finished working in $(basename \"$PWD\")\" -sound default -timeout 10; fi"
}
- Check System Preferences β Notifications
- Grant terminal-notifier permission to send notifications
- Test manually:
terminal-notifier -message "Test"
- Restart Claude Code after changing settings
- Check JSON syntax in your settings file
- Verify file path:
~/.claude/settings.json
If you get "command not found" errors, ensure terminal-notifier is installed:
brew install terminal-notifier
Make sure the setup script is executable:
chmod +x terminal_notifier_setup.sh
Claude Code hooks are event-driven commands that execute at specific points in Claude's lifecycle:
- PreToolUse: Before Claude uses a tool
- PostToolUse: After Claude uses a tool
- Stop: When Claude finishes responding
- Notification: On Claude Code notifications
Hooks are configured in:
~/.claude/settings.json
(user-level, applies globally)<project>/.claude/settings.json
(project-level, applies to that project only)
- Fork this repository
- Create a feature branch
- Make your changes
- Test on macOS
- Submit a pull request
MIT License - see LICENSE file for details.