在 macOS 上,Claude Code 在 Ghostty、Kitty 和 iTerm2 中本身就会发送桌面通知(iTerm2 需要先打开提醒设置),但 Apple Terminal 和大多数其他 terminal 什么都收不到。想在任意 terminal 中收到通知,可以在 ~/.claude/settings.json 里添加一个运行 osascript -e 'display notification ...' 的 Notification hook;如果还想在 Claude 完成的那一刻就知道,再加一个 Stop hook。记得在系统设置中允许“脚本编辑器”发送通知,否则 osascript 命令会静默失败。
01Claude Code 自带的通知行为
当 Claude Code 完成任务或等待权限、而你似乎不在 terminal 前时,它会触发一个通知事件。根据 Anthropic 的 terminal 指南,具体表现取决于所用的 terminal:
对于 iTerm2,打开 Settings > Profiles > Terminal,勾选 Notification Center Alerts,然后点击 Filter Alerts 并开启 Send escape sequence-generated alerts。同时确认在 系统设置 > 通知 中允许 iTerm2 发送通知。
在 Apple Terminal 中,至少可以有声音提醒。在 ~/.claude/settings.json 中设置 "preferredNotifChannel": "terminal_bell",并在 设置 > 描述文件 > 高级 中开启 响铃声。详见 terminal 响铃指南。
内置提醒有局限:只有在 Claude Code 认为你不在时才会触发,只告诉你发生了某件事,而且不会离开这台电脑。
02用 osascript 实现通知 hook
hook 在所有 terminal 中都能用,包括 IDE 内置 terminal。下面是 Anthropic hooks 指南中的 macOS 示例。把它加到 ~/.claude/settings.json 中,保留已有的其他配置项:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}
在 Claude Code 中输入 /hooks,确认它出现在 Notification 下。
脚本编辑器权限
osascript 以“脚本编辑器”的身份发送通知。如果脚本编辑器没有通知权限,命令会静默失败,macOS 也不会弹窗询问。先在终端里运行一次:
osascript -e 'display notification "test"'
第一次运行不会有任何显示。打开 系统设置 > 通知,找到 脚本编辑器,开启 允许通知。再运行一次,测试通知就会出现。
触发时机
空的 matcher 会匹配所有通知类型。最值得关注的两种是 permission_prompt(Claude 等待授权约六秒且你没有输入)和 idle_prompt(Claude 完成约 60 秒后你仍未输入)。Notification hook 指南列出了所有类型及其触发时机。
03在 Claude 完成时立即得知
idle_prompt 要等一分钟。想立刻收到提醒,可以添加 Stop hook,它会在 Claude 结束本轮回复时运行。Stop 不需要 matcher:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude has finished\" with title \"Claude Code\" sound name \"Glass\"'"
}
]
}
]
}
}
sound name 可以用 /System/Library/Sounds 中的任意声音,比如 Glass、Ping 或 Hero。如果只想要声音,命令写成 afplay /System/Library/Sounds/Glass.aiff 即可。关于这个事件的更多内容见 Stop hook 指南。
04显示实际消息内容
hook 通过标准输入接收 JSON。Notification 的输入中有一个 message 字段,例如“Claude needs your permission”。用一个小脚本就能把这段文字放进通知里。将以下内容保存为 ~/.claude/hooks/notify-mac.sh:
#!/bin/bash
msg=$(jq -r '.message // "Claude Code needs your attention"')
osascript -e 'on run argv' \
-e 'display notification (item 1 of argv) with title "Claude Code"' \
-e 'end run' "$msg"
把文字作为参数传入、而不是直接拼进 AppleScript 字符串,这样消息里的引号就不会破坏命令。用 chmod +x ~/.claude/hooks/notify-mac.sh 赋予执行权限,并把 hook 命令设为 ~/.claude/hooks/notify-mac.sh。脚本依赖 jq(如果 jq --version 报错,运行 brew install jq)。
05terminal-notifier:点击通知回到 terminal
点击 osascript 发出的通知会打开脚本编辑器,这显然不是你想去的地方。terminal-notifier 可以指定点击后切换到哪个应用:
brew install terminal-notifier
terminal-notifier -title "Claude Code" -message "Claude has finished" -sound default -activate com.googlecode.iterm2
Apple Terminal 用 com.apple.Terminal,或者填你所用编辑器的 bundle ID。把同样的命令填进 hook 的 command 字段即可。首次使用时要在系统设置中允许 terminal-notifier 发送通知。
06专注模式与勿扰模式
这些都是普通的 macOS 通知,所以专注模式可能会把它们隐藏。如果通知在某些时段消失,检查 系统设置 > 专注模式,并允许发送通知的应用(脚本编辑器、terminal-notifier 或你的 terminal)。如果想让通知按你自己设定的时段静音,请参阅免打扰时段与勿扰模式。
07Claude Code Notifier 的定位
如果你一直坐在 Mac 前、只需要一个提醒,上面的 hook 就够用了。但一旦离开座位就不够了:Mac 通知没法在你去厨房时找到你,也没法替你回复 Claude。
Claude Code Notifier 是一个基于同样 hook 机制的独立工具(由 TouchTap 开发,并非 Anthropic 出品)。它的免费命令行工具 ccn 支持 Mac、Windows 和 Linux。在 Mac 上安装:
curl -fsSL https://claudecodenotifier.com/install.sh | sh
或使用 Homebrew:brew trust --formula touch-tap/tap/ccn && brew install touch-tap/tap/ccn。它会把自己的 hook 配置写入 ~/.claude/settings.json,不改动文件的其他部分,并保留一份备份。之后每当 Claude 完成任务、需要权限或提出问题时,它都会显示 macOS 通知,无需联网,也无需手机。
如果配对了 iPhone 或 Android 手机,同样的事件会以 push 通知送达,你可以直接在手机上允许或拒绝权限、选择 Claude 问题的答案,或发送下一条指令。如果你在过去 30 秒内有输入,terminal 会照常询问,手机端不会等待。参见配对手机和 ccn 页面。手机应用需要订阅或一次性买断,详见价格。
如果装了 ccn,请删除自己配置的 osascript hook,否则每个事件都会收到两条通知。另外还有一个旧版 Mac 菜单栏应用,不要在同一台 Mac 上与 ccn 同时运行。
08常见问题
为什么我的 osascript hook 没有任何显示?
最常见的原因是脚本编辑器(Script Editor)没有通知权限,macOS 会直接丢弃通知,也不报错。先运行一次 osascript -e 'display notification "test"',然后在“系统设置 > 通知”中允许脚本编辑器。如果还是不行,确认没有开启专注模式,并检查 /hooks 里是否列出了你的 hook。
Claude Code 不做任何配置就会发送 macOS 通知吗?
会,在 Ghostty 和 Kitty 中可以;iTerm2 需要先开启通知中心提醒。Apple 终端和 IDE 内置 terminal 默认没有桌面通知,这时可以用 hook 或 ccn。
怎样在 Claude 完成时立刻收到通知,而不是一分钟后?
用 Stop hook。idle_prompt 通知要等 Claude 完成约 60 秒后才触发,而且前提是你没有输入;而 Stop 在每一轮结束时都会运行。
能用声音代替横幅通知吗?
可以。把 hook 命令设为 afplay /System/Library/Sounds/Glass.aiff,或者在 osascript 命令里加上 sound name "Glass",声音和横幅都有。
能直接在 macOS 通知里批准权限请求吗?
osascript 和 terminal-notifier 不行,它们只能显示文字。要在 hook 中响应权限请求,需要用 PermissionRequest 事件,参见通过 hook 响应权限请求;或者用 Claude Code Notifier 在手机上批准。