Введение

Хуки Claude Code — это пользовательские команды оболочки, которые выполняются в различные моменты жизненного цикла Claude Code. Хуки обеспечивают детерминированный контроль над поведением Claude Code, гарантируя, что определенные действия всегда выполняются, а не полагаются на то, что LLM решит их запустить.

Примеры использования:

  • Уведомления: Настройте способ получения уведомлений, когда Claude Code ожидает вашего ввода или разрешения на выполнение чего-либо.
  • Автоматическое форматирование: Запускайте prettier для файлов .ts, gofmt для файлов .go и т.д. после каждого редактирования файла.
  • Логирование: Отслеживайте и подсчитывайте все выполненные команды для соответствия требованиям или отладки.
  • Обратная связь: Предоставляйте автоматическую обратную связь, когда Claude Code создает код, который не соответствует соглашениям вашей кодовой базы.
  • Пользовательские разрешения: Блокируйте изменения в производственных файлах или конфиденциальных каталогах.

Кодируя эти правила как хуки, а не инструкции в промптах, вы превращаете предложения в код уровня приложения, который выполняется каждый раз, когда это ожидается.

Хуки выполняют команды оболочки с вашими полными пользовательскими разрешениями без подтверждения. Вы несете ответственность за обеспечение безопасности ваших хуков. Anthropic не несет ответственности за любую потерю данных или повреждение системы в результате использования хуков. Ознакомьтесь с Соображениями безопасности.

Быстрый старт

В этом быстром старте вы добавите хук, который логирует команды оболочки, выполняемые Claude Code.

Предварительное требование: Установите jq для обработки JSON в командной строке.

Шаг 1: Откройте конфигурацию хуков

Выполните слэш-команду /hooks и выберите событие хука PreToolUse.

Хуки PreToolUse запускаются перед вызовами инструментов и могут блокировать их, предоставляя Claude обратную связь о том, что делать по-другому.

Шаг 2: Добавьте сопоставитель

Выберите + Add new matcher…, чтобы запускать ваш хук только для вызовов инструмента Bash.

Введите Bash в качестве сопоставителя.

Шаг 3: Добавьте хук

Выберите + Add new hook… и введите эту команду:

jq -r '"\(.tool_input.command) - \(.tool_input.description // "No description")"' >> ~/.claude/bash-command-log.txt

Шаг 4: Сохраните конфигурацию

Для места хранения выберите User settings, так как вы логируете в свой домашний каталог. Этот хук будет применяться ко всем проектам, а не только к текущему проекту.

Затем нажмите Esc, пока не вернетесь в REPL. Ваш хук теперь зарегистрирован!

Шаг 5: Проверьте ваш хук

Снова выполните /hooks или проверьте ~/.claude/settings.json, чтобы увидеть вашу конфигурацию:

"hooks": {
  "PreToolUse": [
    {
      "matcher": "Bash",
      "hooks": [
        {
          "type": "command",
          "command": "jq -r '\"\\(.tool_input.command) - \\(.tool_input.description // \"No description\")\"' >> ~/.claude/bash-command-log.txt"
        }
      ]
    }
  ]
}

Конфигурация

Хуки Claude Code настраиваются в ваших файлах настроек:

  • ~/.claude/settings.json - Пользовательские настройки
  • .claude/settings.json - Настройки проекта
  • .claude/settings.local.json - Локальные настройки проекта (не коммитятся)
  • Управляемые корпоративные настройки политики

Структура

Хуки организованы по сопоставителям, где каждый сопоставитель может иметь несколько хуков:

{
  "hooks": {
    "EventName": [
      {
        "matcher": "ToolPattern",
        "hooks": [
          {
            "type": "command",
            "command": "your-command-here"
          }
        ]
      }
    ]
  }
}
  • matcher: Шаблон для сопоставления имен инструментов (применимо только для PreToolUse и PostToolUse)
    • Простые строки сопоставляются точно: Write соответствует только инструменту Write
    • Поддерживает регулярные выражения: Edit|Write или Notebook.*
    • Если опущено или пустая строка, хуки запускаются для всех соответствующих событий
  • hooks: Массив команд для выполнения при совпадении шаблона
    • type: В настоящее время поддерживается только "command"
    • command: Команда bash для выполнения
    • timeout: (Необязательно) Время выполнения команды в секундах перед отменой всех выполняющихся хуков.

