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 stattfinden, anstatt sich darauf zu verlassen, dass das LLM sich dafür entscheidet, sie auszuführen. Verwenden Sie Hooks, um Projektregeln durchzusetzen, sich wiederholende Aufgaben zu automatisieren und Claude Code mit Ihren vorhandenen Tools zu integrieren. Für Entscheidungen, die Urteilsvermögen erfordern, anstatt deterministischer Regeln, können Sie auch Prompt-basierte Hooks oder Agent-basierte Hooks verwenden, die ein Claude-Modell zur Bewertung von Bedingungen nutzen. Für andere Möglichkeiten, Claude Code zu erweitern, siehe skills zum Geben zusätzlicher Anweisungen und ausführbarer Befehle, subagents zum Ausführen von Aufgaben in isolierten Kontexten und plugins zum Verpacken von Erweiterungen, die über Projekte hinweg freigegeben werden können.Documentation Index
Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Richten Sie Ihren ersten Hook ein
Um einen Hook zu erstellen, fügen Sie einenhooks-Block zu einer Einstellungsdatei hinzu. Diese Anleitung erstellt einen Desktop-Benachrichtigungs-Hook, damit Sie benachrichtigt werden, wenn Claude auf Ihre Eingabe wartet, anstatt das Terminal zu beobachten.
Fügen Sie den Hook zu Ihren Einstellungen hinzu
Öffnen Sie Wenn Ihre Einstellungsdatei bereits einen Sie können auch Claude bitten, den Hook für Sie zu schreiben, indem Sie beschreiben, was Sie in der CLI möchten.
~/.claude/settings.json und fügen Sie einen Notification-Hook hinzu. Das Beispiel unten verwendet osascript für macOS; siehe Benachrichtigung erhalten, wenn Claude Eingaben benötigt für Linux- und Windows-Befehle.hooks-Schlüssel hat, fügen Sie Notification als Geschwister der vorhandenen Event-Schlüssel hinzu, anstatt das ganze Objekt zu ersetzen. Jeder Event-Name ist ein Schlüssel innerhalb des einzelnen hooks-Objekts:Überprüfen Sie die Konfiguration
Geben Sie
/hooks ein, um den Hooks-Browser zu öffnen. Sie sehen eine Liste aller verfügbaren Hook-Events mit einer Anzahl neben jedem Event, das Hooks konfiguriert hat. Wählen Sie Notification aus, um zu bestätigen, dass Ihr neuer Hook in der Liste angezeigt wird. Wenn Sie den Hook auswählen, werden seine Details angezeigt: das Event, der Matcher, der Typ, die Quelldatei und der Befehl.Was Sie automatisieren können
Hooks ermöglichen es Ihnen, Code an Schlüsselpunkten im Lebenszyklus von Claude Code auszuführen: Dateien nach Bearbeitungen formatieren, Befehle vor der Ausführung blockieren, Benachrichtigungen senden, wenn Claude Eingaben benötigt, Kontext beim Sitzungsstart injizieren und vieles mehr. Für die vollständige Liste der Hook-Events siehe die Hooks-Referenz. Jedes Beispiel enthält einen einsatzbereiten Konfigurationsblock, den Sie einer Einstellungsdatei hinzufügen. Die häufigsten Muster:- Benachrichtigung erhalten, wenn Claude Eingaben benötigt
- Code nach Bearbeitungen automatisch formatieren
- Bearbeitungen geschützter Dateien blockieren
- Kontext nach Komprimierung erneut injizieren
- Konfigurationsänderungen prüfen
- Umgebung neu laden, wenn sich Verzeichnis oder Dateien ändern
- Bestimmte Berechtigungsaufforderungen automatisch genehmigen
Benachrichtigung erhalten, wenn Claude Eingaben benötigt
Erhalten Sie eine Desktop-Benachrichtigung, wenn Claude die Arbeit beendet und Ihre Eingabe benötigt, damit Sie zu anderen Aufgaben wechseln können, ohne das Terminal zu überprüfen. Dieser Hook verwendet dasNotification-Event, das ausgelöst wird, wenn Claude auf Eingaben oder Berechtigungen wartet. Jede Registerkarte unten verwendet den nativen Benachrichtigungsbefehl der Plattform. Fügen Sie dies zu ~/.claude/settings.json hinzu:
- macOS
- Linux
- Windows (PowerShell)
Wenn keine Benachrichtigung angezeigt wird
Wenn keine Benachrichtigung angezeigt wird
osascript leitet Benachrichtigungen über die integrierte Script Editor-App weiter. Wenn Script Editor keine Benachrichtigungsberechtigung hat, schlägt der Befehl stillschweigend fehl, und macOS fordert Sie nicht auf, sie zu gewähren. Führen Sie dies einmal im Terminal aus, um Script Editor in Ihren Benachrichtigungseinstellungen angezeigt zu bekommen:matcher wird bei allen Benachrichtigungstypen ausgelöst. Um nur bei bestimmten Events ausgelöst zu werden, setzen Sie ihn auf einen dieser Werte:
| Matcher | Wird ausgelöst, wenn |
|---|---|
permission_prompt | Claude benötigt Ihre Genehmigung für einen Tool-Einsatz |
idle_prompt | Claude ist fertig und wartet auf Ihre nächste Eingabe |
auth_success | Authentifizierung ist abgeschlossen |
elicitation_dialog | Ein MCP-Server öffnet ein Elicitation-Formular |
elicitation_complete | Ein MCP-Elicitation-Formular wird eingereicht oder verworfen |
elicitation_response | Eine MCP-Elicitation-Antwort wird an den Server zurückgesendet |
/hooks ein und wählen Sie Notification aus, um zu bestätigen, dass der Hook registriert ist. Für das vollständige Event-Schema siehe die Notification-Referenz.
Code nach Bearbeitungen automatisch formatieren
Führen Sie Prettier automatisch auf jeder Datei aus, die Claude bearbeitet, damit die Formatierung konsistent bleibt, ohne manuelle Eingriffe. Dieser Hook verwendet dasPostToolUse-Event mit einem Edit|Write-Matcher, sodass er nur nach Datei-Bearbeitungs-Tools ausgeführt wird. Der Befehl extrahiert den bearbeiteten Dateipfad mit jq und übergibt ihn an Prettier. Fügen Sie dies zu .claude/settings.json in Ihrem Projektverzeichnis hinzu:
Die Bash-Beispiele auf dieser Seite verwenden
jq zum Parsen von JSON. Installieren Sie es mit brew install jq (macOS), apt-get install jq (Debian/Ubuntu), oder siehe jq-Downloads.Bearbeitungen geschützter Dateien blockieren
Verhindern Sie, dass Claude sensible Dateien wie.env, package-lock.json oder alles in .git/ ändert. Claude erhält Feedback, das erklärt, warum die Bearbeitung blockiert wurde, sodass es seinen Ansatz anpassen kann.
Dieses Beispiel verwendet eine separate Skriptdatei, die der Hook aufruft. Das Skript überprüft den Zieldateipfad gegen eine Liste geschützter Muster und beendet sich mit Code 2, um die Bearbeitung zu blockieren.
Machen Sie das Skript ausführbar (macOS/Linux)
Hook-Skripte müssen ausführbar sein, damit Claude Code sie ausführen kann:
Kontext nach Komprimierung erneut injizieren
Wenn Claudes Kontextfenster voll wird, fasst die Komprimierung das Gespräch zusammen, um Platz freizugeben. Dies kann wichtige Details verlieren. Verwenden Sie einenSessionStart-Hook mit einem compact-Matcher, um nach jeder Komprimierung kritischen Kontext erneut zu injizieren.
Jeder Text, den Ihr Befehl auf stdout schreibt, wird zu Claudes Kontext hinzugefügt. Dieses Beispiel erinnert Claude an Projektkonventionen und aktuelle Arbeiten. Fügen Sie dies zu .claude/settings.json in Ihrem Projektverzeichnis hinzu:
echo durch jeden Befehl ersetzen, der dynamische Ausgabe erzeugt, wie git log --oneline -5, um aktuelle Commits anzuzeigen. Zum Injizieren von Kontext bei jedem Sitzungsstart sollten Sie stattdessen CLAUDE.md verwenden. Für Umgebungsvariablen siehe CLAUDE_ENV_FILE in der Referenz.
Konfigurationsänderungen prüfen
Verfolgen Sie, wenn sich Einstellungs- oder Skills-Dateien während einer Sitzung ändern. DasConfigChange-Event wird ausgelöst, wenn ein externer Prozess oder Editor eine Konfigurationsdatei ändert, sodass Sie Änderungen für Compliance protokollieren oder nicht autorisierte Änderungen blockieren können.
Dieses Beispiel hängt jede Änderung an ein Audit-Protokoll an. Fügen Sie dies zu ~/.claude/settings.json hinzu:
user_settings, project_settings, local_settings, policy_settings oder skills. Um eine Änderung zu blockieren, beenden Sie mit Code 2 oder geben Sie {"decision": "block"} zurück. Siehe die ConfigChange-Referenz für das vollständige Eingabe-Schema.
Umgebung neu laden, wenn sich Verzeichnis oder Dateien ändern
Einige Projekte setzen unterschiedliche Umgebungsvariablen je nachdem, in welchem Verzeichnis Sie sich befinden. Tools wie direnv tun dies automatisch in Ihrer Shell, aber Claudes Bash-Tool übernimmt diese Änderungen nicht automatisch. Das Pairing einesSessionStart-Hooks mit einem CwdChanged-Hook behebt dies. SessionStart lädt die Variablen für das Verzeichnis, in dem Sie starten, und CwdChanged lädt sie jedes Mal neu, wenn Claude das Verzeichnis wechselt. Beide schreiben in CLAUDE_ENV_FILE, die Claude Code vor jedem Bash-Befehl als Skript-Präambel ausführt. Fügen Sie dies zu ~/.claude/settings.json hinzu:
direnv allow einmal in jedem Verzeichnis aus, das eine .envrc hat, damit direnv berechtigt ist, sie zu laden. Wenn Sie devbox oder nix statt direnv verwenden, funktioniert das gleiche Muster mit devbox shellenv oder devbox global shellenv anstelle von direnv export bash.
Um auf bestimmte Dateien statt auf jeden Verzeichniswechsel zu reagieren, verwenden Sie FileChanged mit einem matcher, der die zu überwachenden Dateinamen auflistet, getrennt durch |. Um die Überwachungsliste zu erstellen, wird dieser Wert in Dateinamen aufgeteilt, anstatt als Regex ausgewertet zu werden. Siehe FileChanged für die Funktionsweise desselben Werts, der auch filtert, welche Hook-Gruppen ausgeführt werden, wenn sich eine Datei ändert. Dieses Beispiel überwacht .envrc und .env im Arbeitsverzeichnis:
watchPaths-Ausgabe und CLAUDE_ENV_FILE-Details.
Bestimmte Berechtigungsaufforderungen automatisch genehmigen
Überspringen Sie den Genehmigungsdialog für Tool-Aufrufe, die Sie immer zulassen. Dieses Beispiel genehmigt automatischExitPlanMode, das Tool, das Claude aufruft, wenn es fertig ist, einen Plan zu präsentieren und fragt, ob es fortfahren soll, sodass Sie nicht jedes Mal aufgefordert werden, wenn ein Plan bereit ist.
Im Gegensatz zu den Exit-Code-Beispielen oben erfordert die automatische Genehmigung, dass Ihr Hook eine JSON-Entscheidung auf stdout schreibt. Ein PermissionRequest-Hook wird ausgelöst, wenn Claude Code einen Berechtigungsdialog anzeigen wird, und die Rückgabe von "behavior": "allow" beantwortet ihn in Ihrem Namen.
Der Matcher beschränkt den Hook nur auf ExitPlanMode, sodass keine anderen Aufforderungen betroffen sind. Fügen Sie dies zu ~/.claude/settings.json hinzu:
updatedPermissions mit einem setMode-Eintrag enthalten. Der Wert mode ist ein beliebiger Berechtigungsmodus wie default, acceptEdits oder bypassPermissions, und destination: "session" wendet ihn nur für die aktuelle Sitzung an.
bypassPermissions gilt nur, wenn die Sitzung mit bereits verfügbarem Bypass-Modus gestartet wurde: --dangerously-skip-permissions, --permission-mode bypassPermissions, --allow-dangerously-skip-permissions oder permissions.defaultMode: "bypassPermissions" in Einstellungen, und nicht deaktiviert durch permissions.disableBypassPermissionsMode. Es wird niemals als defaultMode beibehalten.acceptEdits zu wechseln, schreibt Ihr Hook dieses JSON auf stdout:
.* oder das Lassen des Matchers leer würde jede Berechtigungsaufforderung automatisch genehmigen, einschließlich Dateischreibvorgänge und Shell-Befehle. Siehe die PermissionRequest-Referenz für den vollständigen Satz von Entscheidungsfeldern.
Wie Hooks funktionieren
Hook-Events werden an bestimmten Lebenszykluspunkten in Claude Code ausgelöst. Wenn ein Event ausgelöst wird, werden alle übereinstimmenden Hooks parallel ausgeführt, und identische Hook-Befehle werden automatisch dedupliziert. Die folgende Tabelle zeigt jedes Event und wann es ausgelöst wird:| Event | When it fires |
|---|---|
SessionStart | When a session begins or resumes |
Setup | When you start Claude Code with --init-only, or with --init or --maintenance in -p mode. For one-time preparation in CI or scripts |
UserPromptSubmit | When you submit a prompt, before Claude processes it |
UserPromptExpansion | When a user-typed command expands into a prompt, before it reaches Claude. Can block the expansion |
PreToolUse | Before a tool call executes. Can block it |
PermissionRequest | When a permission dialog appears |
PermissionDenied | When a tool call is denied by the auto mode classifier. Return {retry: true} to tell the model it may retry the denied tool call |
PostToolUse | After a tool call succeeds |
PostToolUseFailure | After a tool call fails |
PostToolBatch | After a full batch of parallel tool calls resolves, before the next model call |
Notification | When Claude Code sends a notification |
SubagentStart | When a subagent is spawned |
SubagentStop | When a subagent finishes |
TaskCreated | When a task is being created via TaskCreate |
TaskCompleted | When a task is being marked as completed |
Stop | When Claude finishes responding |
StopFailure | When the turn ends due to an API error. Output and exit code are ignored |
TeammateIdle | When an agent team teammate is about to go idle |
InstructionsLoaded | When a CLAUDE.md or .claude/rules/*.md file is loaded into context. Fires at session start and when files are lazily loaded during a session |
ConfigChange | When a configuration file changes during a session |
CwdChanged | When the working directory changes, for example when Claude executes a cd command. Useful for reactive environment management with tools like direnv |
FileChanged | When a watched file changes on disk. The matcher field specifies which filenames to watch |
WorktreeCreate | When a worktree is being created via --worktree or isolation: "worktree". Replaces default git behavior |
WorktreeRemove | When a worktree is being removed, either at session exit or when a subagent finishes |
PreCompact | Before context compaction |
PostCompact | After context compaction completes |
Elicitation | When an MCP server requests user input during a tool call |
ElicitationResult | After a user responds to an MCP elicitation, before the response is sent back to the server |
SessionEnd | When a session terminates |
type, der bestimmt, wie er ausgeführt wird. Die meisten Hooks verwenden "type": "command", was einen Shell-Befehl ausführt. Vier weitere Typen sind verfügbar:
"type": "http": Event-Daten an eine URL POSTen. Siehe HTTP-Hooks."type": "mcp_tool": ein Tool auf einem bereits verbundenen MCP-Server aufrufen. Siehe MCP-Tool-Hooks."type": "prompt": Single-Turn-LLM-Bewertung. Siehe Prompt-basierte Hooks."type": "agent": Multi-Turn-Verifizierung mit Tool-Zugriff. Agent-Hooks sind experimentell und können sich ändern. Siehe Agent-basierte Hooks.
Ergebnisse aus mehreren Hooks kombinieren
Wenn mehrere Hooks das gleiche Event abgleichen, wird jeder Hook-Befehl bis zur Fertigstellung ausgeführt, bevor Claude Code die Ergebnisse zusammenführt. Ein Hook, derdeny zurückgibt, stoppt nicht die Ausführung von Sibling-Hooks. Verlassen Sie sich nicht darauf, dass ein Hook’s deny Nebenwirkungen in einem anderen Hook unterdrückt.
Nachdem alle übereinstimmenden Hooks fertig sind, kombiniert Claude Code ihre Ausgaben. Für PreToolUse-Berechtigungsentscheidungen gewinnt die restriktivste Antwort: deny überschreibt ask, was allow überschreibt. Text aus additionalContext wird von jedem Hook beibehalten und zusammen an Claude übergeben.
Das folgende Beispiel registriert zwei PreToolUse-Hooks auf Bash. Der erste hängt jeden Befehl an eine Protokolldatei an und beendet sich mit 0. Der zweite führt ein Skript aus, das mit 2 beendet wird, um zu verweigern, wenn der Befehl rm -rf enthält:
rm -rf /tmp/build auszuführen, werden beide Hooks parallel ausgeführt. Der Logging-Hook schreibt den Befehl in ~/.claude/bash.log und beendet sich mit 0, was keine Entscheidung meldet. Der Guardrail-Hook beendet sich mit 2, was den Tool-Aufruf verweigert. Die Verweigerung gewinnt, sodass Claude Code den Befehl blockiert und Claude das Guardrail’s stderr zeigt. Der Log-Eintrag wird trotzdem geschrieben, weil der Logging-Hook bereits ausgeführt wurde.
Eingabe lesen und Ausgabe zurückgeben
Hooks kommunizieren mit Claude Code über stdin, stdout, stderr und Exit-Codes. Wenn ein Event ausgelöst wird, übergibt Claude Code Event-spezifische Daten als JSON an stdin Ihres Skripts. Ihr Skript liest diese Daten, führt seine Arbeit aus und teilt Claude Code mit, was als nächstes zu tun ist, über den Exit-Code.Hook-Eingabe
Jedes Event enthält gemeinsame Felder wiesession_id und cwd, aber jeder Event-Typ fügt unterschiedliche Daten hinzu. Wenn Claude beispielsweise einen Bash-Befehl ausführt, erhält ein PreToolUse-Hook etwa folgendes auf stdin:
UserPromptSubmit-Hooks erhalten stattdessen den prompt-Text, SessionStart-Hooks erhalten die source (startup, resume, clear, compact) und so weiter. Siehe Gemeinsame Eingabefelder in der Referenz für gemeinsame Felder und jeden Event-Abschnitt für Event-spezifische Schemas.
Hook-Ausgabe
Ihr Skript teilt Claude Code mit, was als nächstes zu tun ist, indem es auf stdout oder stderr schreibt und mit einem bestimmten Code beendet wird. Beispielsweise einPreToolUse-Hook, der einen Befehl blockieren möchte:
- Exit 0: die Aktion wird fortgesetzt. Für
UserPromptSubmit,UserPromptExpansionundSessionStart-Hooks wird alles, was Sie auf stdout schreiben, zu Claudes Kontext hinzugefügt. - Exit 2: die Aktion wird blockiert. Schreiben Sie einen Grund auf stderr, und Claude erhält ihn als Feedback, sodass er sich anpassen kann. Einige Events können nicht blockiert werden: Für
SessionStart,Setup,Notificationund andere zeigt exit 2 stderr dem Benutzer an und die Ausführung wird fortgesetzt. Siehe Exit-Code-2-Verhalten pro Event für die vollständige Liste. - Jeder andere Exit-Code: die Aktion wird fortgesetzt. Das Transkript zeigt eine
<hook name> hook error-Meldung gefolgt von der ersten Zeile von stderr; das vollständige stderr geht in das Debug-Protokoll.
Strukturierte JSON-Ausgabe
Exit-Codes geben Ihnen zwei Optionen: zulassen oder blockieren. Für mehr Kontrolle beenden Sie mit 0 und geben stattdessen ein JSON-Objekt auf stdout aus.Verwenden Sie exit 2, um mit einer stderr-Meldung zu blockieren, oder exit 0 mit JSON für strukturierte Kontrolle. Mischen Sie sie nicht: Claude Code ignoriert JSON, wenn Sie mit 2 beenden.
PreToolUse-Hook einen Tool-Aufruf ablehnen und Claude mitteilen, warum, oder ihn dem Benutzer zur Genehmigung eskalieren:
"deny" bricht Claude Code den Tool-Aufruf ab und gibt permissionDecisionReason an Claude als Feedback zurück. Diese permissionDecision-Werte sind spezifisch für PreToolUse:
"allow": die interaktive Berechtigungsaufforderung überspringen. Deny- und Ask-Regeln, einschließlich verwalteter Deny-Listen, gelten weiterhin"deny": Tool-Aufruf abbrechen und den Grund an Claude senden"ask": Berechtigungsaufforderung dem Benutzer wie gewohnt anzeigen
"defer", ist im nicht-interaktiven Modus mit dem Flag -p verfügbar. Er beendet den Prozess mit dem beibehaltenen Tool-Aufruf, sodass ein Agent SDK-Wrapper Eingaben sammeln und fortfahren kann. Siehe Einen Tool-Aufruf für später aufschieben in der Referenz.
Die Rückgabe von "allow" überspringt die interaktive Aufforderung, überschreibt aber nicht Berechtigungsregeln. Wenn eine Deny-Regel dem Tool-Aufruf entspricht, wird der Aufruf blockiert, auch wenn Ihr Hook "allow" zurückgibt. Wenn eine Ask-Regel entspricht, wird der Benutzer immer noch aufgefordert. Dies bedeutet, dass Deny-Regeln aus jedem Einstellungsbereich, einschließlich verwalteter Einstellungen, immer Vorrang vor Hook-Genehmigungen haben.
Andere Events verwenden unterschiedliche Entscheidungsmuster. Beispielsweise verwenden PostToolUse- und Stop-Hooks ein Top-Level-Feld decision: "block", während PermissionRequest hookSpecificOutput.decision.behavior verwendet. Siehe die Zusammenfassungstabelle in der Referenz für eine vollständige Aufschlüsselung nach Event.
Für UserPromptSubmit-Hooks verwenden Sie stattdessen additionalContext, um Text in Claudes Kontext zu injizieren. Prompt-basierte Hooks (type: "prompt") handhaben die Ausgabe anders: siehe Prompt-basierte Hooks.
Hooks mit Matchern filtern
Ohne einen Matcher wird ein Hook bei jedem Auftreten seines Events ausgelöst. Matcher ermöglichen es Ihnen, das einzugrenzen. Wenn Sie beispielsweise einen Formatter nur nach Datei-Bearbeitungen ausführen möchten (nicht nach jedem Tool-Aufruf), fügen Sie einen Matcher zu IhremPostToolUse-Hook hinzu:
"Edit|Write"-Matcher wird ausgelöst, wenn Claude das Edit- oder Write-Tool verwendet, nicht wenn es Bash, Read oder ein anderes Tool verwendet. Siehe Matcher-Muster für die Auswertung von einfachen Namen und regulären Ausdrücken.
Claude kann auch Dateien erstellen oder ändern, indem er Shell-Befehle über das
Bash-Tool ausführt. Wenn Ihr Hook jede Dateiänderung sehen muss, z. B. für Compliance-Scanning oder Audit-Protokollierung, fügen Sie einen Stop-Hook hinzu, der den Arbeitsbaum einmal pro Runde scannt. Für Pro-Aufruf-Abdeckung stattdessen auch Bash abgleichen und Ihr Skript geänderte und nicht verfolgte Dateien mit git status --porcelain auflisten.| Event | Worauf der Matcher filtert | Beispiel-Matcher-Werte |
|---|---|---|
PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDenied | Tool-Name | Bash, Edit|Write, mcp__.* |
SessionStart | wie die Sitzung gestartet wurde | startup, resume, clear, compact |
Setup | welches CLI-Flag das Setup ausgelöst hat | init, maintenance |
SessionEnd | warum die Sitzung endete | clear, resume, logout, prompt_input_exit, bypass_permissions_disabled, other |
Notification | Benachrichtigungstyp | permission_prompt, idle_prompt, auth_success, elicitation_dialog, elicitation_complete, elicitation_response |
SubagentStart | Agent-Typ | general-purpose, Explore, Plan oder benutzerdefinierte Agent-Namen |
PreCompact, PostCompact | was die Komprimierung ausgelöst hat | manual, auto |
SubagentStop | Agent-Typ | gleiche Werte wie SubagentStart |
ConfigChange | Konfigurationsquelle | user_settings, project_settings, local_settings, policy_settings, skills |
StopFailure | Fehlertyp | rate_limit, authentication_failed, oauth_org_not_allowed, billing_error, invalid_request, server_error, max_output_tokens, unknown |
InstructionsLoaded | Ladegrund | session_start, nested_traversal, path_glob_match, include, compact |
Elicitation | MCP-Servername | Ihre konfigurierten MCP-Servernamen |
ElicitationResult | MCP-Servername | gleiche Werte wie Elicitation |
FileChanged | Dateinamen zum Überwachen (siehe FileChanged) | .envrc|.env |
UserPromptExpansion | Befehlsname | Ihre Skill- oder Befehlsnamen |
UserPromptSubmit, PostToolBatch, Stop, TeammateIdle, TaskCreated, TaskCompleted, WorktreeCreate, WorktreeRemove, CwdChanged | keine Matcher-Unterstützung | wird immer bei jedem Auftreten ausgelöst |
- Jeden Bash-Befehl protokollieren
- MCP-Tools abgleichen
- Beim Sitzungsende aufräumen
Gleichen Sie nur
Bash-Tool-Aufrufe ab und protokollieren Sie jeden Befehl in einer Datei. Das PostToolUse-Event wird ausgelöst, nachdem der Befehl abgeschlossen ist, sodass tool_input.command enthält, was ausgeführt wurde. Der Hook erhält die Event-Daten als JSON auf stdin, und jq -r '.tool_input.command' extrahiert nur die Befehlszeichenfolge, die >> an die Protokolldatei anhängt:Hooks mit dem Feld if nach Tool-Name und Argumenten filtern
Das Feld
if erfordert Claude Code v2.1.85 oder später. Frühere Versionen ignorieren es und führen den Hook bei jedem abgeglichenen Aufruf aus.if verwendet Berechtigungsregel-Syntax zum Filtern von Hooks nach Tool-Name und Argumenten zusammen, sodass der Hook-Prozess nur spawnt, wenn der Tool-Aufruf übereinstimmt, oder wenn ein Bash-Befehl zu komplex ist, um ihn zu parsen. Dies geht über matcher hinaus, das nur auf Tool-Name-Ebene filtert.
Beispielsweise, um einen Hook nur auszuführen, wenn Claude git-Befehle verwendet, anstatt alle Bash-Befehle:
git * übereinstimmt, oder wenn der Befehl zu komplex ist, um ihn in Subcommands zu parsen. Für zusammengesetzte Befehle wie npm test && git push wertet Claude Code jeden Subbefehl aus und löst den Hook aus, weil git push übereinstimmt. Das Feld if akzeptiert die gleichen Muster wie Berechtigungsregeln: "Bash(git *)", "Edit(*.ts)" und so weiter. Um mehrere Tool-Namen abzugleichen, verwenden Sie separate Handler, jeder mit seinem eigenen if-Wert, oder gleichen Sie auf der matcher-Ebene ab, wo Pipe-Alternation unterstützt wird.
if funktioniert nur bei Tool-Events: PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest und PermissionDenied. Das Hinzufügen zu einem anderen Event verhindert, dass der Hook ausgeführt wird.
Hook-Speicherort konfigurieren
Wo Sie einen Hook hinzufügen, bestimmt seinen Bereich:| Speicherort | Bereich | Freigegeben |
|---|---|---|
~/.claude/settings.json | Alle Ihre Projekte | Nein, lokal auf Ihrem Computer |
.claude/settings.json | Einzelnes Projekt | Ja, kann im Repo committed werden |
.claude/settings.local.json | Einzelnes Projekt | Nein, gitignoriert |
| Verwaltete Richtlinieneinstellungen | Organisationsweit | Ja, von Admin kontrolliert |
Plugin hooks/hooks.json | Wenn Plugin aktiviert ist | Ja, mit dem Plugin gebündelt |
| Skill oder Agent Frontmatter | Während der Skill oder Agent aktiv ist | Ja, in der Komponentendatei definiert |
/hooks in Claude Code aus, um alle konfigurierten Hooks nach Event gruppiert zu durchsuchen. Um Hooks zu deaktivieren, setzen Sie "disableAllHooks": true in Ihrer Einstellungsdatei. Hooks, die in verwalteten Einstellungen konfiguriert sind, werden weiterhin ausgeführt, es sei denn, disableAllHooks ist auch dort gesetzt.
Wenn Sie Einstellungsdateien direkt bearbeiten, während Claude Code läuft, werden Hook-Änderungen normalerweise automatisch vom Datei-Watcher aufgegriffen.
Prompt-basierte Hooks
Für Entscheidungen, die Urteilsvermögen erfordern, anstatt deterministischer Regeln, verwenden Sietype: "prompt"-Hooks. Anstatt einen Shell-Befehl auszuführen, sendet Claude Code Ihren Prompt und die Hook-Eingabedaten an ein Claude-Modell (standardmäßig Haiku), um die Entscheidung zu treffen. Sie können ein anderes Modell mit dem Feld model angeben, wenn Sie mehr Leistung benötigen.
Die einzige Aufgabe des Modells ist, eine Ja/Nein-Entscheidung als JSON zurückzugeben:
"ok": true: die Aktion wird fortgesetzt"ok": false: was passiert, hängt vom Ereignis ab:StopundSubagentStop: derreasonwird an Claude zurückgegeben, sodass es weiterarbeitetPreToolUse: der Tool-Aufruf wird verweigert und derreasonwird an Claude als Tool-Fehler zurückgegeben, sodass es sich anpassen und fortfahren kannPostToolUse,PostToolBatch,UserPromptSubmitundUserPromptExpansion: der Zug endet und derreasonerscheint im Chat als Warnzeile
Stop-Hook, um das Modell zu fragen, ob alle angeforderten Aufgaben abgeschlossen sind. Wenn das Modell "ok": false zurückgibt, arbeitet Claude weiter und verwendet den reason als nächste Anweisung:
Agent-basierte Hooks
Wenn die Verifizierung das Inspizieren von Dateien oder das Ausführen von Befehlen erfordert, verwenden Sietype: "agent"-Hooks. Im Gegensatz zu Prompt-Hooks, die einen einzelnen LLM-Aufruf tätigen, spawnen Agent-Hooks einen Subagent, der Dateien lesen, Code durchsuchen und andere Tools verwenden kann, um Bedingungen zu überprüfen, bevor eine Entscheidung zurückgegeben wird.
Agent-Hooks verwenden das gleiche "ok" / "reason"-Antwortformat wie Prompt-Hooks, aber mit einem längeren Standard-Timeout von 60 Sekunden und bis zu 50 Tool-Use-Turns.
Dieses Beispiel überprüft, dass Tests bestanden werden, bevor Claude beendet werden darf:
HTTP-Hooks
Verwenden Sietype: "http"-Hooks, um Event-Daten an einen HTTP-Endpunkt zu POSTen, anstatt einen Shell-Befehl auszuführen. Der Endpunkt erhält die gleichen JSON-Daten, die ein Command-Hook auf stdin erhalten würde, und gibt Ergebnisse über den HTTP-Antwortkörper mit dem gleichen JSON-Format zurück.
HTTP-Hooks sind nützlich, wenn Sie möchten, dass ein Webserver, eine Cloud-Funktion oder ein externer Service Hook-Logik handhabt: beispielsweise ein gemeinsamer Audit-Service, der Tool-Use-Events über ein Team hinweg protokolliert.
Dieses Beispiel POSTet jeden Tool-Use an einen lokalen Logging-Service:
hookSpecificOutput-Feldern zurück. HTTP-Statuscodes allein können Aktionen nicht blockieren.
Header-Werte unterstützen Umgebungsvariablen-Interpolation mit $VAR_NAME oder ${VAR_NAME}-Syntax. Nur Variablen, die im Array allowedEnvVars aufgelistet sind, werden aufgelöst; alle anderen $VAR-Referenzen bleiben leer.
Für vollständige Konfigurationsoptionen und Response-Handling siehe HTTP-Hooks in der Referenz.
Einschränkungen und Fehlerbehebung
Einschränkungen
- Command-Hooks kommunizieren nur über stdout, stderr und Exit-Codes. Sie können
/-Befehle oder Tool-Aufrufe nicht auslösen. Text, der überadditionalContextzurückgegeben wird, wird als Systemerinnerung injiziert, die Claude als Klartext liest. HTTP-Hooks kommunizieren stattdessen über den Response-Body. - Hook-Timeouts variieren je nach Typ. Überschreiben Sie pro Hook mit dem Feld
timeoutin Sekunden.command,http,mcp_tool: 10 Minuten.UserPromptSubmitreduziert diese auf 30 Sekunden.prompt: 30 Sekunden.agent: 60 Sekunden.
PostToolUse-Hooks können Aktionen nicht rückgängig machen, da das Tool bereits ausgeführt wurde.PermissionRequest-Hooks werden nicht im nicht-interaktiven Modus (-p) ausgelöst. Verwenden SiePreToolUse-Hooks für automatisierte Berechtigungsentscheidungen.Stop-Hooks werden ausgelöst, wenn Claude antwortet, nicht nur bei Aufgabenabschluss. Sie werden nicht bei Benutzerunterbrechungen ausgelöst. API-Fehler lösen stattdessen StopFailure aus.- Wenn mehrere PreToolUse-Hooks
updatedInputzurückgeben, um die Argumente eines Tools umzuschreiben, gewinnt der letzte, der fertig wird. Da Hooks parallel ausgeführt werden, ist die Reihenfolge nicht deterministisch. Vermeiden Sie, dass mehr als ein Hook die Eingabe desselben Tools ändert.
Hooks und Berechtigungsmodi
PreToolUse-Hooks werden vor jeder Berechtigungsmodus-Überprüfung ausgelöst. Ein Hook, derpermissionDecision: "deny" zurückgibt, blockiert das Tool auch im bypassPermissions-Modus oder mit --dangerously-skip-permissions. Dies ermöglicht es Ihnen, Richtlinien durchzusetzen, die Benutzer nicht umgehen können, indem sie ihren Berechtigungsmodus ändern.
Das Gegenteil ist nicht wahr: Ein Hook, der "allow" zurückgibt, umgeht keine Deny-Regeln aus Einstellungen. Hooks können Einschränkungen verschärfen, aber nicht über das hinaus lockern, was Berechtigungsregeln zulassen.
Hook wird nicht ausgelöst
Der Hook ist konfiguriert, wird aber nie ausgeführt.- Führen Sie
/hooksaus und bestätigen Sie, dass der Hook unter dem richtigen Event angezeigt wird - Überprüfen Sie, dass das Matcher-Muster den Tool-Namen genau abgleicht (Matcher sind Groß-/Kleinschreibung-empfindlich)
- Überprüfen Sie, dass Sie den richtigen Event-Typ auslösen (z. B.
PreToolUsewird vor der Tool-Ausführung ausgelöst,PostToolUsewird danach ausgelöst) - Wenn Sie
PermissionRequest-Hooks im nicht-interaktiven Modus (-p) verwenden, wechseln Sie stattdessen zuPreToolUse
Hook-Fehler in der Ausgabe
Sie sehen eine Meldung wie “PreToolUse hook error: …” im Transkript.- Ihr Skript wurde unerwartet mit einem Nicht-Null-Code beendet. Testen Sie es manuell, indem Sie Beispiel-JSON pipen:
- Wenn Sie “command not found” sehen, verwenden Sie absolute Pfade oder
${CLAUDE_PROJECT_DIR}, um Skripte zu referenzieren. Um Shell-Quoting vollständig zu vermeiden, fügen Sie"args": []hinzu, um zur exec-Form zu wechseln, die das Skript direkt ohne eine Shell spawnt - Wenn Sie “jq: command not found” sehen, installieren Sie
jqoder verwenden Sie Python/Node.js zum Parsen von JSON - Wenn das Skript überhaupt nicht ausgeführt wird, machen Sie es ausführbar:
chmod +x ./my-hook.sh
/hooks zeigt keine konfigurierten Hooks
Sie haben eine Einstellungsdatei bearbeitet, aber die Hooks werden nicht im Menü angezeigt.
- Datei-Bearbeitungen werden normalerweise automatisch aufgegriffen. Wenn sie nach ein paar Sekunden nicht angezeigt wurden, hat der Datei-Watcher die Änderung möglicherweise verpasst: Starten Sie Ihre Sitzung neu, um ein Neuladen zu erzwingen.
- Überprüfen Sie, dass Ihr JSON gültig ist (nachfolgende Kommas und Kommentare sind nicht zulässig)
- Bestätigen Sie, dass die Einstellungsdatei am richtigen Speicherort ist:
.claude/settings.jsonfür Projekt-Hooks,~/.claude/settings.jsonfür globale Hooks
Stop-Hook läuft endlos
Claude arbeitet in einer Endlosschleife weiter, anstatt zu stoppen. Ihr Stop-Hook-Skript muss überprüfen, ob es bereits eine Fortsetzung ausgelöst hat. Parsen Sie das Feldstop_hook_active aus der JSON-Eingabe und beenden Sie früh, wenn es true ist:
JSON-Validierung fehlgeschlagen
Claude Code zeigt einen JSON-Parsing-Fehler an, obwohl Ihr Hook-Skript gültiges JSON ausgibt. Wenn Claude Code einen Shell-Form-Command-Hook ausführt (einen ohneargs), spawnt es sh -c auf macOS und Linux oder Git Bash auf Windows standardmäßig. Diese Shell ist nicht-interaktiv, aber Git Bash und einige Konfigurationen (wie BASH_ENV, das auf ~/.bashrc zeigt) sourcen trotzdem Ihr Profil. Wenn dieses Profil bedingungslose echo-Anweisungen enthält, wird die Ausgabe Ihrem Hook-JSON vorangestellt:
$- enthält Shell-Flags, und i bedeutet interaktiv. Hooks werden in nicht-interaktiven Shells ausgeführt, sodass das Echo übersprungen wird.
Debug-Techniken
Die Transkript-Ansicht, umgeschaltet mitCtrl+O, zeigt eine einzeilige Zusammenfassung für jeden Hook, der ausgelöst wurde: Erfolg ist stumm, Blockierungsfehler zeigen stderr, und Nicht-Blockierungsfehler zeigen eine <hook name> hook error-Meldung gefolgt von der ersten Zeile von stderr.
Für vollständige Ausführungsdetails einschließlich welche Hooks abgeglichen wurden, ihrer Exit-Codes, stdout und stderr, lesen Sie das Debug-Protokoll. Starten Sie Claude Code mit claude --debug-file /tmp/claude.log, um in einen bekannten Pfad zu schreiben, dann tail -f /tmp/claude.log in einem anderen Terminal. Wenn Sie ohne dieses Flag gestartet haben, führen Sie /debug während der Sitzung aus, um Logging zu aktivieren und den Protokollpfad zu finden.
Weitere Informationen
- Hooks-Referenz: vollständige Event-Schemas, JSON-Ausgabeformat, asynchrone Hooks und MCP-Tool-Hooks
- Sicherheitsüberlegungen: überprüfen Sie vor der Bereitstellung von Hooks in gemeinsamen oder Produktionsumgebungen
- Bash-Befehlsvalidator-Beispiel: vollständige Referenzimplementierung