Claude Code hooks are user-defined shell scripts or commands that execute at specific lifecycle points during a 📝Claude Code session, enabling enforcement of security policies, quality gates, workflow automation, and custom integrations. Hooks are configured in ~/.claude/settings.json (user-level) or .claude/settings.json (project-level) using a hooks object that maps event names to executable commands.
The hook system supports several event types: PreToolUse and PostToolUse fire before and after tool execution respectively, receiving structured JSON describing the tool call; PreMessage and PostMessage wrap message-level operations; prompt hooks allow evaluation by a separate Claude model; and HTTP hooks enable remote webhook triggers. Hooks receive input via stdin as structured JSON and must exit with code 0 to allow continuation or a non-zero code to block and cancel the action. PreToolUse hooks are particularly powerful for security enforcement — Brian has implemented a Playwright localhost containment guard that inspects tool calls, blocks external network access attempts that route through userinfo endpoints, and prevents evaluate calls from bypassing the localhost boundary.
Hook scripts can be written in any language; Python is common for more complex logic, while shell scripts suit simpler checks. The async flag enables hooks that perform non-blocking I/O. Brian's current setup includes a ~/.claude/hooks/playwright-localhost-guard.py script tested against five scenarios: localhost allowed, external blocked, userinfo trick blocked, evaluate blocked entirely, and screenshot allowed. The hook is registered in settings.json under the hooks key with a PreToolUse entry pointing to the script path.
Hooks are where Claude Code stops being a tool and starts becoming an operating layer. The moment you can intercept a tool call before it runs, inspect its intent, and decide whether to allow it — that's not automation, that's governance. I've been building toward a system that extends me rather than requires me to babysit it, and hooks are the first real boundary enforcement layer inside the agentic workflow. The Playwright localhost guard is a concrete example: it's the difference between "I trust this agent" and "this agent can only operate within the constraints I've defined." That's sovereignty infrastructure.
