Require Dual Control on a Payment-Initiation MCP Tool
The classic banking "four-eyes" control, enforced at the hook layer instead of relying on the payment system's own approval workflow: a payment/wire-initiation MCP tool is blocked unless a `PAYMENT_REVIEWER` environment variable — set by a second, distinct person's session, not the one making the call — is present.
1. Save this as the hook script
#!/usr/bin/env python3
"""PreToolUse hook — blocks a payment/wire-initiation MCP tool call
unless a second reviewer flag is set. Wire to matcher
"mcp__.*payment.*|mcp__.*wire.*"."""
import json, os, sys
data = json.load(sys.stdin)
reviewer = os.environ.get("PAYMENT_REVIEWER", "")
initiator = os.environ.get("USER", "")
if not reviewer or reviewer == initiator:
print("BLOCKED: payment-initiation tools require PAYMENT_REVIEWER to be "
"set by a second, distinct person — not the session initiator.", file=sys.stderr)
sys.exit(2)
sys.exit(0)
Save to a path inside your project, e.g. .claude/hooks/require-dual-control-payment-initiation.sh, then chmod +x it.
2. Wire it into .claude/settings.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "mcp__.*payment.*|mcp__.*wire.*",
"hooks": [
{"type": "command", "command": "python3 .claude/hooks/require-dual-control-payment-initiation.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