Что такое хуки в Claude Code?
Если ты ищешь «хук что это», представь шлагбаум перед командой. Claude выбрал инструмент. До его запуска Claude Code передаёт событие локальному скрипту. Скрипт смотрит на параметры и решает, пропустить действие или остановить его.
PreToolUse работает до инструмента. Это главное для защиты. Если Claude собирается выполнить Bash-команду, хук может проверить поле tool_input.command. Если команда попала под запрет, скрипт возвращает отказ.
PostToolUse работает после инструмента. Для журнала, форматирования или проверки результата это подходит. Запись к этому моменту уже произошла, поэтому отменить её нельзя: файл мог измениться.
Ты можешь блокировать опасные команды до их выполнения» (пер. с англ.)
Хук отличается от обычной инструкции для модели. В CLAUDE.md можно написать правило: не удаляй файлы, не трогай секреты, сначала покажи план. Но это текст для модели. Она может понять его неправильно, забыть о нём или выбрать обходной путь.
Локальный скрипт проверяет событие независимо от формулировки ответа Claude. Поэтому я бы ставил эти механизмы рядом: инструкция объясняет намерение, хук ставит техническую проверку.
Хук Claude Code и веб-хук: в чём разница?

Если тебе нужен «веб хук», речь обычно идёт об отправке события наружу. Например, одна система сообщает другой о новом заказе, платеже или изменении статуса. Получатель принимает данные через сеть и выполняет свою логику.
Хук Claude Code живёт внутри процесса работы с проектом. Он запускает локальную shell-команду, получает входные данные через stdin и отвечает кодом выхода и stdout. Внешний сервер для такой проверки не нужен.
Разница видна в таблице:
| Характеристика | Локальный хук Claude Code | Веб-хук |
|---|---|---|
| Место работы | Внутри процесса Claude Code | Внешний сервер |
| Входные данные | stdin (JSON события) | HTTP-запрос |
| Может остановить инструмент до запуска | Да (PreToolUse + exit 2) | Нет |
| Требует внешний сервер | Нет | Да |
Веб-хук может отправить уведомление о событии во внешний сервис, но не остановит локальный инструмент до запуска.
Для блокировки опасных действий я выбираю локальный PreToolUse. Уведомления и интеграции с внешними системами отправляй через веб-хук. Название одинаковое, место работы разное.
Какие опасные действия можно остановить хуком?
Проблема начинается не только с ошибки Claude. Anthropic описывает approval fatigue: после большого числа запросов человек перестаёт внимательно читать каждое подтверждение и нажимает разрешение почти автоматически.
Со временем это приводит к усталости от подтверждений, когда люди перестают внимательно следить за тем, что именно они разрешают» (пер. с англ.)
Локальный хук снижает зависимость от такого внимания. Фильтр надо строить вокруг последствий, учитывая, что опасная команда может быть спрятана внутри одной строки. Команда может вызвать оболочку, интерпретатор или готовый скрипт, внутри которого находится опасное действие.
При проверке я бы держал несколько направлений:
- опасные shell-команды и цепочки команд;
python -c,node -eиbash -c;- package-manager scripts;
- удаление или перезапись файлов;
- команды Git, включая операции с удалённым репозиторием;
- обращения к секретам и чувствительным файлам;
- другие инструменты, через которые действие может попасть в файловую систему.
Я бы не давал широкие разрешения на весь Bash, Python, Node или npm run только ради удобства. В таком случае проверка теряет команды, которые способны причинить ущерб.
Я бы начинал с одного узкого правила. Например, блокировал бы конкретные операции с рабочей директорией, .env, базой или Git. Потом добавлял бы тесты на обходы. Большой regex, который никто не понимает, создаёт ложное чувство защиты.
У хука есть и собственный риск. Скрипт запускается с правами пользователя. Изменённый hook или settings.json может стать частью атаки. Конфигурацию из чужого репозитория нельзя считать безопасной только потому, что она лежит локально.
Как сделать локальный хук для блокировки?

