Skip to content

A troubleshooting guide

Claude Code notifications not working? Start here.

On a Mac, Claude Code’s own alert is passed through your terminal, so whether you see it depends on the terminal, on tmux, and on one macOS switch. Here is each cause, in the order it’s usually the answer, with the fix from Claude Code’s docs.

Your terminal decides first

By default Claude Code sends a desktop notification in only three terminals. Everywhere else it stays quiet until you choose a different way to be told.

GhosttyShows the notification: Yes, with no setupIf nothing appears, Ghostty itself isn't allowed to notify: see the first reason below.
KittyShows the notification: Yes, with no setupAs for Ghostty: check Kitty's notification permission in System Settings.
iTerm2Shows the notification: Yes, once forwarding is onSettings → Profiles → Terminal: check “Notification Center Alerts”, then Filter Alerts → “Send escape sequence-generated alerts”.
Warp, Terminal.app, VS Code’s terminal and the restShows the notification: NoThis is Claude Code’s own notification; some of these, Warp among them, have agent alerts of their own. Ring the terminal bell instead with preferredNotifChannel, or add a Notification hook. Both are below.
Any of these, inside tmuxShows the notification: Not until passthrough is ontmux swallows the notification unless allow-passthrough is on. One line in ~/.tmux.conf.

Six reasons it stays silent

1

Your terminal isn't allowed to notify

The alert is posted by your terminal app, so macOS needs to let that app notify. Open System Settings → Notifications, find your terminal and turn on Allow Notifications. A Focus mode or Do Not Disturb holds alerts back too. It’s the first thing Claude Code’s docs say to check.

2

You were looking at it

Claude Code only notifies when you appear to be away from the terminal. A permission prompt waits until you haven’t typed for about six seconds; “waiting for you” comes about 60 seconds after Claude finishes, if you haven’t typed since. To test it, start something, switch to another app and wait.

3

tmux is swallowing it

Inside tmux the notification never reaches the terminal around it unless passthrough is allowed. Add the line below, run tmux source-file ~/.tmux.conf, and it applies to the running server.

4

iTerm2 isn't forwarding it

iTerm2 receives the notification but keeps it to itself until you turn on Notification Center Alerts and, under Filter Alerts, escape sequence-generated alerts. Both are in the profile's Terminal settings.

5

Your osascript hook fails silently

A hook that runs osascript -e 'display notification …' posts as Script Editor. If Script Editor has never been allowed to notify, the command fails without a word and macOS never asks. Run the test command below once, then allow Script Editor in System Settings → Notifications.

6

Your “finished” hook fires on every reply

A hook on Stop runs whenever Claude finishes responding, not only when the task is done. It doesn’t run when you interrupt, and an API error runs StopFailure instead. For “Claude is waiting on me”, use the Notification event with the permission_prompt or idle_prompt matcher.

The settings, ready to paste

Ring the terminal bell, for terminals without the notification

~/.claude/settings.json

{
  "preferredNotifChannel": "terminal_bell"
}

For Warp, Terminal.app, VS Code's terminal and anything else that doesn't show Claude Code's desktop notification.

Let notifications out of tmux

~/.tmux.conf

set -g allow-passthrough on

Then run tmux source-file ~/.tmux.conf to apply it to the running server.

A desktop notification of your own, when Claude asks permission

~/.claude/settings.json

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

Runs alongside the built-in notification. Drop the matcher to hear about every notification type.

Make Script Editor appear in Notifications

Terminal

osascript -e 'display notification "test"'

Nothing shows the first time. Allow Script Editor in System Settings → Notifications, then run it again.

Or skip the per-terminal setup

An alert that doesn’t go through the terminal

Perch takes a different route. Its hooks report each Claude Code session to the Perch app on your Mac, which posts the alert itself — so the terminal you use, tmux passthrough, iTerm2’s filters and Script Editor’s permission don’t come into it. The one switch that matters is Perch’s own, in System Settings → Notifications.

You hear about a permission prompt the moment it’s drawn, the menu bar says which session is waiting, and clicking the alert lands in the exact pane it came from. The same alert reaches your iPhone and Apple Watch with Allow and Deny on it, and an error is never announced as a finish. Every alert Perch sends.

Questions

Notifications, troubleshot

Why does Claude Code only notify me some of the time?
Because it only notifies when you seem to be away. A permission prompt is announced once you haven't typed for about six seconds, and each keystroke pushes that back; the “waiting for you” notification comes about 60 seconds after Claude finishes, and not while a background subagent is still running. Watching the terminal and typing means no notification, by design.
Which Mac terminals show Claude Code notifications without setup?
Ghostty and Kitty, which pass Claude Code's notification to Notification Center by themselves. iTerm2 does once you turn on Notification Center Alerts and escape sequence-generated alerts in the profile's Terminal settings. In other terminals, Warp and VS Code's among them, set preferredNotifChannel to terminal_bell or use a Notification hook.
Do Claude Code notifications work over SSH?
Yes. Claude Code's docs say the desktop notification reaches your local machine over SSH, so a remote session can still alert you — as long as the terminal on your Mac is one that shows it, and tmux on either end has passthrough on.
If I turn Claude Code's notifications off, do Perch's stop too?
No. Perch's alerts come from its hooks, which report to the Perch app on your Mac rather than through the terminal, and Claude Code's docs say preferredNotifChannel — notifications_disabled included — changes only how Claude Code alerts you, not whether hooks run. Turning Claude Code's own notification off is a reasonable way to avoid hearing about the same prompt twice.
Perch is installed and I'm still not getting alerts. What now?
Check System Settings → Notifications → Perch, then that the alert you expect is switched on in Perch’s Settings → Notifications. A session that was already running when Perch installed its hooks says “Restart to enable live updates” on its row; start it again. Still nothing? Tell us.