---
title: "Claude Code hooks explained: PreToolUse, PostToolUse and team workflows · Cork"
description: "How Claude Code hooks work: settings locations, PreToolUse allow and deny, PostToolUse checks, SessionStart context, exit codes, and hook patterns for teams."
canonical: "https://corkcli.com/blog/claude-code-hooks-pretooluse-posttooluse-team-workflows"
last_updated: "2026-10-03"
published: "2026-10-03"
author: "Kevin Vera"
---

# Claude Code hooks explained: PreToolUse, PostToolUse and team workflows

How Claude Code hooks work: settings locations, PreToolUse allow and deny, PostToolUse checks, SessionStart context, exit codes, and hook patterns for teams.

By Kevin Vera · October 3, 2026 · [Guides](https://corkcli.com/blog/c/guides) · 6 min read

Claude Code hooks are commands (or HTTP calls, MCP tool calls or model prompts) that Claude Code runs automatically at fixed points in a session. `PreToolUse` runs before a tool call and can allow it, deny it, ask the user, or rewrite its input. `PostToolUse` runs after a tool call succeeds and can feed context back to Claude or stop the loop. Hooks live in the `hooks` block of a settings file, and the project file `.claude/settings.json` can be committed, which makes hooks the way a team enforces the same rules on every developer's agent.

## Why hooks instead of instructions

Instructions in `CLAUDE.md` are context: Claude usually follows them, but nothing guarantees it. Anthropic's memory docs say so directly: "To block an action regardless of what Claude decides, use a PreToolUse hook instead." Hooks are deterministic. If a hook says a command is denied, it is denied, whatever the model thinks.

## Where hooks are configured

| Location | Scope | Shared with the team |
|---|---|---|
| `~/.claude/settings.json` | All your projects | No |
| `.claude/settings.json` | One project | Yes, commit it |
| `.claude/settings.local.json` | One project | No, gitignored |
| Managed policy settings | Organization | Admin-controlled |
| Plugin `hooks/hooks.json` | When the plugin is enabled | Yes |

Run `/hooks` inside Claude Code to browse configured hooks by event. Set `"disableAllHooks": true` to turn hooks off (managed hooks keep running unless that is set in managed settings too).

## The events you will use most

As of October 2026 the hooks reference lists more than thirty events. The core ones:

- `SessionStart`: when a session starts, resumes, clears or compacts. Output becomes context.
- `UserPromptSubmit`: when a prompt is submitted, before Claude processes it. Can add context or block the prompt.
- `PreToolUse`: before a tool call. Can allow, deny, ask, defer or rewrite input.
- `PostToolUse`: after a tool call succeeds. Can add context, replace the tool output, or block.
- `Stop`: when Claude finishes responding. Can make it keep working.
- `SubagentStart`, `SubagentStop`, `PreCompact`, `PostCompact`, `SessionEnd`, `Notification` and file events such as `FileChanged`.

## PreToolUse: gate actions before they happen

A hook entry has an event, a `matcher` (exact tool name, a `|` list like `Edit|Write`, or a regex like `mcp__memory__.*`), and handlers:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh"
          }
        ]
      }
    ]
  }
}
```

The script receives JSON on stdin with `session_id`, `cwd`, `hook_event_name`, `tool_name`, `tool_input` and more. To deny, exit 0 and print:

```json
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Destructive command blocked by hook"
  }
}
```

`permissionDecision` can be `allow`, `deny`, `ask` (escalate to the user) or `defer`. `updatedInput` rewrites the tool's arguments; Anthropic's cost guide uses this to make test commands print only failures. `additionalContext` adds a note next to the tool result.

Exit codes matter: **0** means success and stdout JSON is parsed; **2** blocks the tool call and stderr is shown to Claude as the reason; any other code is a non-blocking error and the tool proceeds. A `PreToolUse` hook that times out does not block.

## PostToolUse: check work after it happens

`PostToolUse` cannot undo a tool call, but it can react to it. The official example formats every edited file:

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
          }
        ]
      }
    ]
  }
}
```

To tell Claude something, return `additionalContext` in `hookSpecificOutput` (for example "3 tests failed"); it is injected next to the tool result. Return `{"decision": "block", "reason": "..."}` to stop the agentic loop before the next model call. Exit code 2 does not block here, since the tool already ran, but stderr is shown to Claude.

## SessionStart and UserPromptSubmit: inject context

Plain text on stdout from these hooks is added to Claude's context, or you can return `additionalContext`. A `SessionStart` hook with matcher `compact` re-injects key context after compaction; one that prints `git log --oneline -5` tells Claude about recent commits.

## Team workflows with hooks

Commit `.claude/settings.json` and a `.claude/hooks/` folder so every developer's agent runs the same checks. Patterns that work:

