Guides

Get notified when Claude Code finishes or needs your input

Long Claude Code tasks are only useful if you notice when they stop. There are two ways to get alerted without watching the terminal: a built-in terminal bell or notification, and hooks that run any command you like. Here are copy-paste setups for macOS and Linux.

Option 1: desktop notification via a Notification hook

Claude Code fires a Notification event when it is waiting for you, for example at a permission prompt or after it has finished and you haven't typed for a while. Add a hook to ~/.claude/settings.json. On macOS:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

On Linux, swap the command for notify-send:

"command": "notify-send 'Claude Code' 'Claude Code needs your attention'"

The empty matcher fires for every notification type. Run /hooks inside Claude Code to confirm the hook is listed under Notification. Settings files and hook structure are covered in the settings.json guide.

Only notify for what you care about

Set matcher to one notification type to cut the noise:

MatcherFires when
permission_promptClaude needs you to approve a tool use, and the prompt has waited about six seconds (in a terminal)
idle_promptClaude finished responding about 60 seconds ago and you haven't typed since

The docs list further types for MCP elicitations, background sessions and usage-limit resumes; see the Notification section of the hooks reference.

Get told the moment a task finishes

idle_prompt waits about a minute. For an immediate alert, add a Stop hook, which runs whenever Claude finishes responding. Stop hooks don't take a matcher:

"Stop": [
  {
    "hooks": [
      {
        "type": "command",
        "command": "osascript -e 'display notification \"Claude Code finished\" with title \"Claude Code\"'"
      }
    ]
  }
]

This sits next to Notification inside the same "hooks" object. Use notify-send on Linux. Keep the command exit code at 0: for Stop, exit code 2 makes Claude keep going instead of stopping.

Show the actual message

Hooks receive JSON on stdin. For Notification, the text is in the message field. With jq installed, this script shows it (save as ~/.claude/notify.sh and chmod +x it):

#!/usr/bin/env bash
msg=$(jq -r '.message // "Needs your attention"')
if [ "$(uname)" = "Darwin" ]; then
  osascript -e "display notification \"$msg\" with title \"Claude Code\""
else
  notify-send "Claude Code" "$msg"
fi
exit 0

Then point the hook at it with "command": "~/.claude/notify.sh". Messages containing double quotes can break the AppleScript line, so treat this as a starting point.

Option 2: a sound or the terminal bell

For a sound on macOS, use a hook with afplay:

{
  "hooks": {
    "Notification": [
      { "hooks": [{ "type": "command", "command": "afplay /System/Library/Sounds/Glass.aiff" }] }
    ]
  }
}

Alternatively, no hook is needed for the terminal bell. By default Claude Code sends a desktop notification only in Ghostty, Kitty and iTerm2. In other terminals, add this to ~/.claude/settings.json:

{
  "preferredNotifChannel": "terminal_bell"
}

If nothing shows up

Next steps

Notifications are one of the simplest hooks. For blocking, formatting and secret-scanning examples, see 6 practical hook examples. To assemble and sanity-check hook JSON before pasting it into your settings, try the free hook builder. If you're unattended because you're running Claude Code on a schedule or in CI, the GitHub Actions guide is the better fit.

Skip the setup: get the tested versions

Keelwork bundles 10 workflow skills, 5 tested safety hooks (including a full guard-bash and a secret scanner), 3 subagents and 5 CLAUDE.md templates, with a one-command installer that safely merges into your settings.

Get Keelwork — $24 →