Claude Code hooks 是 Claude Code 在 session 中的固定時間點自動執行的命令(也可以是 HTTP 呼叫、prompt 等其他幾種 handler 類型),例如在工具執行前、需要權限時,或 Claude 回應完成時。你可以在設定檔(例如 ~/.claude/settings.json)的 hooks 鍵底下定義它們。每個 hook 會從 stdin 收到描述該事件的 JSON,並可透過 exit code 或 stdout 上的 JSON 物件回覆,藉此記錄 log、發送通知、阻擋某個動作,或代替你回答。
01hook 的組成方式
hook 設定分為三個層級:
- hook 事件,例如
PreToolUse或Stop。 - matcher 群組,用來篩選觸發時機,例如「只針對 Bash 工具」。
- 一個或多個 hook handler,也就是實際執行的部分。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "/path/to/lint-check.sh"
}
]
}
]
}
}
這會在 Claude 寫入或編輯檔案後執行 lint 腳本。若要新增第二個事件,在同一個 hooks 物件內加入同層級的鍵即可。
02hook 存放位置
~/.claude/settings.json你的所有專案否,僅限你的電腦.claude/settings.json單一專案是,可以 commit.claude/settings.local.json單一專案否hooks/hooks.jsonplugin 啟用期間是不同檔案中的 hook 會累加,而不是互相取代。在 Claude Code 中輸入 /hooks,即可查看所有啟用中的 hook 及其來源。
在互動式 session 中,Claude Code 會先暫緩執行 hook(包括你自己的),直到你在該資料夾的工作區信任對話框中按下接受。
03Handler 類型
大多數 hook 是 "type": "command",會執行一個 shell 命令。另外還有四種:
http:將事件 JSON 以 POST 送到某個 URL,並讀取回應內容。mcp_tool:呼叫你已設定的 MCP server 上的工具。prompt:向 Claude 模型提出單輪問題,並讀取 JSON 格式的決定。agent:啟動一個可先讀取檔案再做決定的 subagent(實驗性功能)。
Command hook 會以你的完整使用者權限執行:在 macOS 和 Linux 上透過 sh -c,在 Windows 上則透過 Git Bash(或 PowerShell)。加上 "async": true 可讓它在背景執行,但這樣它就無法再做決定。
04Matcher
matcher 決定事件的哪些情況會執行 hook。比對的對象取決於事件:工具事件比對工具名稱,Notification 比對通知類型,SessionStart 比對 session 的啟動方式,依此類推。
"*"、""或完全不設 matcher,都會比對所有情況。- 英文字母、數字、
_、-、空格、|和,會被視為精確名稱。Edit|Write會比對這兩個工具中的任一個。 - 其他寫法則視為 JavaScript 正規表示式,因此
mcp__memory__.*會比對某個 MCP server 的所有工具。
Matcher 區分大小寫。部分事件(包括 Stop 和 UserPromptSubmit)會忽略 matcher。對於工具事件,可以用 if 欄位搭配權限規則(例如 "Bash(git *)"),進一步縮小單一 handler 的範圍。
05輸入:hook 收到的內容
每個 hook 都會從 stdin 收到 JSON,其中包含幾個共通欄位,例如 session_id、transcript_path、cwd 和 hook_event_name,以及該事件專屬的欄位。例如,針對 Bash 呼叫的 PreToolUse hook 還會收到 tool_name 和 tool_input.command。可以用 jq 或任何 JSON parser 讀取:
#!/bin/bash
input=$(cat)
cmd=$(jq -r '.tool_input.command // empty' <<<"$input")
echo "Claude wants to run: $cmd" >> ~/claude-commands.log
exit 0
06輸出:exit code 與 JSON
hook 有兩種方式回應。
Exit code。0 代表成功。2 是阻擋性錯誤:在可阻擋的事件上,動作會被中止,stderr 的內容會成為原因。其他任何 code(包括常見的 1)都是非阻擋性錯誤,動作會照常進行,你只會看到 hook 錯誤提示。如果 hook 是用來強制執行規則,請以 2 結束,而不是 1。
在 stdout 輸出 JSON。以 0 結束並輸出單一 JSON 物件,可以做更細緻的控制。有些欄位在所有事件都適用,例如用 continue: false 完全停止 Claude。其他欄位則依事件而定:Stop 使用 decision: "block" 搭配 reason,而 PreToolUse 和 PermissionRequest 則把決定放在 hookSpecificOutput 裡。stdout 不要輸出任何其他內容:shell profile 多印出一行,就會讓 Claude Code 無法讀取 JSON。
07所有 hook 事件
SessionStartsession 開始或恢復時否(可加入 context)Setup以 --init-only 啟動,或以 --init / --maintenance 搭配 -p 啟動時否InstructionsLoaded載入 CLAUDE.md 或 .claude/rules/*.md 檔案時否UserPromptSubmit送出 prompt 後、Claude 看到之前是UserPromptExpansion輸入的指令展開成 prompt 時是PreToolUse任何工具呼叫之前是PermissionRequest工具呼叫需要權限決定時透過 JSON 允許或拒絕PermissionDeniedAuto mode 拒絕工具呼叫時否PostToolUse工具呼叫成功之後否(工具已執行)PostToolUseFailure工具呼叫失敗之後否PostToolBatch一批平行工具呼叫結束後、下一次模型呼叫之前是NotificationClaude Code 發送通知時否MessageDisplay顯示 Claude 的回覆文字時否(可修改顯示內容)SubagentStart / SubagentStopsubagent 開始或結束時僅 SubagentStopTaskCreated / TaskCompleted建立任務或標記為完成時是StopClaude 回應結束時是(讓 Claude 繼續)StopFailure該輪因 API 錯誤結束時否TeammateIdleagent team 的成員即將閒置時是ConfigChangesession 期間設定檔變更時是CwdChanged工作目錄變更時否DirectoryAdded以 /add-dir 新增目錄時否FileChanged監看的檔案在磁碟上變更時否WorktreeCreate / WorktreeRemove建立或移除 worktree 時是PreCompact / PostCompactcontext 壓縮之前與之後僅限 PreCompactPreModelSwitch / PostModelSwitch切換模型前後僅限 PreModelSwitchElicitation / ElicitationResultMCP server 要求輸入時,以及你回答之後是SessionEnd工作階段結束時否Anthropic 會不定期新增事件,最新清單與各事件的輸入欄位請參閱 hooks 參考文件。
08哪些事件和通知有關
以下四個事件幾乎涵蓋了大家想收到通知的所有情境:
Stop:「Claude 已完成」。請參閱 Stop hook 指南。Notification:「Claude 正在等你」,類型包括permission_prompt和idle_prompt等。請參閱 Notification hook 指南。PermissionRequest:在需要權限的當下立即通知你,或直接代你回覆。請參閱 PermissionRequest 指南。- 針對
AskUserQuestion工具的PreToolUse:查看或回答 Claude 提出的選擇題。請參閱用手機回答問題。
想要可直接貼上使用的桌面設定,請先看如何在 Claude Code 完成時收到通知。
09Claude Code Notifier 的角色
Claude Code Notifier 完全建構在這些 hook 之上。它的免費命令列工具 ccn 可在 Mac、Windows 和 Linux 上執行。安裝時會在 ~/.claude/settings.json 加入七個 hook 項目,每個都執行 ccn hook,並會為該檔案保留一次性備份。ccn 每個事件只執行幾毫秒就結束,不會有任何程式常駐。
單獨使用時,它會顯示桌面通知。配對 iPhone 或 Android app 後,同樣的 hook 還能把你的回覆傳回去:允許或拒絕權限、回答問題,或在 Claude 停止後送出下一個指令。本工具為獨立開發,並非 Anthropic 出品。如果你只需要記錄 log 或執行 lint,自己寫幾行會更簡單。詳情請見 ccn 頁面。
10常見問題
如何不必等 Claude 就能測試 hook?
將範例 JSON pipe 給腳本並檢查結束代碼:echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./my-hook.sh; echo $?。接著在 Claude Code 中執行 /hooks,確認它已註冊在正確的事件下。
為什麼我的 hook 沒有執行?
常見原因包括:settings.json 的 JSON 格式錯誤(結尾多了逗號、含有註解)、matcher 沒有完全相符(有區分大小寫)、腳本沒有執行權限,或資料夾尚未被信任。用 claude --debug 啟動 Claude Code,再查看 debug log 了解實際執行了什麼。完整清單請見疑難排解檢查清單。
如何暫時關閉所有 hook?
在設定檔中加入 "disableAllHooks": true。若只想在某次執行時略過,可用 --settings '{"disableAllHooks": true}' 啟動 Claude Code。沒有單獨關閉某個 hook 的開關,只能移除它的項目。以上兩種方式都無法關閉組織在 managed settings 中設定的 hook。
hook 的預設 timeout 是多少?
command、HTTP 和 MCP tool hook 為十分鐘(600 秒),prompt hook 為 30 秒,agent hook 為 60 秒。少數事件的預設值較短,你也可以在任何 handler 上以秒為單位設定 timeout。