События хуков

PreToolUse

Запускается после того, как Claude создает параметры инструмента и перед обработкой вызова инструмента.

Распространенные сопоставители:

  • Task - Задачи агента
  • Bash - Команды оболочки
  • Glob - Сопоставление шаблонов файлов
  • Grep - Поиск контента
  • Read - Чтение файлов
  • Edit, MultiEdit - Редактирование файлов
  • Write - Запись файлов
  • WebFetch, WebSearch - Веб-операции

PostToolUse

Запускается сразу после успешного завершения инструмента.

Распознает те же значения сопоставителей, что и PreToolUse.

Notification

Запускается, когда Claude Code отправляет уведомления.

Stop

Запускается, когда основной агент Claude Code завершил ответ.

SubagentStop

Запускается, когда субагент Claude Code (вызов инструмента Task) завершил ответ.

Входные данные хука

Хуки получают данные JSON через stdin, содержащие информацию о сеансе и данные, специфичные для события:

{
  // Общие поля
  session_id: string
  transcript_path: string  // Путь к JSON разговора
  
  // Поля, специфичные для события
  ...
}

Входные данные PreToolUse

Точная схема для tool_input зависит от инструмента.

{
  "session_id": "abc123",
  "transcript_path": "~/.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/path/to/file.txt",
    "content": "file content"
  }
}

Входные данные PostToolUse

Точная схема для tool_input и tool_response зависит от инструмента.

{
  "session_id": "abc123",
  "transcript_path": "~/.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/path/to/file.txt",
    "content": "file content"
  },
  "tool_response": {
    "filePath": "/path/to/file.txt",
    "success": true
  }
}

Входные данные Notification

{
  "session_id": "abc123",
  "transcript_path": "~/.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "message": "Task completed successfully",
  "title": "Claude Code"
}

Входные данные Stop и SubagentStop

stop_hook_active равно true, когда Claude Code уже продолжает работу в результате хука остановки. Проверьте это значение или обработайте транскрипт, чтобы предотвратить бесконечную работу Claude Code.

{
  "session_id": "abc123",
  "transcript_path": "~/.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "stop_hook_active": true
}

Выходные данные хука

Существует два способа возврата выходных данных хуками обратно в Claude Code. Выходные данные сообщают, следует ли блокировать, и любую обратную связь, которая должна быть показана Claude и пользователю.

Простой: Код выхода

Хуки сообщают статус через коды выхода, stdout и stderr:

  • Код выхода 0: Успех. stdout показывается пользователю в режиме транскрипта (CTRL-R).
  • Код выхода 2: Блокирующая ошибка. stderr передается обратно Claude для автоматической обработки. См. поведение для каждого события хука ниже.
  • Другие коды выхода: Неблокирующая ошибка. stderr показывается пользователю и выполнение продолжается.

Напоминание: Claude Code не видит stdout, если код выхода равен 0.

Поведение кода выхода 2

Событие хукаПоведение
PreToolUseБлокирует вызов инструмента, показывает ошибку Claude
PostToolUseПоказывает ошибку Claude (инструмент уже выполнен)
NotificationНеприменимо, показывает stderr только пользователю
StopБлокирует остановку, показывает ошибку Claude
SubagentStopБлокирует остановку, показывает ошибку субагенту Claude

Расширенный: Выход JSON

Хуки могут возвращать структурированный JSON в stdout для более сложного управления:

Общие поля JSON

Все типы хуков могут включать эти необязательные поля:

{
  "continue": true, // Должен ли Claude продолжать после выполнения хука (по умолчанию: true)
  "stopReason": "string" // Сообщение, показываемое, когда continue равно false
  "suppressOutput": true, // Скрыть stdout из режима транскрипта (по умолчанию: false)
}

