PreToolUse API
Documents the PreToolUse hook API for Claude Code, listing input helpers, state methods, output helpers, and exit code behaviors.
What this file does
Documents the PreToolUse hook API for Claude Code, listing input helpers, state methods, output helpers, and exit code behaviors.
When to use it
- Writing a PreToolUse hook that needs to approve, block, or ask permission for tool calls
- Understanding how exit codes and output streams affect tool execution and visibility
- Modifying tool input data before it reaches Claude Code
Assumes this stack
PreToolUse API
Available when inheriting from ClaudeHooks::PreToolUse:
Input Helpers
Input helpers to access the data provided by Claude Code through STDIN.
| Method | Description |
|---|---|
tool_name | Get the name of the tool being used |
tool_input | Get the input data for the tool |
tool_use_id | Get the unique identifier for this tool use (e.g., "toolu_01ABC123...") |
Hook State Helpers
Hook state methods are helpers to modify the hook's internal state (output_data) before yielding back to Claude Code.
๐ Shared hook state methods
| Method | Description |
|---|---|
approve_tool!(reason) | Explicitly approve tool usage |
block_tool!(reason) | Block tool usage with feedback |
ask_for_permission!(reason) | Request user permission |
update_tool_input!(updated_input) | Update the tool input and automatically approve the tool (sets permissionDecision to 'allow') |
Output Helpers
Output helpers provide access to the hook's output data and helper methods for working with the output state.
| Method | Description |
|---|---|
output.allowed? | Check if the tool has been explicitly allowed (permission_decision == 'allow') |
output.denied? | Check if the tool has been denied (permission_decision == 'deny') |
output.blocked? | Alias for denied? |
output.should_ask_permission? | Check if user permission is required (permission_decision == 'ask') |
output.input_updated? | Check if tool input has been updated |
output.permission_decision | Get the permission decision: 'allow', 'deny', or 'ask' |
output.permission_reason | Get the reason for the permission decision |
output.updated_input | Get the updated input (if provided) |
Hook Exit Codes
| Exit Code | Behavior |
|---|---|
exit 0 | Operation continues<br/>STDOUT shown to user in transcript mode |
exit 1 | Non-blocking error<br/>STDERR shown to user |
exit 2 | Blocks the tool call<br/>STDERR shown to Claude |
Exit code behaviors related to chosen output stream
Outputting to a specific stream has a different effect depending on the exit code.
[!TIP] The most common and useful cases expressed in the tables below are handled automatically by calling
hook.output_and_exit. You only need to worry about this when you want very specific behavior.
ALLOW
Claude Code behavior depending on combination
| Exit Code | STDERR | STDOUT |
|---|---|---|
| 0 | RUNS | RUNS |
| 1 | RUNS | RUNS |
| 2 | BLOCKS | RUNS |
Output visibility depending on exit code
| Output Visibility / Exit Code | 0 | 1 | 2 |
|---|---|---|---|
| STDOUT sent to Claude | โ YES | โ YES | โ YES |
| STDOUT shown to User | โ NO | โ NO | โ NO |
| STDERR sent to Claude | โ NO | โ NO | โ YES |
| STDERR shown to User | โ NO | โ YES | โ YES |
ASK
Claude Code behavior depending on combination
| Exit Code | STDERR | STDOUT |
|---|---|---|
| 0 | RUNS | ASKS |
| 1 | RUNS | ASKS |
| 2 | BLOCKS | ASKS |
Output visibility depending on exit code
| Output Visibility / Exit Code | 0 | 1 | 2 |
|---|---|---|---|
| STDOUT sent to Claude | โ YES | โ YES | โ YES |
| STDOUT shown to User | โ YES | โ YES | โ YES |
| STDERR sent to Claude | โ NO | โ NO | โ YES |
| STDERR shown to User | โ NO | โ YES | โ YES |
DENY
Claude Code behavior depending on combination
| Exit Code | STDERR | STDOUT |
|---|---|---|
| 0 | BLOCKS | BLOCKS |
| 1 | BLOCKS | BLOCKS |
| 2 | BLOCKS | BLOCKS |
Output visibility depending on exit code
| Output Visibility / Exit Code | 0 | 1 | 2 |
|---|---|---|---|
| STDOUT sent to Claude | โ YES | โ YES | โ YES |
| STDOUT shown to User | โ YES | โ YES | โ YES |
| STDERR sent to Claude | โ NO | โ NO | โ YES |
| STDERR shown to User | โ NO | โ YES | โ YES |
What's inside
4 method tables (input, state, output, exit codes) and 3 decision matrices for allow/ask/deny scenarios
Change this for your project
- Replace
ClaudeHooks::PreToolUsewith your own hook base class if different - Replace
COMMON.mdlink with your project's shared helpers documentation
Where it goes
Use as the system prompt for your model call, or as the base instructions in your agent framework.
Worth borrowing
- Separating permission decisions into explicit approve, block, and ask states
- Mapping exit codes to distinct behaviors for Claude and user visibility
Related Documents
Character Persona
Defines a Fallout 2 roleplay persona for an LLM agent: charming rogue with social-first combat and moral code.
How to implement tool use
Explains how to define, configure, and control tool use with the Anthropic API, including model selection, tool definitions, output control, and parallel calls.
Gemini by Example
Collects 20+ Gemini API code examples covering text, images, audio, video, PDFs, agents, and token counting.
Claude Tool Use (Function Calling) Documentation
Teaches how to define and use Claude tool use (function calling) with Python, including schema rules, execution patterns, and best practices.