Hook-System
Claude Code Hooks meistern — 17 Lifecycle-Ereignisse, 3 Handler-Typen, 10+ praxisnahe Rezepte und Enterprise-Konfiguration
Auf dieser Seite
- 1. Grundkonzepte
- 2. Vollständige Ereignisliste
- 3. Handler-Typen
- 4. Konfiguration
- 5. Praxisrezepte
- Rezept 1: Automatische Formatierung nach dem Speichern einer Datei
- Rezept 2: Gefährliche Shell-Befehle blockieren
- Rezept 3: Sensible Dateien schützen
- Rezept 4: Systembenachrichtigung bei Abschluss einer Aufgabe
- Rezept 5: Slack-Benachrichtigung
- Rezept 6: ESLint-Autokorrektur
- Rezept 7: Audit-Log
- Rezept 8: Tests automatisch ausführen
- Rezept 9: Migrationsdateien schützen
- Rezept 10: Kontext beim Sitzungsstart injizieren
- 6. Enterprise Hooks
- 7. Debugging
- 8. Vergleich mit Codex Hooks
- Nächste Schritte
Hooks ermöglichen es Ihnen, eigene Logik an Schlüsselpunkten im Claude-Code-Lifecycle einzubinden — Code automatisch formatieren, gefährliche Befehle blockieren, Benachrichtigungen senden, Audit-Logs schreiben. Hooks sind einer der leistungsfähigsten Erweiterungsmechanismen von Claude Code.
1. Grundkonzepte¶
Jeder Hook besteht aus drei Teilen:
Event (When) → Matcher (Which) → Handler (What)
PreToolUse matcher: "Bash" command: "check_safety.sh"
- Event: wann es ausgelöst wird (z. B.
PreToolUse— bevor ein Tool ausgeführt wird) - Matcher: ein optionaler Tool-Namen-Filter (nur
Bash, oder nurWrite) - Handler: ein Shell-Befehl, eine Prompt-Injektion oder ein Subagent
2. Vollständige Ereignisliste¶
Kern-Ereignisse¶
| Ereignis | Auslösung | Blockierbar | Typischer Einsatz |
|---|---|---|---|
| PreToolUse | Vor der Ausführung eines Tools | Ja (Exit 2) | Sicherheitsabfangen, Argumentvalidierung |
| PostToolUse | Nach der Ausführung eines Tools | Nein | Automatische Formatierung, Logging |
| Notification | Claude sendet eine Benachrichtigung | Nein | Slack / Feishu / DingTalk-Alarme |
| Stop | Claude beendet eine Antwort | Nein | Qualitätsprüfung, automatischer Commit |
| UserPromptSubmit | Benutzer reicht einen Prompt ein | Ja | Kontextinjektion, Richtlinienprüfung |
| SessionStart | Sitzung startet | Nein | Umgebungseinrichtung, Begrüßungsnachricht |
Erweiterte Ereignisse (neu in 2026)¶
| Ereignis | Auslösung | Blockierbar | Typischer Einsatz |
|---|---|---|---|
| SubagentStop | Ein Subagent wird beendet | Nein | Subagent-Ergebnisse einsammeln |
| SubagentToolUse | Ein Subagent nutzt ein Tool | Ja | Subagent-Berechtigungen einschränken |
| FileChanged | Eine Datei wird geändert | Nein | Automatisches Linting, Build auslösen |
| CwdChanged | Arbeitsverzeichnis wechselt | Nein | Verzeichnis-spezifische Konfiguration laden |
| ModelChange | Modell wird gewechselt | Nein | Modellnutzung nachverfolgen |
| CompactComplete | /compact wird beendet | Nein | Nachverarbeitung nach Compaction |
| ToolError | Ein Tool wirft einen Fehler | Nein | Fehlererfassung, Retry-Logik |
3. Handler-Typen¶
Typ 1: Command (Shell-Befehl)¶
Der häufigste Typ — führt einen Shell-Befehl aus:
{
"type": "command",
"command": "npx prettier --write $FILEPATH"
}
Umgebungsvariablen:
| Variable | Bedeutung | Verfügbar in |
|------|------|---------|
| $FILEPATH | Pfad der bearbeiteten Datei | PreToolUse/PostToolUse |
| $TOOL_INPUT | Tool-Eingabe als JSON | PreToolUse |
| $TOOL_NAME | Tool-Name | PreToolUse/PostToolUse |
| $SESSION_ID | Sitzungs-ID | Alle |
| $NOTIFICATION_MESSAGE | Benachrichtigungstext | Notification |
stdin-Eingabe: Ein Hook-Skript empfängt zusätzlich einen JSON-Payload auf stdin mit session_id, tool_name und tool_input. Nutzen Sie diesen, wenn Sie strukturierte Daten benötigen — er ist zuverlässiger als das Parsen der Umgebungsvariablen.
Exit-Codes:
0: fortsetzen2: Operation blockieren (nur PreToolUse/UserPromptSubmit)- jeder andere Wert: wird als Fehler behandelt, blockiert aber nicht
Typ 2: Prompt (Prompt-Injektion)¶
Injiziert Text in den Claude-Kontext:
{
"type": "prompt",
"prompt": "Remember: every database operation must use a transaction"
}
Nützlich für: zusätzliche Projektregeln beim SessionStart injizieren.
Typ 3: Subagent¶
Startet einen Subagent zur Verarbeitung des Ereignisses:
{
"type": "subagent",
"prompt": "Review the code that was just modified and check for security vulnerabilities"
}
Nützlich für: automatische Code-Qualitätsprüfung nach PostToolUse.
4. Konfiguration¶
Konfiguration in .claude/settings.json (Projekt-Ebene) oder ~/.claude/settings.json (Benutzer-Ebene):
{
"hooks": {
"EventName": [
{
"matcher": "tool name (optional, | separates several)",
"hooks": [
{
"type": "command|prompt|subagent",
"command": "..."
}
]
}
]
}
}
5. Praxisrezepte¶
Rezept 1: Automatische Formatierung nach dem Speichern einer Datei¶
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write $FILEPATH 2>/dev/null || true"
}
]
}
]
}
}
Rezept 2: Gefährliche Shell-Befehle blockieren¶
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo $TOOL_INPUT | grep -qE 'rm -rf /|sudo rm|git push --force|DROP TABLE|DROP DATABASE' && echo 'dangerous command blocked' && exit 2 || exit 0"
}
]
}
]
}
}
Rezept 3: Sensible Dateien schützen¶
{
"hooks": {
"PreToolUse": [
{
"matcher": "Read|Write|Edit",
"hooks": [
{
"type": "command",
"command": "echo $TOOL_INPUT | grep -qE '\\.env|\\.env\\.|credentials|secrets?\\.ya?ml|private.key' && echo 'access to a sensitive file blocked' && exit 2 || exit 0"
}
]
}
]
}
}
Rezept 4: Systembenachrichtigung bei Abschluss einer Aufgabe¶
macOS:
{
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"$NOTIFICATION_MESSAGE\" with title \"Claude Code\"'"
}
]
}
]
}
}
Linux:
{
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude Code' \"$NOTIFICATION_MESSAGE\""
}
]
}
]
}
}
Rezept 5: Slack-Benachrichtigung¶
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "curl -s -X POST https://hooks.slack.com/services/xxx/yyy/zzz -H 'Content-Type: application/json' -d '{\"text\": \"Claude Code task finished\"}'"
}
]
}
]
}
}
Rezept 6: ESLint-Autokorrektur¶
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npx eslint --fix $FILEPATH 2>/dev/null; npx prettier --write $FILEPATH 2>/dev/null; exit 0"
}
]
}
]
}
}
Rezept 7: Audit-Log¶
{
"hooks": {
"PostToolUse": [
{
"hooks": [
{
"type": "command",
"command": "echo \"$(date -u +%Y-%m-%dT%H:%M:%SZ) | session=$SESSION_ID | tool=$TOOL_NAME | file=$FILEPATH\" >> ~/.claude/audit.log"
}
]
}
]
}
}
Rezept 8: Tests automatisch ausführen¶
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "echo $FILEPATH | grep -qE '\\.(ts|tsx|js|jsx)$' && echo $FILEPATH | grep -qvE '\\.test\\.|\\.spec\\.' && npx vitest related $FILEPATH --run 2>/dev/null || exit 0"
}
]
}
]
}
}
Rezept 9: Migrationsdateien schützen¶
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "echo $FILEPATH | grep -qE 'migrations/|alembic/versions/' && echo 'editing an existing migration is not allowed, create a new one' && exit 2 || exit 0"
}
]
}
]
}
}
Rezept 10: Kontext beim Sitzungsstart injizieren¶
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Important: this project is mid-way through a v3.0 rewrite. All new code must use React Server Components; the pages/ directory is no longer supported."
}
]
}
]
}
}
6. Enterprise Hooks¶
managed-settings.d/-Konfiguration¶
Enterprise-Administratoren können eine unternehmensweite Sicherheitsrichtlinie über das Verzeichnis managed-settings.d/ durchsetzen:
# Create a policy file in the enterprise management directory
mkdir -p /etc/claude-code/managed-settings.d/
// /etc/claude-code/managed-settings.d/security.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/opt/claude-policy/check_command.sh"
}
]
}
],
"PostToolUse": [
{
"hooks": [
{
"type": "command",
"command": "/opt/claude-policy/audit_log.sh"
}
]
}
]
}
}
Eine Enterprise-Richtlinie kann nicht durch Benutzer- oder Projektkonfiguration außer Kraft gesetzt werden.
7. Debugging¶
Ausführlicher Modus¶
Drücken Sie Ctrl+O, um den ausführlichen Modus zu aktivieren. Dieser zeigt:
- wann jeder Hook ausgelöst wird
- stdout/stderr des Hook-Skripts
- den Exit-Code des Hooks
Häufige Probleme¶
| Problem | Ursache | Lösung |
|---|---|---|
| Der Hook wird nie ausgelöst | Tippfehler im Matcher | Groß-/Kleinschreibung des Tool-Namens prüfen: Bash, Write, Edit, Read |
| Der Hook blockiert reguläre Arbeit | Die Exit-Code-Logik ist falsch | Sicherstellen, dass der reguläre Pfad exit 0 ist und nur mit exit 2 blockiert wird |
| Der Hook ist langsam | Das Skript dauert zu lange | Ein Hook sollte in 1–2 Sekunden abgeschlossen sein; lange Aufgaben im Hintergrund ausführen |
| Eine Umgebungsvariable ist leer | Dieses Ereignis stellt sie nicht bereit | Prüfen Sie die obige Tabelle, welche Variablen das Ereignis bereitstellt |
Das Hook-Skript testen¶
Testen Sie es manuell im Terminal, bevor Sie es in die Konfiguration aufnehmen:
# Simulate the PreToolUse environment variables
FILEPATH="src/main.ts" TOOL_INPUT="rm -rf /" bash -c 'echo $TOOL_INPUT | grep -qE "rm -rf" && echo "blocked" && exit 2 || exit 0'
8. Vergleich mit Codex Hooks¶
| Claude Code Hooks | Codex Hooks | |
|---|---|---|
| Anzahl der Ereignisse | 17 | Weniger |
| Konfiguration | settings.json | config.toml |
| Handler-Typen | command/prompt/subagent | command |
| Enterprise-Verwaltung | managed-settings.d/ | Keine |
| Blockierung | Exit-Code 2 | Begrenzt |
Nächste Schritte¶
- Skills — ein erweiterter Mechanismus für Erweiterungen
- MCP-Server — externe Tools anbinden
- Automation & CI/CD — den Headless-Modus nutzen
- CLI-Tipps — Techniken für die Befehlszeile