Large Language Models like Claude possess significant reasoning ability, but on their own they are unpredictable, stateless, and disconnected from the real world. Claude Hooks are custom scripts the harness runs automatically at specific points in a session's lifecycle — giving developers a controlled way to observe, validate, or modify behavior. To understand hooks, you first need to understand the harness that runs them.
Understanding the harness: a prerequisite for Claude Hooks
What is a harness?
A harness is a set of straps or equipment used to control and direct the power of something strong. It enables powerful entities to operate in a controlled, predictable, and useful manner.
Core idea: raw power becomes useful only when controlled through a structured interface.
The analogy
Large Language Models (LLMs), such as Claude, possess significant reasoning capabilities. However, without a harness, they cannot effectively interact with the real world.
Without a harness, an LLM is:
- Unpredictable
- Stateless
- Non-deterministic
- Disconnected from the real world
- Unable to act safely on its own
What does a coding harness provide?
A coding harness extends the capabilities of an LLM by providing controlled access to development tools and system resources. It enables the model to:
- Read files from the filesystem
- Display terminal output
- Manage conversation history
- Track context window usage
- Send API requests to Anthropic
- Parse tool calls generated by the model
- Request user permission before executing commands
- Execute approved commands
- Manage memory efficiently
- Support slash commands
- Spawn sub-agents for specialized tasks
- Extend functionality through MCP servers, plugins, and other integrations
Understanding the Agent Loop
The Agent Loop is the continuous execution cycle that allows Claude to reason, use tools, observe results, and decide on the next action until the task is complete. Instead of producing a single response, Claude repeatedly performs a sequence of steps, enabling it to solve complex, multi-step tasks.
For example, given the request "Add the expense deletion route", the loop might run like this:
- Cycle 1: Model says "Read app.py" → harness reads the file → sends contents back to model.
- Cycle 2: Model says "Read database/schema.sql" → harness reads the file → sends contents back.
- Cycle 3: Model says "Write the delete route to app.py" → harness writes the code to disk → confirms success.
- Cycle 4: Model says "Run python -m pytest tests/" → harness runs pytest → sends test output back.
- Cycle 5: Model sees all tests pass → responds with final text: "I've added the expense deletion route with proper parameterized SQL and a confirmation step. All tests pass."
Why is the Agent Loop important?
The Agent Loop enables Claude to:
- Break complex tasks into smaller steps.
- Use external tools when required.
- Learn from each tool's output before deciding the next action.
- Continue until the requested task is completed.
- Produce more accurate and context-aware responses.
Relationship with the harness
The Agent Loop relies on the coding harness to execute every tool call. While Claude decides what action to perform, the harness is responsible for how that action is executed safely and efficiently.
Understanding the session lifecycle
A session represents the complete interaction between the user and Claude, starting from the initial request and ending when the task is completed or the session is terminated. Throughout the session, Claude maintains context, reasons about the task, executes tools through the harness, and generates responses.
What happens during a session?
During an active session, Claude can:
- Maintain conversation context.
- Track the available context window.
- Access tools through the coding harness.
- Execute multiple iterations of the Agent Loop.
- Store temporary working memory for the current conversation.
- Generate the final response after completing all required actions.
Why is the session lifecycle important?
Understanding the session lifecycle helps explain when different events occur. Claude Hooks are triggered at specific stages of this lifecycle — such as Pre tool use, Post tool use, and Stop — allowing developers to observe, validate, or modify behavior before or after particular actions.
Understanding Claude Hooks
What are Claude Hooks?
Hooks are custom scripts written by the programmer that the harness automatically executes at specific events during a session's lifecycle.
Why use Claude Hooks?
Hooks provide a controlled mechanism for customizing Claude's behavior. They allow applications to:
- Validate requests before execution.
- Enforce security and compliance policies.
- Log user interactions and tool usage.
- Monitor execution for debugging and observability.
- Integrate with external systems and services.
- Modify or enrich execution based on business requirements.
Key characteristics
Claude Hooks are:
- Event-driven
- Automatically invoked
- Extensible
- Non-invasive to Claude's core logic
- Suitable for automation, security, auditing, and workflow customization
Common use cases
Claude Hooks can automate workflows, enforce security policies, and integrate with external systems. Some common use cases include:
- Automatic code formatting & linting — automatically format source code and run linters after files are modified.
- Blocking dangerous shell commands — prevent the execution of unsafe or restricted commands before they reach the terminal.
- Protecting sensitive files — restrict access to critical files or directories by validating file operations before execution.
- Sending notifications — notify developers or external systems when specific events occur, such as task completion or command execution.
- Collecting telemetry — capture execution metrics, tool usage, and performance data for monitoring and analytics.
- Generating session summaries — automatically generate summaries of completed sessions for documentation, auditing, or knowledge sharing.
How Claude Hooks work
Claude Hooks are executed whenever a configured lifecycle event occurs. During the Agent Loop, the harness detects supported events, invokes the corresponding hook, processes its response, and then decides whether to continue or interrupt execution. The following steps illustrate the complete hook execution flow.
Step 1: Configure the hook
Before a hook can be executed, it must be registered in the settings.json file. In the configuration, you specify:
- The hook event (for example,
PreToolUseorPostToolUse) - A matcher that determines when the hook should execute
- The command or script that should run
// .claude/settings.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/block-dangerous.py"
}
]
}
]
}
}Once configured, the harness automatically monitors for matching events during execution.
Step 2: Hook is triggered during execution
When Claude enters the Agent Loop and decides to execute a tool:
- Claude selects the appropriate tool.
- The harness checks whether a hook is registered for the current event.
- If a matching hook exists, the harness executes the configured script.
- The hook receives the event information as input (JSON).
- The script performs its custom logic, such as validation, logging, or security checks.
At this stage, the actual tool execution is temporarily paused until the hook completes.
For example, imagine you ask Claude to "clean up the Spendly project" and it decides to run rm spendly.db. The harness sees a PreToolUse hook with a matcher for "Bash", pipes the tool input to your script as JSON, and your script reads the command, detects rm targeting the database file, prints "Cannot delete the database file" to stderr, and exits with code 2. The harness reads exit code 2, blocks the command, sends the error back to the model, and the Agent Loop continues — your database is safe.
Step 3: Process the hook result
After the hook finishes execution:
- The harness evaluates the hook's exit code and output.
- If the hook succeeds, the original tool execution continues.
- If the hook blocks the request or returns an error, the harness prevents the tool from running.
- Claude receives the hook's response and decides how to proceed with the remaining task.
This process repeats for every configured hook event until the Agent Loop completes. A PostToolUse hook, for instance, can automatically format any Python file right after it is written or edited:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "python3 -c \"import sys, json, subprocess; data = json.load(sys.stdin); file = data.get('tool_input', {}).get('file_path', ''); file.endswith('.py') and subprocess.run(['python3', '-m', 'black', '--quiet', file])\""
}
]
}
]
}
}Execution summary
The overall hook execution flow can be summarized as follows:
- Configure a hook in
settings.json. - Claude begins processing the user's request.
- The Agent Loop reaches a supported hook event.
- The harness checks for a matching hook.
- The configured hook script is executed.
- The hook returns a result.
- The harness evaluates the result.
- The tool is either executed or blocked.
- Claude continues the Agent Loop until the task is complete.
Conclusion
Claude Hooks turn the harness from a fixed runtime into a programmable one. Because they are event-driven, automatically invoked, and non-invasive to Claude's core logic, hooks let teams enforce security policies, standardize code, collect telemetry, and integrate with external systems — all without changing how Claude reasons. Understand the harness, the Agent Loop, and the session lifecycle, and hooks become the natural place to encode your team's rules for how Claude is allowed to act.
Frequently asked questions
What are Claude Hooks?
Claude Hooks are custom scripts, written by the developer, that the coding harness automatically executes at specific events during a session's lifecycle. They let you observe, validate, or modify Claude Code's behavior without changing how Claude reasons.
What is a coding harness in Claude Code?
A coding harness is the layer that gives an LLM controlled access to development tools and system resources — reading files, running commands, managing context and conversation history, requesting permissions, and extending functionality through MCP servers and plugins. Claude decides what to do; the harness decides how it runs safely.
What is the Agent Loop?
The Agent Loop is the continuous cycle in which Claude reasons, uses a tool, observes the result, and decides the next action — repeating until the task is complete. It is what lets Claude break complex tasks into steps and act on each tool's output.
What is the difference between PreToolUse and PostToolUse hooks?
A PreToolUse hook runs before a tool executes and can block or modify it — for example, refusing a dangerous shell command. A PostToolUse hook runs after a tool completes — for example, automatically formatting a Python file right after it is written or edited.
How do you configure a Claude hook?
Register the hook in the settings.json file by specifying the hook event (such as PreToolUse or PostToolUse), a matcher that determines when it should run, and the command or script to execute. The harness then monitors for matching events automatically.
What can you use Claude Hooks for?
Common use cases include automatic code formatting and linting, blocking dangerous shell commands, protecting sensitive files, sending notifications, collecting telemetry, and generating session summaries — enforcing security, automation, and auditing policies.
