ai-machine-learning

Claude Code Hooks: Der vollständige Entwicklerleitfaden mit produktionsreifen Beispielen

Geschrieben von Mert Batur
Apr 5, 2026
16 Lesezeit
Claude Code Hooks: Der vollständige Entwicklerleitfaden mit produktionsreifen Beispielen

Claude Code Hooks: Der vollständige Entwicklerleitfaden mit produktionsreifen Beispielen

Claude Code ist hervorragend darin, Code zu schreiben — aber es bleibt ein probabilistisches System. Sie können es anweisen, nach jeder Dateibearbeitung Prettier auszuführen. Sie können das in Ihrer CLAUDE.md festhalten. Und manchmal wird es das einfach... vergessen. Claude Code Hooks lösen dieses Problem, indem sie Ihnen deterministische, garantierte Kontrolle darüber geben, was vor, während und nach jeder Aktion von Claude passiert.

Ich konfiguriere Hooks seit einigen Monaten in Dutzenden von Projekten, und sie sind leise zum wichtigsten Teil meines Claude Code-Setups geworden. Dieser Leitfaden behandelt alles vom Grundprinzip bis hin zu einem produktionsreifen Starter-Kit, das Sie noch heute in jedes Projekt einfügen können. Wenn Sie Claude Code neben Tools wie Cursor oder Copilot einsetzen, kennen Sie den Wert von Anpassungsmöglichkeiten bereits — Hooks gehen einen entscheidenden Schritt weiter.

Was sind Claude Code Hooks (und warum sollte Sie das interessieren)?

Claude Code Hooks sind benutzerdefinierte Shell-Befehle, HTTP-Endpunkte oder LLM-Prompts, die sich an bestimmten Punkten im Lebenszyklus von Claude Code automatisch ausführen. Laut der offiziellen Anthropic-Dokumentation werden Hooks — im Gegensatz zu Prompt-Anweisungen, die Claude unter Umständen ignoriert — deterministisch bei jedem Aufruf ausgelöst und geben Ihnen garantierte Kontrolle über Formatierung, Sicherheit, Benachrichtigungen und Workflow-Automatisierung.

Das probabilistische Problem

CLAUDE.md-Anweisungen sind Vorschläge, keine Verträge. Sie können schreiben „Führe nach jeder Bearbeitung von TypeScript-Dateien immer npx prettier --write aus", und Claude hält sich meistens daran. Aber „meistens" reicht nicht aus, wenn Sie Codeformatierung im Team durchsetzen, Pushes in die Produktion sperren oder jeden Shell-Befehl für ein Sicherheits-Audit protokollieren müssen.

Das ist die zentrale Spannung in jedem KI-Coding-Tool. Claude ist ein Sprachmodell — es arbeitet mit Wahrscheinlichkeiten. Ihr Context Engineering kann das Verhalten beeinflussen, aber nicht garantieren.

Wie Hooks dieses Problem lösen

Hooks umgehen das LLM vollständig. Es sind Shell-Skripte, HTTP-Aufrufe oder KI-Auswertungen, die bei bestimmten Lifecycle-Events auslösen — bevor ein Tool ausgeführt wird (PreToolUse), nachdem es abgeschlossen wurde (PostToolUse), wenn eine Benachrichtigung erscheint, wenn eine Session startet oder wenn Claude stoppt. Stellen Sie sie sich wie Git-Hooks vor, aber für Ihren KI-Coding-Assistenten.

Es gibt vier Hook-Typen: command (Shell-Skripte), HTTP (Webhook-POST-Anfragen), prompt (einmalige Claude-Ja/Nein-Auswertungen) und agent (startet einen Subagenten mit Tool-Zugang). Wir erklären jeden davon — command-Hooks decken rund 90 % Ihres Bedarfs ab.

Wie Claude Code Hooks funktionieren: Der Lebenszyklus

Claude Code Hooks laufen in einem definierten Lebenszyklus: Ein Event wird ausgelöst (z. B. PreToolUse), der Matcher prüft, ob der Hook zutrifft, das Hook-Skript wird ausgeführt und empfängt JSON über stdin, und der Exit-Code bestimmt das Ergebnis. Exit-Code 0 bedeutet fortfahren, Exit-Code 2 bedeutet die Aktion blockieren. Dieser Ablauf ist unabhängig vom verwendeten Hook-Typ identisch.

Event -> Matcher -> Hook -> Exit-Code (der 4-Schritt-Ablauf)

So funktioniert jede Hook-Ausführung:

text
1. EVENT FIRES          z. B. PreToolUse(Write)
       |
2. MATCHER CHECKS       Entspricht "Write" dem Matcher-Muster des Hooks?
       |
3. HOOK EXECUTES        Shell-Skript läuft, empfängt JSON über stdin
       |
4. EXIT CODE DECIDES    0 = fortfahren | 2 = blockieren | andere = Fehler

Das JSON, das über stdin ankommt, enthält alles über das Event: den tool_name, den tool_input (Dateipfad, Inhalt, Befehl) und Session-Metadaten. Ihr Skript liest dieses JSON, führt die benötigte Logik aus und beendet sich mit dem passenden Code.

