Free

Der vollständige Claude Code Hooks-Leitfaden: Volle Kontrolle über jede Claude-Aktion

Vollständige Analyse des Claude Code Hooks-Mechanismus: fünf Ereignistypen, Exit-Code-Kontrolle und vier reale Konfigurationen für auditierbare, abfangbare und automatisierbare KI-Aktionen.


Jedes Mal, wenn Claude Code eine Datei liest, Code schreibt oder einen Befehl ausführt, läuft im Hintergrund ein Ereignissystem. Hooks sind die Schnittstelle, um sich mit diesem System zu verbinden — du kannst jederzeit eigene Logik einschleusen: automatisch Linter ausführen, Operationen protokollieren, gefährliche Aktionen blockieren oder beliebige Shell-Befehle auslösen.

Dieser Artikel erklärt den Hooks-Mechanismus, die Konfiguration und die praktische Anwendung vollständig.


Was sind Hooks

Hooks sind Shell-Befehle, die in settings.json konfiguriert sind und von Claude Code automatisch ausgeführt werden, wenn bestimmte Ereignisse eintreten.

Die treffendste Analogie: git hooks. Git kann Skripte vor und nach Operationen wie commit und push auslösen. Claude Code Hooks funktionieren genauso — der Unterschied ist, dass die Auslösepunkte die Werkzeugaufrufe der KI sind.

Warum ist das wichtig?

Je leistungsfähiger Claude Code wird, desto mehr brauchst du eine deterministische Kontrollschicht. Hooks bieten:
- Ausführungsgarantien unabhängig vom Prompt (Claude kann Anweisungen ignorieren, aber Hooks laufen immer)
- Auditierbare Operationsprotokolle
- Automatisierte Qualitätsprüfungen


Fünf Hook-Typen

Typ Auslöser Typische Verwendung
PreToolUse Vor einem Werkzeugaufruf Gefährliche Operationen blockieren, Absicht protokollieren
PostToolUse Nach einem Werkzeugaufruf Auto-Lint, Tests ausführen
PreCompact Vor der Kontextkomprimierung Snapshot des aktuellen Zustands speichern
Notification Wenn Claude eine Benachrichtigung sendet Desktop-Benachrichtigungen, Slack-Nachrichten
Stop Wenn Claude die Antwort abschließt Logs zusammenfassen, Folge-Workflows auslösen

Am häufigsten verwendet werden PreToolUse und PostToolUse — zum Abfangen und Nachbearbeiten von Werkzeugaufrufen.


Konfigurationsformat

Hooks werden in ~/.claude/settings.json (global) oder in .claude/settings.json im Projektstamm (Projektebene) geschrieben:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint --silent"
          }
        ]
      }
    ]
  }
}

Drei Kernfelder:

  • matcher: Regex, das Werkzeugnamen abgleicht und bestimmt, welche Werkzeugaufrufe diesen Hook auslösen. "Write|Edit" wird beim Schreiben oder Bearbeiten von Dateien ausgelöst. Leer lassen oder ".*" verwenden, um alle Werkzeuge abzugleichen.
  • type: Derzeit nur "command".
  • command: Beliebiger Shell-Befehl.

Werkzeugname-Referenz

Werkzeugnamen, die du für Matcher kennen musst:

Werkzeugname Aktion
Write Neue Datei schreiben
Edit Datei bearbeiten
Bash Shell-Befehl ausführen
Read Datei lesen
Glob Dateisuche
Grep Inhaltssuche
TodoWrite Aufgabenliste aktualisieren

Hook-Ausführungsumgebung

Während der Ausführung werden Daten als JSON über stdin übergeben:

{
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/path/to/file.rb",
    "content": "..."
  },
  "tool_response": "..."
}

PreToolUse erhält tool_input (die Argumente vor dem Aufruf). PostToolUse erhält zusätzlich tool_response (den Rückgabewert des Werkzeugs).

Beispiel eines Hooks mit bedingter Logik:

#!/bin/bash
input=$(cat)
file=$(echo "$input" | jq -r '.tool_input.file_path')

# Rubocop nur für .rb-Dateien ausführen
if [[ "$file" == *.rb ]]; then
  rubocop "$file" --autocorrect-all --no-color
fi

Bedeutung der Exit-Codes

Der Exit-Code des Hooks steuert das nachfolgende Verhalten von Claude Code:

Exit-Code Bedeutung
0 Erfolg, Ausführung fortsetzen
2 Blockieren: aktuellen Werkzeugaufruf abbrechen, stderr-Ausgabe an Claude zurücksenden
Anderer Nicht-Null Fehler protokollieren, aber fortfahren

Exit-Code 2 ist am nützlichsten — er erlaubt es, Abfanglogik in PreToolUse zu schreiben, um Claude an einer Operation zu hindern und den Grund mitzuteilen.


Praxis: Vier Hook-Konfigurationen

1. Automatische Formatierung nach dem Schreiben von Dateien

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'file=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r .file_path 2>/dev/null); [[ \"$file\" == *.rb ]] && rubocop -A \"$file\" --no-color -q || true'"
          }
        ]
      }
    ]
  }
}

2. Löschen bestimmter Verzeichnisse verhindern

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'cmd=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r .command); if echo \"$cmd\" | grep -qE \"rm.*/(migrations|seeds)\"; then echo \"Das Löschen der Verzeichnisse migrations oder seeds ist nicht erlaubt\" >&2; exit 2; fi'"
          }
        ]
      }
    ]
  }
}

3. Betriebsprotokoll

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo \"$(date '+%Y-%m-%d %H:%M:%S') $CLAUDE_TOOL_NAME: $(echo $CLAUDE_TOOL_INPUT | jq -c .)\" >> ~/.claude/audit.log"
          }
        ]
      }
    ]
  }
}

4. Desktop-Benachrichtigung bei Abschluss

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude ist fertig\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

Global vs. Projektebene

Hooks können an zwei Stellen platziert werden:

Global (~/.claude/settings.json): Regeln, die für alle Projekte gelten — Logs, Benachrichtigungen.

Projektebene (.claude/settings.json): Projektspezifische Prüfungen. Projektebene- und globale Hooks werden zusammengeführt und beide ausgeführt.

Bei Teamprojekten empfiehlt es sich, das projektspezifische settings.json in git einzuchecken, damit alle dasselbe Hooks ausführen.


Hooks debuggen

Schritte zur Fehlersuche, wenn ein Hook nicht ausgelöst wird:

  1. Matcher-Schreibweise prüfen: Werkzeugnamen sind Groß-/Kleinschreibung-sensitiv — write ist nicht Write
  2. Befehl allein ausführen: Den Hook-Befehl kopieren und direkt im Terminal ausführen
  3. Claude Code-Ausgabe prüfen: Hook-stderr erscheint im Gespräch
  4. Zum Testen vereinfachen: Mit echo "hook triggered" >> /tmp/hook.log beginnen, um das Auslösen zu bestätigen

Zusammenfassung

Der Kernwert von Hooks ist es, unvorhersehbares KI-Verhalten mit deterministischen Ingenieursstandards zu verbinden. Claude kann vergessen, Tests auszuführen, ein PostToolUse-Hook nicht. Claude kann versehentlich Dateien löschen, aber ein PreToolUse-Interceptor lässt das nicht zu.

Fang mit einem Hook an: Auto-Lint nach dem Schreiben von Dateien. Wenn das läuft, füge weitere hinzu.