hooks
Claude Code Hooks
Overview
Create and configure Claude Code hooks to automate workflows, validate inputs, add context, and customize behavior across different events in the Claude Code lifecycle.
When to Use This Skill
Use this skill when users request:
- Creating hooks for any event (PreToolUse, PostToolUse, UserPromptSubmit, Stop, SubagentStop, SessionStart, SessionEnd, PreCompact, Notification, PermissionRequest)
- Setting up automation for tool usage validation or formatting
- Adding session context at startup
- Validating or blocking prompts
- Controlling when Claude should continue or stop
- Auto-approving or denying permissions
- Setting up notifications
Pre-requisite: Fetch Latest Documentation
MANDATORY FIRST STEP: Before creating any hook, fetch the latest hooks documentation:
WebFetch: https://code.claude.com/docs/en/hooks
Prompt: "Extract the complete hooks reference documentation including all hook events, input/output formats, configuration structure, and examples."
This ensures access to the most current hook events, JSON schemas, and best practices.
Hook Creation Workflow
1. Understand User Requirements
Ask clarifying questions:
- What event should trigger the hook? (PreToolUse, PostToolUse, UserPromptSubmit, etc.)
- What tools should be matched? (Bash, Write, Edit, specific MCP tools, etc.)
- What action should the hook perform? (Validate, format, add context, block, etc.)
- Where should the hook be configured? (User settings
~/.claude/settings.jsonor project settings.claude/settings.json)
2. Determine Hook Type
Command-based hooks (type: "command"):
- Fast, deterministic validation
- File operations, linting, formatting
- Simple rule-based decisions
- Examples: Bash command validation, code formatting, git checks
Prompt-based hooks (type: "prompt"):
- Context-aware, intelligent decisions using LLM
- Complex evaluation requiring natural language understanding
- Supported for: Stop, SubagentStop, UserPromptSubmit, PreToolUse
- Examples: Task completion checking, security policy evaluation
3. Create Hook Script or Prompt
For command-based hooks, create a script that:
- Reads JSON input from stdin
- Validates/processes the input
- Returns appropriate exit code:
0= Success (stdout shown to user, or added to context for UserPromptSubmit/SessionStart)2= Blocking error (stderr fed back to Claude)- Other = Non-blocking error (stderr shown to user)
- Optionally returns JSON for advanced control
For prompt-based hooks, craft a prompt that:
- Uses
$ARGUMENTSplaceholder for hook input - Clearly states evaluation criteria
- Expects JSON response:
{"decision": "approve"|"block", "reason": "..."}
4. Configure in Settings
Add hook configuration to appropriate settings file:
- User-wide:
~/.claude/settings.json - Project-specific:
.claude/settings.json - Local (not committed):
.claude/settings.local.json
5. Test and Iterate
- Verify hook registration with
/hookscommand - Test with relevant tool calls or prompts
- Use
claude --debugto see execution details - Refine based on results
Common Hook Patterns
PreToolUse: Bash Command Validation
Use case: Enforce best practices for bash commands (use rg instead of grep, fd instead of find)
Script: Reference scripts/bash_command_validator.py and customize validation rules.
Configuration:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/bash_validator.py"
}
]
}
]
}
}
PostToolUse: Code Formatting
Use case: Automatically format code after file edits
Script: Reference scripts/code_formatter.py and customize for project formatters.
Configuration:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/format.py",
"timeout": 60
}
]
}
]
}
}
SessionStart: Load Development Context
Use case: Add git status, recent commits, and environment setup at session start
Script: Reference scripts/session_context_loader.sh and customize for project needs.
Configuration:
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/load_context.sh"
}
]
}
]
}
}
UserPromptSubmit: Validate and Add Context
Use case: Block prompts with secrets, add current timestamp
Script: Reference scripts/prompt_validator.py and customize validation patterns.
Configuration:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/validate_prompt.py"
}
]
}
]
}
}
Stop: Intelligent Continuation (Prompt-based)
Use case: Use LLM to decide if Claude should continue working
Configuration:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Evaluate if Claude should stop: $ARGUMENTS\n\nCheck if:\n1. All user tasks are complete\n2. Any errors need addressing\n3. Follow-up work is needed\n\nReturn JSON: {\"decision\": \"approve\" or \"block\", \"reason\": \"explanation\"}",
"timeout": 30
}
]
}
]
}
}
PermissionRequest: Auto-Approve Safe Operations
Use case: Automatically approve read operations for documentation files
Script example:
#!/usr/bin/env python3
import json
import sys
input_data = json.load(sys.stdin)
tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})
file_path = tool_input.get("file_path", "")
if tool_name == "Read" and file_path.endswith((".md", ".txt", ".json")):
output = {
"hookSpecificOutput": {
"hookEventName": "PermissionRequest",
"decision": {
"behavior": "allow"
}
}
}
print(json.dumps(output))
sys.exit(0)
# Let normal permission flow proceed
sys.exit(0)
Hook Input/Output Reference
Common Input Fields (All Hooks)
{
"session_id": "string",
"transcript_path": "string",
"cwd": "string",
"permission_mode": "string",
"hook_event_name": "string"
}
Event-Specific Fields
Consult the fetched documentation for complete schemas for each event type (PreToolUse, PostToolUse, UserPromptSubmit, etc.).
JSON Output Schema
Common fields:
{
"continue": true,
"stopReason": "string",
"suppressOutput": true,
"systemMessage": "string"
}
Event-specific hookSpecificOutput: See fetched documentation for each event type.
Working with MCP Tools
MCP tools follow the pattern mcp__<server>__<tool>:
mcp__memory__create_entitiesmcp__filesystem__read_filemcp__github__search_repositories
Example matcher: "matcher": "mcp__memory__.*" to match all memory server tools.
Security Best Practices
- Validate inputs: Never trust hook input data blindly
- Quote variables: Use
"$VAR"not$VARin shell scripts - Block path traversal: Check for
..in file paths - Use absolute paths: Reference scripts with
$CLAUDE_PROJECT_DIR - Skip sensitive files: Avoid processing
.env,.git/, keys, credentials - Set timeouts: Prevent hooks from hanging indefinitely
- Test in safe environment: Verify hooks before production use
Environment Variables
$CLAUDE_PROJECT_DIR- Project root directory (all hooks)$CLAUDE_ENV_FILE- File for persisting env vars (SessionStart only)$CLAUDE_CODE_REMOTE- "true" in web environment, empty in CLI
Debugging Hooks
- Check registration: Run
/hookscommand - Verify syntax: Ensure JSON is valid
- Test commands manually: Run hook scripts directly with sample input
- Check permissions: Ensure scripts are executable (
chmod +x) - Review logs: Use
claude --debugfor detailed execution info - Validate JSON schemas: Test input/output with sample data
Resources
scripts/
Example hook scripts to customize:
bash_command_validator.py- Validate and suggest better bash commandscode_formatter.py- Format code after file editssession_context_loader.sh- Load git context and environment at session startprompt_validator.py- Validate prompts and add timestamp context
assets/
Template configurations to adapt:
pretooluse_template.json- PreToolUse hook examplesposttooluse_template.json- PostToolUse hook examplessessionstart_template.json- SessionStart hook examplesstop_hook_template.json- Prompt-based Stop hook exampleuserpromptsubmit_template.json- UserPromptSubmit hook example
Implementation Steps
When implementing a hook for a user:
- Fetch latest docs from https://code.claude.com/docs/en/hooks
- Clarify requirements - event type, matcher, action
- Choose hook type - command-based or prompt-based
- Create script or prompt using examples as templates
- Make executable if command-based:
chmod +x script.py - Add configuration to appropriate settings.json
- Test with
/hooksandclaude --debug - Document the hook's purpose and usage for the user
More from benjaming/ai-skills
confluence-cli
Use confluence-cli (NPM package) to manage Confluence content, pages, and spaces from the command line. Ideal for documentation workflows, bulk content operations, page migration, and when users request CLI-based Confluence interactions. Trigger on requests like "use Confluence CLI", "create Confluence pages via CLI", "migrate Confluence content", "automate documentation workflows", or when users want to script Confluence operations.
43atlassian-cli-jira
Use Atlassian CLI (acli) to manage Jira work items, projects, and workflows from the command line. Ideal for bulk operations, automation, scripting, and when users request CLI-based Jira interactions. Trigger on requests like "use Jira CLI", "create Jira issues via CLI", "bulk update Jira tickets", "automate Jira workflows", or when users want to script Jira operations.
29ralph-loop
Create autonomous iterative loops (Ralph Wiggum pattern) for multi-step tasks. Use when setting up automated workflows that iterate over a backlog of tasks with clear acceptance criteria. Triggers on requests like "create a ralph loop", "set up an iterative agent", "automate this migration", or "create an autonomous loop".
21interview
Interview user to clarify any topic - exploring codebase, investigating issues, planning features, understanding requirements, or drilling into plans. Socratic questioning to uncover details.
20codex-cli
Use OpenAI Codex CLI in non-interactive mode for automated code analysis, review, and programmatic task execution. Trigger on requests like "use Codex to analyze", "run codex exec", "codex code review", or when users want AI-powered code analysis without interactive prompts. Ideal for automation workflows, code quality checks, and generating structured analysis reports.
19daily-standup
Daily standup assistant for Benjamin that compiles work priorities from Jira and Slack into a single prioritized task list. This skill should be used when Benjamin asks for morning standup, daily priorities, what to work on today, or needs to compile work items.
18