當 Claude Code 在遠端伺服器上執行時,notify-send 或 osascript hook 會在伺服器上觸發,但那裡沒有桌面可以顯示通知。可行的方法有兩種。第一種是 terminal escape sequence:Claude Code 內建的通知,或回傳 terminalSequence 的 hook,會經由 SSH 連線傳回,由你本機的 terminal(Ghostty、Kitty 或 iTerm2)顯示,但前提是你保持連線且 terminal 開著。第二種是透過網路從伺服器 push 到手機,經由 ntfy、webhook 或 Claude Code Notifier,即使筆電闔上也照樣能收到。
01為什麼本機通知指令在 SSH 上沒有作用
hook 是 Claude Code 在執行 Claude Code 的那台機器上所執行的指令。如果是透過 SSH 連線的伺服器,那台機器就是伺服器本身。在那裡使用 notify-send 需要桌面通知 daemon,而 Anthropic 的 hooks 指南也提到,headless 伺服器和 SSH 工作階段都沒有這個 daemon。至於 osascript 和 PowerShell 的 toast 通知,在那裡則完全不存在。
所以問題不是「該用哪個通知指令」,而是「訊號要怎麼從伺服器傳到我這裡」。有三種方法:
02方法 1:透過 SSH terminal 接收通知
Claude Code 本身的通知是寫入 terminal 的 escape sequence。Anthropic 的 terminal 指南說明它會經由 SSH 傳回你的本機,所以遠端 session 也能提醒你。Ghostty 和 Kitty 不需任何設定,就會把它轉給桌面的通知中心。iTerm2 則需要先啟用:到 Settings > Profiles > Terminal,勾選 Notification Center Alerts,再到 Filter Alerts 開啟 Send escape sequence-generated alerts。
如果你的 terminal 不在上述清單中,或想自訂文字,可以讓 hook 回傳 escape sequence 交給 Claude Code 寫出。Hook 本身沒有 terminal,所以要放在 terminalSequence 欄位回傳。在伺服器上將以下內容存成 ~/.claude/hooks/notify-ssh.sh:
#!/bin/bash
body=$(jq -r '.message // "Claude Code needs your attention"')
# OSC 9 for iTerm2, WezTerm and ConEmu; use '\033]777;notify;%s;%s\007' for Ghostty
seq=$(printf '\033]9;%s\007' "$body")
jq -nc --arg seq "$seq" '{terminalSequence: $seq}'
接著把它加到伺服器上的 ~/.claude/settings.json:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{ "type": "command", "command": "~/.claude/hooks/notify-ssh.sh" }
]
}
]
}
}
執行 chmod +x ~/.claude/hooks/notify-ssh.sh,並在伺服器上安裝 jq。Anthropic 的參考文件列出了支援的 sequence:OSC 9(iTerm2、ConEmu、Windows Terminal、WezTerm)、OSC 99(Kitty)、OSC 777(urxvt、Ghostty、Warp),以及單純的 bell。Claude Code 只有在互動式 session 且介面顯示在畫面上時才會寫出 sequence。
這種做法有先天限制。只要 SSH 連線中斷、筆電進入睡眠,或關掉分頁,就什麼都收不到。如果你在 tmux 裡執行 Claude Code,請在伺服器的 ~/.tmux.conf 加上 set -g allow-passthrough on;tmux 指南有說明這部分以及 detached session 的情況。
03方法 2:從伺服器 push
Push 不依賴你的 terminal,因此很適合長時間執行的工作。Hook 會從伺服器發出 HTTPS 請求,再由服務送到你的手機或聊天工具。ntfy 指南和 Telegram、Slack 與 Discord 指南都有可直接使用的 hook。這些只能告訴你發生了什麼事,無法核准指令或回答問題,所以 Claude 仍會等你重新連線。
04方法 3:在伺服器上使用 Claude Code Notifier
Claude Code Notifier 是獨立工具(由 TouchTap 開發,並非 Anthropic)。它的免費命令列工具 ccn 可在 Mac、Windows 和 Linux 上執行,所以請把它安裝在執行 Claude Code 的伺服器上:
curl -fsSL https://claudecodenotifier.com/install.sh | sh
它會把自己的 hook 項目加到伺服器的 ~/.claude/settings.json,保留其他設定並建立備份。ccn 的桌面通知會顯示在 ccn 所執行的機器上,在 headless 伺服器上等於沒有用。真正有用的是手機:手機通知會經由 TouchTap 的加密中繼伺服器傳送,而不是透過你的 SSH 連線,所以只要機器能連上網路,不論 ccn 在哪台機器上執行都能運作。
透過 SSH 配對
配對不需要在伺服器上開瀏覽器。你可以在 SSH session 中執行 ccn pair,它會在 terminal 中顯示 QR code 讓你用手機相機掃描,並提供一個 24 小時內有效的連結。或者在手機上開啟 App,前往 Computers > Add a computer,執行畫面上顯示的那行指令,一步完成安裝與配對:
curl -fsSL https://claudecodenotifier.com/install.sh | sh -s 482913
(六位數代碼僅為範例,請使用 App 顯示的代碼。)一支手機可以連接多台電腦,所以筆電和伺服器都能回報到同一支手機。詳情請參考配對指南。
可以從手機做哪些事
配對完成後,Claude 完成工作、需要權限或提出問題時,你都會收到 push 通知。你可以針對權限選擇允許一次、在本次 session 中允許或拒絕,也可以選擇 Claude 問題的答案,並在 Claude 完成後送出下一個指令。如果你不在電腦前,terminal 會等待手機的回覆,最長等到你設定的上限;只要你一碰鍵盤就會停止等待。在伺服器上執行 ccn doctor 即可檢查 hook、憑證以及與 relay 的連線。手機 App 的費用請見價格方案;命令列工具則是免費的。
05SSH 斷線時讓 Claude Code 繼續執行
這三種方式都需要 Claude Code 本身持續執行。如果你直接在 SSH shell 裡啟動 claude,連線一斷,session 也會跟著結束。請在 tmux 或 GNU screen 裡執行,這樣斷線後仍會存活,之後再重新 attach 即可。在 detached session 中 hook 依然會觸發,這正是手機 push 派上用場的時候。tmux 指南與離開電腦執行長時間任務有詳細說明這套流程。
06常見問題
為什麼透過 SSH 使用 Claude Code 時,notify-send 沒有任何反應?
因為 hook 是在伺服器上執行,而伺服器沒有桌面通知 daemon。請改用本機 terminal 看得懂的 escape sequence,或使用 push 服務。
Claude Code 內建的通知可以透過 SSH 運作嗎?
可以,只要 terminal 支援。Anthropic 的文件指出,桌面通知可透過 SSH 傳到你的本機;Ghostty 和 Kitty 不需設定就能顯示,iTerm2 則需先啟用 escape sequence 警示。前提是連線必須保持開啟。
ccn 要裝在筆電上還是伺服器上?
裝在伺服器上,因為 Claude Code 和它的 hook 都在那裡執行。如果你也會在筆電上執行 Claude Code,筆電也一起裝;同一支手機可以同時與兩者配對。
SSH session 斷線後,我還會收到通知嗎?
只有從伺服器發出的 push 才行,而且 Claude Code 必須仍在執行,例如在 tmux 裡。escape sequence 在連線關閉的那一刻就會失效。
伺服器需要開放任何連接埠才能收到手機通知嗎?
ccn 不需要任何對內連線,只需要能對外連上網際網路,以連到 relay 伺服器。