- **Protected paths**: a `PreToolUse` hook on `Edit|Write` denies edits to migrations, generated code or another team's directory.
- **Shared quality gate**: a `PostToolUse` hook on `Edit|Write` runs the linter or type checker on the changed file and returns failures as `additionalContext`.
- **Safe shell**: a `PreToolUse` hook on `Bash` denies `rm -rf`, force pushes or production commands, or returns `ask`.
- **Shared context**: a `SessionStart` hook prints the module ownership map and recent commits.
- **Cross-tool parity**: Codex supports the same core events (`SessionStart`, `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, `Stop`) in `.codex/hooks.json`, and Cursor has `preToolUse`, `postToolUse`, `afterFileEdit` and more in `.cursor/hooks.json`, so one script can back all three.

Command hooks are shell commands that run on each developer's machine, so review hook scripts in pull requests like any other code.

## How Cork helps

Hooks are a good place for team rules, but each developer's hooks only know about their own machine. They cannot tell your agent that a teammate's agent is editing the same function right now. Cork is the [coordination layer](https://corkcli.com/blog/coordination-layer-ai-coding-agents) for multiplayer coding agents: it keeps Claude Code, Codex and Cursor agents, on one machine or across a team's machines, from overwriting each other on one codebase, and hands each agent what the others already learned.

Cork is itself built on hooks in Claude Code, Codex and Cursor, with no extra model calls:

- **Briefing** at session start and on each prompt: exact signatures, callers and recent changes of the code the agent is about to touch.
- **[Write gate](https://corkcli.com/blog/write-gate)** before edits: an edit against code another agent is changing right now is held until your agent has their version.
- **Live awareness** after each step: when another agent changes code yours depends on, your agent hears it on its next step.
- **[Semantic lint](https://corkcli.com/blog/semantic-lint)**: a teammate's rename or signature change becomes a rule your agents are checked against.

Install it once for every repo on the machine:

```bash
curl -fsSL https://corkcli.com/install.sh | sh
```

## Frequently asked questions

### What is the difference between PreToolUse and PostToolUse in Claude Code?

`PreToolUse` runs before a tool call and can allow, deny, ask or rewrite it. `PostToolUse` runs after it succeeds and can add context, replace the output or stop the loop, but cannot undo the call.

### How do I block a command with a Claude Code hook?

In a `PreToolUse` hook, exit 2 with the reason on stderr, or exit 0 and print JSON with `permissionDecision: "deny"` and a `permissionDecisionReason`.

### Where do I put Claude Code hooks so my whole team gets them?

In `.claude/settings.json` in the project, committed to the repo. Personal hooks go in `~/.claude/settings.json` or `.claude/settings.local.json`.

### Can a hook add context to Claude's conversation?

Yes. `SessionStart` and `UserPromptSubmit` stdout is added to context, and `PreToolUse`, `PostToolUse`, `SessionStart` and `UserPromptSubmit` accept `additionalContext` in `hookSpecificOutput`.

## Sources

- <https://code.claude.com/docs/en/hooks>
- <https://code.claude.com/docs/en/hooks-guide>
- <https://code.claude.com/docs/en/memory>
- <https://code.claude.com/docs/en/costs>
- <https://learn.chatgpt.com/docs/hooks.md>
- <https://cursor.com/docs/hooks>

## Related reading

- [Setting up Claude Code multi-agent work on Windows (Git Bash and PowerShell)](https://corkcli.com/blog/claude-code-multi-agent-windows-setup): Run several Claude Code agents on Windows: install, Git Bash vs PowerShell, worktrees, hooks in either shell, agent teams, messaging and WSL, per the docs.
- [How to stop Claude Code agents from overwriting each other's changes](https://corkcli.com/blog/stop-claude-code-agents-overwriting-changes): Why parallel Claude Code agents overwrite each other's edits, and how to stop it with worktrees, file ownership, deny rules, PreToolUse hooks and a write gate.
- [How to share context between Claude Code sessions](https://corkcli.com/blog/share-context-between-claude-code-sessions): Six ways to carry context between Claude Code sessions: CLAUDE.md, auto memory, handoff files, resume and fork, cross-session messaging, SessionStart hooks.
- [How to give AI coding agents context about recent changes](https://corkcli.com/blog/give-ai-coding-agents-context-recent-changes): Give Claude Code, Codex and Cursor context about recent changes: good commit messages, SessionStart and prompt hooks that inject git history, and live updates.

[All articles](https://corkcli.com/blog.md) · [Cork in Markdown](https://corkcli.com/index.md) · [llms.txt](https://corkcli.com/llms.txt)

This page in HTML: https://corkcli.com/blog/claude-code-hooks-pretooluse-posttooluse-team-workflows
