playbook/outfitter-agents/plugins/outfitter/skills/claude-hooks/references/matchers.md

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 extension
  • path/*.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:

  1. Case sensitivity: Write works, write doesn't
  2. Exact tool names: Use claude --debug to see actual tool names
  3. File patterns: Ensure the pattern matches the file path format
  4. 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"}