The hook system — shipped scripts that Claude Code runs on session and tool lifecycle events

Quickstart

Read the payload, decide, exit — failing open on anything malformed:

import json
import sys

try:
    payload = json.load(sys.stdin)       # {"tool_name": ..., "tool_input": ...}
except (json.JSONDecodeError, ValueError):
    sys.exit(0)                          # fail open on malformed input

if isinstance(payload, dict) and payload.get("tool_name") == "Bash":
    print("Bash blocked by policy", file=sys.stderr)
    sys.exit(2)                          # 2 = block
sys.exit(0)                             # 0 = allow