
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:
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 = FehlerDas 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:
| Bereich | Datei | In Git eingecheckt? | Verwendungszweck |
|---|---|---|---|
| User | ~/.claude/settings.json | Nein | Persönliche Standardwerte (Benachrichtigungen, Formatierungseinstellungen) |
| Project | .claude/settings.json | Ja | Team-übergreifende Hooks (Dateischutz, Test-Runner, Linting) |
| Local | .claude/settings.local.json | Nein (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.
{
"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:
| Event | Wann es auslöst | Kann blockieren? | Häufiger Verwendungszweck |
|---|---|---|---|
| PreToolUse | Bevor ein Tool ausgeführt wird | Ja (exit 2) | Gefährliche Befehle blockieren, Dateien schützen |
| PostToolUse | Nachdem ein Tool abgeschlossen hat | Nein | Auto-Format, Tests ausführen, Aktionen protokollieren |
| Notification | Wenn Claude eine Benachrichtigung sendet | Nein | Desktop-Benachrichtigungen, Slack-Nachrichten |
| Stop | Wenn Claude eine Antwort beendet | Nein | Aufräumen, Zusammenfassungen erstellen |
| SessionStart | Bei der Session-Initialisierung | Nein | Kontext einschleusen, Umgebung setzen |
| UserPromptSubmit | Wenn der Nutzer einen Prompt sendet | Ja (exit 2) | Eingabevalidierung, Inhaltsfilterung |
| PreCompact | Vor der Kontextverdichtung | Nein | Zustand speichern, bevor der Speicher bereinigt wird |
| PostCompact | Nach der Kontextverdichtung | Nein | Kritischen Kontext neu einschleusen |
| ConfigChange | Wenn sich Einstellungen ändern | Nein | Umgebungsvariablen hot-reloaden |
| FileChanged | Wenn eine überwachte Datei geändert wird | Nein | Rebuilds auslösen, Caches invalidieren |
| TaskCreated | Wenn eine neue Aufgabe erstellt wird | Nein | Aufgaben-Tracking, Ressourcenzuweisung |
| PermissionDenied | Wenn eine Berechtigungsprüfung fehlschlägt | Nein | Audit-Logging, Benachrichtigung bei blockierten Aktionen |
| WorktreeCreate | Wenn ein neuer Git-Worktree erstellt wird | Nein | Worktree-spezifische Einstellungen initialisieren |
| SubagentStart | Wenn ein Subagent startet | Nein | Subagenten-Aktivität überwachen |
| SubagentStop | Wenn ein Subagent abgeschlossen hat | Nein | Subagenten-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.
| Typ | Geschwindigkeit | Komplexität | Am besten für | Beispiel |
|---|---|---|---|---|
| Command | Schnell | Gering | Formatierung, Blockieren, Logging | Prettier nach Dateibearbeitung ausführen |
| HTTP | Mittel | Mittel | Externe Dienste, Webhooks | POST an Slack bei Abschluss |
| Prompt | Langsam | Mittel | Subjektive Entscheidungen | „Ist dieser Code sicher auszuführen?" |
| Agent | Am langsamsten | Hoch | Komplexe dateibasierte Überprüfung | Prü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.
{
"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).
{
"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.
{
"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.
{
"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
{
"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
{
"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
{
"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
{
"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
{
"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)
{
"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)
{
"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
| Mechanismus | Deterministisch? | Wann es läuft | Am besten für | Beispiel |
|---|---|---|---|---|
| Hooks | Ja | Automatisch bei Lifecycle-Events | Durchsetzung, Automatisierung, Benachrichtigungen | Auto-Format, Dateibearbeitung blockieren |
| MCP | Nein (Claude entscheidet) | Wenn Claude das MCP-Tool aufruft | Neue Fähigkeiten, externer Datenzugriff | Datenbank abfragen, Notion durchsuchen |
| Skills | Nein (Nutzer löst aus) | Wenn der Nutzer einen Slash-Befehl aufruft | Wiederverwendbare Anweisungssets | /review für Code-Review-Workflow |
| CLAUDE.md | Nein (Richtlinie) | Beim Session-Start gelesen | Projektkontext, 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
{
"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
| Stack | Format-Befehl | Test-Befehl | Zu überwachende Erweiterungen |
|---|---|---|---|
| Node/TypeScript | npx prettier --write | npx jest --no-coverage | .ts, .tsx, .js, .jsx |
| Python | black | pytest -x | .py |
| Go | gofmt -w | go test ./... | .go |
| Rust | rustfmt | cargo 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:
/hooks-Befehl -- Geben Sie/hooksin Claude Code ein, um alle registrierten Hooks, ihre Matcher und ihren Status zu sehen.- 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.
- Schnelles Deaktivieren -- Fügen Sie
"disableAllHooks": truezu Ihrer settings.json hinzu, um alle Hooks vorübergehend zu deaktivieren, ohne die Konfiguration zu löschen. Entfernen Sie es (oder setzen Sie es auffalse), 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-Event | Interaktiver Modus | Headless-Modus (-p) | CI-Empfehlung |
|---|---|---|---|
| PreToolUse (exit 2) | Blockiert, zeigt Nachricht | Pausiert für --resume | Für obligatorische menschliche Freigaben |
| PostToolUse | Läuft normal | Läuft normal | Formatter und Logger behalten |
| Notification | Desktop-Benachrichtigung | Löst aus (keine UI) | In Log-Datei oder Slack-Webhook umleiten |
| Stop | Führt Aufräumarbeiten aus | Führt Aufräumarbeiten aus | Gut für CI-Artefakt-Sammlung |
| SessionStart | Schleust Kontext ein | Schleust Kontext ein | CI-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:
- 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 dasWrite-Tool nicht. Prüfen Sie genaue Tool-Namen mit/hooks. - Falsche Settings-Datei -- Hooks in
~/.claude/settings.jsonerscheinen nicht in der/hooks-Ausgabe für den Projektbereich. Versuchen Sie.claude/settings.jsonim 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.