claude-plugins · notify

System notifications when Claude finishes.

macOS and Linux system notifications for Claude Code, with a notification cooldown so rapid back-to-back responses don't spam you. When Claude finishes a long job in the background, a notification fires carrying the repo name, branch, and Claude's actual last message.

notifications macos linux hooks
install + setupbash
claude plugin install notify@apurvbazari-plugins
/notify:setup
4
skills
3
events
2
platforms · macOS + Linux
1
config file
01 — how a notification fires

From Claude stopping to a system alert

A linear pipeline runs on every hook event. Click a stage to see detail in the side panel.

trigger
Claude stops
→
hook
notify.sh
→
filter
cooldown check
→
output
system notification

The cooldown is the key primitive — each event carries its own minDurationSeconds value: at most one stop or subagentStop notification per that many seconds. Inside the window, the script exits silently. Otherwise it builds a repo / branch subtitle from git and extracts Claude's actual last message as notification content. The script always exits 0, so a missing backend or failed notification can never block Claude.

Intentionally minimal

notify does one thing well: native desktop alerts, with a cooldown and project context. Install globally to get alerts across every Claude Code session, or per-project to tune settings per repo. Both scopes can coexist; the hook reads one config, the project's own when it has one.

02 — event model

Three events, each independently configurable

Notification content is extracted from Claude's real last message. Each event has its own enabled flag, sound, and cooldown. Edit notify-config.json directly — changes take effect immediately, no re-running setup.

EventWhenDefault soundminDurationSecondsDefault state
stop Claude finishes a response Hero 0 enabled
notification Claude needs your attention Glass 0 enabled
subagentStop A subagent finishes work — — disabled (too noisy)

stop fires on every Claude response. Its default is 0 (no cooldown); setup recommends 30, so after one notification fires, further stop notifications stay quiet for 30 seconds. notification is never cooldown-filtered, because it means Claude is actively waiting on you. subagentStop is opt-in only.

03 — skills

Three user-facing skills

All under /notify:<name>. check is auto-invocable and read-only; setup and uninstall are destructive and require explicit user invocation.

SkillInvocationWhat it does
/notify:setup user-only Detects platform, installs the backend (terminal-notifier via Homebrew on macOS, notify-send from libnotify on Linux), detects your editor for click-to-focus, asks global vs per-project, configures all three events, and sends a test notification.
/notify:check auto Health check — reports which scopes are installed and the current event configuration (sounds, cooldowns, enabled flags) for each, and offers to send a test notification on request.
/notify:uninstall user-only Surgically removes notify-owned hooks from settings.json and deletes notify-config.json. Leaves unrelated hooks untouched, and leaves the backend installed.
wizard internal The interactive Q&A that customizes sounds, the notification cooldown, matcher regex, and per-event toggles. A building block invoked by setup (user-invocable: false) — not a command you run.
04 — configuration

Per-event knobs in notify-config.json

All configuration lives in notify-config.json, written by /notify:setup. Both scopes can coexist, but the hook reads exactly one file: the project-local one when it exists, otherwise the global one. Edit directly after setup; the hook reads it on every invocation.

enabled
Event toggle

Turn any event on or off without re-running setup. true or false per event.

sound
Alert sound

14 macOS system sounds (Hero, Glass, Ping, Purr, Pop, Submarine, …). Maps to urgency level on Linux.

minDurationSeconds
Notification cooldown

At most one stop / subagentStop notification per this many seconds, timed from the last one that fired. Default 0 (no cooldown). notification events are never cooldown-filtered.

activate
Click-to-focus

Bundle ID of the app to bring forward on notification click (e.g. VS Code, Cursor, iTerm2). macOS only.

message
Fallback text

Shown when contextual content can't be extracted from Claude's response. Static safety net.

scope resolution
Global or per-project

Install globally for all sessions, per-project to override. The project-local file is used whole when it exists — there is no key-level merge with the global one.

05 — platform support

Cross-platform: macOS and Linux

Same hook, two backends. Cooldown and repo / branch subtitle work everywhere. Sounds and click-to-focus are richer on macOS.

macOS
terminal-notifier

14 system sounds, click-to-focus via bundle ID, title + subtitle + message, Homebrew install. JSON parsed via jq with python3 fallback.

Linux
notify-send / libnotify

Urgency levels (low/normal/critical mapped from sound setting), app-name, message body. Cooldown and repo/branch subtitle work identically.

WSL
Linux backend, caveats

notify-send reaches the Linux desktop only if a notification daemon is running. For Windows-side toasts, route through a Windows notifier (e.g. wsl-notify-send) or run Claude Code natively on Windows.

notify · v2.0.3 · MIT · by Apurv Bazari
✕