Get notified when Claude Code finishes or needs you on a Mac.

You can get a Claude Code notification in any Mac terminal when it's done or when it stops to wait for your OK. What you set up depends on your terminal.

By default, Claude Code sends a desktop notification only in Ghostty, Kitty and iTerm2, when it finishes or waits for your permission and you seem to be away. Terminal.app, Warp and the VS Code terminal get no banner. There, set Local notifications in /config to the terminal bell, or add a hook: Stop for when it finishes, Notification for when it needs you.

Last updated

Cowork Island

macOS 14 or later.
Apple silicon and Intel.
No account needed for Free.

Download for free

See what your terminal does on its own.

Claude Code's built-in alert fires when Claude finishes a task or pauses for a permission prompt, and you appear to be away from the terminal. Whether that alert shows as a banner depends on the terminal app.

Claude Code's default alert on a Mac, by terminal
TerminalWith no setupWhat to do
GhosttyDesktop notificationAllow the terminal's notifications in macOS.
KittyDesktop notificationAllow the terminal's notifications in macOS.
iTerm2Desktop notification, after one iTerm2 settingTurn on iTerm2's escape-sequence alerts (next section).
Terminal.appNo banner. The default rings the bell only if Terminal's audible bell is off.Use the terminal bell setting or a hook.
WarpNo bannerUse the terminal bell setting or a hook.
VS Code terminalNo bannerUse the terminal bell setting or a hook.
tmux, in any terminalNotifications don't get throughAdd set -g allow-passthrough on to ~/.tmux.conf, then run tmux source-file ~/.tmux.conf.

Turn on the built-in alert.

Claude Code has one setting for this, preferredNotifChannel. In Claude Code, type /config and open Local notifications. The default is auto. The other choices are terminal_bell, iterm2, iterm2_with_bell, kitty, ghostty and notifications_disabled.

The terminal bell is the short sound or flash a terminal makes when a program asks for attention. To use it in Terminal.app, Warp or VS Code, you can also add this line to a Claude Code settings file, such as ~/.claude/settings.json, inside its outer braces:

"preferredNotifChannel": "terminal_bell"

  • iTerm2: open Settings > Profiles > Terminal, check Notification Center Alerts, click Filter Alerts and turn on Send escape sequence-generated alerts.
  • Terminal.app: to make the bell easier to notice, open Settings > Profiles > Advanced and, under Bell, choose to badge the Dock icon or bounce it when Terminal is in the background. If you accepted Claude Code's first-run terminal setup, it turned Terminal's audible bell off; check Audible bell there if you want to hear it.
  • Any terminal: the terminal app itself needs permission to post notifications in System Settings > Notifications.

Older posts tell you to run claude config set. That command no longer exists: use /config or edit the settings file.

Use Stop for finished and Notification for needs you.

A hook is a shell command that Claude Code runs at a set moment. You list hooks in a settings file. They work in every terminal, because the terminal plays no part in running them.

Anthropic's own "get notified" recipe uses the Notification event. That event tells you Claude has finished only through idle_prompt, about 60 seconds later, and only if you haven't typed since. For an alert the moment Claude stops, use Stop.

Claude Code hook events for alerts
Event and matcherWhen it firesUse it for
StopWhen Claude finishes responding, at the end of every turn, but not after you interrupt it.An alert when Claude is done
Notification + permission_promptWhen a permission prompt has waited about six seconds. Typing in the terminal delays it.An alert when Claude needs your OK
Notification + elicitation_dialogWhen an MCP server (a tool plugged into Claude Code) opens a form and you haven't typed for about six seconds.An alert when Claude needs your input
Notification + elicitation_url_dialogWhen an MCP server asks you to open a web page and you haven't typed for about six seconds.An alert when Claude needs your input
Notification + idle_promptAbout 60 seconds after Claude finished, if you haven't typed and no background subagent is still running.A late reminder

A turn that ends on an API error, such as a rate limit, fires StopFailure instead of Stop. Notification hooks can't block anything: they only run your command.

Copy a ready-made hook.

Each snippet below goes in ~/.claude/settings.json, which applies to all your projects. Each one was checked for valid JSON and shell syntax and needs no extra software.

