Hooks
Hooks
.claude/settings.json
Vendor docs
event
| name | type | required | meaning | concept | |
|---|---|---|---|---|---|
| ConfigChange | event | docs ↗ | |||
| CwdChanged | event | docs ↗ | |||
| Elicitation | event | docs ↗ | |||
| ElicitationResult | event | docs ↗ | |||
| FileChanged | event | docs ↗ | |||
| InstructionsLoaded | event | docs ↗ | |||
| MessageDisplay | event | docs ↗ | |||
| Notification | event | docs ↗ | |||
| PermissionDenied | event | docs ↗ | |||
| PermissionRequest | event | docs ↗ | |||
| PostCompact | event | docs ↗ | |||
| PostToolBatch | event | docs ↗ | |||
| PostToolUse | event | docs ↗ | |||
| PostToolUseFailure | event | docs ↗ | |||
| PreCompact | event | docs ↗ | |||
| PreToolUse | event | docs ↗ | |||
| SessionEnd | event | docs ↗ | |||
| SessionStart | event | docs ↗ | |||
| Setup | event | docs ↗ | |||
| Stop | event | docs ↗ | |||
| StopFailure | event | docs ↗ | |||
| SubagentStart | event | docs ↗ | |||
| SubagentStop | event | docs ↗ | |||
| TaskCompleted | event | docs ↗ | |||
| TaskCreated | event | docs ↗ | |||
| TeammateIdle | event | docs ↗ | |||
| UserPromptExpansion | event | docs ↗ | |||
| UserPromptSubmit | event | docs ↗ | |||
| WorktreeCreate | event | docs ↗ | |||
| WorktreeRemove | event | docs ↗ |
stdin
| name | type | required | meaning | concept | |
|---|---|---|---|---|---|
| agent_id | string |
Unique identifier for the subagent. Present only when the hook fires inside a subagent call. Use this to distinguish subagent hook calls from main-thread calls.
|
docs ↗ | ||
| agent_type | string |
Agent name (for example, `"Explore"` or `"security-reviewer"`). Present when the session uses `--agent` or the hook fires inside a subagent. For subagents, the subagent's type takes precedence over the session's `--agent` value. For custom subagents, this is the `name` field from the agent's frontmatter, not the filename. For subagents shipped by a plugin, this is the plugin-scoped identifier such as `my-plugin:reviewer`, not the bare frontmatter name. See SubagentStart for how to write a matcher against a plugin-scoped name.
|
docs ↗ | ||
| cwd | string |
Current working directory when the hook is invoked
|
docs ↗ | ||
| effort | string |
Object with a `level` field holding the active effort level for the turn: `"low"`, `"medium"`, `"high"`, `"xhigh"`, or `"max"`. If the requested model effort exceeds what the current model supports, this is the downgraded level the model actually used. Ultracode is not a distinct level and reports as `"xhigh"`. The object matches the status line `effort` field. Present for events that fire within a tool-use context, such as `PreToolUse`, `PostToolUse`, `Stop`, and `SubagentStop`, when the current model supports the effort parameter. The level is also available to hook commands and the Bash tool as the `$CLAUDE_EFFORT` environment variable.
|
docs ↗ | ||
| hook_event_name | string |
Name of the event that fired
|
docs ↗ | ||
| permission_mode | string |
Current permission mode: `"default"`, `"plan"`, `"acceptEdits"`, `"auto"`, `"dontAsk"`, or `"bypassPermissions"`. The mode labeled **Manual** arrives as `"default"`, never as `"manual"`, so scripts that match `"default"` keep working. Not all events receive this field. Check the JSON example in each hook event section
|
docs ↗ | ||
| prompt_id | string |
UUID identifying the user prompt currently being processed. Matches the `prompt.id` attribute on OpenTelemetry events, so you can correlate hook output with telemetry for a single prompt. Absent until the first user input. Requires Claude Code v2.1.196 or later
|
docs ↗ | ||
| session_id | string |
Current session identifier
|
docs ↗ | ||
| transcript_path | string |
Path to conversation JSON. The transcript file is written asynchronously and may lag the in-memory conversation, so it may not yet include the current turn's most recent messages when a hook fires. Hooks that need the final assistant text of the current turn should use `last_assistant_message` on Stop and SubagentStop instead of reading the transcript
|
docs ↗ |
handler
| name | type | required | meaning | concept | |
|---|---|---|---|---|---|
| allowedEnvVars | string |
List of environment variable names that may be interpolated into header values. References to unlisted variables are replaced with empty strings. Required for any env var interpolation to work
|
docs ↗ | ||
| args | string |
Argument list. When present, `command` is resolved as an executable and spawned directly with `args` as the argument vector, with no shell involved. See Exec form and shell form
|
docs ↗ | ||
| async | string |
If `true`, runs in the background without blocking. See Run hooks in the background
|
docs ↗ | ||
| asyncRewake | string |
If `true`, runs in the background and wakes Claude on exit code 2. Implies `async`. The hook's stderr, or stdout if stderr is empty, is shown to Claude as a system reminder so it can react to a long-running background failure
|
docs ↗ | ||
| command | string | yes |
Shell command to execute. With `args`, the executable to spawn directly. See Exec form and shell form
|
docs ↗ | |
| headers | string |
Additional HTTP headers as key-value pairs. Values support environment variable interpolation using `$VAR_NAME` or `${VAR_NAME}` syntax. Only variables listed in `allowedEnvVars` are resolved
|
docs ↗ | ||
| if | string |
Permission rule syntax to filter when this hook runs, such as `"Bash(git *)"` or `"Edit(*.ts)"`. The hook command only runs if the tool call matches the pattern. See the Bash matching table below for how Bash patterns evaluate against subcommands, `$()`, and backticks. Only evaluated on tool events: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`, and `PermissionDenied`. On other events, a hook with `if` set never runs. Uses the same syntax as permission rules
|
docs ↗ | ||
| input | string |
Arguments passed to the tool. String values support `${path}` substitution from the hook's JSON input, such as `"${tool_input.file_path}"`
|
docs ↗ | ||
| model | string |
Model to use for evaluation. Defaults to a fast model
|
docs ↗ | ||
| once | string |
If `true`, runs once per session then is removed. Only honored for hooks declared in skill frontmatter; ignored in settings files and agent frontmatter
|
docs ↗ | ||
| prompt | string | yes |
Prompt text to send to the model. Use `$ARGUMENTS` as a placeholder for the hook input JSON. Escape with a backslash to include literal text: `\$1.00` renders as `$1.00`
|
docs ↗ | |
| server | string | yes |
Name of a configured MCP server. For a plugin-bundled server, this is the scoped name `plugin:<plugin-name>:<server-name>`, such as `plugin:my-plugin:db`, not the bare server key. The server must already be connected; the hook never triggers an OAuth or connection flow
|
docs ↗ | |
| shell | string |
Shell to use for this hook. Accepts `"bash"` or `"powershell"`. Defaults to `"bash"`, or to `"powershell"` on Windows when Git Bash isn't installed. Setting `"powershell"` runs the command via PowerShell on Windows. Does not require `CLAUDE_CODE_USE_POWERSHELL_TOOL` since hooks spawn PowerShell directly. Ignored when `args` is set
|
docs ↗ | ||
| statusMessage | string |
Custom spinner message displayed while the hook runs
|
docs ↗ | ||
| timeout | string |
Seconds before canceling. Defaults: 600 for `command`, `http`, and `mcp_tool`; 30 for `prompt`; 60 for `agent`. `UserPromptSubmit` lowers the `command`, `http`, and `mcp_tool` default to 30, and `MessageDisplay` lowers it to 10
|
docs ↗ | ||
| tool | string | yes |
Name of the tool to call on that server
|
docs ↗ | |
| type | string | yes |
`"command"`, `"http"`, `"mcp_tool"`, `"prompt"`, or `"agent"`
|
docs ↗ | |
| url | string | yes |
URL to send the POST request to
|
docs ↗ |