Хуки Claude Code — це користувацькі shell-команди (а також HTTP-ендпоінти і промпти), які агент запускає автоматично в конкретних точках свого життєвого циклу: перед викликом інструмента, після запису файлу, на старті сесії, коли зупиняється. Головна відмінність від промпта чи навички: хук спрацьовує гарантовано, а не «якщо модель вирішить». Це найпотужніший важіль налаштування Claude Code — і водночас найнебезпечніший, бо командний хук виконується з повними правами вашого користувача в системі.
- Що таке хуки і навіщо вони потрібні
- Як оголосити хук у settings.json
- Події життєвого циклу: 30 точок, з яких ходових — десяток
- Exit-коди і як хук блокує дію
- Три робочі рецепти: формат, гейт на секрети, сповіщення
- Де ламається: шари захисту та їхні слабкі місця
- Безпека і ризики: хук — це довільний код з повними правами
- FAQ
Хуки — швидкозмінна частина Claude Code: офіційний перелік подій уже виріс приблизно до 30, тому будь-який гайд на цю тему має термін придатності, і дату звірки варто тримати в голові.
Нижче — робоча ментальна модель механізму, розбір settings.json з прикладами JSON, повна логіка exit-кодів, три перевірені за документацією рецепти і чесний розбір ризиків із датованими інцидентами, а не загальними словами «будьте обережні з shell».
Що таке хуки і навіщо вони потрібні
Хук — це зв’язка «подія → умова → дія». Коли в Claude Code настає подія (наприклад, агент збирається виконати bash-команду), система перевіряє ваші налаштування, і якщо умова збіглася, запускає задану команду. Офіційна документація формулює суть через одне слово — детермінізм: хуки дають передбачуваний контроль над поведінкою агента, гарантуючи, що потрібна дія станеться завжди, а не залежатиме від того, чи «згадає» модель про інструкцію.
Це ключова межа між хуком і сусідніми механізмами розширення. Навичка (skill) — інструкція, якій модель може дотриматись, а може й ні. MCP-інструмент — функція, яку модель викличе, якщо визнає за потрібне. Хук же не питає модель: умова виконана — команда запущена. Таку саму логіку детермінованого контролю незалежно описують і російськомовні розбори теми, і офіційний гайд Anthropic.
Практичний висновок: хуки потрібні там, де «попросити модель» недостатньо надійно. Автоформатування коду, заборона правити секрети, запуск тестів, аудит-лог кожної команди, сповіщення на телефон — усе це має відбуватися щоразу, а не через раз.Механізм Хто вирішує, запускати Коли обирати Хук Умова в settings.json (детерміновано) Дія зобов’язана статися завжди: формат, гейт, лог Навичка (skill) Модель — за контекстом Потрібна гнучка процедура, де доречне судження моделі MCP-інструмент Модель — викликає за потреби Доступ до зовнішніх даних і API як до інструмента Субагент Модель — делегує завдання Важка ізольована робота в окремому контексті Sandboxing / permission-правила Рушій Claude Code Обмежити файли й мережу, дозволити/заборонити інструмент
Ще один недооцінений плюс: командні та HTTP-хуки майже не витрачають токени моделі. Форматувальник, лінтер чи перевірка запускаються як звичайний процес ОС, а не як міркування LLM — спільнота прямо цінує це як «автоматизацію за нуль токенів». Навичка чи субагент на те саме завдання з’їли б частину контекстного вікна; хук — ні.
Хуки з’явилися в Claude Code не одразу: за офіційним CHANGELOG репозиторію anthropics/claude-code їх випустили у версії v1.0.38. Це той випадок, коли точну версію релізу корисно знати — майже жоден сторонній гайд її не називає, а вона пояснює, чому перелік подій відтоді так розрісся.
Як оголосити хук у settings.json
Хуки описуються декларативно у файлі settings.json. Конфігурація має три рівні вкладеності, і розуміння цієї структури знімає більшу частину запитань:
- Подія — на що реагуємо (
PreToolUse,PostToolUse,Stopтощо). - Matcher-група — фільтр, коли саме спрацьовувати (наприклад, «лише для інструмента Bash»).
- Обробники (handlers) — одна чи кілька команд, які запускаються при збігу.
Мінімальний приклад: перед кожним викликом Bash проганяти власний скрипт-перевірку.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/Users/me/.claude/hooks/check-bash.sh"
}
]
}
]
}
}
Поле matcher трактується за простими правилами. Порожнє, "*" або відсутнє — збігається завжди. Рядок лише з літер, цифр, _, -, пробілів, ком і | — точний збіг або список точних значень через | (наприклад, "Edit|Write"). Будь-який інший символ перетворює значення на JavaScript-регулярний вираз без якорів — зручно, але легко вистрелити собі в ногу, якщо не пам’ятати про це.
Обробник буває п’яти типів: command (shell-команда), http (POST на ендпоінт), mcp_tool, prompt і agent. У переважній більшості практичних випадків ви пишете саме command.
Де лежить файл — визначає область дії хука. Це важливо з погляду безпеки: хук із чужого репозиторію діє так само, як ваш власний.Розташування Область Комітиться в репозиторій ~/.claude/settings.jsonУсі ваші проєкти Ні, локально на машині .claude/settings.jsonОдин проєкт Так, потрапляє в git .claude/settings.local.jsonОдин проєкт Ні, у .gitignoreManaged policy settings Уся організація Задає адміністратор hooks/hooks.json плагінаПроєкти з плагіном Через маркетплейс плагінів Frontmatter навички/субагента При активації навички Разом із навичкою
Перевірити, які хуки взагалі зареєстровані, допомагає вбудована команда /hooks — вона відкриває read-only список усіх подій із числом хуків, matcher’ами, типом і файлом-джерелом. Змінювати хуки просто з меню не можна: лише правкою JSON або через прохання до агента.
Події життєвого циклу: 30 точок, з яких ходових — десяток
Ось той самий розрив, який важливо зафіксувати явно. Більшість туторіалів 2026 року перелічують 9–13 «подій життєвого циклу»: один із топових англомовних гайдів прямо озаглавлений «All 12 Lifecycle Events». Актуальний офіційний reference на липень 2026 року містить їх близько 30 — від SessionStart і Setup до Elicitation і SessionEnd. Це не помилка авторів гайдів, а протухання контенту: перелік розширюється швидше, ніж матеріали встигають оновлюватися. Повну таблицю тримає першоджерело; тут — ходові події, які закривають майже всі реальні сценарії.Подія Коли спрацьовує Може заблокувати дію SessionStartСтарт сесії Claude Code — UserPromptSubmitКористувач надіслав запит Так (може відхилити/доповнити промпт) PreToolUseПеред викликом будь-якого інструмента Так — єдине з повним контролем рішення PostToolUseОдразу після виконання інструмента Ні — інструмент уже відпрацював NotificationАгент чекає на відповідь/дозвіл — StopАгент завершує хід Так (може повернути його в роботу) SubagentStopЗавершився субагент Так PreCompactПеред стисненням контексту — SessionEndКінець сесії —
Події зручно ділити за кадансом — як часто вони спрацьовують. Офіційний reference виділяє три групи: раз на сесію (SessionStart, SessionEnd), раз на хід (UserPromptSubmit, Stop, StopFailure) і на кожен виклик інструмента всередині агентного циклу (PreToolUse, PostToolUse). Це одразу підказує, де хук смикатиметься десятки разів за завдання (і має бути швидким), а де — одноразово.
Практичний кістяк: PreToolUse — для заборон і перевірок до дії; PostToolUse — для реакції після (формат, тести); Notification — щоб не пропустити, що агент вас чекає; Stop — щоб не дати завершити, поки не виконано умову; SessionStart — щоб підвантажити контекст. Решта подій існує під тонкі сценарії, і лізти в них варто, лише коли ходових не вистачає.
Exit-коди і як хук блокує дію
Хук спілкується з Claude Code двома каналами: кодом повернення процесу і JSON на stdout. Почнемо з кодів — тут у конкурентів трапляється пряма помилка.
- Exit 0 — успіх. Claude Code читає stdout; якщо там валідний JSON, він його розбирає та враховує.
- Exit 2 — блокувальна помилка. Для
PreToolUseце скасовує виклик інструмента; stdout ігнорується, а текст зі stderr передається моделі як причина відмови. - Будь-який інший код — неблокувальна помилка для більшості подій (виняток —
WorktreeCreate, де будь-який ненульовий код скасовує операцію).
Тут важлива поправка до поширеного джерела: популярний туторіал DataCamp приписує коду exit 3 значення «Deferred execution». В офіційному reference такого коду немає — є лише 0, 2 і «інше». Слово «defer» в документації стосується поля permissionDecision, а не коду повернення. Якщо ви читали про «exit 3» — це неточний переказ, не закладайте його у свої скрипти.
Точний контроль над дозволами дає не код, а JSON. У події PreToolUse є унікальна можливість: повернути в hookSpecificOutput.permissionDecision одне з чотирьох рішень — allow (пропустити без запиту), deny (заборонити виклик), ask (запитати користувача) або defer (акуратно вийти, не втручаючись). Якщо кілька PreToolUse-хуків повернули різні рішення, пріоритет такий: deny > defer > ask > allow. Приклад відповіді, яка жорстко блокує команду:
{
"hookSpecificOutput": {
"permissionDecision": "deny",
"permissionDecisionReason": "Правка .env заборонена політикою проєкту"
}
}
На вхід кожен командний хук отримує JSON через stdin. Спільні для всіх подій поля: session_id, prompt_id, transcript_path (шлях до JSON-транскрипту розмови), cwd, permission_mode і hook_event_name; для подій-інструментів додаються tool_name і tool_input. HTTP-хуки отримують той самий JSON тілом POST-запиту. Звідси просте правило: скрипт-хук читає stdin, парсить потрібні поля і вирішує, що робити.
Окремо про PostToolUse: він не може відкотити вже виконану дію. Exit 2 покаже моделі ваш stderr як зворотний зв’язок, але інструмент до цього моменту вже відпрацював. Тому заборони вішають на PreToolUse (до дії), а PostToolUse використовують для того, що доречно робити після — форматування, запуску перевірок, логування.
Три робочі рецепти: формат, гейт на секрети, сповіщення
Нижче — три готові сценарії, зібрані за офіційним guide. Кожен — це command-хук; шлях до скрипта підставте свій.
1. Автоформатування після Edit/Write. Класичний PostToolUse: щойно агент записав файл, проганяємо форматувальник. Економить рев’ю і тримає стиль рівним — і все це за нуль токенів моделі.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" }
]
}
]
}
}
2. Блокування правки .env та інших захищених файлів. Це PreToolUse з рішенням deny. Скрипт читає tool_input зі stdin, дивиться шлях і, якщо він веде до секрету або в .git, повертає exit 2 з причиною в stderr (або JSON із permissionDecision: deny). Агент не зможе торкнутися файлу, навіть якщо «дуже захоче» — на відміну від текстової інструкції в промпті, яку модель може проігнорувати.
3. Десктоп-сповіщення, коли агент чекає на вас. Подія Notification спрацьовує, коли Claude Code зупинився в очікуванні відповіді або дозволу. Хук на macOS може смикнути системний банер:
{
"hooks": {
"Notification": [
{
"matcher": "*",
"hooks": [
{ "type": "command", "command": "osascript -e 'display notification \"Claude чекає на відповідь\" with title \"Claude Code\"'" }
]
}
]
}
}
Для тривалих завдань є важлива деталь. За замовчуванням хук блокує роботу агента, поки не завершиться. Якщо перевірка важка (повний прогін тестів, деплой), задайте в command-хука поле "async": true — він піде у фон, а агент продовжить роботу; таймаут за замовчуванням — 10 хвилин. Додаткове поле "asyncRewake": true «розбудить» агента, якщо фоновий хук завершиться з exit 2. Цю зв’язку майже не описують у гайдах, хоча саме вона дозволяє вбудувати тривалі перевірки без просідання швидкості роботи.
Скільки це коштує? Не в токенах (їх хуки майже не витрачають), а в праці на налаштування і в ризику зламати потік. Корисно оцінювати хуки за цією рамкою до впровадження:Хук Що дає Що зламає при помилці у скрипті Автоформат ( PostToolUse)Єдиний стиль без ручного рев’ю Зіпсований файл, якщо форматувальник падає Гейт на секрети ( PreToolUse deny)Заборона правити .env/.gitХибні блокування, агент «застрягає» Сповіщення ( Notification)Не пропустити очікування агента Спам банерів при частих паузах Async-перевірка (тести/деплой) Тривалі гейти без блокування Непомічений провал, якщо забути asyncRewake
Де ламається: шари захисту та їхні слабкі місця
Тут найчастіша прогалина конкурентів: хуки подають як єдиний абсолютний бар’єр. Насправді захист багатошаровий, і в кожного шару своя межа.
Хук-deny сильніший за режим обходу прав. PreToolUse-хуки спрацьовують до перевірки режиму дозволів. Хук, що повернув permissionDecision: deny, блокує інструмент навіть у режимі bypassPermissions і з прапорцем --dangerously-skip-permissions. Зворотне неправильне: allow від хука не скасовує deny-правила з налаштувань. Тобто для жорсткої заборони PreToolUse-хук надійніший, ніж правила дозволів самі по собі.
Чому це не абстракція — показав суміжний баг. Adversa AI 2 квітня 2026 року описала, що легасі regex-парсер Claude Code переставав застосовувати deny-правила дозволів, якщо bash-команда містила понад 50 підкоманд (через &&, || або ;), і падав у загальний дозвільний запит. Виправлений парсер існував у кодовій базі, але на дату звіту не був у публічній збірці. Практичний висновок рівно той самий: для критичних заборон спирайтеся на PreToolUse-хук, а не лише на allow/deny в settings.json.
Але й хук — не бетон. Усередині обробника є best-effort фільтр if, яким зручно обмежувати спрацьовування за вмістом bash-команди. Офіційна документація чесно попереджає: цей фільтр fail-open — якщо команду не вдалося розпарсити, хук запуститься в будь-якому разі. Багато практиків інтуїтивно вважають if жорсткою стіною; для справжнього hard-deny документація прямо рекомендує permission-систему, а не фільтр у хуку.
Stop-хук може залипнути. Хук на події Stop вміє повертати агента в роботу, поки не виконано умову — але це ж створює ризик нескінченного циклу. Захист вбудований: Claude Code примусово завершує хід після 8 поспіль блокувань Stop-хуком без прогресу. Якщо вашій перевірці легітимно потрібно більше ітерацій, ліміт піднімається змінною оточення CLAUDE_CODE_STOP_HOOK_BLOCK_CAP.
Це той клас завдань, де детермінований хук чесніший за агентну автоматизацію: одна річ — навичка, яка веде базу знань і сама вирішує, що і коли записати, і зовсім інша — жорсткий гейт, який зобов’язаний спрацювати при кожному коміті. Якщо вам потрібен не гарантований тригер, а гнучкий автономний помічник — це вже інший клас інструмента, і хук тут не заміна.
Безпека і ризики: хук — це довільний код з повними правами
Головна теза розділу пряма: командний хук виконується з повними правами вашого системного користувача. Офіційний дисклеймер не залишає двозначності — хук може прочитати, змінити чи видалити будь-який файл, до якого у вас є доступ, виконати довільний bash, сходити в мережу, дістатися до змінних оточення з ключами. Незалежні security-розбори формулюють те саме. Звідси правило: будь-який хук треба прочитати і протестувати до того, як він потрапить у конфіг.
Небезпеку посилює те, що settings.json психологічно сприймається як «метадані», а не як виконуваний код. Це робить хуки тихим вектором supply-chain атак — і це вже не гіпотеза.
CVE-2025-59536 і CVE-2026-21852. Дослідники Check Point (Авів Доненфельд, Одед Вануну) показали, що хук SessionStart із .claude/settings.json чужого репозиторію виконувався без явного підтвердження користувача — на відміну від звичайних bash-команд. Через це вдавалося дійти до віддаленого виконання коду та ексфільтрації API-ключа (підміна ANTHROPIC_BASE_URL). Перший баг отримав CVSS 8.7 (High), другий — 5.3. CVE-2026-21852 опублікований Anthropic 21 січня 2026 року, публічне розкриття Check Point — 25 лютого 2026 року; на дату звіту обидві вразливості вже були повністю пропатчені.
Кампанія Shai-Hulud. Той самий SessionStart-хук використали як механізм персистентності supply-chain малварі в npm-пакетах. Техніка «впровадити SessionStart-хук через .claude/settings.json із пакета» вперше з’явилася у Wave 3 кампанії (пакети SAP CAP-JS/MBT, квітень 2026 року, близько 4 пакетів) і повернулася у Wave 5: 19 травня 2026 року через скомпрометований акаунт мейнтейнера приблизно за годину опублікували, за даними Socket через Snyk, 637 версій у 323 пакетах (@antv/* і ще понад 310); у звіті BleepingComputer і в GitHub-issue фігурує цифра 639 версій — розбіжність на пару версій пояснюється різним моментом знімка. Хук переживає перезапуск і запускає код атакувальника при наступному відкритті Claude Code — ще до будь-якого введення користувача. Хронологія Wave 3 → Wave 5 наочно показує, що це еволюція однієї техніки, а не розрізнені інциденти.
Претензія спільноти. GitHub-issue #49778 (створений 17 квітня, закритий як not_planned 26 червня 2026 року) формулює архітектурну проблему: у активних хуків немає постійного індикатора в інтерфейсі, і немає підтвердження, коли хук реєструє сторонній процес — npm postinstall, плагін, навичку. Показово, що Shai-Hulud Wave 5 (19 травня) на практиці реалізувала рівно той ризик, який issue описав теоретично.
Що з цим робити:
- Не довіряйте
.claude/settings.jsonіз чужих і клонованих репозиторіїв. Після клонування запустіть/hooksі подивіться, що зареєстровано. - Для команд і організацій є жорсткі важелі:
allowManagedHooksOnlyблокує користувацькі, проєктні та плагінні хуки, аdisableAllHooks: trueвимикає хуки зовсім. Вимкнути managed-хуки може лишеdisableAllHooks, заданий на рівні managed-політики — пересічний користувач їх не зніме. - Суміжна лінія захисту — sandboxed Bash tool: він окремо обмежує файлову систему і мережу та доповнює, а не замінює
PreToolUse-deny хуки.
Екосистема при цьому жива: найбільша відкрита колекція прикладів disler/claude-code-hooks-mastery набрала 3822 зірки і 627 форків (знімок на 11 липня 2026 року). Готові хуки — це зручно, але кожен із них — чужий код із вашими правами, тож правило «прочитав і перевірив» поширюється і на них.
Варто відділяти цей матеріал від схожого за назвою Agent SDK hooks: якщо ви будуєте застосунок на Claude Agent SDK, там хуки — це програмні callback-функції в коді (TypeScript/Python), а не JSON-конфіг у settings.json. Механіка близька, спосіб під’єднання різний. Схожа екосистема розширень — навички, MCP, хуки — стала стандартом і в продуктів на базі Claude Code: наприклад, постійного ШІ-колегу в Slack збирають на тій самій зв’язці.
FAQ
Чим PreToolUse відрізняється від PostToolUse простими словами?
PreToolUse спрацьовує до виклику інструмента і може його заблокувати, дозволити або відправити на підтвердження — це єдина подія з повним контролем рішення. PostToolUse спрацьовує після: він бачить результат і може дати моделі зворотний зв’язок, але скасувати вже виконану дію не здатен. Заборони вішають на перший, реакції (формат, тести, логи) — на другий.
Хук з exit-кодом 3 існує?
Ні. Офіційний reference описує лише exit 0 (успіх), exit 2 (блокувальна помилка) і «будь-який інший код» як неблокувальну помилку. Значення «Deferred execution» для exit 3 трапляється в сторонньому туторіалі DataCamp, але це неточність: «defer» — це одне зі значень поля permissionDecision, а не код повернення процесу.
Скільки подій життєвого циклу в Claude Code насправді?
На липень 2026 року офіційний довідник перелічує близько 30 подій. Багато гайдів називають 9–13 — вони писалися раніше і просто застаріли, бо перелік активно розширюється. Ходових при цьому близько десятка: PreToolUse, PostToolUse, UserPromptSubmit, Notification, Stop, SubagentStop, SessionStart, PreCompact, SessionEnd.
Чи можуть хуки нашкодити комп’ютеру?
Так, якщо хук шкідливий. Командний хук виконується з повними правами вашого користувача і може робити все, що можете ви. Уже задокументовані реальні випадки: CVE-2025-59536 (RCE через SessionStart-хук чужого репозиторію, пропатчено) і кампанія Shai-Hulud, де SessionStart-хук у npm-пакетах слугував механізмом закріплення малварі. Тому чужі settings.json не запускають наосліп.
Чи витрачають хуки токени моделі?
Практично ні. Командні та HTTP-хуки — це звичайні процеси ОС і мережеві запити, вони не йдуть через контекст моделі. Саме тому форматувальники, лінтери та перевірки на хуках вважаються «безкоштовною» в токенах автоматизацією, на відміну від навичок і субагентів, які витрачають частину контекстного вікна.
Як заборонити агентові чіпати певні файли?
Повісьте PreToolUse-хук на інструменти Edit|Write (і Bash, якщо правки йдуть командами), який читає шлях із tool_input і повертає permissionDecision: deny для захищених шляхів на кшталт .env або .git. Такий хук тримається навіть у режимі обходу прав. Для організацій жорсткіше — allowManagedHooksOnly і disableAllHooks на рівні managed-політики.
Курс «Claude Code з нуля до продакшену» · модуль «Конфіг, пам'ять, навички». Повна програма і два маршрути навчання — на сторінці курсу.
Попередній урок: MCP у Claude Code: налаштування, Tool Search
