What is a hook
A hook is a shell script (or any command) executed automatically when Claude Code triggers an event. Comparable to git hooks, but for the agent environment. The script receives a JSON via stdin describing the event context.
Main events
| Event | Moment | Can block |
|---|---|---|
SessionStart | Startup or resume | No |
UserPromptSubmit | Before prompt processing | Yes |
PreToolUse | Before a tool call | Yes |
PostToolUse | After a tool succeeds | No |
Notification | Claude sends a notification | No |
Stop | Claude finishes responding | Yes |
SubagentStop | A sub-agent ends | Yes |
Agent Teams events (v2.1.32+)
| Event | Use |
|---|---|
TeammateIdle | A team member is about to go idle |
TaskCompleted | A task is about to be marked complete |
ConfigChange | A config file changed during the session |
These events allow implementing quality gates at the agent team level: preventing a task from being marked completed if tests fail, for example.
Configuration in settings.json
{ "hooks": { "PostToolUse": [{ "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": ".claude/hooks/auto-format.sh", "timeout": 10000, "async": true }] }], "PreToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": ".claude/hooks/security.sh" }] }] }}Exit codes
| Code | Meaning |
|---|---|
0 | Success, continue normally |
2 | Block the action (stderr message visible to Claude) |
| Other non-0 | Error surfaced to Claude |
For PreToolUse hooks, exit 2 prevents the tool from executing. Claude reads the stderr message and can adapt its behavior.
Synchronous vs Asynchronous
Synchronous hooks (default): Claude waits for the script to finish. Suited for validation and type checking. Asynchronous hooks (async: true): Claude continues immediately. Suited for formatting, notifications, and logging, where feedback is not needed for the next step.
stdin data flow
# Example JSON received on stdin (PostToolUse){ "tool_name": "Edit", "tool_input": { "file_path": "src/auth.ts" }, "tool_response": { "success": true }, "hook_event_name": "PostToolUse"}The Stop event also includes a last_assistant_message field since v2.1.47, giving direct access to Claude’s last response without parsing transcripts.
Enter your email to read the full card and get the complete PDF bundle.
All content is free and open-source. We just ask for your email.