Merge, don't overwrite. If the file already has a "hooks" object, add the "Stop" or "Notification" key inside it, next to what is there. If that key is already there (Cowork Island, for one, adds both), don't add it a second time: copy the snippet's entry, the part in braces inside the square brackets, into that key's list as a new item, with a comma between items. Don't paste a second "hooks" block, which can drop your other hooks, and don't replace the file, which deletes your other settings. The file is strict JSON, so no comments and no trailing commas.

A Mac banner when Claude finishes.

In ~/.claude/settings.json

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'on run argv' -e 'display notification (item 1 of argv) with title \"Claude Code\" sound name \"Glass\"' -e 'end run' \"Finished in ${PWD##*/}\""
          }
        ]
      }
    ]
  }
}

A Mac banner when Claude needs your OK.

In ~/.claude/settings.json

{
  "hooks": {
    "Notification": [
      {
        "matcher": "permission_prompt|elicitation_dialog|elicitation_url_dialog",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'on run argv' -e 'display notification (item 1 of argv) with title \"Claude Code needs you\" sound name \"Ping\"' -e 'end run' \"Waiting for your OK in ${PWD##*/}\""
          }
        ]
      }
    ]
  }
}

Both banners name the folder the session runs in.

Let Script Editor show the banners.

On a Mac, osascript banners come from the built-in Script Editor app. Until Script Editor is allowed to post notifications, the command fails silently, and macOS won't ask you for permission.

  1. In Terminal, run this once:

osascript -e 'display notification "test"'

  1. Open System Settings > Notifications, find Script Editor and turn on Allow Notifications.

A sound instead of a banner.

In ~/.claude/settings.json

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

A spoken alert.

In ~/.claude/settings.json

{
  "hooks": {
    "Stop": [
      { "hooks": [ { "type": "command", "command": "say \"Claude has finished\"", "async": true } ] }
    ],
    "Notification": [
      { "matcher": "permission_prompt", "hooks": [ { "type": "command", "command": "say \"Claude needs your permission\"", "async": true } ] }
    ]
  }
}

"async": true lets Claude Code carry on while the Mac speaks.

For a banner for one event and a sound for the other, use the notify hook generator twice: pick one event and its alert style each time, then use its merge box to add both results to your file. It tells you which file each snippet goes in, and everything runs in your browser.

Check these if nothing happens.

  • Trust the folder. Claude Code holds back every hook, even those in ~/.claude/settings.json, until you accept the workspace trust dialog for that folder.
  • See what is loaded. Type /hooks in Claude Code. It lists your hooks and the file each one comes from, but it can't add them. Claude Code normally picks up your edits on its own; if it doesn't, restart the session.
  • Work Macs. An organization can allow only its own managed hooks. Then /hooks shows "Only hooks from managed settings run here", and personal hooks won't run.
  • Two alerts at once. Hooks from every settings level add up, so an alert hook in a project file and a different alert hook in your user file both fire. The exact same hook in several files runs only once. Hooks also run alongside the built-in notification. If you get both, set Local notifications to notifications_disabled and keep the hook.
  • Too many alerts. Stop fires after every turn, not only when a whole task is done.
  • If you also use Cowork Island. Keep each of your hooks in its own entry, as in the snippets above, and outside ~/.perch/. The app treats only commands containing /.perch/ as its own, and it replaces whole entries, so a command placed inside its entry would be removed with it.

The no-setup option.

Cowork Island is a Mac app by the maker of this guide. It keeps your AI agent sessions in a notch panel and shows the state of each one, so you can see at a glance which one needs you. It works with or without a notch.

  • Claude Code connects on its own. The app adds its own hook entries, which sit alongside your existing hooks.
  • Each session shows as Working, Pending or “Needs you”. By default, when one starts needing you, the island opens by itself, unless that session's terminal is already in front.
  • When a session finishes, the island opens for 5 seconds by default. You can switch that to a dot on the island, or to nothing.
  • For Claude Code, you can allow or deny an action, or answer a multiple-choice question on the island. Answering there is free.
  • Sounds are off until you turn them on. The "Approval needed" sound is free; the "Session complete" chime is part of Pro.
  • It posts no macOS banners of its own. The alert is the island opening, plus a sound if you turned sound on.

Free shows one session card at a time. Pro shows all your sessions, and jumping back to a session's window, tab or pane is part of Pro. A 7-day Pro trial starts by itself, once per Mac, without payment details. See plans and the install guide.

Download for free

Sources.

Send yourself the download link for later.