18 18
19<div style={{maxWidth: "500px", margin: "0 auto"}}>19<div style={{maxWidth: "500px", margin: "0 auto"}}>
20 <Frame>20 <Frame>
21 <img src="https://mintcdn.com/claude-code/c5r9_6tjPMzFdDDT/images/hooks-lifecycle.svg?fit=max&auto=format&n=c5r9_6tjPMzFdDDT&q=85&s=996ed41d03e106ab6bc9a8fdd4ebcf26" alt="Hook lifecycle diagram showing the sequence of hooks from SessionStart through the agentic loop to SessionEnd, with WorktreeCreate, WorktreeRemove, and InstructionsLoaded as standalone async events" width="520" height="1020" data-path="images/hooks-lifecycle.svg" />21 <img src="https://mintcdn.com/claude-code/lBsitdsGyD9caWJQ/images/hooks-lifecycle.svg?fit=max&auto=format&n=lBsitdsGyD9caWJQ&q=85&s=be3486ef2cf2563eb213b6cbbce93982" alt="Hook lifecycle diagram showing the sequence of hooks from SessionStart through the agentic loop (PreToolUse, PermissionRequest, PostToolUse, SubagentStart/Stop, TaskCompleted) to PostCompact and SessionEnd, with Elicitation and ElicitationResult nested inside MCP tool execution and WorktreeCreate, WorktreeRemove, Notification, ConfigChange, and InstructionsLoaded as standalone async events" width="520" height="1100" data-path="images/hooks-lifecycle.svg" />
22 </Frame>22 </Frame>
23</div>23</div>
24 24
43| `WorktreeCreate` | When a worktree is being created via `--worktree` or `isolation: "worktree"`. Replaces default git behavior |43| `WorktreeCreate` | When a worktree is being created via `--worktree` or `isolation: "worktree"`. Replaces default git behavior |
44| `WorktreeRemove` | When a worktree is being removed, either at session exit or when a subagent finishes |44| `WorktreeRemove` | When a worktree is being removed, either at session exit or when a subagent finishes |
45| `PreCompact` | Before context compaction |45| `PreCompact` | Before context compaction |
46| `PostCompact` | After context compaction completes |
47| `Elicitation` | When an MCP server requests user input during a tool call |
48| `ElicitationResult` | After a user responds to an MCP elicitation, before the response is sent back to the server |
46| `SessionEnd` | When a session terminates |49| `SessionEnd` | When a session terminates |
47 50
48### How a hook resolves51### How a hook resolves
310}313}
311```314```
312 315
313<Note>
314 HTTP hooks must be configured by editing settings JSON directly. The `/hooks` interactive menu only supports adding command hooks.
315</Note>
316
317#### Prompt and agent hook fields316#### Prompt and agent hook fields
318 317
319In addition to the [common fields](#common-fields), prompt and agent hooks accept these fields:318In addition to the [common fields](#common-fields), prompt and agent hooks accept these fields:
411 410
412### The `/hooks` menu411### The `/hooks` menu
413 412
414Type `/hooks` in Claude Code to open the interactive hooks manager, where you can view, add, and delete hooks without editing settings files directly. For a step-by-step walkthrough, see [Set up your first hook](/en/hooks-guide#set-up-your-first-hook) in the guide.413Type `/hooks` in Claude Code to open a read-only browser for your configured hooks. The menu shows every hook event with a count of configured hooks, lets you drill into matchers, and shows the full details of each hook handler. Use it to verify configuration, check which settings file a hook came from, or inspect a hook's command, prompt, or URL.
415 414
416Each hook in the menu is labeled with a bracket prefix indicating its source:415The menu displays all four hook types: `command`, `prompt`, `agent`, and `http`. Each hook is labeled with a `[type]` prefix and a source indicating where it was defined:
417 416
418* `[User]`: from `~/.claude/settings.json`417* `User`: from `~/.claude/settings.json`
419* `[Project]`: from `.claude/settings.json`418* `Project`: from `.claude/settings.json`
420* `[Local]`: from `.claude/settings.local.json`419* `Local`: from `.claude/settings.local.json`
421* `[Plugin]`: from a plugin's `hooks/hooks.json`, read-only420* `Plugin`: from a plugin's `hooks/hooks.json`
421* `Session`: registered in memory for the current session
422* `Built-in`: registered internally by Claude Code
423
424Selecting a hook opens a detail view showing its event, matcher, type, source file, and the full command, prompt, or URL. The menu is read-only: to add, modify, or remove hooks, edit the settings JSON directly or ask Claude to make the change.
422 425
423### Disable or remove hooks426### Disable or remove hooks
424 427
425To remove a hook, delete its entry from the settings JSON file, or use the `/hooks` menu and select the hook to delete it.428To remove a hook, delete its entry from the settings JSON file.
426 429
427To temporarily disable all hooks without removing them, set `"disableAllHooks": true` in your settings file or use the toggle in the `/hooks` menu. There is no way to disable an individual hook while keeping it in the configuration.430To temporarily disable all hooks without removing them, set `"disableAllHooks": true` in your settings file. There is no way to disable an individual hook while keeping it in the configuration.
428 431
429The `disableAllHooks` setting respects the managed settings hierarchy. If an administrator has configured hooks through managed policy settings, `disableAllHooks` set in user, project, or local settings cannot disable those managed hooks. Only `disableAllHooks` set at the managed settings level can disable managed hooks.432The `disableAllHooks` setting respects the managed settings hierarchy. If an administrator has configured hooks through managed policy settings, `disableAllHooks` set in user, project, or local settings cannot disable those managed hooks. Only `disableAllHooks` set at the managed settings level can disable managed hooks.
430 433
517| `SessionStart` | No | Shows stderr to user only |520| `SessionStart` | No | Shows stderr to user only |
518| `SessionEnd` | No | Shows stderr to user only |521| `SessionEnd` | No | Shows stderr to user only |
519| `PreCompact` | No | Shows stderr to user only |522| `PreCompact` | No | Shows stderr to user only |
523| `PostCompact` | No | Shows stderr to user only |
524| `Elicitation` | Yes | Denies the elicitation |
525| `ElicitationResult` | Yes | Blocks the response (action becomes decline) |
520| `WorktreeCreate` | Yes | Any non-zero exit code causes worktree creation to fail |526| `WorktreeCreate` | Yes | Any non-zero exit code causes worktree creation to fail |
521| `WorktreeRemove` | No | Failures are logged in debug mode only |527| `WorktreeRemove` | No | Failures are logged in debug mode only |
522| `InstructionsLoaded` | No | Exit code is ignored |528| `InstructionsLoaded` | No | Exit code is ignored |
567Not every event supports blocking or controlling behavior through JSON. The events that do each use a different set of fields to express that decision. Use this table as a quick reference before writing a hook:573Not every event supports blocking or controlling behavior through JSON. The events that do each use a different set of fields to express that decision. Use this table as a quick reference before writing a hook:
568 574
569| Events | Decision pattern | Key fields |575| Events | Decision pattern | Key fields |
570| :---------------------------------------------------------------------------------- | :----------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |576| :------------------------------------------------------------------------------------ | :----------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
571| UserPromptSubmit, PostToolUse, PostToolUseFailure, Stop, SubagentStop, ConfigChange | Top-level `decision` | `decision: "block"`, `reason` |577| UserPromptSubmit, PostToolUse, PostToolUseFailure, Stop, SubagentStop, ConfigChange | Top-level `decision` | `decision: "block"`, `reason` |
572| TeammateIdle, TaskCompleted | Exit code or `continue: false` | Exit code 2 blocks the action with stderr feedback. JSON `{"continue": false, "stopReason": "..."}` also stops the teammate entirely, matching `Stop` hook behavior |578| TeammateIdle, TaskCompleted | Exit code or `continue: false` | Exit code 2 blocks the action with stderr feedback. JSON `{"continue": false, "stopReason": "..."}` also stops the teammate entirely, matching `Stop` hook behavior |
573| PreToolUse | `hookSpecificOutput` | `permissionDecision` (allow/deny/ask), `permissionDecisionReason` |579| PreToolUse | `hookSpecificOutput` | `permissionDecision` (allow/deny/ask), `permissionDecisionReason` |
574| PermissionRequest | `hookSpecificOutput` | `decision.behavior` (allow/deny) |580| PermissionRequest | `hookSpecificOutput` | `decision.behavior` (allow/deny) |
575| WorktreeCreate | stdout path | Hook prints absolute path to created worktree. Non-zero exit fails creation |581| WorktreeCreate | stdout path | Hook prints absolute path to created worktree. Non-zero exit fails creation |
576| WorktreeRemove, Notification, SessionEnd, PreCompact, InstructionsLoaded | None | No decision control. Used for side effects like logging or cleanup |582| Elicitation | `hookSpecificOutput` | `action` (accept/decline/cancel), `content` (form field values for accept) |
583| ElicitationResult | `hookSpecificOutput` | `action` (accept/decline/cancel), `content` (form field values override) |
584| WorktreeRemove, Notification, SessionEnd, PreCompact, PostCompact, InstructionsLoaded | None | No decision control. Used for side effects like logging or cleanup |
577 585
578Here are examples of each pattern in action:586Here are examples of each pattern in action:
579 587
1540}1548}
1541```1549```
1542 1550
1551### PostCompact
1552
1553Runs after Claude Code completes a compact operation. Use this event to react to the new compacted state, for example to log the generated summary or update external state.
1554
1555The same matcher values apply as for `PreCompact`:
1556
1557| Matcher | When it fires |
1558| :------- | :------------------------------------------------- |
1559| `manual` | After `/compact` |
1560| `auto` | After auto-compact when the context window is full |
1561
1562#### PostCompact input
1563
1564In addition to the [common input fields](#common-input-fields), PostCompact hooks receive `trigger` and `compact_summary`. The `compact_summary` field contains the conversation summary generated by the compact operation.
1565
1566```json theme={null}
1567{
1568 "session_id": "abc123",
1569 "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
1570 "cwd": "/Users/...",
1571 "permission_mode": "default",
1572 "hook_event_name": "PostCompact",
1573 "trigger": "manual",
1574 "compact_summary": "Summary of the compacted conversation..."
1575}
1576```
1577
1578PostCompact hooks have no decision control. They cannot affect the compaction result but can perform follow-up tasks.
1579
1543### SessionEnd1580### SessionEnd
1544 1581
1545Runs when a Claude Code session ends. Useful for cleanup tasks, logging session1582Runs when a Claude Code session ends. Useful for cleanup tasks, logging session
1578CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS=5000 claude1615CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS=5000 claude
1579```1616```
1580 1617
1618### Elicitation
1619
1620Runs when an MCP server requests user input mid-task. By default, Claude Code shows an interactive dialog for the user to respond. Hooks can intercept this request and respond programmatically, skipping the dialog entirely.
1621
1622The matcher field matches against the MCP server name.
1623
1624#### Elicitation input
1625
1626In addition to the [common input fields](#common-input-fields), Elicitation hooks receive `mcp_server_name`, `message`, and optional `mode`, `url`, `elicitation_id`, and `requested_schema` fields.
1627
1628For form-mode elicitation (the most common case):
1629
1630```json theme={null}
1631{
1632 "session_id": "abc123",
1633 "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
1634 "cwd": "/Users/...",
1635 "permission_mode": "default",
1636 "hook_event_name": "Elicitation",
1637 "mcp_server_name": "my-mcp-server",
1638 "message": "Please provide your credentials",
1639 "mode": "form",
1640 "requested_schema": {
1641 "type": "object",
1642 "properties": {
1643 "username": { "type": "string", "title": "Username" }
1644 }
1645 }
1646}
1647```
1648
1649For URL-mode elicitation (browser-based authentication):
1650
1651```json theme={null}
1652{
1653 "session_id": "abc123",
1654 "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
1655 "cwd": "/Users/...",
1656 "permission_mode": "default",
1657 "hook_event_name": "Elicitation",
1658 "mcp_server_name": "my-mcp-server",
1659 "message": "Please authenticate",
1660 "mode": "url",
1661 "url": "https://auth.example.com/login"
1662}
1663```
1664
1665#### Elicitation output
1666
1667To respond programmatically without showing the dialog, return a JSON object with `hookSpecificOutput`:
1668
1669```json theme={null}
1670{
1671 "hookSpecificOutput": {
1672 "hookEventName": "Elicitation",
1673 "action": "accept",
1674 "content": {
1675 "username": "alice"
1676 }
1677 }
1678}
1679```
1680
1681| Field | Values | Description |
1682| :-------- | :---------------------------- | :--------------------------------------------------------------- |
1683| `action` | `accept`, `decline`, `cancel` | Whether to accept, decline, or cancel the request |
1684| `content` | object | Form field values to submit. Only used when `action` is `accept` |
1685
1686Exit code 2 denies the elicitation and shows stderr to the user.
1687
1688### ElicitationResult
1689
1690Runs after a user responds to an MCP elicitation. Hooks can observe, modify, or block the response before it is sent back to the MCP server.
1691
1692The matcher field matches against the MCP server name.
1693
1694#### ElicitationResult input
1695
1696In addition to the [common input fields](#common-input-fields), ElicitationResult hooks receive `mcp_server_name`, `action`, and optional `mode`, `elicitation_id`, and `content` fields.
1697
1698```json theme={null}
1699{
1700 "session_id": "abc123",
1701 "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
1702 "cwd": "/Users/...",
1703 "permission_mode": "default",
1704 "hook_event_name": "ElicitationResult",
1705 "mcp_server_name": "my-mcp-server",
1706 "action": "accept",
1707 "content": { "username": "alice" },
1708 "mode": "form",
1709 "elicitation_id": "elicit-123"
1710}
1711```
1712
1713#### ElicitationResult output
1714
1715To override the user's response, return a JSON object with `hookSpecificOutput`:
1716
1717```json theme={null}
1718{
1719 "hookSpecificOutput": {
1720 "hookEventName": "ElicitationResult",
1721 "action": "decline",
1722 "content": {}
1723 }
1724}
1725```
1726
1727| Field | Values | Description |
1728| :-------- | :---------------------------- | :--------------------------------------------------------------------- |
1729| `action` | `accept`, `decline`, `cancel` | Overrides the user's action |
1730| `content` | object | Overrides form field values. Only meaningful when `action` is `accept` |
1731
1732Exit code 2 blocks the response, changing the effective action to `decline`.
1733
1581## Prompt-based hooks1734## Prompt-based hooks
1582 1735
1583In addition to command and HTTP hooks, Claude Code supports prompt-based hooks (`type: "prompt"`) that use an LLM to evaluate whether to allow or block an action, and agent hooks (`type: "agent"`) that spawn an agentic verifier with tool access. Not all events support every hook type.1736In addition to command and HTTP hooks, Claude Code supports prompt-based hooks (`type: "prompt"`) that use an LLM to evaluate whether to allow or block an action, and agent hooks (`type: "agent"`) that spawn an agentic verifier with tool access. Not all events support every hook type.
1596Events that only support `type: "command"` hooks:1749Events that only support `type: "command"` hooks:
1597 1750
1598* `ConfigChange`1751* `ConfigChange`
1752* `Elicitation`
1753* `ElicitationResult`
1599* `InstructionsLoaded`1754* `InstructionsLoaded`
1600* `Notification`1755* `Notification`
1756* `PostCompact`
1601* `PreCompact`1757* `PreCompact`
1602* `SessionEnd`1758* `SessionEnd`
1603* `SessionStart`1759* `SessionStart`