7.1 KiB
7.1 KiB
Matcher Patterns Reference
Matchers determine which tool invocations or events trigger a hook. They are case-sensitive strings that support exact matching, regex patterns, wildcards, and file patterns.
Matcher Types
Simple String Match
Match exact tool name:
{"matcher": "Write"} // Only Write tool
{"matcher": "Edit"} // Only Edit tool
{"matcher": "Bash"} // Only Bash tool
{"matcher": "Read"} // Only Read tool
{"matcher": "Grep"} // Only Grep tool
{"matcher": "Glob"} // Only Glob tool
{"matcher": "Task"} // Only Task tool (subagents)
{"matcher": "WebFetch"} // Only WebFetch tool
{"matcher": "WebSearch"}// Only WebSearch tool
OR Patterns (Pipe)
Match multiple tools with |:
{"matcher": "Edit|Write"} // Edit OR Write
{"matcher": "Read|Grep|Glob"} // Any read/search operation
{"matcher": "Write|Edit|NotebookEdit"} // Multiple specific tools
{"matcher": "WebFetch|WebSearch"} // Web operations
Wildcard Match
Match all tools with *:
{"matcher": "*"} // Matches everything
Use cases:
- Logging all tool usage
- Global validation
- Universal context injection
- Metrics collection
File Pattern Match
Match tools operating on specific file types with (pattern):
{"matcher": "Write(*.py)"} // Write Python files
{"matcher": "Edit(*.ts)"} // Edit TypeScript files
{"matcher": "Write(*.md)"} // Write Markdown files
{"matcher": "Write|Edit(*.js)"} // Write or Edit JavaScript
{"matcher": "Write|Edit(*.ts|*.tsx)"} // TypeScript and TSX files
Supported patterns:
*.ext- Any file with extensionpath/*.ext- Files in specific directory (relative to project)**/*.ext- Recursive file match
More examples:
{"matcher": "Write(*.tsx)"} // React components
{"matcher": "Write|Edit(*.rs)"} // Rust files
{"matcher": "Write(src/**/*.ts)"} // TS files in src/
{"matcher": "Edit(.env*)"} // .env files
{"matcher": "Write(*.json)"} // JSON files
{"matcher": "Write|Edit(*.yaml|*.yml)"} // YAML files
Regex Patterns
Full regex support for complex matching:
{"matcher": "^Write$"} // Exactly "Write", no prefix/suffix
{"matcher": ".*Edit.*"} // Contains "Edit" anywhere
{"matcher": "Notebook.*"} // Starts with "Notebook"
{"matcher": "Bash|WebFetch"} // Bash or WebFetch
Regex features:
|- OR operator.- Any character*- Zero or more+- One or more^- Start of string$- End of string[abc]- Character class\w- Word character\d- Digit
MCP Tool Matchers
MCP (Model Context Protocol) tools follow naming: mcp__<server-name>__<tool-name>
Match All MCP Tools
{"matcher": "mcp__.*__.*"} // Any MCP tool from any server
Match Specific Server
{"matcher": "mcp__memory__.*"} // All memory MCP tools
{"matcher": "mcp__github__.*"} // All GitHub MCP tools
{"matcher": "mcp__filesystem__.*"} // All filesystem MCP tools
{"matcher": "mcp__brave-search__.*"}// All Brave search tools
Match Specific Tools
{"matcher": "mcp__github__create_issue"} // Specific GitHub tool
{"matcher": "mcp__github__create_pull_request"} // Create PR tool
{"matcher": "mcp__memory__add_memory"} // Add to memory
{"matcher": "mcp__memory__search_memory"} // Search memory
Complex MCP Patterns
// All delete operations across MCP servers
{"matcher": "mcp__.*__delete.*"}
// Create operations in GitHub
{"matcher": "mcp__github__(create_issue|create_comment|create_pull_request)"}
// All read operations in filesystem
{"matcher": "mcp__filesystem__(read|list|search).*"}
// Dangerous operations to block
{"matcher": "mcp__.*(delete|remove|destroy).*"}
Lifecycle Event Matchers
Some hooks use special matchers for lifecycle events instead of tool names.
SessionStart Matchers
{"matcher": "startup"} // Fresh Claude Code start
{"matcher": "resume"} // Session resume (--resume, --continue)
{"matcher": "clear"} // After /clear command
{"matcher": "compact"} // After context compaction
{"matcher": "*"} // Any session start type
SessionEnd Matchers
{"matcher": "clear"} // User ran /clear
{"matcher": "logout"} // User logged out
{"matcher": "prompt_input_exit"} // Exited during prompt
{"matcher": "other"} // Other reasons
{"matcher": "*"} // Any end reason
PreCompact Matchers
{"matcher": "manual"} // User triggered /compact
{"matcher": "auto"} // Automatic compaction
{"matcher": "*"} // Any compact type
Stop/SubagentStop Matchers
{"matcher": "*"} // Always matches (lifecycle events)
Complex Matcher Examples
Multiple Tools with File Patterns
// Format Python or TypeScript
{"matcher": "Write|Edit(*.py)|Write|Edit(*.ts)"}
// All code files
{"matcher": "Write|Edit(*.ts|*.tsx|*.js|*.jsx|*.py|*.rs)"}
Excluding Patterns
There's no direct exclusion, but you can handle this in the hook script:
#!/usr/bin/env bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
# Skip test files
if [[ "$FILE_PATH" =~ \.(test|spec)\. ]]; then
exit 0
fi
# Skip node_modules
if [[ "$FILE_PATH" =~ node_modules/ ]]; then
exit 0
fi
# Continue with validation...
Combining with Regex
// Bash or any MCP tool
{"matcher": "Bash|mcp__.*__.*"}
// Read operations (multiple tools)
{"matcher": "Read|Grep|Glob|WebFetch"}
// File modifications only
{"matcher": "Write|Edit|NotebookEdit"}
Matcher Debugging
If your hook isn't firing, check:
- Case sensitivity:
Writeworks,writedoesn't - Exact tool names: Use
claude --debugto see actual tool names - File patterns: Ensure the pattern matches the file path format
- MCP naming: Verify server and tool names match exactly
Testing Matchers
# See what tools Claude is calling
claude --debug 2>&1 | grep "tool_name"
# Test regex patterns
echo "Write" | grep -E '^Write$' # Should match
echo "WriteFile" | grep -E '^Write$' # Should not match
Common Matcher Patterns
Security Validation
// All file operations
{"matcher": "Write|Edit|Read"}
// Dangerous commands
{"matcher": "Bash"}
// Network operations
{"matcher": "WebFetch|WebSearch|mcp__.*"}
Auto-Formatting
// TypeScript/JavaScript
{"matcher": "Write|Edit(*.ts|*.tsx|*.js|*.jsx)"}
// Python
{"matcher": "Write|Edit(*.py)"}
// Rust
{"matcher": "Write|Edit(*.rs)"}
// All supported
{"matcher": "Write|Edit(*.ts|*.tsx|*.py|*.rs|*.go)"}
Logging
// All tool operations
{"matcher": "*"}
// All MCP operations
{"matcher": "mcp__.*__.*"}
// File operations only
{"matcher": "Write|Edit|Read|Grep|Glob"}
External Integration
// GitHub operations
{"matcher": "mcp__github__.*"}
// Memory operations
{"matcher": "mcp__memory__.*"}
// All external services
{"matcher": "mcp__.*__.*|WebFetch|WebSearch"}