hook-creator

This skill provides comprehensive guidance for creating and managing Claude Code hooks—powerful automation tools that intercept and respond to Claude Code events.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "hook-creator" with this command: npx skills add vitadynamics/vita-cc-market/vitadynamics-vita-cc-market-hook-creator

Hook Creator

This skill provides comprehensive guidance for creating and managing Claude Code hooks—powerful automation tools that intercept and respond to Claude Code events.

Quick Start

Create a simple PreToolUse hook that validates Bash commands:

~/.claude/settings.json or .claude/settings.json

{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": ""$CLAUDE_PROJECT_DIR"/.claude/hooks/validate-command.sh", "timeout": 30 } ] } ] } }

#!/bin/bash

.claude/hooks/validate-command.sh

input=$(cat) command=$(echo "$input" | jq -r '.tool_input.command // empty')

Block destructive commands

if [[ "$command" =~ ^rm\ -rf ]]; then echo "Destructive command blocked" >&2 exit 2 fi

exit 0

What Are Hooks?

Hooks are event-driven automation points that intercept Claude Code execution at specific moments. They receive JSON input via stdin and communicate back through exit codes and stdout.

Hook Capabilities

  • Validate or block tool calls before execution (PreToolUse)

  • Auto-approve permission requests (PermissionRequest)

  • Run post-processing after tool execution (PostToolUse)

  • Add context to conversations (UserPromptSubmit, SessionStart)

  • Control session lifecycle (Stop, SubagentStop)

  • Handle notifications from Claude Code (Notification)

  • Integrate with MCP tools using pattern matching

Hook Types

Command hooks (type: "command" ): Execute bash scripts

  • Fast, deterministic, ideal for validation rules

  • Have access to environment variables

  • Return status via exit codes and JSON output

Prompt hooks (type: "prompt" ): Use LLM for intelligent decisions

  • Context-aware evaluation

  • Best for complex, nuanced decisions

  • Only supported for Stop and SubagentStop events

Hook Events

PreToolUse

Runs after tool parameters are created but before execution.

Common matchers: Bash , Write , Edit , Read , Task , Glob , Grep

Use cases:

  • Validate or modify tool inputs before execution

  • Auto-approve specific tool calls

  • Block dangerous operations

Decision control:

  • allow : Bypass permission system

  • deny : Prevent tool execution

  • ask : Show user confirmation dialog

PermissionRequest

Runs when user is shown a permission dialog.

Use cases:

  • Auto-approve known-safe operations

  • Deny specific permission requests

  • Modify tool inputs before approval

PostToolUse

Runs immediately after successful tool completion.

Use cases:

  • Trigger notifications or logging

  • Validate tool outputs

  • Add feedback for Claude to consider

UserPromptSubmit

Runs when user submits a prompt, before Claude processes it.

Use cases:

  • Add contextual information to conversations

  • Validate prompts for security issues

  • Block inappropriate prompts

Stop / SubagentStop

Runs when Claude or a subagent finishes responding.

Use cases:

  • Prevent premature stopping

  • Ensure task completion

  • Continue work automatically

SessionStart

Runs when Claude starts or resumes a session.

Matchers: startup , resume , clear , compact

Use cases:

  • Load development context (recent issues, changes)

  • Install dependencies or configure environment

  • Persist environment variables via $CLAUDE_ENV_FILE

SessionEnd

Runs when a Claude Code session ends.

Use cases:

  • Cleanup tasks or logging

  • Save session state or statistics

Notification

Runs when Claude Code sends notifications.

Matchers: permission_prompt , idle_prompt , auth_success , elicitation_dialog

Use cases:

  • Custom notification handling

  • Forward notifications to external systems

Configuration Structure

Basic Structure

{ "hooks": { "EventName": [ { "matcher": "ToolPattern|*", "hooks": [ { "type": "command|prompt", "command": "bash-command", "prompt": "llm-prompt", "timeout": 60 } ] } ] } }

Configuration Locations

Hooks are configured in settings files (priority order):

  • ~/.claude/settings.json

  • User settings

  • .claude/settings.json

  • Project settings

  • .claude/settings.local.json

  • Local project (not committed)

  • Plugin hooks - Auto-merged when plugins enabled

Matcher Patterns

  • Exact match: Write matches only Write tool

  • Multiple tools: Edit|Write matches Edit or Write

  • Wildcards: .* or * matches all tools

  • Empty/omitted: Matches all tools (for events without matchers)

Environment Variables

Available in all hook commands:

  • $CLAUDE_PROJECT_DIR : Project root directory

  • $CLAUDE_PLUGIN_ROOT : Plugin directory (plugin hooks only)

  • $CLAUDE_CODE_REMOTE : "true" in remote web environment (unset locally)

  • $CLAUDE_ENV_FILE : Persist environment vars (SessionStart only)

Hook Input/Output

Input Format

Hooks receive JSON via stdin:

{ "session_id": "abc123", "transcript_path": "/path/to/session.jsonl", "cwd": "/current/working/directory", "permission_mode": "default", "hook_event_name": "PreToolUse", "tool_name": "Bash", "tool_input": { "command": "echo 'hello'" }, "tool_use_id": "toolu_01ABC123..." }

Output: Exit Codes

  • 0: Success (stdout shown in verbose mode, except UserPromptSubmit/SessionStart where stdout is added as context)

  • 2: Blocking error (stderr fed back to Claude, blocks action for applicable events)

  • Other: Non-blocking error (stderr shown in verbose mode)

Output: JSON Control

Return structured JSON in stdout for advanced control:

{ "continue": true, "stopReason": "Message shown when stopping", "suppressOutput": true, "systemMessage": "Warning to user" }

PreToolUse JSON Output

{ "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "allow|deny|ask", "permissionDecisionReason": "Explanation", "updatedInput": { "field_to_modify": "new value" } } }

PostToolUse JSON Output

{ "decision": "block", "reason": "Explanation", "hookSpecificOutput": { "hookEventName": "PostToolUse", "additionalContext": "Extra information for Claude" } }

Stop/SubagentStop JSON Output

{ "decision": "block", "reason": "Why Claude should continue (required when blocking)" }

Common Patterns

Pattern 1: Command Validation

Validate bash commands before execution:

{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": ""$CLAUDE_PROJECT_DIR"/.claude/hooks/validate-bash.sh", "timeout": 30 } ] } ] } }

#!/bin/bash

.claude/hooks/validate-bash.sh

input=$(cat) command=$(echo "$input" | jq -r '.tool_input.command // empty')

Enforce better tools

if echo "$command" | grep -qE '\bgrep\b(?!.*|)'; then echo "Use 'rg' (ripgrep) instead of 'grep'" >&2 exit 2 fi

if echo "$command" | grep -qE '\bfind\s+\S+\s+-name\b'; then echo "Use 'rg --files' instead of 'find -name'" >&2 exit 2 fi

exit 0

Pattern 2: Auto-Approve Safe Operations

Auto-approve documentation file reads:

{ "hooks": { "PermissionRequest": [ { "matcher": "Read", "hooks": [ { "type": "command", "command": ""$CLAUDE_PROJECT_DIR"/.claude/hooks/auto-approve-docs.sh" } ] } ] } }

#!/usr/bin/env python3

.claude/hooks/auto-approve-docs.sh

import json import sys

input_data = json.load(sys.stdin) file_path = input_data.get("tool_input", {}).get("file_path", "")

Auto-approve documentation files

if file_path.endswith((".md", ".mdx", ".txt", ".json")): output = { "hookSpecificOutput": { "hookEventName": "PermissionRequest", "decision": { "behavior": "allow" } }, "suppressOutput": True } print(json.dumps(output)) sys.exit(0)

sys.exit(0)

Pattern 3: Add Session Context

Load recent changes on session start:

{ "hooks": { "SessionStart": [ { "matcher": "startup|resume", "hooks": [ { "type": "command", "command": ""$CLAUDE_PROJECT_DIR"/.claude/hooks/load-context.sh" } ] } ] } }

#!/bin/bash

.claude/hooks/load-context.sh

cd "$CLAUDE_PROJECT_DIR" || exit 0

Get recent commits (last 5)

recent_changes=$(git log -5 --oneline --pretty=format:"- %s" 2>/dev/null)

Get current branch

current_branch=$(git branch --show-current 2>/dev/null)

if [ -n "$recent_changes" ] || [ -n "$current_branch" ]; then echo "# Repository Context" echo "" echo "Current branch: $current_branch" echo "" echo "Recent changes:" echo "$recent_changes" fi

exit 0

Pattern 4: Prompt-Based Stop Hook

Use LLM to intelligently decide if Claude should stop:

{ "hooks": { "Stop": [ { "hooks": [ { "type": "prompt", "prompt": "Analyze the conversation context: $ARGUMENTS\n\nDetermine if:\n1. All requested tasks are complete\n2. All tests pass\n3. No errors remain unaddressed\n\nRespond with JSON: {"decision": "approve"|"block", "reason": "explanation"}", "timeout": 30 } ] } ] } }

Pattern 5: MCP Tool Integration

Target specific MCP tools:

{ "hooks": { "PreToolUse": [ { "matcher": "mcp__memory__.", "hooks": [ { "type": "command", "command": "echo 'Memory operation' >> ~/hooks.log" } ] }, { "matcher": "mcp__.__write.*", "hooks": [ { "type": "command", "command": "/path/to/validate-mcp-write.sh" } ] } ] } }

Security Considerations

Disclaimer

USE AT YOUR OWN RISK: Hooks execute arbitrary shell commands automatically. You are solely responsible for hook commands. Malicious or poorly written hooks can cause data loss or system damage.

Best Practices

  • Validate inputs: Never trust input data blindly

  • Quote variables: Use "$VAR" not $VAR

  • Block path traversal: Check for .. in file paths

  • Use absolute paths: Specify full paths via $CLAUDE_PROJECT_DIR

  • Skip sensitive files: Avoid .env , .git/ , keys

  • Test thoroughly: Test hooks in safe environment first

Configuration Safety

Direct edits to hooks don't take effect immediately. Claude Code:

  • Captures hook snapshot at startup

  • Uses snapshot throughout session

  • Warns if hooks modified externally

  • Requires review in /hooks menu for changes

Debugging

Basic Troubleshooting

  • Check configuration: Run /hooks to verify hook registration

  • Verify syntax: Ensure JSON settings are valid

  • Test commands: Run hook commands manually first

  • Check permissions: Ensure scripts are executable (chmod +x )

  • Review logs: Use claude --debug for execution details

Common Issues

  • Quotes not escaped: Use " inside JSON strings

  • Wrong matcher: Tool names are case-sensitive

  • Command not found: Use absolute paths for scripts

  • Exit code confusion: Exit code 2 blocks, others warn

Debug Output

Run claude --debug to see detailed hook execution:

[DEBUG] Executing hooks for PostToolUse:Write [DEBUG] Found 1 hook matchers in settings [DEBUG] Matched 1 hooks for query "Write" [DEBUG] Executing hook command: <command> with timeout 60000ms [DEBUG] Hook command completed with status 0

Plugin Hooks

Plugins can provide hooks that integrate with user/project hooks:

{ "description": "Automatic code formatting", "hooks": { "PostToolUse": [ { "matcher": "Write|Edit", "hooks": [ { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh", "timeout": 30 } ] } ] } }

Place in plugins/your-plugin/hooks/hooks.json or specify custom path in plugin metadata.

Execution Details

  • Timeout: 60 seconds default (configurable per command)

  • Parallelization: All matching hooks run in parallel

  • Deduplication: Identical hook commands auto-deduplicated

  • Environment: Current directory with Claude Code's environment

  • Input: JSON via stdin

  • Output: Varies by event (see above)

Guidelines

  • Keep hooks simple: Prefer bash scripts for straightforward logic

  • Use prompt hooks sparingly: Only for nuanced, context-aware decisions

  • Set appropriate timeouts: Adjust based on expected execution time

  • Handle errors explicitly: Scripts should validate inputs and handle errors

  • Test thoroughly: Verify hooks work as expected before production use

  • Document purpose: Add comments explaining hook behavior

  • Use environment variables: Leverage $CLAUDE_PROJECT_DIR for portability

Examples

See examples.md for complete working examples of common hook patterns.

Reference

For complete API details, see:

  • official-hooks-docs.md - Full Claude Code hooks documentation

  • hook-input-schemas.md - Detailed input/output schemas

  • security-guide.md - Security best practices

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

heal-skill

No summary provided by upstream source.

Repository SourceNeeds Review
General

medium-plan

No summary provided by upstream source.

Repository SourceNeeds Review
General

create-command

No summary provided by upstream source.

Repository SourceNeeds Review
General

review

No summary provided by upstream source.

Repository SourceNeeds Review