Bei PreToolUse-Hooks ist Exit-Code 2 der mächtige — er blockiert die Aktion vollständig und sendet Ihre stdout-Nachricht als Feedback an Claude zurück. Claude sieht Ihre Nachricht und kann seinen Ansatz anpassen.

Konfigurationsbereiche: User, Project und Local

Hooks leben in settings.json auf drei Ebenen:

BereichDateiIn Git eingecheckt?Verwendungszweck
User~/.claude/settings.jsonNeinPersönliche Standardwerte (Benachrichtigungen, Formatierungseinstellungen)
Project.claude/settings.jsonJaTeam-übergreifende Hooks (Dateischutz, Test-Runner, Linting)
Local.claude/settings.local.jsonNein (gitignored)Persönliche Überschreibungen für dieses Projekt

Project-Settings sind für Teams am nützlichsten. Fügen Sie Ihre Hooks in .claude/settings.json ein, committen Sie die Datei, und jeder Entwickler im Team bekommt die gleichen Schutzmaßnahmen automatisch.

Das if-Feld: Detailliertes Filtern

Seit Claude Code v2.1.85 unterstützen Hooks ein if-Feld, mit dem Sie nach Tool-Argumenten filtern können — nicht nur nach Tool-Namen. Wie in der Anthropic Hooks-Referenz dokumentiert, können Sie damit einen Hook schreiben, der nur bei Bash-Befehlen auslöst, die git push enthalten, statt bei jedem einzelnen Bash-Aufruf.

json
{
  "matcher": "Bash",
  "if": "tool_input.command matches 'git push'",
  "hooks": [{ "type": "command", "command": "./scripts/check-branch.sh" }]
}

Das war ein echter Wendepunkt. Vor if musste man entweder zu breit matchen (jeder Bash-Befehl) oder das Filtern im Skript erledigen — unübersichtlich.

Alle Claude Code Hook-Events: Schnellreferenztabelle

Claude Code stellt über 20 Hook-Events über seinen Lebenszyklus bereit, wie in der offiziellen Hooks-Referenz und dem Claude Code Changelog dokumentiert. Am häufigsten genutzt werden PreToolUse, PostToolUse, Notification und Stop — neuere Events wie ConfigChange und FileChanged eröffnen aber fortgeschrittene Automatisierungsmuster.

Hier die vollständige Referenz:

EventWann es auslöstKann blockieren?Häufiger Verwendungszweck
PreToolUseBevor ein Tool ausgeführt wirdJa (exit 2)Gefährliche Befehle blockieren, Dateien schützen
PostToolUseNachdem ein Tool abgeschlossen hatNeinAuto-Format, Tests ausführen, Aktionen protokollieren
NotificationWenn Claude eine Benachrichtigung sendetNeinDesktop-Benachrichtigungen, Slack-Nachrichten
StopWenn Claude eine Antwort beendetNeinAufräumen, Zusammenfassungen erstellen
SessionStartBei der Session-InitialisierungNeinKontext einschleusen, Umgebung setzen
UserPromptSubmitWenn der Nutzer einen Prompt sendetJa (exit 2)Eingabevalidierung, Inhaltsfilterung
PreCompactVor der KontextverdichtungNeinZustand speichern, bevor der Speicher bereinigt wird
PostCompactNach der KontextverdichtungNeinKritischen Kontext neu einschleusen
ConfigChangeWenn sich Einstellungen ändernNeinUmgebungsvariablen hot-reloaden
FileChangedWenn eine überwachte Datei geändert wirdNeinRebuilds auslösen, Caches invalidieren
TaskCreatedWenn eine neue Aufgabe erstellt wirdNeinAufgaben-Tracking, Ressourcenzuweisung
PermissionDeniedWenn eine Berechtigungsprüfung fehlschlägtNeinAudit-Logging, Benachrichtigung bei blockierten Aktionen
WorktreeCreateWenn ein neuer Git-Worktree erstellt wirdNeinWorktree-spezifische Einstellungen initialisieren
SubagentStartWenn ein Subagent startetNeinSubagenten-Aktivität überwachen
SubagentStopWenn ein Subagent abgeschlossen hatNeinSubagenten-Output validieren

Profi-Tipp: Sie werden PreToolUse und PostToolUse für 80 % Ihrer Hooks nutzen. SessionStart ist der nächste Kandidat — perfekt für das Einschleusen von Projektkontext, den Claude zu Beginn jeder Session braucht.

Die 4 Claude Code Hook-Typen erklärt

Claude Code unterstützt vier Handler-Typen: command-Hooks führen Shell-Skripte aus, HTTP-Hooks senden POST-Anfragen an URLs, prompt-Hooks fragen Claude eine Ja/Nein-Frage, und agent-Hooks starten einen Subagenten mit Tool-Zugang. Aus unserer Erfahrung decken command-Hooks 90 % der Anwendungsfälle ab. Nutzen Sie HTTP für externe Integrationen, prompt- und agent-Hooks für differenzierte Entscheidungen, die KI-Urteil erfordern.

