"Ich möchte nach jeder Bearbeitung automatisch formatieren." "Niemand soll jemals .env oder package-lock.json überschreiben." "Gefährliche rm -rf-Befehle stoppen." Der Weg, diese "das muss immer passieren"-Regeln real werden zu lassen – ohne von den Launen der KI abhängig zu sein – sind Claude Code Hooks. Ein Hook ist ein Shell-Befehl, der an bestimmten Punkten im Lebenszyklus von Claude Code automatisch ausgeführt wird, und Hooks sind außerdem ein Baustein von Plugins.

Dieser Artikel legt auf Basis der offiziellen Dokumentation dar, was Hooks sind, die Event-Liste, wie man sie konfiguriert, den Ein-/Ausgabe-Kontrakt, Anwendungsfälle und die Sicherheit. Drei Punkte vorweg. ① Ein Hook ist "deterministische Logik, die der Harness (Claude Code selbst) ausführt" – er feuert garantiert, ohne darauf zu warten, dass das Modell sich dafür "entscheidet". ② Hooks schreibt man in settings.json als Event-Name → matcher → command. ③ Events wie PreToolUse können per Exit-Code 2 oder JSON "blockieren" – und so Bearbeitungen geschützter Dateien oder gefährliche Befehle stoppen.

CLAUDE CODE · HOOKS

Feuert "garantiert" an wichtigen Lebenszyklus-Punkten

— der Harness führt ihn deterministisch aus, nicht das Ermessen des Modells

SessionStart Session beginnt. Die Ausgabe wird als Kontext eingespeist
UserPromptSubmit Wenn ein Prompt abgeschickt wird [kann blockieren]
PreToolUse Direkt bevor ein Tool läuft = der Türsteher [kann blockieren]
PostToolUse Nachdem ein Tool erfolgreich war = Auto-Format / Audit
Stop Wenn eine Antwort endet = weitermachen, bis die Tests bestehen usw. [kann blockieren]

An jedem Punkt läuft dein Shell-Befehl. Die Klassiker: PreToolUse, um gefährliche Aktionen schon an der Tür abzuweisen, PostToolUse, um automatisch zu formatieren.

1. Was sind Claude Code Hooks?

Die offizielle Definition lautet: "Hooks sind benutzerdefinierte Shell-Befehle, die an bestimmten Punkten im Lebenszyklus von Claude Code ausgeführt werden. Sie bieten deterministische Kontrolle über das Verhalten von Claude Code und stellen sicher, dass bestimmte Aktionen immer geschehen, anstatt sich darauf zu verlassen, dass das LLM sich für ihre Ausführung entscheidet." Man setzt sie ein, um Projektregeln durchzusetzen, sich wiederholende Aufgaben zu automatisieren und Claude Code in vorhandene Tools zu integrieren.

Der Kern ist Determinismus. Bitte Claude, "die Tests auszuführen", und ob es das tut, hängt von seinem "Ermessen" ab. Aber mit einem Hook führt der Harness ihn immer aus – keine Laune kommt ins Spiel. Neben Befehlen (command) gibt es inzwischen auch Handler-Typen wie HTTP, MCP-Tools, LLM-Prompts und Subagent-Verifikation – aber zum Einstieg reicht es, sich Hooks als "einen Mechanismus, um an wichtigen Punkten immer einen Shell-Befehl auszuführen" vorzustellen.

2. Die Hook-Events

Ein Event steht dafür, "wo im Lebenszyklus es feuert". Beginne mit den neun Klassikern ("kann blockieren" = du kannst diese Aktion per Exit-Code 2 oder JSON stoppen).

EventFeuert, wennBlockieren
SessionStartEine Session beginnt oder wird fortgesetzt (stdout wird als Kontext eingespeist)Nein
UserPromptSubmitDu schickst einen Prompt ab, bevor Claude ihn verarbeitetJa
PreToolUseDirekt vor einem Tool-Aufruf (der wichtigste Türsteher)Ja
PostToolUseNachdem ein Tool erfolgreich war (die Aktion selbst lässt sich nicht rückgängig machen)Ja
NotificationBei einer Benachrichtigung (Warten auf Eingabe/Berechtigung usw.)Nein
StopWenn Claude mit dem Antworten fertig ist (blockieren = weiterarbeiten)Ja
SubagentStopWenn ein Subagent fertig istJa
SessionEndWenn eine Session beendet wirdNein
PreCompactVor der Kontext-KompaktierungJa

Die Doku von 2026 ergänzt viele weitere Events – PermissionRequest, PostToolUseFailure, ConfigChange, FileChanged, WorktreeCreate und andere. Aber Event-Namen können zwischen Versionen hinzukommen oder sich ändern, deshalb stützt sich dieser Artikel auf die stabilen neun Klassiker plus den Kontrakt im nächsten Abschnitt (die vollständige aktuelle Liste findest du in der offiziellen Doku).

3. Hooks konfigurieren

