Skip to content
Module 3Lesson 11 of 15·4:49

Defining and Configuring Hooks

Deep dive into creating Claude Code hooks. Learn the four-step process: choosing hook type, setting tool matchers, processing JSON input, and controlling flow with exit codes.

Building a hook in Claude Code follows a clear four-step process. Once you understand the data flow — how Claude sends tool call information to your script and how your script communicates back — you can create hooks for virtually any automation scenario.

The Four Steps to Building a Hook

1

Choose PreToolUse or PostToolUse

PreToolUse hooks can prevent tool calls from executing. PostToolUse hooks run after the tool has already been used — they cannot block, but they can react.

2

Set the tool matcher

Specify exactly which tools should trigger your hook. Use pipe (|) syntax for multiple tools: "Read|Grep" catches both read and search operations.

3

Write the command script

Your script receives JSON data about the tool call via standard input. Parse it to understand what Claude is trying to do.

4

Return the right exit code

Exit code 0 means "allow the operation." Exit code 2 means "block it" (PreToolUse only). Any message written to stderr is sent back to Claude as feedback.

Understanding the Tool Call Data

When your hook command runs, Claude sends a JSON payload through standard input containing everything you need to make a decision:

Standard Input (JSON)
1{
2 "session_id": "2d6a1e4d-6...",
3 "transcript_path": "/Users/dev/.claude/transcripts/...",
4 "hook_event_name": "PreToolUse",
5 "tool_name": "Read",
6 "tool_input": {
7 "file_path": "/code/project/.env"
8 }
9}

The tool_input field varies depending on which tool Claude is calling. For a Read tool, it contains the file path. For a Bash tool, it contains the command. Your script parses this JSON and decides how to respond.

Exit Codes: Controlling the Flow

Your hook communicates back to Claude through two channels: the process exit code and standard error output.

  • Exit code 0 — the operation is allowed to proceed normally
  • Exit code 2 — the operation is blocked (PreToolUse only). Any message written to stderr is sent to Claude explaining why

Feedback matters

When blocking an operation with exit code 2, always write a clear message to stderr. Claude reads this feedback and adjusts its behavior accordingly — for example, choosing a different approach or informing you why the operation was restricted.

Available Tools You Can Monitor

Claude Code provides several built-in tools that you can target with hook matchers:

  • Read — reading file contents
  • Write — creating new files
  • Edit / MultiEdit — modifying existing files
  • Bash — executing shell commands
  • Grep — searching file contents
  • Glob — finding files by pattern
  • Any MCP server tools (prefixed with mcp__servername__)

The available tools can change when you add MCP servers. You can always ask Claude Code directly to list its current tools for an up-to-date reference.

Key Takeaways

  • 01Building a hook involves four steps: choose type, set matcher, write command, handle exit codes.
  • 02Hook commands receive JSON data via stdin with session info, tool name, and tool input.
  • 03Exit code 0 allows the operation; exit code 2 blocks it (PreToolUse only).
  • 04Write clear stderr messages when blocking — Claude uses this feedback to adjust its approach.
  • 05You can monitor any built-in tool or MCP server tool with the matcher pattern.