TypGeschwindigkeitKomplexitätAm besten fürBeispiel
CommandSchnellGeringFormatierung, Blockieren, LoggingPrettier nach Dateibearbeitung ausführen
HTTPMittelMittelExterne Dienste, WebhooksPOST an Slack bei Abschluss
PromptLangsamMittelSubjektive Entscheidungen„Ist dieser Code sicher auszuführen?"
AgentAm langsamstenHochKomplexe dateibasierte ÜberprüfungPrüfen, ob neuer Code Projektmuster einhält

Command-Hooks (das Arbeitspferd)

Command-Hooks führen einen Shell-Befehl aus und verwenden den Exit-Code zur Bestimmung des Ergebnisses. Sie empfangen die JSON-Daten des Events über stdin.

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "jq -r '.tool_input.command' | grep -q 'rm -rf /' && exit 2 || exit 0"
      }]
    }]
  }
}

Das ist, was Sie für Formatierung, Dateischutz, Benachrichtigungen und die meisten Automatisierungsaufgaben einsetzen werden. Schnell, einfach und vorhersehbar.

HTTP-Hooks (externe Integrationen)

HTTP-Hooks senden eine POST-Anfrage an eine URL mit dem Event-JSON als Body. Der Antwort-Statuscode bestimmt das Ergebnis (200 = fortfahren, 403 = blockieren).

json
{
  "hooks": {
    "Stop": [{
      "matcher": "",
      "hooks": [{
        "type": "http",
        "url": "https://your-api.com/claude-webhook"
      }]
    }]
  }
}

Ideal zum Senden von Events an Slack, Discord, PagerDuty oder ein eigenes Dashboard. Sie könnten damit auch eine externe Policy-Engine abfragen, bevor eine Tool-Ausführung zugelassen wird.

Prompt-Hooks (KI-gestützte Entscheidungen)

Prompt-Hooks übergeben die Event-Daten an Claude selbst für eine einmalige Ja/Nein-Auswertung. Claude gibt eine JSON-Antwort mit "decision": "allow" oder "decision": "block" sowie einer Begründung zurück.

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "prompt",
        "prompt": "Is this bash command safe to run in a production environment? Consider: does it modify system files, delete data, or access sensitive credentials?"
      }]
    }]
  }
}

Setzen Sie diese sparsam ein. Sie erhöhen die Latenz (ein vollständiger LLM-Aufruf pro Hook-Ausführung) und verursachen Kosten. Für wirklich subjektive Sicherheitsprüfungen — etwa „sieht diese Datenbankmigration destruktiv aus?" — sind sie jedoch kaum zu schlagen. Wenn Sie neugierig auf das Wechseln von Claude Code-Modellen sind: Das für Prompt-Hooks verwendete Modell richtet sich nach Ihrem aktuellen Session-Modell.

Agent-Hooks (Tool-gestützte Überprüfung)

Agent-Hooks starten einen Subagenten mit Zugang zu Read-, Grep- und Glob-Tools. Der Subagent kann Dateien inspizieren, bevor er seine Entscheidung trifft.

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Write",
      "hooks": [{
        "type": "agent",
        "prompt": "Check if the file being written follows the project's naming conventions and import patterns. Read .claude/CONVENTIONS.md for the rules."
      }]
    }]
  }
}

Das ist der leistungsstärkste Hook-Typ, aber auch der langsamste. Reservieren Sie ihn für Hochrisiko-Prüfungen, bei denen Sie Dateikontext benötigen, um eine fundierte Entscheidung zu treffen.

7 produktionsreife Claude Code Hook-Beispiele (kopierbereit)

Die nützlichsten Claude Code Hooks umfassen Auto-Formatierung mit Prettier oder Black nach Dateibearbeitungen, das Blockieren von Schreibzugriffen auf geschützte Dateien, Desktop-Benachrichtigungen bei Task-Abschluss, das Einschleusen von Projektkontext beim Session-Start, das Ausführen von Tests nach Code-Änderungen, das Durchsetzen von Branch-Schutz und das Auditing aller Tool-Nutzung. Ich betreibe Variationen davon in jedem Projekt seit den letzten drei Monaten.

Jedes Beispiel unten ist ein vollständiges settings.json-Snippet, das Sie in Ihre .claude/settings.json einfügen können. Community-Sammlungen wie awesome-claude-code bieten noch mehr Muster.

1. Auto-Formatierung beim Speichern

json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{
        "type": "command",
        "command": "FILE=$(jq -r '.tool_input.file_path // .tool_input.file' /dev/stdin); case \"$FILE\" in *.ts|*.tsx|*.js|*.jsx) npx prettier --write \"$FILE\" 2>/dev/null;; *.py) black \"$FILE\" 2>/dev/null;; esac; exit 0"
      }]
    }]
  }
}

Dieser Hook löst nach jedem Write oder Edit aus, extrahiert den Dateipfad aus dem stdin-JSON und führt den passenden Formatter aus. Das exit 0 am Ende stellt sicher, dass der Hook nie blockiert — Formatierungsfehler sollten Claude nicht aufhalten.

