Ambient › Guides

How to get notified when Claude Code finishes or needs you on Mac

Updated · 6 min read

Claude Code already sends a desktop notification in Ghostty, Kitty and iTerm2 when it finishes or waits for permission. In any other terminal, set preferredNotifChannel to "terminal_bell", or add a Notification hook to ~/.claude/settings.json. To watch several sessions at once and click straight back to the right tab, use a notch status app such as Ambient.

The quickest setup works in any terminal. Add this to ~/.claude/settings.json (merge it into an existing "hooks" block if you have one), then restart Claude Code. Each time Claude finishes a turn, you get a notification and a ding:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude is done\" with title \"Claude Code\"'; afplay /System/Library/Sounds/Glass.aiff"
          }
        ]
      }
    ]
  }
}

Get Ambient Free for macOS 14 and later.

Which option should you use?

Built-inNotification hookAmbient
SetupNone in Ghostty and Kitty, one setting in iTerm2Edit settings.jsonInstall, click Connect All
Works inGhostty, Kitty, iTerm2 (a bell elsewhere)Any terminalAny terminal or editor, and the Claude desktop app
Status while it worksNoNoYes: notch, menu bar and Dock
Many sessions at onceOne notification eachOne notification eachEvery session, most urgent first
Click takes you toDepends on the terminalScript Editor, with osascriptThe exact tab, tmux pane or Claude chat
Other agentsNoNoCodex and Gemini CLI

If you run one session in iTerm2, the built-in notification is enough. If you run several agents, or work in VS Code, Cursor or Terminal, read on.

Option 1: Claude Code's built-in notifications

When Claude finishes a task or pauses for a permission prompt while you appear to be away from the terminal, Claude Code fires a notification. By default it becomes a desktop notification only in Ghostty, Kitty and iTerm2.

// ~/.claude/settings.json
{
  "preferredNotifChannel": "terminal_bell"
}

Inside tmux, notifications never reach the outer terminal until you allow passthrough. Add this to ~/.tmux.conf and run tmux source-file ~/.tmux.conf:

set -g allow-passthrough on

Still nothing? Check that your terminal app is allowed to post notifications in System Settings › Notifications.

Option 2: A Notification hook

A hook runs a command of your choice at a point in Claude Code's lifecycle, in any terminal. This one posts a macOS notification whenever Claude needs your attention:

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

If your file already has a hooks key, add Notification next to the events already in it. Type /hooks in Claude Code to confirm the hook is registered.

When the Notification event fires

Put one of those in "matcher" to alert on only that case. For an alert the moment Claude finishes, use the Stop event, which runs when the main agent finishes responding:

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

Two things that trip people up

Option 3: Ambient, a live status for every session

Ambient is a free Mac app that turns Claude Code's hooks into a status you can read at a glance. A black pill at the notch shows a coral orb while Claude works, an amber pulse when it needs you, green when it's done and red when a turn fails. Banners and soft chimes arrive only for those moments, and a click takes you back to where the agent runs.

  1. Download Ambient from yaml.cafe and drag it to Applications.
  2. Open it and click Connect All.
  3. Restart Claude Code sessions that were already open, so they load the new hooks.

Connecting adds one hook group per Claude Code event to ~/.claude/settings.json, each running ~/.ambient/bin/ambient hook claude in the background. Ambient backs the file up first and never touches your other settings. Each hook finishes in about 15 ms and sends a few short fields over a Unix socket on your Mac. Nothing leaves the machine.

Claude Code runs inA click opens
The Claude desktop appThe exact chat
Terminal or iTerm2The exact tab
tmux or cmuxThe exact pane
VS Code, Cursor and other editorsThe project's window

Ambient stays quiet while you're already in the app running the agent, and skips banners for turns shorter than 20 seconds. The built-in notification keeps working alongside it, so you can use both.

Stop babysitting terminals.

Free for macOS 14 and later. Works with Claude Code, Codex and Gemini CLI.

Get Ambient

Or brew install --cask viveky259259/tap/ambient · Star on GitHub

Common questions

Why don't I get Claude Code notifications in the VS Code, Cursor or Warp terminal?

Claude Code sends desktop notifications by default only in Ghostty, Kitty and iTerm2. In the VS Code or Cursor integrated terminal, Terminal.app or Warp, set preferredNotifChannel to terminal_bell, add a Notification hook, or use Ambient, which works in any terminal or editor.

Why does the "Claude is done" notification take a minute to arrive?

The idle_prompt notification fires about 60 seconds after Claude finishes responding, and only if you haven't typed since. For an alert the moment Claude finishes, add a Stop hook, or use Ambient, which marks the session done as soon as the turn ends.

Do Claude Code notifications work inside tmux?

Built-in desktop notifications need set -g allow-passthrough on in ~/.tmux.conf so they reach the outer terminal. Hooks don't pass through the terminal, so a Notification hook and Ambient work in tmux without that setting, and Ambient returns you to the exact pane.

Do Claude Code notifications work over SSH?

The built-in desktop notification reaches your local machine over SSH in Ghostty, Kitty and iTerm2. Hooks run on the machine where Claude Code runs, so an osascript hook only works when Claude Code runs on your Mac. Ambient can follow agents on another machine: pair it with ambient remote add, and its sessions show up on your Mac over your own ssh.

How do I get a notification when Claude Code is done?

Claude Code's built-in idle_prompt notification fires about a minute after a reply, and only in Ghostty, Kitty and iTerm2. For an alert the moment it finishes, add a Stop hook that runs osascript -e 'display notification "Claude is done"', or install Ambient, which posts a notification and a soft chime when any session's turn ends and shows green at the notch until you look.

Can I get Claude Code notifications on my phone?

Not from the built-in channels, which only reach your terminal. A Stop or Notification hook can call a push service instead, for example curl -d "Claude is done" ntfy.sh/your-topic, and the alert lands on your phone. Ambient shows agents on your Mac, not on a phone; it can follow Claude Code running on another machine over your own ssh.

Do Claude Code notifications work on Windows and Linux?

The hooks do; only the command changes. On Linux a Notification hook can run notify-send, and on Windows a PowerShell toast. The built-in desktop notification still depends on the terminal you use. Ambient is a macOS app.

Sources

More guides: Notifications not working · Claude Code sound when done · Permission notifications · tmux · Multiple sessions · Notification apps compared · Codex · Gemini CLI · On your phone · Text to speech · OpenCode and Copilot CLI