Claude Code Hooks 2026: Automatisierung auf Systemebene

Hooks sind das versteckteste und mächtigste Feature von Claude Code. Mit vier Hook-Typen kannst du Shell-Befehle bei jedem Tool-Aufruf, nach jeder Antwort und beim Session-Ende automatisch ausführen — ohne ein einziges Wort an Claude.

Was sind Hooks?

Hooks sind Shell-Befehle, die Claude Code automatisch zu bestimmten Zeitpunkten ausführt — unabhängig davon, was Claude gerade macht. Sie laufen im Hintergrund und können:

Warum ist das mächtig? Hooks laufen deterministisch — sie werden immer ausgeführt, egal was Claude entscheidet. Das ist der Unterschied zwischen "ich bitte Claude, zu testen" und "Tests laufen immer, ob Claude will oder nicht".

Hooks sind seit Anfang 2026 offiziell dokumentiert und in allen Claude Code Versionen ab 1.x verfügbar. In Deutschland sind sie kaum bekannt — die meisten Nutzer kennen nur CLAUDE.md und Tool-Konfiguration.

Die vier Hook-Typen

Hook-Typ Wann ausgeführt Typischer Einsatz
PreToolUse Bevor Claude ein Tool aufruft (Bash, Edit, Write…) Logging, Validierung, Blockierung gefährlicher Befehle
PostToolUse Nachdem ein Tool-Aufruf abgeschlossen ist Linting, Tests, Auto-Commit nach Dateiänderungen
Stop Wenn Claude eine Antwort beendet hat Session-Cleanup, Zusammenfassung, Heartbeat-Reset
Notification Bei internen Claude-Benachrichtigungen Desktop-Alerts, Telegram-Pings, Slack-Nachrichten

Hooks konfigurieren

Hooks werden in der settings.json konfiguriert. Je nach Scope gibt es drei Speicherorte:

# 1. Global (gilt für alle Projekte)
~/.claude/settings.json

# 2. Projekt-lokal (gilt nur im aktuellen Projekt)
.claude/settings.json

# 3. Projekt-lokal, nicht in Git (sensitive Hooks)
.claude/settings.local.json

Die Grundstruktur einer Hook-Konfiguration:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo \"Claude führt Bash aus: $CLAUDE_TOOL_INPUT\" >> /tmp/bash.log"
          }
        ]
      }
    ]
  }
}

Das matcher-Feld akzeptiert Tool-Namen ("Bash", "Edit", "Write") oder "*" für alle Tools. Der Befehl bekommt Umgebungsvariablen mit Kontext:

VariableInhalt
$CLAUDE_TOOL_NAMEName des aufgerufenen Tools (z.B. "Bash")
$CLAUDE_TOOL_INPUTJSON mit den Tool-Parametern
$CLAUDE_SESSION_IDAktuelle Session-ID
$CLAUDE_CWDAktuelles Arbeitsverzeichnis

7 praktische Hook-Beispiele

1. Vollständiges Bash-Logging

Jeder Bash-Befehl, den Claude ausführt, wird mit Timestamp in eine Log-Datei geschrieben. Unverzichtbar für Audits und Debugging.

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "echo \"[$(date -u +%H:%M:%S)] BASH: $CLAUDE_TOOL_INPUT\" >> /logs/agent.log"
      }]
    }]
  }
}

2. Auto-Lint nach Dateiänderungen

Nach jedem Edit oder Write führt Claude automatisch ESLint aus. Keine manuellen Lint-Befehle mehr.

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit",
      "hooks": [{
        "type": "command",
        "command": "cd $CLAUDE_CWD && npx eslint --fix $(echo $CLAUDE_TOOL_INPUT | jq -r '.file_path') 2>&1 || true"
      }]
    }]
  }
}

3. Gefährliche Befehle blockieren

Exit-Code 2 aus einem PreToolUse-Hook blockiert den Tool-Aufruf vollständig. Nützlich um destruktive Befehle zu verhindern.

# hook-guard.sh
#!/bin/bash
CMD=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command // ""')

# rm -rf auf wichtige Verzeichnisse verhindern
if echo "$CMD" | grep -qE "rm -rf.*(home|root|var|etc)"; then
  echo "BLOCKED: Gefährlicher rm-Befehl verweigert" >&2
  exit 2
fi

# git push --force auf main/master verhindern
if echo "$CMD" | grep -qE "git push.+--force.+(main|master)"; then
  echo "BLOCKED: Force-Push auf main/master verboten" >&2
  exit 2
fi

exit 0
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "bash /home/user/hooks/hook-guard.sh"
      }]
    }]
  }
}