Profi-Tipp: Fügen Sie *.go mit gofmt und *.rs mit rustfmt hinzu, wenn Sie sprachübergreifend arbeiten.

2. Schreibzugriff auf geschützte Dateien blockieren

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Write|Edit",
      "if": "tool_input.file_path matches '(\\.env|\\.env\\.local|package-lock\\.json|yarn\\.lock|pnpm-lock\\.yaml)'",
      "hooks": [{
        "type": "command",
        "command": "echo '{\"message\": \"BLOCKED: This file is protected. Edit it manually.\"}' && exit 2"
      }]
    }]
  }
}

Exit-Code 2 blockiert die Aktion und sendet die JSON-Nachricht an Claude zurück. Claude sieht das Feedback und passt sich an — meistens teilt es Ihnen mit, dass es die Datei bearbeiten wollte, und fordert Sie auf, das manuell zu tun. Das if-Feld verhindert, dass dies bei jedem einzelnen Write-Aufruf ausgelöst wird.

3. Desktop-Benachrichtigung bei Abschluss

json
{
  "hooks": {
    "Notification": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "MSG=$(jq -r '.message // \"Claude Code task finished\"' /dev/stdin); if [ \"$(uname)\" = 'Darwin' ]; then osascript -e \"display notification \\\"$MSG\\\" with title \\\"Claude Code\\\"\"; else notify-send 'Claude Code' \"$MSG\"; fi; exit 0"
      }]
    }]
  }
}

Funktioniert auf macOS (osascript) und Linux (notify-send). Der leere Matcher bedeutet, dass es bei allen Benachrichtigungen auslöst. Das ist wirklich nützlich, wenn Sie eine längere Aufgabe starten und in ein anderes Fenster wechseln.

4. Kontexteinschleusung beim Session-Start

json
{
  "hooks": {
    "SessionStart": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "echo '{\"message\": \"Project: '\"$(basename $(pwd))\"' | Branch: '\"$(git branch --show-current 2>/dev/null || echo none)\"' | Last commit: '\"$(git log --oneline -1 2>/dev/null || echo none)\"'\"}'; exit 0"
      }]
    }]
  }
}

Dieser Hook schleust den aktuellen Projektnamen, den Git-Branch und den letzten Commit in jede Session ein. Claude erhält diesen Kontext automatisch — Sie müssen nicht mehr angeben, auf welchem Branch Sie sich befinden.

5. Tests nach Code-Änderungen automatisch ausführen

json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Write|Edit",
      "if": "tool_input.file_path matches '\\.(ts|tsx|js|jsx|py)$'",
      "hooks": [{
        "type": "command",
        "command": "FILE=$(jq -r '.tool_input.file_path' /dev/stdin); TEST_FILE=$(echo \"$FILE\" | sed 's/\\.[^.]*$/.test&/'); if [ -f \"$TEST_FILE\" ]; then npx jest \"$TEST_FILE\" --no-coverage 2>&1 | tail -5; fi; exit 0",
        "timeout": 30000
      }]
    }]
  }
}

Wenn eine passende Testdatei existiert, wird sie automatisch ausgeführt, nachdem Claude die Quelldatei bearbeitet hat. Das tail -5 hält die Ausgabe kompakt, und der Timeout verhindert endlose Test-Suites. Das lässt sich gut mit einem KI-gestützten Code-Review-Workflow kombinieren.

6. Branch-Schutz durchsetzen (fortgeschritten)

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "if": "tool_input.command matches 'git push.*(main|master|production)'",
      "hooks": [{
        "type": "command",
        "command": "echo '{\"message\": \"BLOCKED: Direct push to protected branch. Use a feature branch and open a PR.\"}' && exit 2"
      }]
    }]
  }
}

Dieser Hook blockiert jeden git push, der auf die Branches main, master oder production abzielt. Claude bekommt das Feedback und wird vorschlagen, stattdessen einen Feature-Branch zu erstellen.

7. Sicherheits-Audit-Logging (fortgeschritten)

json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "INPUT=$(cat /dev/stdin); CMD=$(echo \"$INPUT\" | jq -r '.tool_input.command'); echo \"[$(date -u +%Y-%m-%dT%H:%M:%SZ)] BASH: $CMD\" >> .claude/audit.log; exit 0"
      }]
    }]
  }
}

Protokolliert jeden Bash-Befehl, den Claude ausführt, mit einem UTC-Zeitstempel in eine Audit-Datei. Unschätzbar für Sicherheitsreviews und um zu verstehen, was Claude während einer Session tatsächlich getan hat. Fügen Sie .claude/audit.log zu Ihrer .gitignore hinzu.

Hooks vs. MCP vs. Skills vs. CLAUDE.md: Wann was verwenden?

