Claude Code Hooks with Terminal Notifications π
July 7, 2025 Β· View on GitHub
Get macOS desktop notifications when Claude Code finishes working using the official Claude Code hooks feature.
π― What This Does
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.

β¨ Features
- π 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
π Quick Setup
Prerequisites
- macOS with Homebrew installed
- Claude Code CLI tool
- Terminal access
Installation
-
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! π
π What The Setup Does
- Installs terminal-notifier via Homebrew (if not already installed)
- Creates/updates
~/.claude/settings.jsonwith hooks configuration - Backs up your existing settings
- Tests the notification system
- Provides customization guidance
π How It Works
User-Level Hooks (Global)
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
βοΈ Customization
Change Notification Sound
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
Change Notification Message
Customize the title, subtitle, and message:
"command": "terminal-notifier -title \"π€ Claude\" -subtitle \"Task Done\" -message \"Completed work in $(basename \"$PWD\")\" -sound Glass -timeout 10"
Add Notification Timeout
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"
π― Per-Project Notifications
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.
π Advanced Examples
Multiple Hook Types
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"
}
]
}
]
}
}
Conditional Notifications
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"
}
π§ Troubleshooting
Notifications Not Appearing
- Check System Preferences β Notifications
- Grant terminal-notifier permission to send notifications
- Test manually:
terminal-notifier -message "Test"
Settings Not Taking Effect
- Restart Claude Code after changing settings
- Check JSON syntax in your settings file
- Verify file path:
~/.claude/settings.json
Command Not Found
If you get "command not found" errors, ensure terminal-notifier is installed:
brew install terminal-notifier
Permission Denied
Make sure the setup script is executable:
chmod +x terminal_notifier_setup.sh
π Understanding Claude Code Hooks
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)
π Learn More
π€ Contributing
- Fork this repository
- Create a feature branch
- Make your changes
- Test on macOS
- Submit a pull request
π License
MIT License - see LICENSE file for details.