Выбери событие перед запуском.
Нужен
PreToolUse. Он получает параметры инструмента до выполнения. Для Bash matcher должен выбирать Bash-вызовы, а сам скрипт должен работать с полемtool_input.command.Создай в проекте файл
.claude/settings.json. Подключи в нём локальный обработчик. Точная конфигурация зависит от актуального синтаксиса Claude Code, поэтому перед публикацией сверься с официальной документацией Claude Code Hooks: там полный перечень событий.json{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": ".claude/hooks/block-dangerous.sh" } ] } ] } }Подготовь локальный скрипт.
Сделай файл
.claude/hooks/block-dangerous.sh. Он получает JSON через стандартный ввод. Из него надо достать фактическое значениеtool_input.command, а не проверять только текст запроса Claude.В следующем шаблоне опасными считаются несколько очевидных направлений. Это стартовая точка для собственных проверок, а sandbox решает более широкую задачу.
bash#!/usr/bin/env bash set -euo pipefail event_json="$(cat)" command_text="$( printf '%s' "$event_json" | python -c 'import json, sys; print(json.load(sys.stdin).get("tool_input", {}).get("command", ""))' )" if printf '%s' "$command_text" | grep -Eiq \ '(^|[;&|()[:space:]])rm([[:space:]]|$)|rm[[:space:]]+-rf|python[[:space:]]+-c|node[[:space:]]+-e|bash[[:space:]]+-c|(^|[[:space:]])tee([[:space:]]|$)|(^|[[:space:]])dd([[:space:]]|$)|git[[:space:]]+push[[:space:]]+--force|\.env'; then printf '%s\n' \ 'Команда заблокирована локальным PreToolUse-хуком: проверь последствия и выбери безопасный способ.' \ >&2 exit 2 fi exit 0Код
exit 2здесь обязателен. Обычный ненулевой код не равен блокировке: в практических наблюдениях именноexit 2останавливает действие.Оставь безопасные команды штатной проверке.
В безопасной ветке скрипт не должен возвращать
permissionDecision: "allow". Не надо автоматически разрешать всё, что не совпало с фильтром.Такая логика сохраняет обычные запросы разрешений Claude Code:
- опасное совпало - вывести причину в
stderrи вернутьexit 2; - опасное не совпало - не выносить отдельное разрешение;
- дальше решение принимает штатная система разрешений.
permissionDecision: "allow"выглядит удобно, но может отключить стандартные подтверждения для остальных команд. Такой режим оставит всё остальное без вопроса и обойдёт ожидаемую защиту от опасных действий.- опасное совпало - вывести причину в
Проверь вход и отказ.
Сначала проверь, что скрипт действительно читает событие из
stdinи достаётtool_input.command. Потом вызови его с тестовым JSON, не запуская разрушительную команду.bashprintf '%s\n' '{"tool_input":{"command":"rm -rf test-directory"}}' | .claude/hooks/block-dangerous.sh printf 'exit code: %s\n' "$?"Для заблокированной команды ожидается
exit 2. Причина должна попасть вstderr. Реальное удаление в этом тесте не запускается: скрипту передаётся только JSON-текст.Сделай файл исполняемым.
Подключение в настройках не заменяет права доступа к скрипту. Дай файлу право на запуск и проверь путь.
bashchmod +x .claude/hooks/block-dangerous.sh test -x .claude/hooks/block-dangerous.shПлатформенные различия Bash, права доступа и доступность интерпретатора надо сверить с окружением. Для первого варианта я бы не добавлял сеть, внешние разрешения и автоматические коммиты. Чем меньше частей у блокировщика, тем проще понять его поведение.
Практикум полезен именно на этом переходе: там ты собираешь рабочие ограничения руками, а не просто просишь агента «не ломать проект». Хуки, разрешения и проверки становятся частью одной схемы. Пройти практикум
Практикум «Старт»
Три дня живой практики: от идеи до работающего проекта по ссылке
2 000 ₽старт 5 августа, 18:00 МСК
Как установить и проверить хук?
Если ты ищешь «установить хук», начни с пути к скрипту и .claude/settings.json. Настройка может включать событие, matcher и команду обработчика. Проверь, что путь указывает на существующий исполняемый файл.
Дальше проведи пять проверок:
- Передай тестовое событие с опасной командой. Скрипт должен вывести причину в
stderrи вернутьexit 2. - Передай тестовое событие с безопасной командой. Скрипт не должен возвращать
permissionDecision: "allow". - Запусти Claude Code и убедись, что опасное действие останавливается до Bash.
- Проверь, что безопасная команда передаётся штатной системе разрешений.
- Убедись, что
PostToolUseне используется как предохранитель: после записи он уже не отменит изменение.
Есть неприятная особенность. exit 2 точно останавливает инструмент, но Claude не всегда продолжает сценарий сам. Иногда он прекращает ответ и ждёт ручного ввода. В такой ситуации придётся самому решить, что делать дальше, или написать Claude команду продолжить после исправления.
Правильный запуск скрипта тоже не означает автоматическое продолжение работы. Хук отвечает за остановку действия. Он не обязан чинить план агента и выбирать безопасную замену.
Рабочий файл и правильный exit 2 ещё не доказывают, что защита закрывает нужную поверхность. Проверь опасную команду, безопасную команду, оболочки и другие инструменты, через которые может пройти то же действие.
Что делать, если хук пропускает опасную команду?
Совпадение по одной строке не даёт полной защиты. Команда rm -rf может исчезнуть из видимого текста и оказаться внутри интерпретатора или другого скрипта. Запись файла можно выполнить через tee, cp, mv или Git. Чтение секрета через Read не закрывает чтение через Bash.
Проверь несколько поверхностей выполнения:
- Bash-команды и цепочки с
;,&&,||; python -c,node -e,bash -c;tee,dd,cp,mv;- Git-операции;
- MCP-серверы;
- subagents;
- фоновые задачи;
- симлинки и переименованные копии;
- сам
.claude/settings.json; - сам hook-скрипт.
В сообществе Claude Code на Reddit отмечают, что хуки не являются границей безопасности: Any way for Claude Code to circumvent hooks?
Отдельно проверь конфигурацию. Если агент может изменить hook или settings.json, он способен ослабить собственную проверку. Для таких изменений нужен отдельный контроль, включая просмотр diff и подтверждение человеком.
Секреты лучше не держать в рабочей папке открытым текстом. Хук для Read контролирует конкретный вызов Read, но не все способы прочитать тот же файл. Для Bash нужна отдельная проверка.
Я бы не пытался закрыть все обходы одним regex. Сначала выбери последствия, которые нельзя допустить. Потом проверь каждый способ их вызвать. Если риск высокий, добавь sandbox и ручной контроль.
Практикум «Старт»
Три дня живой практики: от идеи до работающего проекта по ссылке
2 000 ₽старт 5 августа, 18:00 МСК
Почему хук не заменяет sandbox и обычные разрешения?

PreToolUse полезен как точечный предохранитель. Он может запретить конкретную Bash-команду до запуска. Но он не контролирует автоматически все инструменты, MCP, фоновые процессы и способы обойти строковый фильтр.
Sandbox работает иначе. Он ограничивает доступ к файлам, возможность записи за пределами рабочего каталога и сетевой доступ. Его ограничения распространяются также на программы и subprocesses, запущенные командой.
Обычная система разрешений остаётся отдельным слоем. Без permissionDecision: "allow" безопасная команда может пройти через штатное подтверждение. Человек видит действие и решает, пропускать его или нет.
Version control нужен для восстановления и проверки изменений. Он не отменяет необходимость остановить опасную команду, но помогает увидеть, что реально изменилось. Если проект уже пострадал от неосторожной правки, воспользуйся схемой из статьи Как починить проект после вайб-кодинга.
Собери слои так:
- узкий
PreToolUseдля известных опасных действий; - sandbox для уменьшения последствий;
- обычные разрешения без широкого blanket-доступа;
- version control для diff и отката;
- проверка человеком перед важными изменениями.
Anthropic формулирует этот принцип прямо:
The deterministic boundary is what gets hit when everything probabilistic misses» (пер. с англ.: «Детерминированная граница: то, что срабатывает, когда всё вероятностное промахивается»)
Хук не делает Claude Code безопасным вообще. Он закрывает выбранный риск. На этом месте я останавливаюсь: если нужна полноценная изоляция, одного скрипта недостаточно.
Вопросы и ответы
Вопросы и ответы
Что такое хук в Claude Code?
Хук - локальная shell-команда, которую Claude Code запускает до или после события. Она получает данные через stdin, отвечает через код выхода и stdout. Для блокировки опасной команды используется PreToolUse. Похожим образом ИИ-агент получает доступ к внешним инструментам через MCP.
Как устроена система хуков в Claude Code?
Система состоит из событий, matcher-правил и локальных обработчиков. Обработчик получает параметры инструмента, выполняет проверку и возвращает результат. В Claude Code появились также события PermissionRequest, PermissionDenied, ConfigChange и другие расширения. Подробнее о протоколе интеграций читай в статье MCP или Skills в Claude Code: где хранить инструкцию для повторяемой задачи в 2026.
Как добавить новый хук в проект?
Создай локальный скрипт, подключи его в .claude/settings.json, укажи событие PreToolUse, matcher инструмента и путь к обработчику. После этого проверь права доступа и тестовое событие через stdin.
Как выбрать подходящий хук для блокировки опасных изменений?
Для блокировки до выполнения лучший хук: PreToolUse. PostToolUse подходит для проверки результата или логирования, но не отменяет уже выполненную запись. Для более широкой защиты добавь sandbox и оставь обычные разрешения включёнными.
Где находятся официальные настройки хуков Claude Code?
Проектный файл .claude/settings.json: основной уровень конфигурации. Полный перечень уровней конфигурации и точные расположения пользовательских файлов надо сверять на официальной reference-странице Claude Code Hooks.
Какой скрипт использовать для хука Claude Code?
Для первого блокировщика подходит локальный Bash-скрипт без внешних разрешений и сетевых вызовов. Он читает JSON из stdin, проверяет tool_input.command, пишет причину в stderr и возвращает exit 2 при отказе.
Какая версия скрипта нужна для локального хука?
Отдельная версия скрипта не нужна: это локальный файл в проекте. Важно, чтобы Claude Code поддерживал нужное событие и формат решения. Самое раннее найденное упоминание Hooks в changelog относится к версии 1.0.54; актуальная зафиксированная версия: 2.1.223.
Что такое веб-хук и связан ли он с хуками Claude Code?
Веб-хук отправляет уведомление или данные во внешнюю систему. Локальный хук Claude Code работает внутри жизненного цикла инструмента. Название похоже, но веб-хук не заменяет PreToolUse для блокировки локальной команды.
Как установить локальный хук в Claude Code?
Подключи обработчик через конфигурацию проекта, укажи путь к скрипту и выдай ему право на запуск. После этого протестируй опасное событие без выполнения разрушительной команды и проверь безопасный сценарий.
Где проверить официальную документацию по хукам Claude Code?
Проверяй актуальную страницу Claude Code Hooks и changelog Claude Code - это официальный источник. Там сверяй структуру конфигурации, matcher, формат входного JSON и поддерживаемые решения.
Можно ли блокировать опасную команду только регулярным выражением?
Можно начать с регулярного выражения для выбранных паттернов, но полной защиты оно не даёт. Команда может пройти через интерпретатор, другую оболочку, Git, MCP, фоновые задачи или изменённую конфигурацию. Проверяй последствия и несколько поверхностей выполнения.
Источники
- Claude Code power user customization: How to configure hooks
- Claude Code Hooks documentation
- How Claude Code auto mode works
- Making Claude Code more secure and autonomous with sandboxing
- How we contain Claude across products
- Any way for Claude Code to circumvent hooks?
- When a PreToolUse hook blocks a tool call
- PostToolUse hook returns exit code 2
- PermissionDecision allow disables permission prompts
- Claude Code changelog
Практикум «Старт»
Три дня живой практики: от идеи до работающего проекта по ссылке
2 000 ₽старт 5 августа, 18:00 МСК