Verwenden Sie Hooks für deterministische Automatisierung, die immer ausgeführt werden muss (Formatierung, Blockieren, Benachrichtigungen). Verwenden Sie MCP, um Claude Zugang zu externen Tools und Daten zu geben. Verwenden Sie Skills für wiederverwendbare Prompt-Pakete. Verwenden Sie CLAUDE.md für Verhaltensrichtlinien und Projektkontext. Hooks sind garantiert; alles andere ist probabilistisch. Das ist die wichtigste Unterscheidung, und ich komme immer wieder darauf zurück, wenn ich Teams berate.

Die Entscheidungsmatrix

MechanismusDeterministisch?Wann es läuftAm besten fürBeispiel
HooksJaAutomatisch bei Lifecycle-EventsDurchsetzung, Automatisierung, BenachrichtigungenAuto-Format, Dateibearbeitung blockieren
MCPNein (Claude entscheidet)Wenn Claude das MCP-Tool aufruftNeue Fähigkeiten, externer DatenzugriffDatenbank abfragen, Notion durchsuchen
SkillsNein (Nutzer löst aus)Wenn der Nutzer einen Slash-Befehl aufruftWiederverwendbare Anweisungssets/review für Code-Review-Workflow
CLAUDE.mdNein (Richtlinie)Beim Session-Start gelesenProjektkontext, Coding-Standards„Nutze Tailwind, schreibe Tests für allen neuen Code"

Für einen tiefen Einblick in MCP lesen Sie unseren MCP-Leitfaden. Wenn Sie von Cursor kommen: Cursors Rules-System ist in etwa das Pendant zu CLAUDE.md — aber Cursor hat nichts Vergleichbares zu Hooks.

Wenn sie sich überschneiden (und wie man wählt)

Hier ist das Flussdiagramm, das ich verwende:

  • „Muss das JEDES MAL passieren, ohne Ausnahme?" -- Hook. Code formatieren, geschützte Dateien blockieren, Benachrichtigungen senden. Kein Spielraum.
  • „Braucht Claude eine neue FÄHIGKEIT, die es noch nicht hat?" -- MCP-Server. Auf eine Datenbank zugreifen, eine API aufrufen, externe Docs durchsuchen.
  • „Möchte ich wiederverwendbare ANWEISUNGEN für einen bestimmten Workflow?" -- Skill (Slash-Befehl). Code-Review-Vorlagen, Deployment-Checklisten.
  • „Möchte ich das VERHALTEN von Claude in diesem Projekt gestalten?" -- CLAUDE.md. Coding-Standards, Architekturentscheidungen, bevorzugte Bibliotheken.

Konkrete Beispiele, die die Grenze verdeutlichen:

  • „Immer mit Prettier formatieren" = Hook (muss jedes Mal passieren)
  • „Prettier zur Formatierung verwenden" in CLAUDE.md = Richtlinie (Claude könnte es vergessen)
  • „Unsere Unternehmensdocs durchsuchen" = MCP (neue Fähigkeit)
  • „Beim Code-Review unseren Styleguide befolgen" = Skill oder CLAUDE.md

Wie in der Anthropic Plugins-Ankündigung beschrieben, sind Hooks ein Teil eines umfassenderen Plugin-Ökosystems, das auch MCP und Skills umfasst. Sie ergänzen sich — sie konkurrieren nicht.

Das Starter-Kit: Drop-in Claude Code Hooks-Konfiguration für jedes Projekt

Eine gute Starter-Hooks-Konfiguration für Claude Code sollte Auto-Format bei Dateibearbeitungen, Benachrichtigungen bei Task-Abschluss, Dateischutz für sensible Dateien, Session-Kontexteinschleusung und einen Stop-Hook für das Aufräumen umfassen. Das ist genau die Konfiguration, die ich in jedes neue Projekt einfüge — an den Stack angepasst, aber die Struktur bleibt gleich.

Die Konfiguration

json
{
  "hooks": {
    "SessionStart": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "echo '{\"message\": \"Project: '\"$(basename $(pwd))\"' | Branch: '\"$(git branch --show-current 2>/dev/null)\"' | Node: '\"$(node -v 2>/dev/null)\"'\"}'; exit 0"
      }]
    }],
    "PreToolUse": [{
      "matcher": "Write|Edit",
      "if": "tool_input.file_path matches '(\\.env|\\.env\\..+|.*lock\\.json|.*lock\\.yaml)'",
      "hooks": [{
        "type": "command",
        "command": "echo '{\"message\": \"Protected file. Edit manually.\"}' && exit 2"
      }]
    }],
    "PostToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{
        "type": "command",
        "command": "FILE=$(jq -r '.tool_input.file_path // .tool_input.file' /dev/stdin); case \"$FILE\" in *.ts|*.tsx|*.js|*.jsx) npx prettier --write \"$FILE\" 2>/dev/null;; *.py) black \"$FILE\" 2>/dev/null;; *.go) gofmt -w \"$FILE\" 2>/dev/null;; esac; exit 0"
      }]
    }],
    "Notification": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "MSG=$(jq -r '.message // \"Done\"' /dev/stdin); osascript -e \"display notification \\\"$MSG\\\" with title \\\"Claude Code\\\"\" 2>/dev/null || notify-send 'Claude Code' \"$MSG\" 2>/dev/null; exit 0"
      }]
    }],
    "Stop": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "echo '[STOP] '\"$(date +%H:%M:%S)\"'' >> .claude/session.log; exit 0"
      }]
    }]
  }
}

