Claude Code hooks for simple macOS notifications
I’ve been using Claude Code for a while now, and one thing that always bugged me was not knowing when it finished running a long task. You ask Claude to refactor a large codebase or generate a bunch of tests, then you switch to another window to check Slack, Discord or get up to date on Hacker News. Twenty minutes later you realize you forgot to check if Claude finished!
Anthropic recently released Claude Code hooks, and they offer a simple solution to this problem! Let’s dive into how you can set up desktop notifications on macOS whenever Claude Code finishes a task or needs your attention.
What are Claude Code hooks?
Claude Code hooks are essentially shell commands that run automatically at specific points during Claude’s workflow. Think of them as triggers – when Claude finishes responding, needs your input, or performs certain actions, your custom commands execute automatically.
The beauty of hooks is that they’re deterministic – they always run when they’re supposed to, unlike hoping that Claude will run some MCP tool you prompted it to. π€·
Setting up terminal-notifier
First, we need to install terminal-notifier, a handy command-line tool that sends notifications to macOS Notification Center. If you have Homebrew installed, it’s as simple as:
brew install terminal-notifier
You can test it by running:
terminal-notifier -message "Hello from Terminal" -sound default
You should see a notification pop up and hear the default notification sound!

If you’re not seeing the notifications, try going to the Mac Notification settings and enable notifications for the Terminal and/or terminal-notifier apps.
Configuring Claude Code hooks
Now it’s time to set up our hooks. Claude Code looks for the file ~/.claude/settings.json
.
Here’s the configuration I use. You can either replace your whole settings.json file with this config, or pick out just the hooks
object.
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "terminal-notifier -message \"Claude Code Finished\" -sound default"
}
]
}
],
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "terminal-notifier -message \"Claude Code Needs Help\" -sound Basso"
}
]
}
]
}
}
The empty `matcher` field means these hooks will run for all events of their type. You could get more specific if you only wanted notifications for certain tools or file types.
A few things to keep in mind
Hooks run with your user permissions, so they can do anything you can do in your terminal. This is powerful but also means you should be careful about what commands you run.
Give it a try and let me know what creative uses you find for Claude Code hooks. Happy coding!
Photo by Volodymyr Hryshchenko on Unsplash
View Comments
Building portable web apps with SvelteKit’s new single-file bundle strategy and hash router
I’ve been building static single page apps using adapter-static for a while...
This is great, thanks!
If you don’t want an external dependency you can send notifications with the builtin AppleScript. For example here’s a simple Bash function I use in a script …
“`a
notify() {
# Configure notifications in: System Settings > Notifications > Script Editor
osascript -e “display notification \”by $(basename $0)\” with title \”$1\””
}
“`