Trên macOS, Claude Code đã tự gửi thông báo desktop trong Ghostty, Kitty và iTerm2 (iTerm2 cần bật cài đặt cảnh báo), nhưng Apple Terminal và hầu hết các terminal khác thì không có gì. Để có thông báo ở mọi terminal, hãy thêm một hook Notification chạy osascript -e 'display notification ...' vào ~/.claude/settings.json, và thêm hook Stop nếu bạn cũng muốn biết ngay khi Claude làm xong. Nhớ cho phép Script Editor gửi thông báo trong System Settings, nếu không lệnh osascript sẽ thất bại mà không báo lỗi gì.
01Claude Code tự làm được gì
Claude Code phát ra sự kiện thông báo khi hoàn thành một tác vụ hoặc đang chờ cấp quyền mà có vẻ bạn không ở trước terminal. Bạn thấy gì sẽ tùy vào terminal, theo hướng dẫn terminal của Anthropic:
Với iTerm2, mở Settings > Profiles > Terminal, tick Notification Center Alerts, rồi bấm Filter Alerts và bật Send escape sequence-generated alerts. Kiểm tra thêm rằng iTerm2 được phép gửi thông báo trong System Settings > Notifications.
Trong Apple Terminal, ít nhất bạn có thể có âm thanh. Đặt "preferredNotifChannel": "terminal_bell" trong ~/.claude/settings.json và bật Audible bell ở Settings > Profiles > Advanced. Hướng dẫn terminal bell trình bày chi tiết cách này.
Cảnh báo có sẵn có những hạn chế. Nó chỉ bật khi Claude Code nghĩ bạn không ở đó, chỉ báo rằng có chuyện gì đó xảy ra, và không bao giờ đến được thiết bị nào ngoài máy tính.
02Hook thông báo với osascript
Hook hoạt động trong mọi terminal, kể cả terminal của IDE. Đây là ví dụ macOS trong hướng dẫn hooks của Anthropic. Thêm nó vào ~/.claude/settings.json, giữ nguyên các key khác đã có:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}
Gõ /hooks trong Claude Code để kiểm tra hook đã nằm trong Notification.
Quyền của Script Editor
osascript gửi thông báo dưới danh nghĩa Script Editor. Nếu Script Editor chưa có quyền thông báo, lệnh sẽ thất bại âm thầm và macOS cũng không hỏi. Chạy lệnh này một lần trong Terminal:
osascript -e 'display notification "test"'
Lần đầu sẽ không có gì hiện lên. Mở System Settings > Notifications, tìm Script Editor và bật Allow Notifications. Chạy lại lệnh, thông báo thử sẽ xuất hiện.
Khi nào chạy
Matcher rỗng sẽ bắt mọi loại thông báo. Hai loại quan trọng nhất là permission_prompt (Claude đã chờ duyệt khoảng sáu giây mà bạn chưa gõ gì) và idle_prompt (Claude đã xong khoảng 60 giây mà bạn chưa gõ gì kể từ đó). Hướng dẫn Notification hook liệt kê đầy đủ các loại và thời điểm kích hoạt.
03Biết ngay khi Claude làm xong
idle_prompt phải chờ một phút. Muốn được báo ngay, hãy thêm hook Stop, chạy khi Claude kết thúc lượt của mình. Stop không dùng matcher:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude has finished\" with title \"Claude Code\" sound name \"Glass\"'"
}
]
}
]
}
}
sound name nhận bất kỳ âm thanh nào trong /System/Library/Sounds, ví dụ Glass, Ping hoặc Hero. Nếu chỉ muốn âm thanh, dùng lệnh afplay /System/Library/Sounds/Glass.aiff là đủ. Xem thêm về sự kiện này trong hướng dẫn Stop hook.
04Hiển thị nội dung thông báo thật
Hook nhận JSON qua standard input. Input của Notification có trường message, ví dụ "Claude needs your permission". Một script nhỏ có thể đưa nội dung đó vào thông báo. Lưu script này thành ~/.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"
Truyền nội dung dưới dạng tham số thay vì nhét vào chuỗi AppleScript giúp dấu nháy trong message không làm hỏng lệnh. Cấp quyền thực thi bằng chmod +x ~/.claude/hooks/notify-mac.sh và đặt command của hook là ~/.claude/hooks/notify-mac.sh. Script cần jq (chạy brew install jq nếu jq --version báo lỗi).
05terminal-notifier: bấm để quay lại terminal
Thông báo từ osascript khi bấm vào sẽ mở Script Editor, đâu phải nơi bạn muốn tới. terminal-notifier cho phép bạn chọn app sẽ được đưa lên trước:
brew install terminal-notifier
terminal-notifier -title "Claude Code" -message "Claude has finished" -sound default -activate com.googlecode.iterm2
Dùng com.apple.Terminal cho Apple Terminal, hoặc bundle ID của editor bạn dùng. Đặt cùng lệnh đó vào trường command của hook. Lần đầu, hãy cho phép terminal-notifier gửi thông báo trong System Settings.
06Focus và Do Not Disturb
Tất cả đều là thông báo macOS bình thường nên chế độ Focus có thể ẩn chúng. Nếu thông báo biến mất vào những lúc nhất định, hãy kiểm tra System Settings > Focus và cho phép app gửi chúng (Script Editor, terminal-notifier hoặc terminal của bạn). Nếu muốn thông báo tuân theo khung giờ riêng của bạn, xem quiet hours và Do Not Disturb.
07Claude Code Notifier nằm ở đâu trong bức tranh này
Các hook trên là đủ nếu bạn ngồi trước Mac và chỉ cần một lời nhắc. Chúng không còn đủ khi bạn rời bàn, vì thông báo trên Mac không thể tìm đến bạn dưới bếp và cũng không thể trả lời Claude.
Claude Code Notifier là một công cụ độc lập (do TouchTap làm, không phải Anthropic) xây dựng trên chính các hook này. Công cụ dòng lệnh miễn phí của nó, ccn, chạy trên Mac, Windows và Linux. Cài trên Mac bằng:
curl -fsSL https://claudecodenotifier.com/install.sh | sh
hoặc bằng Homebrew: brew trust --formula touch-tap/tap/ccn && brew install touch-tap/tap/ccn. Nó thêm các hook của mình vào ~/.claude/settings.json, không đụng tới phần còn lại của file và giữ một bản sao lưu. Từ đó, nó sẽ hiện thông báo macOS khi Claude làm xong, cần cấp quyền hoặc đặt câu hỏi, không cần mạng và không cần điện thoại.
Nếu bạn ghép nối điện thoại iPhone hoặc Android, các sự kiện đó sẽ đến dưới dạng push notification, và bạn có thể cho phép hoặc từ chối quyền, chọn câu trả lời cho câu hỏi của Claude, hoặc gửi chỉ dẫn tiếp theo ngay từ điện thoại. Nếu bạn vừa gõ trong 30 giây gần nhất, terminal sẽ hỏi như bình thường và không có gì chờ trên điện thoại. Xem ghép nối điện thoại và trang ccn. App điện thoại cần gói đăng ký hoặc mua trọn đời; xem bảng giá.
Nếu dùng ccn, hãy gỡ các hook osascript bạn tự thêm, nếu không mỗi sự kiện sẽ hiện hai thông báo. Ngoài ra còn có một app menu bar cũ hơn cho Mac; đừng chạy nó cùng lúc với ccn trên cùng một máy Mac.
08Câu hỏi thường gặp
Vì sao hook osascript của tôi không hiện gì?
Thường gặp nhất là Script Editor chưa có quyền thông báo, nên macOS bỏ qua thông báo mà không báo lỗi. Hãy chạy osascript -e 'display notification "test"' một lần, rồi cho phép Script Editor trong System Settings > Notifications. Nếu vẫn không được, hãy kiểm tra xem chế độ Focus có đang bật không và /hooks có liệt kê hook của bạn không.
Claude Code có gửi thông báo macOS mà không cần thiết lập gì không?
Có, trong Ghostty và Kitty, và trong iTerm2 khi đã bật cảnh báo Notification Center. Apple Terminal và terminal trong IDE mặc định không có thông báo desktop, nên ở đó hãy dùng hook hoặc ccn.
Làm sao để nhận thông báo ngay khi Claude xong việc, thay vì một phút sau?
Dùng hook Stop. Thông báo idle_prompt chỉ kích hoạt khoảng 60 giây sau khi Claude xong và chỉ khi bạn chưa gõ gì, còn Stop chạy ở cuối mỗi lượt.
Tôi có thể nghe âm thanh thay vì thấy banner không?
Có. Dùng afplay /System/Library/Sounds/Glass.aiff làm lệnh của hook, hoặc thêm sound name "Glass" vào lệnh osascript để có cả hai.
Tôi có thể duyệt quyền ngay từ thông báo macOS không?
Với osascript hay terminal-notifier thì không: chúng chỉ hiển thị chữ. Muốn trả lời yêu cầu quyền từ hook thì cần sự kiện PermissionRequest; xem trả lời yêu cầu quyền từ hook hoặc duyệt từ điện thoại với Claude Code Notifier.