Anpassung für Ihren Stack

StackFormat-BefehlTest-BefehlZu überwachende Erweiterungen
Node/TypeScriptnpx prettier --writenpx jest --no-coverage.ts, .tsx, .js, .jsx
Pythonblackpytest -x.py
Gogofmt -wgo test ./....go
Rustrustfmtcargo test.rs

Tauschen Sie die Format- und Test-Befehle in der obigen Konfiguration gegen die passenden für Ihren Stack aus. Die Struktur bleibt identisch.

Überprüfen, ob Ihre Hooks funktionieren

Drei Möglichkeiten, um zu bestätigen, dass Hooks aktiv sind:

  1. /hooks-Befehl -- Geben Sie /hooks in Claude Code ein, um alle registrierten Hooks, ihre Matcher und ihren Status zu sehen.
  2. Transcript-Inspektion -- Nachdem ein Hook ausgelöst hat, prüfen Sie das Session-Transcript. Hook-Ausführungen erscheinen dort mit ihrer Ausgabe und dem Exit-Code.
  3. Schnelles Deaktivieren -- Fügen Sie "disableAllHooks": true zu Ihrer settings.json hinzu, um alle Hooks vorübergehend zu deaktivieren, ohne die Konfiguration zu löschen. Entfernen Sie es (oder setzen Sie es auf false), um sie wieder zu aktivieren.

CI/CD-Integration: Claude Code Hooks im Headless-Modus

Claude Code Hooks funktionieren im Headless-Modus (claude -p) mit einigen Unterschieden: Notification-Hooks lösen weiterhin aus, sollten aber auf Logging statt Desktop-Benachrichtigungen umgeleitet werden. PreToolUse-Hooks mit Exit-Code 2 können Headless-Sessions für menschliche Überprüfung pausieren. GitHub Actions verwendet anthropics/claude-code-action@v1 zusammen mit Hooks für automatisierte Workflows.

Verhalten im Headless-Modus

Hook-EventInteraktiver ModusHeadless-Modus (-p)CI-Empfehlung
PreToolUse (exit 2)Blockiert, zeigt NachrichtPausiert für --resumeFür obligatorische menschliche Freigaben
PostToolUseLäuft normalLäuft normalFormatter und Logger behalten
NotificationDesktop-BenachrichtigungLöst aus (keine UI)In Log-Datei oder Slack-Webhook umleiten
StopFührt Aufräumarbeiten ausFührt Aufräumarbeiten ausGut für CI-Artefakt-Sammlung
SessionStartSchleust Kontext einSchleust Kontext einCI-Umgebungsvariablen einschleusen

Die große Überraschung im Headless-Modus: PreToolUse-Hooks, die mit Code 2 beenden, schlagen nicht einfach lautlos fehl. Sie pausieren die Session und ermöglichen eine Wiederaufnahme mit --resume — was Ihnen ein Human-in-the-Loop-Muster für CI/CD-Pipelines gibt, bei dem bestimmte Aktionen eine manuelle Freigabe erfordern.

GitHub Actions-Integration

Hier ist ein minimaler GitHub Actions-Workflow, der Claude Code mit Hooks verwendet. Wie in der offiziellen GitHub Actions-Anleitung dokumentiert:

yaml
- name: Run Claude Code
  uses: anthropics/claude-code-action@v1
  with:
    prompt: "Review this PR and suggest improvements"
    allowed_tools: "Read,Grep,Glob"
  env:
    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

Ihre .claude/settings.json-Hooks reisen mit dem Repository mit, sodass sie in CI genauso ausgelöst werden wie lokal. Stellen Sie sicher, dass Hooks, die sich auf Desktop-spezifische Tools verlassen (wie osascript), Fallbacks oder Bedingungen haben.

Team-Hook-Management

Ein bewährtes Muster für Teams:

  • .claude/settings.json (eingecheckt) -- Team-übergreifende Hooks: Dateischutz, Formatter, Branch-Schutz. Jeder bekommt diese.
  • .claude/settings.local.json (gitignored) -- Persönliche Hooks: Benachrichtigungseinstellungen, benutzerdefiniertes Logging, experimentelle Hooks.
  • ~/.claude/settings.json (benutzerglobal) -- Ihre Standardwerte über alle Projekte: Benachrichtigungsstil, persönliche Formatierungseinstellungen.

Das entspricht dem Muster von .editorconfig (eingecheckt) und lokalen IDE-Einstellungen (persönlich). Wie in Angelo Limas CI/CD-Leitfaden festgestellt, haben Teams, die auf gemeinsame Hooks standardisieren, weniger „bei mir läuft es"-Probleme mit Claude Code.

Fehlerbehebung bei Claude Code Hooks und häufige Fehler