Hooks schreibt man unter dem Schlüssel "hooks" in settings.json. Der Ort legt den Geltungsbereich fest: Benutzer (~/.claude/settings.json) / Projekt (.claude/settings.json, per Git teilbar) / lokal (.claude/settings.local.json) / verwaltete Richtlinie (Organisation) / die hooks/hooks.json eines Plugins. Die JSON-Form sieht so aus.

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

Die Struktur ist "hooks → Event-Name → ein Array aus { matcher, hooks:[...] } → jeder Hook hat type + command." Der matcher gibt den Ziel-Tool-Namen an: "*" (oder weggelassen) passt auf alle, "Edit|Write" ist eine durch | getrennte Liste, und andere Zeichen sind regulärer Ausdruck (z. B. mcp__memory__.*). Groß-/Kleinschreibung ist relevant. Der Befehl /hooks listet die konfigurierten Hooks auf, ist aber schreibgeschützt – zum Hinzufügen oder Ändern bearbeitet man settings.json direkt. Alle deaktivieren mit "disableAllHooks": true.

4. Der Ein-/Ausgabe-Kontrakt

Ein Hook empfängt JSON über die Standardeingabe (stdin) und gibt sein Ergebnis über den Exit-Code oder JSON auf der Standardausgabe zurück.

Eingabe (stdin): Zu den gemeinsamen Feldern gehören session_id, transcript_path, cwd und hook_event_name. Tool-Events ergänzen tool_name und tool_input (z. B. {"command":"rm -rf /tmp/build"}); UserPromptSubmit ergänzt prompt. Exit-Codes: 0 = Erfolg (bei manchen Events wird stdout zum Kontext hinzugefügt – wobei Exit 0 bei PreToolUse keine "Freigabe" ist; der normale Berechtigungsfluss gilt weiterhin), 2 = blockieren (stderr wird Claude als Material zum Nachjustieren übergeben, und JSON-Ausgabe wird ignoriert).

# Beispiel: "deny" von PreToolUse über strukturierte JSON-Ausgabe (auf stdout ausgegeben)
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Database writes are not allowed"
  }
}
# Gemeinsame Felder: continue (false = vollständig stoppen) / decision:"block"+reason /
#                additionalContext (für Claude angehängt) / updatedInput (Argumente umschreiben)

Das wichtigste Prinzip: "Hooks können Beschränkungen verschärfen, aber nicht lockern." Die Rückgabe von allow überspringt nur die Abfrage; deny-Regeln in jedem Geltungsbereich (einschließlich verwalteter Einstellungen) haben immer Vorrang. Ein PreToolUse-deny blockiert sogar unter bypassPermissions / --dangerously-skip-permissions. Zum umfassenderen Berechtigungsmodell siehe Berechtigungsmodi und Sicherheit.

5. Beispiel-Anwendungsfälle

Die offiziellen Klassiker, jeweils mit ihrer Konfiguration.

USE CASES

Die klassischen Automatisierungen

Auto-Format nach Bearbeitungen
PostToolUse + Edit|Write führt automatisch prettier / einen Linter aus.
Kritische Dateien schützen
PreToolUse blockiert (Exit 2) Bearbeitungen an .env, .git/ usw.
Gefährliche Befehle stoppen
PreToolUse erkennt rm -rf usw. und gibt deny zurück.
Kontext erneut einspeisen
SessionStart-stdout lädt Konventionen und Notizen jedes Mal neu (auch nach Kompaktierung).
Benachrichtigungen & Audit-Log
Notification für Desktop-Hinweise; PostToolUse, um den Befehlsverlauf zu protokollieren.
Testen vor dem Stoppen
Stop lässt Claude nicht stoppen, bis die Tests bestehen (weiterarbeiten, bis grün).

Hinweis: Claude kann Dateien auch über Bash ändern. Um jede Änderung zu erfassen, füge einen Stop-Hook hinzu, der den Arbeitsbaum einmal pro Runde durchsucht.

6. Sicherheit

Hooks sind mächtig, aber sie führen automatisch beliebige Shell-Befehle mit deinen Rechten aus – nimm das nicht auf die leichte Schulter.

⚠️ Die offizielle Warnung

"Hooks führen automatisch beliebige Shell-Befehle aus. Du allein bist für die Sicherheit der Hooks verantwortlich, die du konfigurierst. NUTZUNG AUF EIGENE GEFAHR." Hooks können Dateien lesen, deine Codebasis verändern, Daten exfiltrieren oder jeden beliebigen Befehl ausführen – konfiguriere nur solche, denen du vollständig vertraust.

Startup-Snapshot (ein zentrales Sicherheitsmerkmal): Die Hook-Konfiguration wird beim Session-Start erfasst, sodass Konfigurationsänderungen mitten in der Session nicht wirksam werden. Das verhindert, dass ein bösartiger Prompt oder eine Tool-Ausgabe deine Hook-Konfiguration umschreibt während einer Session. Wende Änderungen in einer neuen Session an.

