HMRHarden My Repo

Claude Code hooks · practical guide

Use hooks for behavior that must happen every time.

A useful hook is small, deterministic, and easy to trigger on purpose. Start with one repository-specific risk or repeated verification step—not a second orchestration system.

Claude Code hooks execute automatically during the agent lifecycle. Review every command as executable repository configuration, pin down its inputs, and test both the allow and block path before sharing it with a team.

Pick the event from the guarantee you need

NeedHook eventGood first use
Inspect a tool call before it runsPreToolUseBlock a protected path or a dangerous repository command.
React after a successful edit or tool callPostToolUseFormat only the file just changed.
Verify work before Claude stopsStopRun a bounded fast-test command with a loop guard.
Orient a fresh or resumed sessionSessionStartReport branch and dirty-tree state.
Alert when attention is neededNotificationSend a local desktop notification without interpolating model text into code.

Anthropic’s current hooks guide documents additional events and handler types. Re-check the live reference before relying on a recently added field.

Install three tested starter hooks

The open-source Harden My Repo hooks plugin includes a narrow dangerous-command gate, a protected-path gate, and format-on-edit. Review the scripts first, then run these commands inside Claude Code:

/plugin marketplace add hardenmyrepo/claude-code-hooks
/plugin install harden-my-repo-hooks@harden-my-repo

The repository passes Claude Code’s marketplace validator and behavioral tests. The hooks make no network requests and install no dependencies. Use /hooks after installation to inspect what is enabled.

Minimal project hook wiring

Shared project hooks belong in .claude/settings.json. This example invokes one checked-in command hook before Bash calls:

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/check-command.sh",
            "args": [],
            "timeout": 10
          }
        ]
      }
    ]
  }
}

The command receives event data as JSON on standard input. Parse it as data. Do not paste tool input, filenames, or model text into an eval, shell command string, AppleScript source, SQL statement, or template that can execute it.

Three hooks worth considering first

1. Protected-path gate

Match Edit|Write on PreToolUse. Parse the target path, normalize it relative to the repository, and reject exact high-risk patterns such as local environment files, private keys, generated migrations, or deployment state. Keep the list repository-specific and provide the matched reason.

2. Fast verification before stop

Run one documented, bounded command—such as a changed-only test selection—when the tree is dirty. Add a loop guard so a persistent failure does not bounce forever. A full integration suite that takes twenty minutes is a poor interactive hook.

3. Formatter after an edit

Use the repository’s installed formatter on only the path reported by the hook. Skip unsupported extensions and missing tools. Never install dependencies from inside the hook.

Give every hook a trigger test

Common failure modes

For the current event schema, matcher rules, output behavior, and troubleshooting steps, use Anthropic’s official hooks reference.

Check before adding automation

Audit the repository’s current agent setup first.

The free browser audit checks for instructions, project policy, hooks, CI, tests, ownership, documentation, dependency locking, and secret-hygiene signals without uploading repository contents.

Get 3 hooks on GitHubAudit a repo freeDownload Lite