Follow Discord
Sweep 09 Oct 2026 · 17:27Z Build v2.1.296 517 read Stable v2.1.287 Latest v2.1.296 Next v2.1.296 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

Intercept and control agent behavior with hooks changedagent-sdk/hooks

Nearest release: v2.1.273, published 5 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 15 Sep 2026 23:29 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 28 Sep 2026 23:37 UTC.

Upstream edited
Recorded here
Lines+44added
Lines−44removed
From line 140 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits13to this page, all time

The whole hunk

from line 140, old and new numbered
/
lines
from line 140
140140 
141141The SDK provides hooks for different stages of agent execution. Some hooks are available in both SDKs, while others are TypeScript-only.
142142 
143| Hook Event | Python SDK | TypeScript SDK | What triggers it | Example use case |
144| ------------------------------------------------------ | ---------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
145| `PreToolUse` | Yes | Yes | Tool call request (can block or modify) | Block dangerous shell commands |
146| `PostToolUse` | Yes | Yes | Tool execution result | Log all file changes to audit trail |
147| `PostToolUseFailure` | Yes | Yes | Tool execution failure | Handle or log tool errors |
148| `PostToolBatch` | No | Yes | A full batch of tool calls resolves, once per batch before the next model call | Inject conventions once for the whole batch |
149| `UserPromptSubmit` | Yes | Yes | User prompt submission | Inject additional context into prompts |
150| [`UserPromptExpansion`](/docs/en/hooks#userpromptexpansion) | No | Yes | A user-typed command, or an MCP prompt, expands into a prompt before it reaches Claude. Doesn't fire when Claude invokes a skill itself | Block a command from direct invocation or add context when a skill is typed |
151| `MessageDisplay` | No | Yes | An assistant message with text completes, once per message with the full message text | Redact or reformat the displayed text without changing the transcript |
152| `Stop` | Yes | Yes | Agent execution stop | Save session state before exit |
153| `StopFailure` | No | Yes | The turn ends with an API error instead of a normal stop | Log failures or send alerts |
154| `SubagentStart` | Yes | Yes | Subagent initialization | Track parallel task spawning |
155| `SubagentStop` | Yes | Yes | Subagent completion | Aggregate results from parallel tasks |
156| `PreCompact` | Yes | Yes | Conversation compaction request | Archive full transcript before summarizing |
157| `PostCompact` | No | Yes | Conversation compaction completes | Log the generated summary |
158| [`PreModelSwitch`](/docs/en/hooks#premodelswitch) | No | Yes | A requested model switch, before it happens (can block) | Block switching to a specific model |
159| [`PostModelSwitch`](/docs/en/hooks#postmodelswitch) | No | Yes | The session's model changes, including an automatic fallback | Give Claude model-specific guidance for the new model |
160| `PermissionRequest` | Yes | Yes | A tool call needs a permission decision | Custom permission handling |
161| `PermissionDenied` | No | Yes | Auto mode denies a tool call, including denials without a classifier verdict | Log denials, or tell the model it may retry; Claude Code ignores `retry: true` for no-verdict denials. See [PermissionDenied](/docs/en/hooks#permissiondenied) |
162| `SessionStart` | No | Yes | Session initialization | Initialize logging and telemetry |
163| `SessionEnd` | No | Yes | Session termination | Clean up temporary resources |
164| `Notification` | Yes | Yes | Agent status messages | Send agent status updates to Slack or PagerDuty |
165| `Setup` | No | Yes | Session setup/maintenance | Run initialization tasks |
166| `TeammateIdle` | No | Yes | Teammate becomes idle | Reassign work or notify |
167| `TaskCreated` | No | Yes | A task is created via the `TaskCreate` tool | Enforce task naming conventions |
168| [`TaskCompleted`](/docs/en/hooks#taskcompleted) | No | Yes | A task is marked completed | Require passing tests before a task closes |
169| `Elicitation` | No | Yes | An MCP server requests user input mid-task | Respond to MCP input requests programmatically |
170| `ElicitationResult` | No | Yes | A user responds to an MCP elicitation | Modify or block the response before it returns to the server |
171| `ConfigChange` | No | Yes | Configuration file changes | Reload settings dynamically |
172| `InstructionsLoaded` | No | Yes | A `CLAUDE.md` or rules file is loaded into context | Audit which instruction files load |
173| `WorktreeCreate` | No | Yes | Git worktree created | Track isolated workspaces |
174| `WorktreeRemove` | No | Yes | Git worktree removed | Clean up workspace resources |
175| `CwdChanged` | No | Yes | The working directory changes during a session | Reload environment variables per directory |
176| `FileChanged` | No | Yes | A watched file is modified, created, or deleted | Reload configuration when project files change |
177| `DirectoryAdded` | No | Yes | A working directory is added during a session | Install dependencies for a repository added mid-session |
143| Hook Event | Python SDK | TypeScript SDK | What triggers it | Example use case |
144| - | - | - | - | - |
145| `PreToolUse` | Yes | Yes | Tool call request (can block or modify) | Block dangerous shell commands |
146| `PostToolUse` | Yes | Yes | Tool execution result | Log all file changes to audit trail |
147| `PostToolUseFailure` | Yes | Yes | Tool execution failure | Handle or log tool errors |
148| `PostToolBatch` | No | Yes | A full batch of tool calls resolves, once per batch before the next model call | Inject conventions once for the whole batch |
149| `UserPromptSubmit` | Yes | Yes | User prompt submission | Inject additional context into prompts |
150| [`UserPromptExpansion`](/docs/en/hooks#userpromptexpansion) | No | Yes | A user-typed command, or an MCP prompt, expands into a prompt before it reaches Claude. Doesn't fire when Claude invokes a skill itself | Block a command from direct invocation or add context when a skill is typed |
151| `MessageDisplay` | No | Yes | An assistant message with text completes, once per message with the full message text | Redact or reformat the displayed text without changing the transcript |
152| `Stop` | Yes | Yes | Agent execution stop | Save session state before exit |
153| `StopFailure` | No | Yes | The turn ends with an API error instead of a normal stop | Log failures or send alerts |
154| `SubagentStart` | Yes | Yes | Subagent initialization | Track parallel task spawning |
155| `SubagentStop` | Yes | Yes | Subagent completion | Aggregate results from parallel tasks |
156| `PreCompact` | Yes | Yes | Conversation compaction request | Archive full transcript before summarizing |
157| `PostCompact` | No | Yes | Conversation compaction completes | Log the generated summary |
158| [`PreModelSwitch`](/docs/en/hooks#premodelswitch) | No | Yes | A requested model switch, before it happens (can block) | Block switching to a specific model |
159| [`PostModelSwitch`](/docs/en/hooks#postmodelswitch) | No | Yes | The session's model changes, including an automatic fallback | Give Claude model-specific guidance for the new model |
160| `PermissionRequest` | Yes | Yes | A tool call needs a permission decision | Custom permission handling |
161| `PermissionDenied` | No | Yes | Auto mode denies a tool call, including denials without a classifier verdict | Log denials, or tell the model it may retry; Claude Code ignores `retry: true` for no-verdict denials. See [PermissionDenied](/docs/en/hooks#permissiondenied) |
162| `SessionStart` | No | Yes | Session initialization | Initialize logging and telemetry |
163| `SessionEnd` | No | Yes | Session termination | Clean up temporary resources |
164| `Notification` | Yes | Yes | Agent status messages | Send agent status updates to Slack or PagerDuty |
165| `Setup` | No | Yes | Session setup/maintenance | Run initialization tasks |
166| `TeammateIdle` | No | Yes | Teammate becomes idle | Reassign work or notify |
167| `TaskCreated` | No | Yes | A task is created via the `TaskCreate` tool | Enforce task naming conventions |
168| [`TaskCompleted`](/docs/en/hooks#taskcompleted) | No | Yes | A task is marked completed | Require passing tests before a task closes |
169| `Elicitation` | No | Yes | An MCP server requests user input mid-task | Respond to MCP input requests programmatically |
170| `ElicitationResult` | No | Yes | A user responds to an MCP elicitation | Modify or block the response before it returns to the server |
171| `ConfigChange` | No | Yes | Configuration file changes | Reload settings dynamically |
172| `InstructionsLoaded` | No | Yes | A `CLAUDE.md` or rules file is loaded into context | Audit which instruction files load |
173| `WorktreeCreate` | No | Yes | Git worktree created | Track isolated workspaces |
174| `WorktreeRemove` | No | Yes | Git worktree removed | Clean up workspace resources |
175| `CwdChanged` | No | Yes | The working directory changes during a session | Reload environment variables per directory |
176| `FileChanged` | No | Yes | A watched file is modified, created, or deleted | Reload configuration when project files change |
177| `DirectoryAdded` | No | Yes | A working directory is added during a session | Install dependencies for a repository added mid-session |
178178 
179179## Configure hooks
180180 
from line 217
217217 
218218SDK matchers follow the same rules as [matchers in settings files](/docs/en/hooks#matcher-patterns). That section documents the exact-string and regular-expression evaluation paths, their version requirements, and the matcher values for each event type.
219219 
220| Option | Type | Default | Description |
221| --------- | ---------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
222| `matcher` | `string` | `undefined` | Pattern matched against the event's filter field, following the [rules for matchers in settings files](/docs/en/hooks#matcher-patterns). For tool hooks, this is the tool name. Built-in tools include `Bash`, `Read`, `Write`, `Edit`, `Glob`, `Grep`, `WebFetch`, `Agent`, and others (see [Tool Input Types](/docs/en/agent-sdk/typescript#tool-input-types) for the full list). MCP tools use the pattern `mcp__<server>__<action>`, where `<server>` is the key you use in the `mcpServers` configuration. |
223| `hooks` | `HookCallback[]` | - | Required. Array of callback functions to execute when the pattern matches |
224| `timeout` | `number` | `undefined` | Timeout in seconds. When omitted, Claude Code applies the [event's default timeout](#hook-timeout). Your SDK callbacks follow the `command` hook defaults |
220| Option | Type | Default | Description |
221| - | - | - | - |
222| `matcher` | `string` | `undefined` | Pattern matched against the event's filter field, following the [rules for matchers in settings files](/docs/en/hooks#matcher-patterns). For tool hooks, this is the tool name. Built-in tools include `Bash`, `Read`, `Write`, `Edit`, `Glob`, `Grep`, `WebFetch`, `Agent`, and others (see [Tool Input Types](/docs/en/agent-sdk/typescript#tool-input-types) for the full list). MCP tools use the pattern `mcp__<server>__<action>`, where `<server>` is the key you use in the `mcpServers` configuration. |
223| `hooks` | `HookCallback[]` | - | Required. Array of callback functions to execute when the pattern matches |
224| `timeout` | `number` | `undefined` | Timeout in seconds. When omitted, Claude Code applies the [event's default timeout](#hook-timeout). Your SDK callbacks follow the `command` hook defaults |
225225 
226226Use the `matcher` pattern to target specific tools whenever possible. A matcher with `'Bash'` only runs for Bash commands, while omitting the pattern runs your callbacks for every occurrence of the event. Omit it on purpose to log every tool call your session makes.
227227 
from line 274
274274 ```
275275</CodeGroup>
276276 
277| Field | Type | Description |
278| -------------- | -------- | -------------------------------------------------------------------------------------------------------------- |
279| `async` | `true` | Signals async mode. The agent proceeds without waiting. In Python, use `async_` to avoid the reserved keyword. |
280| `asyncTimeout` | `number` | Optional timeout in milliseconds for the background operation |
277| Field | Type | Description |
278| - | - | - |
279| `async` | `true` | Signals async mode. The agent proceeds without waiting. In Python, use `async_` to avoid the reserved keyword. |
280| `asyncTimeout` | `number` | Optional timeout in milliseconds for the background operation |
281281 
282282<Note>
283283 Async outputs can't block, modify, or inject context into the operation since the agent has already moved on. Use them only for side effects like logging, metrics, or notifications.
Feedback