Skip to main content
Hooks let you attach commands, HTTP calls, or LLM prompts to lifecycle events inside Claude Code. Whenever a matching event fires—such as before a tool runs or when the session ends—your hook executes. Use hooks for audit logging, enforcing team policies, sending notifications, or any side effect that should run automatically alongside Claude.

Hook events

Each hook is keyed by an event name. The full list of available events is:

Configuring hooks

Hooks are defined in a hooks key in any Claude Code settings file:
  • User settings: ~/.claude/settings.json
  • Project settings: .claude/settings.json
  • Local settings: .claude/settings.local.json
  • Managed settings: /etc/claude-code/managed-settings.json (Linux) or MDM profile (macOS/Windows)
The hooks object is a map from event name to an array of matcher objects. Each matcher optionally filters by a string pattern (e.g., a tool name) and contains an array of hook commands.
You can also manage hooks interactively with the /hooks command inside a Claude Code session.

Hook types

Claude Code supports four hook types.
Runs a shell command. The hook input is passed as JSON on stdin.
Exit codes for command hooks:
  • 0 — success, execution continues
  • 2 — blocks the operation and surfaces stderr to Claude as an error
  • Any other non-zero — shows stderr to the user only (non-blocking)
Evaluates a prompt with an LLM. Use $ARGUMENTS in the prompt string to receive the hook input JSON.
Runs a multi-turn LLM agent to verify a condition. The agent must call a structured output tool with {ok: boolean, reason?: string}.
POSTs the hook input JSON to a URL. Useful for sending events to external systems.
Only env vars explicitly listed in allowedEnvVars are interpolated. All other $VAR references in headers resolve to empty strings.

Matcher patterns

The matcher field on a hook entry filters which invocations trigger the hook. It is matched against values relevant to the event—most often the tool name for PreToolUse / PostToolUse events. The if field inside an individual hook command provides finer-grained filtering using permission rule syntax (e.g., "Bash(git *)" or "Read(*.ts)"). A hook with an if condition only runs when the tool call matches that pattern.

Environment variables in hook scripts

Shell command hooks (type: "command") inherit the full process environment plus the following additional variables:
When running inside GitHub Actions with CLAUDE_CODE_SUBPROCESS_ENV_SCRUB set, sensitive credentials (e.g., ANTHROPIC_API_KEY, AWS_SECRET_ACCESS_KEY) are stripped from the hook subprocess environment to prevent prompt-injection exfiltration.

Example configurations

Use cases

  • Audit logging — record every tool call to a file or SIEM system
  • Policy enforcement — block specific commands (exit code 2 surfaces an error to Claude)
  • Notifications — send Slack or webhook messages when sessions complete
  • Environment setup — load .envrc or inject credentials at session start via CLAUDE_ENV_FILE
  • Quality gates — use agent hooks to verify tests pass before allowing commits

Security considerations

Hook commands run with the same OS privileges as Claude Code itself. Only configure hooks from sources you trust.
  • allowManagedHooksOnly — when set to true in managed settings, only hooks from managed settings (MDM/managed-settings.json) run. User, project, and local hooks are silently ignored. This lets IT administrators restrict hook execution to approved scripts.
  • disableAllHooks — setting this to true in any settings file disables all hooks and status line execution.
  • allowedHttpHookUrls — an allowlist of URL patterns HTTP hooks may target. When set, HTTP hooks with non-matching URLs are blocked. Supports * as a wildcard (e.g., "https://hooks.example.com/*").
  • httpHookAllowedEnvVars — restricts which env vars HTTP hooks may interpolate into headers; the effective set is the intersection of this list and each hook’s own allowedEnvVars.
  • Hook scripts should validate their inputs. The JSON input is controlled by Claude Code but may reflect user-supplied content.