Если continue равно false, Claude прекращает обработку после выполнения хуков.

  • Для PreToolUse это отличается от "decision": "block", который только блокирует конкретный вызов инструмента и предоставляет автоматическую обратную связь Claude.
  • Для PostToolUse это отличается от "decision": "block", который предоставляет автоматическую обратную связь Claude.
  • Для Stop и SubagentStop это имеет приоритет над любым выходом "decision": "block".
  • Во всех случаях "continue" = false имеет приоритет над любым выходом "decision": "block".

stopReason сопровождает continue с причиной, показываемой пользователю, но не показываемой Claude.

Управление решениями PreToolUse

Хуки PreToolUse могут контролировать, продолжается ли вызов инструмента.

  • “approve” обходит систему разрешений. reason показывается пользователю, но не Claude.
  • “block” предотвращает выполнение вызова инструмента. reason показывается Claude.
  • undefined приводит к существующему потоку разрешений. reason игнорируется.
{
  "decision": "approve" | "block" | undefined,
  "reason": "Explanation for decision"
}

Управление решениями PostToolUse

Хуки PostToolUse могут контролировать, продолжается ли вызов инструмента.

  • “block” автоматически запрашивает Claude с reason.
  • undefined ничего не делает. reason игнорируется.
{
  "decision": "block" | undefined,
  "reason": "Explanation for decision"
}

Управление решениями Stop/SubagentStop

Хуки Stop и SubagentStop могут контролировать, должен ли Claude продолжать.

  • “block” предотвращает остановку Claude. Вы должны заполнить reason, чтобы Claude знал, как действовать дальше.
  • undefined позволяет Claude остановиться. reason игнорируется.
{
  "decision": "block" | undefined,
  "reason": "Must be provided when Claude is blocked from stopping"
}

Пример выхода JSON: Редактирование команд Bash

#!/usr/bin/env python3
import json
import re
import sys

# Define validation rules as a list of (regex pattern, message) tuples
VALIDATION_RULES = [
    (
        r"\bgrep\b(?!.*\|)",
        "Use 'rg' (ripgrep) instead of 'grep' for better performance and features",
    ),
    (
        r"\bfind\s+\S+\s+-name\b",
        "Use 'rg --files | rg pattern' or 'rg --files -g pattern' instead of 'find -name' for better performance",
    ),
]


def validate_command(command: str) -> list[str]:
    issues = []
    for pattern, message in VALIDATION_RULES:
        if re.search(pattern, command):
            issues.append(message)
    return issues


try:
    input_data = json.load(sys.stdin)
except json.JSONDecodeError as e:
    print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
    sys.exit(1)

tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})
command = tool_input.get("command", "")

if tool_name != "Bash" or not command:
    sys.exit(1)

# Validate the command
issues = validate_command(command)

if issues:
    for message in issues:
        print(f"• {message}", file=sys.stderr)
    # Exit code 2 blocks tool call and shows stderr to Claude
    sys.exit(2)

Работа с инструментами MCP

Хуки Claude Code бесшовно работают с инструментами Model Context Protocol (MCP). Когда серверы MCP предоставляют инструменты, они появляются со специальным шаблоном именования, который вы можете сопоставить в ваших хуках.

Именование инструментов MCP

Инструменты MCP следуют шаблону mcp__<server>__<tool>, например:

  • mcp__memory__create_entities - Инструмент создания сущностей сервера памяти
  • mcp__filesystem__read_file - Инструмент чтения файлов файловой системы
  • mcp__github__search_repositories - Инструмент поиска GitHub

Настройка хуков для инструментов MCP

Вы можете нацеливаться на конкретные инструменты MCP или целые серверы MCP:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "mcp__memory__.*",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Memory operation initiated' >> ~/mcp-operations.log"
          }
        ]
      },
      {
        "matcher": "mcp__.*__write.*",
        "hooks": [
          {
            "type": "command",
            "command": "/home/user/scripts/validate-mcp-write.py"
          }
        ]
      }
    ]
  }
}

