Back to .md Directory

PreToolUse API

Documents the PreToolUse hook API for Claude Code, listing input helpers, state methods, output helpers, and exit code behaviors.

May 2, 2026
0 downloads
0 views
ai claude
View source

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

RubyClaude CodeClaudeHooks

PreToolUse API

Available when inheriting from ClaudeHooks::PreToolUse:

Input Helpers

Input helpers to access the data provided by Claude Code through STDIN.

๐Ÿ“š Shared input helpers

MethodDescription
tool_nameGet the name of the tool being used
tool_inputGet the input data for the tool
tool_use_idGet 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

MethodDescription
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.

๐Ÿ“š Shared output helpers

MethodDescription
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_decisionGet the permission decision: 'allow', 'deny', or 'ask'
output.permission_reasonGet the reason for the permission decision
output.updated_inputGet the updated input (if provided)

Hook Exit Codes

Exit CodeBehavior
exit 0Operation continues<br/>STDOUT shown to user in transcript mode
exit 1Non-blocking error<br/>STDERR shown to user
exit 2Blocks 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 CodeSTDERRSTDOUT
0RUNSRUNS
1RUNSRUNS
2BLOCKSRUNS

Output visibility depending on exit code

Output Visibility / Exit Code012
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 CodeSTDERRSTDOUT
0RUNSASKS
1RUNSASKS
2BLOCKSASKS

Output visibility depending on exit code

Output Visibility / Exit Code012
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 CodeSTDERRSTDOUT
0BLOCKSBLOCKS
1BLOCKSBLOCKS
2BLOCKSBLOCKS

Output visibility depending on exit code

Output Visibility / Exit Code012
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::PreToolUse with your own hook base class if different
  • Replace COMMON.md link 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