4. Auto-Commit bei Session-Ende

Der Stop-Hook wird aufgerufen wenn Claude fertig ist. Perfekt für automatische Commits nach jeder Arbeitssession.

{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "cd $CLAUDE_CWD && git add -A && git diff --staged --quiet || git commit -m '[auto] Claude Session $(date +%Y-%m-%d-%H%M)'"
      }]
    }]
  }
}

5. Tests nach jedem Schreibvorgang

Nach jedem Write auf Test-Dateien läuft pytest automatisch. Claude sieht das Ergebnis und kann sofort iterieren.

# test-runner-hook.sh
#!/bin/bash
FILE=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.file_path // ""')

# Nur für Python-Dateien
if [[ "$FILE" == *.py ]]; then
  cd $CLAUDE_CWD
  python -m pytest tests/ -x -q --tb=short 2>&1 | tail -20
fi
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Write",
      "hooks": [{
        "type": "command",
        "command": "bash /home/user/hooks/test-runner-hook.sh"
      }]
    }]
  }
}

6. Telegram-Benachrichtigung bei Abschluss

Nach jeder Claude-Antwort (Stop-Hook) wird eine Telegram-Nachricht geschickt. Ideal für lang laufende Agentenaufgaben.

# telegram-notify.sh
#!/bin/bash
BOT_TOKEN="$TELEGRAM_BOT_TOKEN"
CHAT_ID="$TELEGRAM_CHAT_ID"
MSG="✅ Claude fertig in $CLAUDE_CWD — $(date +%H:%M)"

curl -s "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
  -d "chat_id=${CHAT_ID}" \
  -d "text=${MSG}" > /dev/null

7. Heartbeat-System für autonome Agenten

In Multi-Agent-Systemen muss jeder Agent regelmäßig seinen Status melden. Ein Stop-Hook aktualisiert automatisch die Heartbeat-Datei.

{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "python3 -c \"import json,time; open('/tmp/agent_heartbeat.json','w').write(json.dumps({'epoch':int(time.time()),'status':'idle','session':'$CLAUDE_SESSION_ID'}))\""
      }]
    }]
  }
}

Sicherheit und Exit-Codes

Hooks haben direkten Einfluss auf Claude Code. Die wichtigsten Regeln:

Exit-Code-Semantik:
0 — Hook erfolgreich, Claude fährt fort
1 — Hook-Fehler, wird an Claude gemeldet (aber Claude fährt fort)
2 — Tool-Aufruf wird BLOCKIERT (nur PreToolUse)

Hooks + CLAUDE.md kombinieren

Die mächtigste Kombination: Hooks übernehmen deterministisches Verhalten, CLAUDE.md definiert das Reasoning. Beispiel aus unserer Produktions-Infrastruktur:

# CLAUDE.md (Verhaltensebene)
## Commit-Regeln
- Nach jedem abgeschlossenen Task committen
- Format: [rolle] task-N: kurze Beschreibung
- Niemals mehr als 5 Dateien pro Commit

# settings.json (Enforcement-Ebene)
{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "bash ~/.claude/hooks/auto-commit.sh"
      }]
    }],
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "bash ~/.claude/hooks/bash-guard.sh"
      }]
    }]
  }
}

Das Ergebnis: CLAUDE.md sagt Claude wie es denken soll, Hooks stellen sicher dass bestimmte Aktionen immer passieren — unabhängig vom Reasoning.

Hooks in echten Agenten-Systemen erleben

In unserem Kurs zeigen wir, wie wir Hooks in einer Produktions-Infrastruktur mit 20+ Agenten einsetzen — Heartbeat-System, Auto-Commits, Safety-Guards und Telegram-Alerts inklusive.

14 Tage kostenlos testen →

Häufige Fehler mit Hooks

1. Hook blockiert Claude dauerhaft

Ein fehlerhafter PreToolUse-Hook der immer Exit-Code 2 zurückgibt, blockiert alle Tool-Aufrufe. Lösung: Hooks immer lokal testen bevor sie aktiviert werden. bash hook-script.sh direkt im Terminal ausführen.

2. Sensitive Daten in settings.json

API-Keys direkt in der Hook-Konfiguration landen schnell im Git. Besser: Umgebungsvariablen in settings.local.json und diese Datei in .gitignore.

3. Hook-Output überlädt Claudes Kontext

Wenn ein Hook sehr viel Output produziert, wird dieser als Kontext an Claude übergeben — und belegt Context-Window. Hooks sollten daher nur relevante, kurze Ausgaben produzieren. Verbose-Output umleiten: command >> /log/file 2>&1; echo "OK"