Примеры

Форматирование кода

Автоматическое форматирование кода после изменения файлов:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "/home/user/scripts/format-code.sh"
          }
        ]
      }
    ]
  }
}

Уведомление

Настройте уведомление, которое отправляется, когда Claude Code запрашивает разрешение или когда ввод промпта стал неактивным.

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/my_custom_notifier.py"
          }
        ]
      }
    ]
  }
}

Соображения безопасности

Отказ от ответственности

ИСПОЛЬЗУЙТЕ НА СВОЙ СТРАХ И РИСК: Хуки Claude Code выполняют произвольные команды оболочки на вашей системе автоматически. Используя хуки, вы признаете, что:

  • Вы несете единоличную ответственность за команды, которые вы настраиваете
  • Хуки могут изменять, удалять или получать доступ к любым файлам, к которым имеет доступ ваша учетная запись пользователя
  • Вредоносные или плохо написанные хуки могут привести к потере данных или повреждению системы
  • Anthropic не предоставляет гарантий и не несет ответственности за любой ущерб, возникший в результате использования хуков
  • Вы должны тщательно тестировать хуки в безопасной среде перед производственным использованием

Всегда просматривайте и понимайте любые команды хуков перед добавлением их в вашу конфигурацию.

Лучшие практики безопасности

Вот несколько ключевых практик для написания более безопасных хуков:

  1. Проверяйте и очищайте входные данные - Никогда не доверяйте входным данным слепо
  2. Всегда заключайте переменные оболочки в кавычки - Используйте "$VAR", а не $VAR
  3. Блокируйте обход пути - Проверяйте наличие .. в путях файлов
  4. Используйте абсолютные пути - Указывайте полные пути для скриптов
  5. Пропускайте конфиденциальные файлы - Избегайте .env, .git/, ключей и т.д.

Безопасность конфигурации

Прямые изменения хуков в файлах настроек не вступают в силу немедленно. Claude Code:

  1. Делает снимок хуков при запуске
  2. Использует этот снимок на протяжении всего сеанса
  3. Предупреждает, если хуки изменены извне
  4. Требует проверки в меню /hooks для применения изменений

Это предотвращает влияние вредоносных изменений хуков на ваш текущий сеанс.

Детали выполнения хуков

  • Тайм-аут: Ограничение выполнения 60 секунд по умолчанию, настраивается для каждой команды.
    • Если какая-либо отдельная команда превышает время ожидания, все выполняющиеся хуки отменяются.
  • Параллелизация: Все соответствующие хуки выполняются параллельно
  • Окружение: Запускается в текущем каталоге с окружением Claude Code
  • Ввод: JSON через stdin
  • Вывод:
    • PreToolUse/PostToolUse/Stop: Прогресс показывается в транскрипте (Ctrl-R)
    • Notification: Логируется только в отладке (--debug)

Отладка

Для устранения неполадок хуков:

  1. Проверьте, отображает ли меню /hooks вашу конфигурацию
  2. Убедитесь, что ваши файлы настроек являются валидным JSON
  3. Протестируйте команды вручную
  4. Проверьте коды выхода
  5. Проверьте ожидания формата stdout и stderr
  6. Убедитесь в правильном экранировании кавычек
  7. Используйте claude --debug для отладки ваших хуков. Вывод успешного хука выглядит следующим образом.
[DEBUG] Executing hooks for PostToolUse:Write
[DEBUG] Getting matching hook commands for PostToolUse with query: Write
[DEBUG] Found 1 hook matchers in settings
[DEBUG] Matched 1 hooks for query "Write"
[DEBUG] Found 1 hook commands to execute
[DEBUG] Executing hook command: <Your command> with timeout 60000ms
[DEBUG] Hook command completed with status 0: <Your stdout>

Сообщения о прогрессе появляются в режиме транскрипта (Ctrl-R), показывая:

  • Какой хук выполняется
  • Выполняемая команда
  • Статус успеха/неудачи
  • Выходные данные или сообщения об ошибках