Häufige Probleme mit Claude Code Hooks umfassen: Hooks lösen nicht aus (Matcher-Schreibweise und settings.json-Pfad prüfen), Hooks laufen aber blockieren nicht (falscher Exit-Code — 2 verwenden, nicht 1), Endlosschleifen (Stop-Hook löst sich selbst aus) und langsamer Start (zu viele synchrone Hooks). Der häufigste Fehler, den ich sehe, ist Exit-Code-Verwechslung — Entwickler verwenden exit 1, wenn sie exit 2 meinen.

Hook löst nicht aus

Symptome: Sie haben einen Hook hinzugefügt, aber nichts passiert, wenn das Event eintritt.

Lösungen:

  • Matcher-Tippfehler -- Matcher unterscheiden Groß- und Kleinschreibung. "write" matcht das Write-Tool nicht. Prüfen Sie genaue Tool-Namen mit /hooks.
  • Falsche Settings-Datei -- Hooks in ~/.claude/settings.json erscheinen nicht in der /hooks-Ausgabe für den Projektbereich. Versuchen Sie .claude/settings.json im Projektstamm.
  • JSON-Syntaxfehler -- Ein überschüssiges Komma oder eine fehlende Klammer deaktiviert die gesamte Hooks-Konfiguration lautlos. Führen Sie Ihre settings.json durch jq ., um sie zu validieren.
  • disableAllHooks: true -- Prüfen Sie, ob jemand (oder eine frühere Debug-Session) dieses Flag gesetzt hat.

Hook läuft, blockiert aber nicht

Symptome: Ihr PreToolUse-Hook wird ausgeführt, aber die Aktion wird trotzdem durchgeführt.

Lösungen:

  • Falscher Exit-Code -- Exit-Code 1 bedeutet „Fehler" (Hook fehlgeschlagen), nicht „blockieren". Verwenden Sie exit 2, um eine Aktion zu blockieren. Das verwirrt fast jeden, wie in den offiziellen Docs vermerkt.
  • Fehlende stdout-JSON -- Bei blockierenden Hooks geben Sie eine JSON-Nachricht aus, damit Claude weiß, warum die Aktion blockiert wurde: echo '{"message": "Blocked: reason"}'

Endlosschleifen

Symptome: Claude versucht dieselbe Aktion immer wieder, oder Ihr Rechner wird ungewöhnlich warm.

Lösungen:

  • Stop-Hook löst Aktionen aus -- Wenn Ihr Stop-Hook eine Datei schreibt oder einen Befehl ausführt, der Claude zu einer Reaktion veranlasst, haben Sie eine Schleife erstellt. Stop-Hooks sollten nur passive Dinge tun: loggen, benachrichtigen, aufräumen.
  • PostToolUse-Hook verursacht Bearbeitungen -- Ein PostToolUse-Hook, der eine Datei modifiziert, löst ein weiteres PostToolUse-Event aus. Schützen Sie sich davor mit spezifischen Matchern oder dem if-Feld.

Performance-Probleme

Symptome: Claude braucht deutlich länger zum Starten oder zum Ausführen von Tools.

