Scan MCP Tool Arguments for Embedded Secrets

The commit-time and file-read hooks only cover the local repo. Once an MCP server is in play, the actual exfiltration risk is a secret pattern getting copied into a tool argument and sent to a third-party server over the wire. This checks every `mcp__*` tool call's arguments before they're sent.

Secrets & Credentials Event: PreToolUse Claude Code Open source · Free

1. Save this as the hook script

#!/usr/bin/env python3
"""PreToolUse hook — blocks an MCP tool call whose arguments contain a
secret-shaped string. Wire this to a matcher like "mcp__.*"."""
import json, re, sys

data = json.load(sys.stdin)
tool_name = data.get("tool_name", "")
args = json.dumps((data.get("tool_input") or {}))

if not tool_name.startswith("mcp__"):
    sys.exit(0)

PATTERNS = [
    r"AKIA[0-9A-Z]{16}", r"sk-(ant|proj|live)-[A-Za-z0-9_-]{20,}",
    r"ghp_[A-Za-z0-9]{36}", r"-----BEGIN (RSA|OPENSSH|EC) PRIVATE KEY-----",
]

for p in PATTERNS:
    if re.search(p, args):
        print(f"BLOCKED: argument to {tool_name} matches secret pattern `{p}` — "
              f"refusing to send it to an external MCP server.", file=sys.stderr)
        sys.exit(2)

sys.exit(0)

Save to a path inside your project, e.g. .claude/hooks/scan-mcp-args-for-secrets.sh, then chmod +x it.

2. Wire it into .claude/settings.json

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "mcp__.*",
        "hooks": [
          {"type": "command", "command": "python3 .claude/hooks/scan-mcp-args-for-secrets.py"}
        ]
      }
    ]
  }
}

Before you use this

A hook runs with your local shell's permissions — review the script above before adding it, the same way you'd review any script you didn't write yourself. See our guide on hook security risks for the specific CVEs this category of feature has already produced.

Related hooks

← All hooks
FEEDBACK