Hook Notification в Claude Code запускается каждый раз, когда Claude Code отправляет уведомление — чаще всего потому, что ожидает запрос разрешения (permission_prompt), или потому, что Claude закончил, а Вы не ответили (idle_prompt). Он рассчитан на момент, когда Вас, судя по всему, нет на месте: permission_prompt срабатывает, если запрос ждёт около шести секунд без нажатий клавиш, а idle_prompt — примерно через 60 секунд после того, как Claude закончил. Hook получает текст уведомления в виде JSON, ничего не может заблокировать и предназначен для побочных действий, например уведомления на рабочем столе или push на телефон.
01Типы уведомлений
matcher у hook Notification — это тип уведомления. Оставьте его пустым, чтобы hook срабатывал на все типы, или перечислите нужные через |. Чаще всего используются:
permission_promptClaude нужно Ваше одобрение на использование инструмента (или сетевой запрос команды в sandbox), и запрос ждёт около шести секундidle_promptClaude закончил отвечать примерно 60 секунд назад, и с тех пор Вы ничего не вводилиelicitation_dialogMCP-сервер открыл форму, и Вы около шести секунд ничего не вводилиelicitation_url_dialogMCP-сервер попросил открыть URL, и Вы около шести секунд ничего не вводилиauth_successАутентификация завершенаЕсть и другие, например agent_needs_input и agent_completed для фоновых сессий в agent view, а также набор типов quota_auto_resume_* для ожидания при достижении лимитов использования. Полный актуальный список — в справочнике по hooks.
02Правила тайминга
Именно здесь многие спотыкаются. У hook Notification те же тайминги, что и у встроенных desktop-уведомлений Claude Code, поэтому в терминальной сессии он срабатывает, только когда Вы отвлеклись:
permission_promptзапускает таймер примерно на шесть секунд, когда появляется запрос. Каждое нажатие клавиши сбрасывает его. Если Вы отвечаете быстро, он не срабатывает вовсе.idle_promptсрабатывает примерно через 60 секунд после того, как Claude закончил, и только если Вы с тех пор ничего не вводили и ни один фоновый агент ещё не работает. Он не срабатывает, пока Claude Code ждёт сброса лимита использования.- Для запроса, пришедшего, пока открыт другой диалог, отсчёт идёт с момента его поступления, поэтому уведомление может прийти, пока запрос ещё ждёт за открытым диалогом.
Хосты, которые отвечают на запросы разрешений через Agent SDK, например Claude Desktop и расширение для VS Code, отсчитывают permission_prompt иначе: примерно шесть секунд после запроса, без отсрочки из-за ввода, и уведомление пропускается, если Вы или hook PermissionRequest ответили раньше.
Если нужен сигнал без задержки, используйте другое событие:
PermissionRequestStopNotification с idle_prompt03Что получает hook
Помимо общих полей (session_id, transcript_path, cwd, hook_event_name), hook Notification получает message уведомления, необязательный title и notification_type:
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"hook_event_name": "Notification",
"message": "Claude needs your permission",
"title": "Permission needed",
"notification_type": "permission_prompt"
}
message — это собственная формулировка Claude Code, поэтому её можно смело показывать как есть. cwd пригодится, если у Вас открыто несколько сессий и нужно понять, какой проект ждёт ответа.
04Что hook может и чего не может
Hook Notification не может заблокировать, отложить или изменить уведомление. Его код выхода и stderr игнорируются, а systemMessage и continue из его JSON-вывода Claude Code отбрасывает. Он нужен исключительно для побочных эффектов.
Есть одно поле вывода, которое он может использовать: terminalSequence. Hooks запускаются без терминала, поэтому сами не могут выводить escape-последовательности, но могут передать её Claude Code для вывода. Так hook может вызвать нативное уведомление терминала в iTerm2, Ghostty, Kitty, WezTerm, Windows Terminal и других, даже внутри tmux. Это работает только в интерактивной сессии, когда интерфейс Claude Code на экране.
Настройка preferredNotifChannel тоже не отключает hook. Даже при выключенных встроенных уведомлениях событие Notification всё равно срабатывает. Эта настройка меняет только то, как оповещает Вас сам Claude Code; подробнее в руководстве по terminal bell.
05Примеры
Разные обработчики для разных типов
Запускайте отдельный скрипт для запросов разрешений и для напоминаний о простое:
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [{ "type": "command", "command": "~/.claude/hooks/permission-alert.sh" }]
},
{
"matcher": "idle_prompt",
"hooks": [{ "type": "command", "command": "~/.claude/hooks/idle-alert.sh" }]
}
]
}
}
Сделайте каждый скрипт исполняемым с помощью chmod +x. Команды desktop-уведомлений для Mac, Windows и Linux описаны в статье как получить уведомление, когда Claude Code закончит, поэтому здесь они не повторяются.
Показ реального сообщения и проекта
Этот скрипт (macOS и Linux) выводит в уведомлении сообщение Claude Code и папку проекта вместо фиксированной строки:
#!/bin/bash
# ~/.claude/hooks/notify.sh
input=$(cat)
msg=$(jq -r '.message // "Claude Code needs your attention"' <<<"$input")
project=$(basename "$(jq -r '.cwd // "."' <<<"$input")")
if command -v osascript >/dev/null 2>&1; then
osascript -e 'on run argv' \
-e 'display notification (item 1 of argv) with title (item 2 of argv)' \
-e 'end run' "$msg" "Claude Code: $project"
elif command -v notify-send >/dev/null 2>&1; then
notify-send "Claude Code: $project" "$msg"
fi
exit 0
Передача текста через аргументы (on run argv) не даёт AppleScript сломаться, если в сообщении есть кавычки. Нужен установленный jq.
Нативное уведомление терминала
В собственном примере Anthropic используется terminalSequence с OSC 777, который понимают Ghostty, Warp и urxvt:
#!/bin/bash
input=$(cat)
title="Claude Code"
body=$(jq -r '.message // "Needs your attention"' <<<"$input")
seq=$(printf '\033]777;notify;%s;%s\007' "$title" "$body")
jq -nc --arg seq "$seq" '{terminalSequence: $seq}'
Для iTerm2, Windows Terminal или WezTerm используйте OSC 9, а для Kitty — OSC 99. Всё, что не входит в список разрешённых последовательностей, игнорируется.
06Место Claude Code Notifier
Hook Notification, вызывающий push-сервис, доставит оповещение на телефон, и многим этого достаточно. Этот вариант описан в руководстве по ntfy.
Не хватает только ответа. К моменту срабатывания permission_prompt Claude ждёт ответа в диалоге, на который hook Notification ответить не может. Claude Code Notifier решает это через hooks, которые могут: PermissionRequest возвращает Ваше решение, а PreToolUse для AskUserQuestion — Ваш ответ. Его бесплатная утилита командной строки ccn работает на Mac, Windows и Linux и сама показывает desktop-уведомления. Если подключено приложение для iPhone или Android, Вы можете с телефона разрешить один раз, разрешить на всю сессию или отклонить. Если Вы что-то вводили в последние 30 секунд, ожидания телефона нет и терминал спрашивает как обычно. Это независимый инструмент, не созданный Anthropic. Установка описана на странице ccn.
07FAQ
Почему мой Notification hook никогда не срабатывает?
Чаще всего потому, что Вы всё ещё за клавиатурой. Каждое нажатие откладывает permission_prompt, а idle_prompt срабатывает, только если Вы ничего не вводили около минуты после того, как Claude закончил. Для проверки вызовите запрос разрешения, переключитесь в другое окно и подождите не менее шести секунд. Если hook всё равно не срабатывает, проверьте, что он есть в /hooks, и загляните в чек-лист по устранению неполадок.
Что такое idle_prompt?
Это тип уведомления, который Claude Code отправляет, когда Claude закончил отвечать около 60 секунд назад, а Вы с тех пор ничего не вводили. Это напоминание, что ход за Вами, а не мгновенный сигнал «готово». Для такого сигнала используйте hook Stop.
Может ли Notification hook одобрить разрешение?
Нет. У hooks Notification нет управления решениями, поэтому ничто из их вывода не ответит на запрос. Чтобы разрешать или отклонять, используйте hook PermissionRequest, как описано в руководстве по PermissionRequest.
Запускается ли Notification hook, если задать preferredNotifChannel значение notifications_disabled?
Да. Этот параметр меняет только то, как Claude Code сам уведомляет Вас. Событие Notification и Ваши hooks продолжают работать.
Почему я получаю два уведомления?
Встроенное уведомление Claude Code и Ваш hook срабатывают параллельно. В iTerm2, Ghostty или Kitty Вы можете увидеть оба. Отключите одно из них, например с помощью preferredNotifChannel, или оставьте только hook.