Skip to content

Hooks with MCP Tools

Claude Code hooks work seamlessly with Model Context Protocol (MCP) tools. When MCP servers provide tools, they appear with a special naming pattern.

MCP Tool Naming

MCP tools follow the pattern mcp__{server}__{tool}:

  • mcp__memory__create_entities — Memory server's create entities tool
  • mcp__filesystem__read_file — Filesystem server's read file tool
  • mcp__github__search_repositories — GitHub server's search tool
  • mcp__playwright__screenshot — Playwright server's screenshot tool

Targeting MCP Tools in Hooks

You can target specific MCP tools or entire MCP servers:

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "mcp__memory__.*",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Memory operation initiated' >> ~/mcp-operations.log"
          }
        ]
      },
      {
        "matcher": "mcp__.*__write.*",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/validate-mcp-write.py"
          }
        ]
      }
    ]
  }
}

Log All MCP Calls

Track which MCP tools are being used:

python
#!/usr/bin/env python3
import json
import sys
from datetime import datetime

try:
    data = json.load(sys.stdin)
except:
    sys.exit(0)

tool_name = data.get("tool_name", "")

# Only log MCP tools
if not tool_name.startswith("mcp__"):
    sys.exit(0)

timestamp = datetime.utcnow().isoformat()
log_line = f"{timestamp} MCP: {tool_name}\n"

try:
    with open("/tmp/mcp-usage.log", "a") as f:
        f.write(log_line)
except:
    pass

sys.exit(0)

Validate Playwright Operations

The adw_review.py phase uses Playwright MCP for screenshots. Add validation:

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

Block Specific MCP Servers

If you want to prevent Claude from using a particular MCP server:

python
#!/usr/bin/env python3
import json
import sys

try:
    data = json.load(sys.stdin)
except:
    sys.exit(0)

tool_name = data.get("tool_name", "")

# Block filesystem MCP server except for reads
if tool_name.startswith("mcp__filesystem__") and "read" not in tool_name:
    output = {
        "hookSpecificOutput": {
            "hookEventName": "PreToolUse",
            "permissionDecision": "deny",
            "permissionDecisionReason": "Filesystem MCP server is restricted to read operations in this project."
        }
    }
    print(json.dumps(output))
    sys.exit(0)

sys.exit(0)

Debugging MCP Hook Issues

If your MCP tool hooks aren't firing:

  1. Check the tool name pattern: claude --debug shows exact tool names
  2. MCP tool names are case-sensitive and include double underscores
  3. Use "matcher": "mcp__.*" to catch all MCP tools and log them first
  4. Verify the MCP server is registered in your settings.json or ~/.claude/settings.json

Agentics SOP — AI Developer Workflow & Agentic Coding Reference