Skip to content
Mastering Claude

Home / Extending: skills, MCP, subagents, hooks, plugins

Extending: skills, MCP, subagents, hooks, plugins7 minApplication

Hooks: automating the lifecycle

A hook is an action the harness executes itself on a precise lifecycle event, never a preference entrusted to the model in the hope that it remembers.

A hook is an action the harness executes itself when a precise lifecycle event occurs, never a request the model interprets at the moment of acting. Writing to a memory file every time you commit, running the tests, remains a preference: the model may forget it after a long conversation or a compaction. A hook declared on the corresponding event runs on every occurrence, independently of what the model recalls at that moment.

The mechanism: an event, a command, a decision

A hook is declared in settings.json, or in a plugin's hooks.json file, tied to a lifecycle event and an action type: a shell command, an HTTP call, an MCP tool, a prompt, or an agent. When the event occurs, the harness runs that action and waits for a decision in return, before the question reaches the model.

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": "./verifier-avant-commande.sh" }
        ]
      }
    ]
  }
}

This declaration ties the PreToolUse event, restricted to calls of the Bash tool, to a script that runs before every proposed command. Each hook type carries its own default timeout, different depending on the event that triggers it: the next lesson details these timeouts event by event, along with the precise JSON fields a hook returns to block, allow, or enrich what the model sees.

Hook versus memory rule: what each actually guarantees

A memory rule depends on a model that rereads it and decides to apply it, within a context window that grows over the course of a session. A hook depends on the harness, which checks the event independently of what the conversation holds at that moment. The difference shows up most on a long session: an instruction repeated twenty times in a memory file can dilute within a loaded context, whereas a hook declared once continues to run identically on the thousandth call as on the first.

Translating an intended automatism into a hook rather than a memory note is therefore less a matter of style than a matter of mechanical reliability: one depends on a careful reading by the model, the other on an event the harness itself observes.

Figure 1

From trigger to decision

01
Lifecycle event
A command about to run, a session starting, a file changing: the harness detects the event, not the model.
02
Hook consulted
settings.json or a plugin's hooks.json states which action to launch for this precise event.
03
Action executed
A shell command, an HTTP call, an MCP tool, a prompt, or an agent runs, depending on the declared type.
04
Decision returned
The hook returns its response to the harness, which applies it before the conversation resumes its course.
The sequence shows where the harness steps in and where the model no longer has a say, between the event and the decision, no step relies on what the model recalls.
Figure 2

Memory rule versus declared hook

Making a repeated automatism reliableWhat triggers the actionBehaviour on a long sessionWhere the automatism is declared
Rule written in memoryA reading by the model, which must remember it at the right momentCan dilute after a compaction or a loaded contextA CLAUDE.md file, interpreted by the model
Declared hookA lifecycle event, observed by the harness itselfRuns identically on every occurrence of the eventsettings.json or a plugin's hooks.json, executed by the harness
The table isolates three criteria to distinguish a rule written in memory, which depends on a reading by the model, from a hook, which depends on an event observed by the harness.
Calibrate it yourself

A developer declares a PreToolUse hook in settings.json that blocks any call to the Bash tool containing the pattern rm followed by -rf. He then asks Claude Code to run a command containing this pattern, and sees the hook trigger.

Write in one sentence what this situation establishes, and in one sentence what it does not establish.

What to remember
  • A hook fires because a lifecycle event occurs, never because the model decides to apply it at the moment of acting.
  • A rule repeated in a memory file can dilute within a loaded context, a hook declared once runs identically on every occurrence of the event.
  • A hook is declared in settings.json or in a plugin's hooks.json file, tied to an action type among shell command, HTTP call, MCP tool, prompt, or agent.
  • Each hook type carries its own default timeout, detailed event by event in the next lesson.
Do this now

Create a minimal .claude/settings.json file in a test repository, declare a PreToolUse hook there that prints a message before every Bash command so you can watch the mechanism trigger, then remove that hook once the demonstration is done.

Check the source

Every datable claim in this lesson links here to the public text behind it. A source that does not open proves nothing.