In der Praxis: validiere und quote Eingaben immer (mit jq extrahieren; ungequotete Variablen können zu zusätzlichen Argumenten oder Shell-Syntax werden), nutze absolute Pfade und ${CLAUDE_PROJECT_DIR}, fass sensible Dateien wie .env oder .ssh nicht an und führe niemals eval auf Tool-Ausgaben aus. Hooks laufen ohne kontrollierendes Terminal (kein /dev/tty). In Organisationen können Admins Hooks mit allowManagedHooksOnly einschränken.

Zusammenfassung

Claude Code Hooks sind benutzerdefinierte Shell-Befehle, die an wichtigen Lebenszyklus-Punkten automatisch laufen und machen "das muss immer passieren" real und deterministisch, ohne vom Ermessen des Modells abhängig zu sein. Die klassischen Events sind die neun: SessionStart / UserPromptSubmit / PreToolUse / PostToolUse / Notification / Stop / SubagentStop / SessionEnd / PreCompact (PreToolUse und andere können blockieren – und so Bearbeitungen geschützter Dateien oder gefährliche Befehle stoppen). Konfiguriert werden sie in settings.json unter "hooks" als Event → matcher → type + command.

Die E/A ist JSON auf stdin, Exit-Code 0 (Erfolg) / 2 (blockieren) oder strukturiertes JSON auf stdout. Das Prinzip: "du kannst verschärfen, aber nicht lockern" (deny gewinnt immer). Die klassischen Anwendungsfälle: Auto-Format, Dateien schützen, gefährliche Befehle stoppen, Kontext erneut einspeisen, Audit, Testen vor dem Stoppen. Aber weil sie beliebigen Code ausführen, sei streng damit, nur sicheren Hooks zu vertrauen und Eingaben zu validieren/quoten, und verstehe, dass die Konfiguration beim Start erfasst wird. Verwandt: Plugins, MCP, Claude Code Fehler.

FAQ

F. Wofür sind Hooks da?
A. Sie automatisieren deterministisch "das muss immer passieren". Dinge wie "nach Bearbeitungen formatieren", "geschützte Dateien dürfen nie überschrieben werden", "gefährliche rm -rf stoppen" und "Tests bestehen, bevor gestoppt wird" werden garantiert vom Harness ausgeführt, ohne sich auf das Ermessen der KI zu verlassen. Ein Hook ist ein Shell-Befehl, der an wichtigen Lebenszyklus-Punkten läuft und in settings.json konfiguriert wird.

F. Welche Events (Zeitpunkte) gibt es?
A. Die Klassiker sind neun: SessionStart (Beginn), UserPromptSubmit (beim Abschicken), PreToolUse (direkt vor einem Tool), PostToolUse (nach einem Tool), Notification, Stop (Antwort endet), SubagentStop, SessionEnd (Beendigung), PreCompact (vor der Kompaktierung). Davon können PreToolUse, UserPromptSubmit, Stop, PreCompact und andere blockieren und die Aktion stoppen. Das Release 2026 ergänzt viele weitere Events, aber die Namen können sich zwischen Versionen ändern, prüfe also die offizielle Doku für den aktuellsten Stand.

F. Kann ich Bearbeitungen an geschützten Dateien oder gefährliche Befehle stoppen?
A. Ja – mit einem PreToolUse-Hook. Ein Skript inspiziert den Dateipfad oder Befehl in tool_input, und wenn er auf .env, rm -rf usw. passt, gibt es Exit-Code 2 (oder JSON mit permissionDecision:"deny") zurück, um ihn zu blockieren. Entscheidend: deny hat immer Vorrang und stoppt sogar unter bypassPermissions. Hooks wirken nur in Richtung "Beschränkungen verschärfen".

F. Ich habe meine Konfiguration geändert, aber sie wird nicht wirksam.
A. Das ist so gewollt (ein Sicherheitsmerkmal). Die Hook-Konfiguration wird beim Session-Start als Snapshot erfasst, sodass Änderungen mitten in der Session nicht greifen. Das verhindert, dass ein bösartiger Prompt oder eine Tool-Ausgabe deine Hook-Konfiguration heimlich umschreibt. Starte eine neue Session, um sie anzuwenden. Beachte, dass /hooks eine schreibgeschützte Liste ist; Hooks fügt man hinzu oder ändert man, indem man settings.json direkt bearbeitet.

F. Sind Hooks sicher?
A. Nicht bedingungslos. Hooks führen beliebige Shell-Befehle mit deinen Rechten aus, weshalb die Doku "Nutzung auf eigene Gefahr" sagt. Konfiguriere nur Hooks, denen du vertraust, validiere und quote Eingaben mit jq, nutze absolute Pfade und fass .env / .ssh nicht an und führe niemals eval auf Tool-Ausgaben aus. In Organisationen können Admins Hooks mit allowManagedHooksOnly einschränken.