Lösungen:

  • Zu viele SessionStart-Hooks -- Jeder davon läuft synchron beim Start. Halten Sie diese leichtgewichtig (unter 1 Sekunde pro Hook).
  • Schwere Skripte auf häufig genutzten Pfaden -- Hooks auf PreToolUse und PostToolUse werden häufig ausgelöst. Wenn Ihr Skript Netzwerkanfragen oder schwere Berechnungen durchführt, fügen Sie ein timeout-Feld (in Millisekunden) hinzu und überlegen Sie, ob es stattdessen ein HTTP-Hook sein sollte.
  • Kein Caching -- Wenn Sie dieselbe Sache wiederholt prüfen (etwa „ist das ein geschützter Branch?"), speichern Sie das Ergebnis in einer temporären Datei, statt bei jedem Hook-Aufruf Git-Befehle auszuführen.

Häufig gestellte Fragen

Was sind Claude Code Hooks und wie funktionieren sie?

Claude Code Hooks sind benutzerdefinierte Automatisierungsskripte, die bei bestimmten Lifecycle-Events während einer Claude Code-Session ausgeführt werden. Sie konfigurieren sie in settings.json mit einem Matcher-Muster und einem Handler (Shell-Befehl, HTTP-Endpunkt, Prompt oder Agent). Wenn das passende Event eintritt, läuft der Hook automatisch und verwendet Exit-Codes zur Steuerung des Ergebnisses.

Wie konfiguriere ich Hooks in der Claude Code settings.json?

Fügen Sie ein "hooks"-Objekt zu einem der drei Konfigurationsorte hinzu: ~/.claude/settings.json (benutzerglobal), .claude/settings.json (projektübergreifend) oder .claude/settings.local.json (projektpersönlich). Jeder Event-Typ wird einem Array von Hook-Definitionen mit matcher, optionalem if-Feld und einem hooks-Array zugeordnet, das Handler-Objekte mit type und command oder url enthält.

Was ist der Unterschied zwischen PreToolUse- und PostToolUse-Hooks?

PreToolUse löst aus, bevor ein Tool ausgeführt wird, und gibt Ihnen die Möglichkeit, es mit Exit-Code 2 zu blockieren. PostToolUse löst nach dem Abschluss der Ausführung aus und eignet sich für Formatierung, Tests oder Logging. PreToolUse ist für Prävention und Absicherung. PostToolUse ist für Validierung und Aufräumen. Beide empfangen den Tool-Namen und -Input als JSON über stdin.

Können Claude Code Hooks gefährliche Befehle blockieren?

Ja. PreToolUse-Hooks mit Exit-Code 2 blockieren jede Tool-Ausführung. Sie können sensible Dateien vor Schreibzugriffen schützen, Shell-Befehle mit gefährlichen Mustern wie rm -rf oder git push main blockieren und den Zugriff auf Produktionsdatenbanken verhindern. Die Blockierungsnachricht wird als Feedback an Claude zurückgesendet, sodass es seinen Ansatz anpassen kann.

Welche Hook-Events sind in Claude Code verfügbar?

Claude Code stellt 15+ Events bereit: PreToolUse und PostToolUse für Tool-Ausführung, Notification für Benachrichtigungen, Stop für das Session-Ende, SessionStart für die Initialisierung, UserPromptSubmit für Eingabefilterung, PreCompact und PostCompact für Kontextverwaltung sowie neuere Events wie ConfigChange, FileChanged, TaskCreated und PermissionDenied. Sehen Sie die vollständige Referenztabelle im Hook-Events-Abschnitt oben.

Wie unterscheiden sich Hooks von MCP-Tools und Skills?

Hooks sind deterministisch — sie lösen immer bei passenden Events aus, unabhängig davon, was Claude entscheidet. MCP-Tools erweitern Claudes Fähigkeiten (Datenbankzugang, API-Aufrufe), aber Claude entscheidet, wann es sie nutzt. Skills sind wiederverwendbare Anweisungspakete, die über Slash-Befehle aufgerufen werden. CLAUDE.md gibt Verhaltensrichtlinien vor. Verwenden Sie Hooks, wenn etwas jedes Mal passieren muss; MCP, wenn Claude neue Fähigkeiten braucht.

Funktionieren Claude Code Hooks im Headless-Modus?

Ja, mit Einschränkungen. Hooks lösen normal im Headless-Modus (claude -p) aus, aber Desktop-spezifische Hooks wie macOS-Benachrichtigungen benötigen Fallbacks. Wichtig: PreToolUse-Hooks, die mit Code 2 beenden, können Headless-Sessions für menschliche Freigabe via --resume pausieren. Das ermöglicht Human-in-the-Loop-CI/CD-Pipelines, bei denen bestimmte Aktionen eine manuelle Genehmigung erfordern.

Wie viele Hooks sind zu viele? Verlangsamen Hooks Claude Code?

Es gibt kein hartes Limit, aber jeder synchrone Hook erhöht die Latenz. SessionStart-Hooks laufen beim Start — halten Sie sie schnell (unter 1 Sekunde pro Hook). PreToolUse- und PostToolUse-Hooks lösen bei jedem passenden Tool-Aufruf aus — schwere Skripte summieren sich schnell. Ich empfehle, insgesamt unter 10–15 Hooks zu bleiben, das if-Feld zur Eingrenzung zu nutzen und timeout-Werte zu setzen, um endlose Skriptläufe zu verhindern.

Kann ich Hooks verwenden, um Code automatisch mit Prettier oder Black zu formatieren?

Ja — das ist der beliebteste Hook-Anwendungsfall. Erstellen Sie einen PostToolUse-Hook, der Write|Edit matcht, extrahieren Sie den Dateipfad aus dem stdin-JSON und führen Sie den passenden Formatter basierend auf der Dateiendung aus. Sehen Sie Beispiel Nummer eins im Abschnitt mit den Produktionsbeispielen für eine vollständige, kopierfertige Konfiguration, die TypeScript-, JavaScript- und Python-Dateien behandelt.

Sind Claude Code Hooks sicher? Was sind die Sicherheitsrisiken?

Hooks laufen mit Ihren vollständigen Nutzerrechten — es gibt keine Sandbox. Ein bösartiger Hook könnte Ihre SSH-Keys lesen, Dateien löschen oder Daten exfiltrieren. Verwenden Sie nur Hooks aus vertrauenswürdigen Quellen, prüfen Sie jede geteilte .claude/settings.json, bevor Sie sie in Ihr Projekt übernehmen, und nutzen Sie .claude/settings.local.json für persönliche Hooks, die nicht geteilt werden sollten. Für umfassendere KI-Sicherheitsmuster lesen Sie unseren LLM-Guardrails-Leitfaden.

Tags

claude code hooksclaude codeentwicklerwerkzeugeKI-AutomatisierungWorkflow-Automatisierungsettings.jsonPreToolUsePostToolUse

Diesen Artikel teilen

Ihr Projekt starten

Bereit, etwas Außergewöhnliches zu bauen?

Machen wir aus Ihrer Vision ein fertiges Produkt. Unser Team baut mit Ihnen Software, die spürbar etwas bewegt.