Хуки
Хуки позволяют отслеживать, контролировать и расширять цикл Agent с помощью пользовательских скриптов. Определяйте хуки в файлах hooks.json на уровне проекта или пользователя либо устанавливайте их через плагины в разделе Настроить. Хуки — это отдельные процессы, обменивающиеся данными через stdio в формате JSON. Они запускаются до или после определённых этапов цикла Agent и могут отслеживать, блокировать или изменять поведение.
С помощью хуков можно:
- Запускать форматтеры после изменений
- Добавлять аналитику событий
- Проверять наличие персональных данных или секретов
- Ограничивать рискованные операции (например, запись в SQL)
- Контролировать выполнение субагентов (инструмент Task)
- Добавлять контекст в начале сессии
Ищете готовые интеграции? См. Партнёрские интеграции — решения для безопасности, управления и управления секретами от наших партнёров по экосистеме.
Cursor поддерживает загрузку хуков из сторонних инструментов, таких как Claude Code. Подробнее о совместимости и конфигурации см. в разделе Сторонние хуки.
Категории хуков
Хуки делятся на три категории в зависимости от события, которое их вызывает:
Хуки Agent (Cmd+K/Agent Chat) срабатывают во время сессии агента:
sessionStart/sessionEnd- Управление жизненным циклом сессииpreToolUse/postToolUse/postToolUseFailure- Общие хуки использования инструментов (срабатывают для всех инструментов)subagentStart/subagentStop- Жизненный цикл субагента (инструмент Task)beforeShellExecution/afterShellExecution- Управление shell-командамиbeforeMCPExecution/afterMCPExecution- Управление использованием инструментов MCPbeforeReadFile/afterFileEdit- Управление доступом к файлам и правкамиbeforeSubmitPrompt- Проверка промптов перед отправкойpreCompact- Отслеживание сжатия контекстного окнаstop- Обработка завершения работы агентаafterAgentResponse/afterAgentThought- Отслеживание ответов агента
Хуки Tab (встроенные дополнения) срабатывают при автономных операциях Tab:
beforeTabFileRead- Управление доступом к файлам для Tab completionsafterTabFileEdit- Постобработка правок Tab
Хуки жизненного цикла приложения срабатывают вне сессий агента:
workspaceOpen- Срабатывает при открытии рабочего пространства в Cursor и при каждом изменении папки рабочего пространства. Может возвращать дополнительные пути к плагинам для загрузки в текущем рабочем пространстве.
Эти отдельные типы хуков позволяют применять разные политики к автономным операциям Tab, операциям Agent, инициированным пользователем, и запуску рабочего пространства.
Поддержка облачных агентов
Облачные агенты запускают хуки на основе команд из вашего репозитория. Если в корне проекта в файле .cursor/hooks.json определены хуки, облачные агенты обнаружат и запустят их в процессе работы.
На тарифах Enterprise облачные агенты также запускают хуки команды и хуки, управляемые на уровне Enterprise, настроенные через веб-дашборд.
Иногда на первых этапах исследования облачные агенты работают в среде только для чтения. В это время хуки не запускаются. Они начинают работать, когда агент получает среду с возможностью записи.
Поддерживаемые хуки
В облачных агентах поддерживаются следующие хуки:
| Хук | Поддерживается |
|---|---|
beforeShellExecution | Да |
afterShellExecution | Да |
beforeReadFile | Да |
afterFileEdit | Да |
preToolUse | Да |
postToolUse | Да |
postToolUseFailure | Да |
subagentStart | Да |
subagentStop | Да |
beforeSubmitPrompt | Да |
preCompact | Да |
afterAgentResponse | Да |
afterAgentThought | Да |
stop | Да |
Хуки, недоступные в облачных агентах
Некоторые хуки недоступны для облачных агентов из-за различий в среде выполнения:
| Хук | Причина |
|---|---|
sessionStart | Отложен, так как облачные агенты могут запускаться в среде только для чтения. В ней хуки не загружаются, поэтому облачный sessionStart сработал бы слишком поздно — после первой записи, а не в момент фактического начала сессии. |
sessionEnd | У облачных агентов нет границы сессии, связанной со временем работы редактора. sessionEnd привязан к сессии IDE, а не к чату облачного агента. |
beforeMCPExecution / afterMCPExecution | Отложены, так как облачные агенты могут запускаться в среде только для чтения, где хуки не загружаются, а время срабатывания MCP-хуков не определено. |
beforeTabFileRead / afterTabFileEdit | Tab Completions — функция IDE, недоступная в облачных агентах. |
workspaceOpen | Это хук жизненного цикла IDE, который не применяется к облачным агентам. |
Источники конфигурации
Облачные агенты загружают хуки из следующих источников:
- Хуки проекта (
.cursor/hooks.jsonв вашем репозитории): загружаются и выполняются во время работы облачного агента. - Хуки команды (Enterprise): распространяются через дашборд и выполняются в облачных агентах.
- Хуки Enterprise (Enterprise): управляемые системные хуки, выполняемые в облачных агентах.
Хуки уровня пользователя (~/.cursor/hooks.json) недоступны в облачных агентах. ВМ облачных агентов не имеют доступа к конфигурации в вашем локальном домашнем каталоге.
Воркеры Self-Hosted Machines (пулы и My Machines) выполняют те же хуки проекта на основе команд, а на тарифе Enterprise — также хуки команды и хуки, управляемые на уровне Enterprise. На таких воркерах sessionStart и sessionEnd срабатывают, когда сессия резервирует воркер и когда это резервирование освобождается. См. Хуки в пулах.
Ограничения по типам выполнения
Облачные агенты поддерживают только хуки на основе команд. Для хуков на основе промптов требуется настроить аутентификацию между хуком и циклом агента, что недоступно в облачной среде выполнения.
Быстрый старт
Создайте файл hooks.json. Его можно создать на уровне проекта (<project>/.cursor/hooks.json) или в домашнем каталоге (~/.cursor/hooks.json). Хуки уровня проекта действуют только в конкретном проекте, а хуки из домашнего каталога — глобально.
Чтобы создать пользовательские хуки, действующие глобально, создайте файл ~/.cursor/hooks.json:
{ "version": 1, "hooks": { "afterFileEdit": [{ "command": "./hooks/format.sh" }] }}Создайте скрипт хука в ~/.cursor/hooks/format.sh:
#!/bin/bash# Прочитайте входные данные, выполните нужные действия и завершите работу с кодом 0cat > /dev/nullexit 0Сделайте его исполняемым:
chmod +x ~/.cursor/hooks/format.shCursor отслеживает файлы конфигурации хуков и автоматически перезагружает их. Хук запускается после каждого редактирования файла.
Типы хуков
Хуки поддерживают два типа выполнения: командный (по умолчанию) и промптовый (с оценкой LLM).
Хуки на основе команд
Командные хуки выполняют скрипты оболочки, получающие входные данные в формате JSON через stdin и возвращающие выходные данные в формате JSON через stdout.
{ "version": 1, "hooks": { "beforeShellExecution": [ { "command": "./scripts/approve-network.sh", "timeout": 30, "matcher": "curl|wget|nc" } ] }}Поведение кодов выхода:
- Код выхода
0— хук успешно выполнен, используйте выходные данные JSON. Для хуков прав доступа (beforeShellExecution,beforeMCPExecution,beforeReadFile,beforeTabFileRead,subagentStart,preToolUse) некорректный JSON или ответ, не соответствующий схеме хука, блокирует действие. - Код выхода
2— заблокировать действие (эквивалентно возвратуpermission: "deny") - Другие коды выхода — хук завершился с ошибкой, действие выполняется (по умолчанию ошибка не блокирует выполнение)
Промпт-хуки
Промпт-хуки используют LLM для проверки условия, сформулированного на естественном языке. Они позволяют применять политики без написания пользовательских скриптов.
{ "version": 1, "hooks": { "beforeShellExecution": [ { "type": "prompt", "prompt": "Does this command look safe to execute? Only allow read-only operations.", "timeout": 10 } ] }}Функции:
- Возвращает структурированный ответ
{ ok: boolean, reason?: string } - Использует быструю модель для быстрой оценки
- Заполнитель
$ARGUMENTSавтоматически заменяется JSON входных данных хука - Если
$ARGUMENTSотсутствует, входные данные хука добавляются автоматически - Необязательное поле
modelдля переопределения LLM-модели по умолчанию
Примеры
В приведённых ниже примерах используются пути ./hooks/..., которые подходят для пользовательских хуков (~/.cursor/hooks.json): скрипты запускаются из ~/.cursor/. Для хуков проекта (<project>/.cursor/hooks.json) используйте пути .cursor/hooks/..., поскольку скрипты запускаются из корня проекта.
{ "version": 1, "hooks": { "sessionStart": [ { "command": "./hooks/session-init.sh" } ], "sessionEnd": [ { "command": "./hooks/audit.sh" } ], "beforeShellExecution": [ { "command": "./hooks/audit.sh" }, { "command": "./hooks/block-git.sh" } ], "beforeMCPExecution": [ { "command": "./hooks/audit.sh" } ], "afterShellExecution": [ { "command": "./hooks/audit.sh" } ], "afterMCPExecution": [ { "command": "./hooks/audit.sh" } ], "afterFileEdit": [ { "command": "./hooks/audit.sh" } ], "beforeSubmitPrompt": [ { "command": "./hooks/audit.sh" } ], "preCompact": [ { "command": "./hooks/audit.sh" } ], "stop": [ { "command": "./hooks/audit.sh" } ], "beforeTabFileRead": [ { "command": "./hooks/redact-secrets-tab.sh" } ], "afterTabFileEdit": [ { "command": "./hooks/format-tab.sh" } ] }}Хук автоматизации stop на TypeScript
Выберите TypeScript, если в одном хуке нужны типизированный JSON, надёжные файловые операции и HTTP-вызовы. Этот хук stop на базе Bun отслеживает на диске количество сбоев в каждом диалоге, отправляет структурированные телеметрические данные во внутренний API и может автоматически запланировать повторную попытку, если Agent дважды подряд завершится с ошибкой.
{ "version": 1, "hooks": { "stop": [ { "command": "bun run .cursor/hooks/track-stop.ts --stop" } ] }}Задайте для AGENT_TELEMETRY_URL внутренний endpoint для получения сводок о запусках.
Хук защиты манифестов Kubernetes на Python
Python особенно удобен, когда нужны мощные библиотеки для парсинга. Этот хук использует pyyaml для проверки манифестов Kubernetes перед запуском kubectl apply; Bash было бы сложно безопасно обработать YAML с несколькими документами.
{ "version": 1, "hooks": { "beforeShellExecution": [ { "command": "python3 .cursor/hooks/kube_guard.py" } ] }}Установите PyYAML (например, pip install pyyaml) везде, где запускаются скрипты хуков, чтобы импорт парсера выполнялся успешно.
Партнёрские интеграции
Мы сотрудничаем с поставщиками в экосистеме, которые добавили поддержку хуков в Cursor. Эти интеграции включают сканирование безопасности, управление, управление секретами и многое другое.
Управление MCP и прозрачность
| Партнёр | Описание |
|---|---|
| MintMCP | Составляйте полный список MCP‑серверов, отслеживайте использование инструментов и проверяйте ответы на наличие конфиденциальных данных до их передачи ИИ-модели. |
| Oasis Security | Применяйте политики минимальных привилегий к действиям ИИ-агентов и ведите полные журналы аудита во всех корпоративных системах. |
| Runlayer | Оборачивайте инструменты MCP и интегрируйтесь с MCP-брокером Runlayer для централизованного контроля и отслеживания взаимодействий между агентами и инструментами. |
Безопасность кода и рекомендации по лучшим практикам
| Партнёр | Описание |
|---|---|
| Corridor | Получайте обратную связь в реальном времени по реализации кода и решениям в области безопасности прямо во время написания кода. |
| Semgrep | Автоматически проверяйте сгенерированный ИИ код на уязвимости и получайте обратную связь в реальном времени, чтобы повторно генерировать код до устранения уязвимостей. |
Безопасность зависимостей
| Партнёр | Описание |
|---|---|
| Endor Labs | Перехватывайте установку пакетов и проверяйте их на наличие вредоносных зависимостей, предотвращая атаки на цепочку поставок до того, как они попадут в вашу кодовую базу. |
Безопасность и защита Agent
| Партнёр | Описание |
|---|---|
| Snyk | Отслеживайте действия Agent в реальном времени с Evo Agent Guard, чтобы выявлять и предотвращать такие угрозы, как промпт-инъекции и опасные вызовы инструментов. |
Управление секретами
| Партнёр | Описание |
|---|---|
| 1Password | Проверяйте, что файлы среды из 1Password Environments корректно смонтированы перед выполнением shell-команд. Это обеспечивает доступ к секретам по мере необходимости без записи учётных данных на диск. |
Подробнее о наших партнёрах по хукам читайте в статье «Хуки для команд безопасности и платформ».
Конфигурация
Определяйте хуки в файле hooks.json. Конфигурация может задаваться на нескольких уровнях. Выполняются все подходящие хуки из всех источников, и Cursor объединяет их ответы: любой deny имеет приоритет над ask, а ask — над allow, независимо от источника. Значения user_message и agent_message объединяются. Для остальных полей, например followup_message, побеждает последний ответ. Ответы объединяются в указанном ниже порядке приоритета, поэтому для таких полей источник с более низким приоритетом переопределяет источник с более высоким:
~/.cursor/├── hooks.json└── hooks/ ├── audit.sh └── block-git.sh- Enterprise (управляемые через MDM, общесистемные):
- macOS:
/Library/Application Support/Cursor/hooks.json - Linux/WSL:
/etc/cursor/hooks.json - Windows:
C:\\ProgramData\\Cursor\\hooks.json
- macOS:
- Команда (распространяемые через Cloud, только для Enterprise):
- Настраиваются в веб-дашборде и автоматически синхронизируются со всеми участниками команды
- Проект (для конкретного проекта):
<project-root>/.cursor/hooks.json- Хуки проекта запускаются в любом доверенном рабочем пространстве и добавляются в систему контроля версий вместе с проектом
- Пользователь (для конкретного пользователя):
~/.cursor/hooks.json
Порядок приоритета (от высшего к низшему): Enterprise → Команда → Проект → Пользователь
Объект hooks сопоставляет имена хуков с массивами определений хуков. Каждое определение в настоящее время поддерживает свойство command, которое может быть строкой для оболочки, абсолютным или относительным путём. Рабочий каталог зависит от источника хука:
- Хуки проекта (
.cursor/hooks.jsonв репозитории): Запускаются из корня проекта - Пользовательские хуки (
~/.cursor/hooks.json): Запускаются из~/.cursor/ - Хуки Enterprise (общесистемная конфигурация): Запускаются из каталога конфигурации Enterprise
- Хуки команды (распространяемые через Cloud): Запускаются из каталога управляемых хуков
Для хуков проекта используйте пути вроде .cursor/hooks/script.sh (относительно корня проекта), а не ./hooks/script.sh (который будет искать <project>/hooks/script.sh).
Файл конфигурации
В этом примере показан файл пользовательских хуков (~/.cursor/hooks.json). Для хуков на уровне проекта замените пути, например ./hooks/script.sh, на .cursor/hooks/script.sh:
{ "version": 1, "hooks": { "sessionStart": [{ "command": "./session-init.sh" }], "sessionEnd": [{ "command": "./audit.sh" }], "preToolUse": [ { "command": "./hooks/validate-tool.sh", "matcher": "Shell|Read|Write" } ], "postToolUse": [{ "command": "./hooks/audit-tool.sh" }], "subagentStart": [{ "command": "./hooks/validate-subagent.sh" }], "subagentStop": [{ "command": "./hooks/audit-subagent.sh" }], "beforeShellExecution": [{ "command": "./script.sh" }], "afterShellExecution": [{ "command": "./script.sh" }], "afterMCPExecution": [{ "command": "./script.sh" }], "afterFileEdit": [{ "command": "./format.sh" }], "preCompact": [{ "command": "./audit.sh" }], "stop": [{ "command": "./audit.sh", "loop_limit": 10 }], "beforeTabFileRead": [{ "command": "./redact-secrets-tab.sh" }], "afterTabFileEdit": [{ "command": "./format-tab.sh" }], "workspaceOpen": [{ "command": "./register-workspace-plugins.sh" }] }}Хуки Agent (sessionStart, sessionEnd, preToolUse, postToolUse, postToolUseFailure, subagentStart, subagentStop, beforeShellExecution, afterShellExecution, beforeMCPExecution, afterMCPExecution, beforeReadFile, afterFileEdit, beforeSubmitPrompt, preCompact, stop, afterAgentResponse, afterAgentThought) применяются к операциям Cmd+K и Agent Chat. Хуки Tab (beforeTabFileRead, afterTabFileEdit) применяются только к встроенным автодополнениям Tab. Хук жизненного цикла приложения (workspaceOpen) срабатывает при открытии рабочего пространства и изменении его папок независимо от сессии агента.
Глобальные параметры конфигурации
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
version | число | обязательно | Версия схемы конфигурации. Должна быть положительным целым числом (используйте 1). |
Параметры конфигурации отдельных скриптов
| Параметр | Тип | По умолчанию | Описание | |
|---|---|---|---|---|
command | string | обязательно | Путь к скрипту или команда | |
type | "command" | "prompt" | "command" | Тип выполнения хука |
timeout | number | значение платформы по умолчанию | Тайм-аут выполнения в секундах | |
loop_limit | number | null | 5 | Ограничение количества циклов для каждого скрипта в хуках stop/subagentStop. null означает отсутствие ограничения. По умолчанию: 5 для хуков Cursor, null для хуков Claude Code. |
failClosed | boolean | false | Если true, сбой хука (аварийное завершение, тайм-аут, ненулевой код выхода, отсутствие выходных данных) блокирует действие вместо его выполнения. Хуки прав доступа блокируют действие при недопустимом JSON или недопустимом ответе, даже если здесь указано false. Полезно для критически важных с точки зрения безопасности хуков. | |
matcher | string | - | Регулярное выражение, определяющее, когда запускается хук. Пустая строка или "*" соответствует всему. |
Конфигурация сопоставителя
Сопоставитель позволяет указать, при каких условиях запускается hook. Сопоставитель — это строка с регулярным выражением; пустая строка или "*" соответствует всему. То, с каким значением сверяется регулярное выражение, зависит от hook:
{ "version": 1, "hooks": { "preToolUse": [ { "command": "./validate-shell.sh", "matcher": "Shell" } ], "subagentStart": [ { "command": "./validate-explore.sh", "matcher": "explore|shell" } ], "beforeShellExecution": [ { "command": "./approve-network.sh", "matcher": "curl|wget|nc " } ] }}- subagentStart: сопоставитель проверяет тип субагента (например,
explore,shell,generalPurpose). Используйте его, чтобы запускать хуки только при запуске субагента определённого типа. В примере вышеvalidate-explore.shзапускается только для субагентов типа explore или shell. - beforeShellExecution: сопоставитель проверяет строку shell-команды. Используйте его, чтобы запускать хуки только когда команда соответствует шаблону (например, выполняет сетевые вызовы или удаляет файлы). В примере выше
approve-network.shзапускается только если команда содержитcurl,wgetилиnc.
Доступные сопоставители для каждого хука:
- preToolUse / postToolUse / postToolUseFailure: фильтрация по типу инструмента. Возможные значения:
Shell,Read,Write,Grep,Delete,Taskи инструменты MCP в форматеMCP:<tool_name>. - subagentStart / subagentStop: фильтрация по типу субагента (
generalPurpose,explore,shellи т. д.). - beforeShellExecution / afterShellExecution: фильтрация по тексту shell-команды; сопоставитель проверяет полную строку команды.
- beforeReadFile: сопоставляется со значением
Read. - afterFileEdit: сопоставляется со значением
Write. - beforeTabFileRead: сопоставляется со значением
TabRead. - afterTabFileEdit: сопоставляется со значением
TabWrite. - beforeSubmitPrompt: сопоставляется со значением
UserPromptSubmit. - stop: сопоставляется со значением
Stop. - afterAgentResponse: сопоставляется со значением
AgentResponse. - afterAgentThought: сопоставляется со значением
AgentThought.
Распространение в команде
Хуки можно распространять среди участников команды через хуки проекта (с помощью системы контроля версий), инструменты MDM или систему облачного распространения Cursor.
Хуки проекта (контроль версий)
Хуки проекта — самый простой способ поделиться хуками с командой. Поместите файл hooks.json в <project-root>/.cursor/hooks.json и закоммитьте его в репозиторий. Когда участники команды открывают проект в доверенном рабочем пространстве, Cursor автоматически загружает и запускает хуки проекта.
Облачные агенты также загружают эти хуки проекта, когда работают с вашим репозиторием в облаке.
Хуки проекта:
- Хранятся в системе контроля версий вместе с кодом
- Автоматически загружаются для всех участников команды в доверенных рабочих пространствах
- Могут быть настроены для конкретного проекта (например, обеспечивать соблюдение стандартов форматирования в определённой кодовой базе)
- Для запуска требуют доверенного рабочего пространства (в целях безопасности)
Распространение через MDM
Распространяйте хуки в своей организации с помощью инструментов управления мобильными устройствами (MDM). Разместите файл hooks.json и скрипты хуков в соответствующих каталогах на каждом компьютере.
Домашний каталог пользователя (распространение для отдельных пользователей):
~/.cursor/hooks.json~/.cursor/hooks/(для скриптов хуков)
Глобальные каталоги (распространение для всей системы):
- macOS:
/Library/Application Support/Cursor/hooks.json - Linux/WSL:
/etc/cursor/hooks.json - Windows:
C:\\ProgramData\\Cursor\\hooks.json
Примечание: распространением через MDM полностью управляет ваша организация. Cursor не развертывает файлы и не управляет ими через ваше MDM-решение. Убедитесь, что ваша внутренняя ИТ-команда или команда безопасности выполняет настройку, развертывание и обновление в соответствии с политиками вашей организации.
Облачное распространение (только для Enterprise)
Команды Enterprise могут использовать встроенное облачное распространение Cursor для автоматической синхронизации хуков со всеми участниками команды. Настройте хуки в веб-дашборде. Cursor автоматически доставляет настроенные хуки на все клиентские компьютеры, когда участники команды входят в систему.
Облачное распространение обеспечивает:
- Автоматическую синхронизацию со всеми участниками команды каждые тридцать минут
- Выбор целевой операционной системы для платформозависимых хуков
- Централизованное управление через дашборд
Администраторы Enterprise могут создавать, редактировать и управлять командными хуками через дашборд без доступа к отдельным компьютерам.
Свяжитесь с отделом продаж, чтобы подключить облачное распространение хуков Enterprise.
Справочник
Общая схема
Входные данные (все хуки)
Помимо полей, специфичных для каждого хука, все хуки получают базовый набор полей:
{ "conversation_id": "string", "generation_id": "string", "model": "string", "model_id": "string", "model_params": [{ "id": "string", "value": "string" }], "hook_event_name": "string", "cursor_version": "string", "workspace_roots": ["<path>"], "user_email": "string | null", "transcript_path": "string | null"}| Поле | Тип | Описание | |
|---|---|---|---|
conversation_id | string | Стабильный ID диалога, сохраняющийся на протяжении нескольких шагов | |
generation_id | string | Текущая генерация, меняющаяся с каждым сообщением пользователя | |
model | string | Слаг устаревшей модели, настроенной для composer, вызвавшего хук | |
model_id | string (optional) | Структурированный ID выбранной модели, если доступен | |
model_params | array (optional) | Параметры выбранной модели, например thinking, контекст или уровень усилий. У каждого элемента есть id и value. | |
hook_event_name | string | Выполняемый хук | |
cursor_version | string | Версия приложения Cursor (например, "1.7.2") | |
workspace_roots | string[] | Список корневых папок рабочего пространства (обычно одна, но в рабочих пространствах с несколькими корневыми папками их может быть несколько) | |
user_email | string | null | Адрес электронной почты аутентифицированного пользователя, если доступен |
transcript_path | string | null | Путь к файлу транскрипта основного диалога (null, если транскрипты отключены) |
Хуки жизненного цикла приложения (workspaceOpen) срабатывают вне любой сессии Agent, поэтому запрос не включает conversation_id, generation_id, model, session_id и transcript_path. Они по-прежнему получают hook_event_name, cursor_version, workspace_roots и user_email.
События хуков
preToolUse
Вызывается перед выполнением любого инструмента. Это универсальный хук, который срабатывает для всех типов инструментов (Shell, Read, Write, MCP, Task и т. д.). Используйте сопоставители, чтобы отфильтровать конкретные инструменты.
// Входные данные{ "tool_name": "Shell", "tool_input": { "command": "npm install", "working_directory": "/project" }, "tool_use_id": "abc123", "cwd": "/project", "model": "claude-opus-4-7-thinking-max", "model_id": "claude-opus-4-7", "model_params": [ { "id": "thinking", "value": "true" }, { "id": "context", "value": "1m" }, { "id": "effort", "value": "max" } ], "agent_message": "Installing dependencies..."}// Выходные данные{ "permission": "allow" | "deny", "user_message": "<message shown in client when denied>", "agent_message": "<message sent to agent when denied>", "updated_input": { "command": "npm ci" }}| Выходные данные | Тип | Описание |
|---|---|---|
permission | string | "allow" — разрешить, "deny" — заблокировать. "ask" принимается схемой, но пока не применяется для preToolUse. |
user_message | string (необязательно) | Сообщение, отображаемое пользователю при отклонении действия |
agent_message | string (необязательно) | Сообщение, передаваемое агенту при отклонении действия |
updated_input | object (необязательно) | Изменённые входные данные инструмента, используемые вместо исходных |
postToolUse
Вызывается после успешного выполнения инструмента. Используется для аудита, аналитики и добавления контекста.
// Входные данные{ "tool_name": "Shell", "tool_input": { "command": "npm test" }, "tool_output": "{\"exitCode\":0,\"stdout\":\"All tests passed\"}", "tool_use_id": "abc123", "cwd": "/project", "duration": 5432, "model": "claude-opus-4-7-thinking-max", "model_id": "claude-opus-4-7", "model_params": [ { "id": "thinking", "value": "true" }, { "id": "context", "value": "1m" }, { "id": "effort", "value": "max" } ]}// Выходные данные{ "updated_mcp_tool_output": { "modified": "output" }, "additional_context": "Test coverage report attached."}| Поле входных данных | Тип | Описание |
|---|---|---|
duration | number | Время выполнения в миллисекундах |
tool_output | string | Результат работы инструмента, сериализованный в JSON-строку (не необработанный текст терминала) |
| Поле выходных данных | Тип | Описание |
|---|---|---|
updated_mcp_tool_output | object (optional) | Только для инструментов MCP: заменяет выходные данные инструмента, отображаемые модели |
additional_context | string (optional) | Дополнительный контекст, добавляемый в диалог после результата работы инструмента |
postToolUseFailure
Вызывается, если инструмент завершился с ошибкой, превысил время ожидания или получил отказ. Используется для отслеживания ошибок и логики восстановления.
// Входные данные{ "tool_name": "Shell", "tool_input": { "command": "npm test" }, "tool_use_id": "abc123", "cwd": "/project", "error_message": "Command timed out after 30s", "failure_type": "timeout" | "error" | "permission_denied", "duration": 5000, "is_interrupt": false}// Выходные данные{ "additional_context": "Tests time out on CI runners. Retry with --maxWorkers=2."}| Поле входных данных | Тип | Описание |
|---|---|---|
error_message | string | Описание ошибки |
failure_type | string | Тип ошибки: "error", "timeout" или "permission_denied" |
duration | number | Время до возникновения ошибки в миллисекундах |
is_interrupt | boolean | Вызвана ли эта ошибка прерыванием или отменой пользователем |
| Поле выходных данных | Тип | Описание |
|---|---|---|
additional_context | string (optional) | Дополнительный контекст, добавляемый в диалог после неудачного вызова инструмента |
subagentStart
Вызывается перед созданием субагента (инструмент Task). Позволяет разрешить или запретить его создание.
// Входные данные{ "subagent_id": "abc-123", "subagent_type": "generalPurpose", "task": "Explore the authentication flow", "parent_conversation_id": "conv-456", "tool_call_id": "tc-789", "subagent_model": "claude-sonnet-4-20250514", "is_parallel_worker": false, "git_branch": "feature/auth"}// Выходные данные{ "permission": "allow" | "deny", "user_message": "<message shown when denied>"}| Поле входных данных | Тип | Описание |
|---|---|---|
subagent_id | string | Уникальный идентификатор экземпляра субагента |
subagent_type | string | Тип субагента: generalPurpose, explore, shell и т. д. |
task | string | Описание задачи, переданной субагенту |
parent_conversation_id | string | ID диалога родительской сессии агента |
tool_call_id | string | ID вызова инструмента, запустившего субагента |
subagent_model | string | Модель, которую будет использовать субагент |
is_parallel_worker | boolean | Выполняется ли этот субагент как параллельный воркер |
git_branch | string (optional) | Ветка Git, в которой будет работать субагент, если применимо |
| Поле выходных данных | Тип | Описание |
|---|---|---|
permission | string | "allow" — разрешить продолжение, "deny" — заблокировать. "ask" не поддерживается для subagentStart и обрабатывается как "deny". |
user_message | string (optional) | Сообщение, отображаемое пользователю при отказе субагенту |
subagentStop
Вызывается, когда субагент завершает работу, завершается с ошибкой или прерывается. Может запускать последующие действия.
// Входные данные{ "subagent_type": "generalPurpose", "status": "completed" | "error" | "aborted", "task": "Explore the authentication flow", "description": "Exploring auth flow", "summary": "<subagent output summary>", "duration_ms": 45000, "message_count": 12, "tool_call_count": 8, "loop_count": 0, "modified_files": ["src/auth.ts"], "agent_transcript_path": "/path/to/subagent/transcript.txt"}// Выходные данные{ "followup_message": "<auto-continue with this message>"}| Поле входных данных | Тип | Описание | |
|---|---|---|---|
subagent_type | string | Тип субагента: generalPurpose, explore, shell и т. д. | |
status | string | "completed", "error" или "aborted" | |
task | string | Описание задачи, поставленной субагенту | |
description | string | Краткое описание назначения субагента | |
summary | string | Сводка выходных данных субагента | |
duration_ms | number | Время выполнения в миллисекундах | |
message_count | number | Количество сообщений, которыми обменялись в ходе сессии субагента | |
tool_call_count | number | Количество вызовов инструментов, выполненных субагентом | |
loop_count | number | Количество уже сработавших последующих действий subagentStop для этого субагента (начинается с 0) | |
modified_files | string[] | Файлы, изменённые субагентом | |
agent_transcript_path | string | null | Путь к собственному файлу транскрипта субагента (отдельному от родительского диалога) |
| Поле выходных данных | Тип | Описание |
|---|---|---|
followup_message | string (optional) | Автоматически продолжить с этим сообщением. Используется только при status "completed". |
Поле followup_message поддерживает циклические сценарии, в которых завершение работы субагента запускает следующую итерацию. К последующим действиям применяется то же настраиваемое ограничение числа циклов, что и к хуку stop (по умолчанию — 5, настраивается через loop_limit).
beforeShellExecution / beforeMCPExecution
Вызывается перед выполнением любой shell-команды или инструмента MCP. Верните решение о предоставлении права доступа.
Недопустимый JSON или ответ, не соответствующий схеме хука, блокирует действие. Аварийные завершения, timeout и ненулевые коды выхода, кроме 2, по умолчанию приводят к fail-open: Cursor записывает сбой в лог и разрешает действие. Задайте failClosed: true в определении хука, чтобы блокировать действие и при таких сбоях. Это рекомендуется для критически важных с точки зрения безопасности хуков beforeMCPExecution.
// Входные данные beforeShellExecution{ "command": "<full terminal command>", "cwd": "<current working directory>", "sandbox": false}// Входные данные beforeMCPExecution{ "tool_name": "<tool name>", "tool_input": "<json params>", "mcp_server_name": "<server name from mcp.json>"}// А также одно из (HTTP/SSE-серверы):{ "url": "<server url>", "mcp_server_url": "<server url>" }// Или (stdio-серверы):{ "command": "<launch command and args>" }// Выходные данные{ "permission": "allow" | "deny" | "ask", "user_message": "<message shown in client>", "agent_message": "<message sent to agent>"}| Поле | Тип | Описание |
|---|---|---|
tool_name | строка | Имя запускаемого инструмента MCP |
tool_input | строка | Строка JSON-параметров, передаваемая инструменту |
mcp_server_name | строка | Ключ сервера в его mcp.json (например, linear). Используйте его, чтобы распознать конкретный сервер. |
mcp_server_url | строка | URL сервера; доступен только для HTTP/SSE-серверов |
url | строка | То же, что mcp_server_url; доступен только для HTTP/SSE-серверов |
command | строка | Команда запуска stdio и аргументы, разделённые пробелами; доступна только для stdio-серверов |
Сопоставляйте mcp_server_name (и tool_name), чтобы определить, предназначен ли вызов вашему серверу. command — строка запуска из конфигурации сервера; она может различаться в разных установках: относительные пути, подстановка ${CURSOR_PLUGIN_ROOT} или HTTP-транспорт (у которого command вообще нет). Хук, разрешающий всё, что не распознаёт, должен считать отсутствующий или неожиданный mcp_server_name отказом.
afterShellExecution
Срабатывает после выполнения команды в оболочке; используется для аудита или сбора метрик из выходных данных команды.
// Входные данные{ "command": "<full terminal command>", "output": "<full terminal output>", "duration": 1234, "sandbox": false}| Поле | Тип | Описание |
|---|---|---|
command | string | Полная выполненная команда в Терминале |
output | string | Полные выходные данные, полученные из Терминала |
duration | number | Время выполнения shell-команды в миллисекундах (без учёта времени ожидания одобрения) |
sandbox | boolean | Выполнялась ли команда в изолированной инфраструктуре |
afterMCPExecution
Срабатывает после выполнения инструмента MCP; содержит входные параметры инструмента и полный результат в формате JSON.
// Входные данные{ "tool_name": "<tool name>", "tool_input": "<json params>", "mcp_server_name": "<server name from mcp.json>", "result_json": "<tool result json>", "duration": 1234}| Поле | Тип | Описание |
|---|---|---|
tool_name | string | Имя выполненного MCP-инструмента |
tool_input | string | JSON-строка параметров, переданных инструменту |
mcp_server_name | string | Ключ сервера в его mcp.json |
mcp_server_url | string | URL сервера; доступен только для HTTP/SSE-серверов |
result_json | string | JSON-строка ответа инструмента |
duration | number | Время выполнения MCP-инструмента в миллисекундах (без учёта времени ожидания одобрения) |
afterFileEdit
Срабатывает после редактирования файла Agent; полезно для форматтеров или учёта кода, написанного агентом.
// Входные данные{ "file_path": "<absolute path>", "edits": [{ "old_string": "<search>", "new_string": "<replace>" }]}beforeReadFile
Вызывается перед тем, как Agent читает файл. Используйте для контроля доступа, чтобы предотвратить отправку конфиденциальных файлов в модель.
Недопустимый JSON или ответ, не соответствующий схеме хука, блокирует чтение. Аварийные завершения, timeout и ненулевые коды выхода, отличные от 2, записываются в log, а чтение по умолчанию разрешается. Чтобы блокировать чтение и при таких сбоях, задайте failClosed: true в определении хука.
// Входные данные{ "file_path": "<absolute path>", "content": "<file contents>", "attachments": [ { "type": "file" | "rule", "file_path": "<absolute path>" } ]}// Выходные данные{ "permission": "allow" | "deny", "user_message": "<message shown when denied>"}| Поле входных данных | Тип | Описание |
|---|---|---|
file_path | string | Абсолютный путь к считываемому файлу |
content | string | Полное содержимое файла |
attachments | array | Вложения контекста, связанные с промптом. Каждая запись содержит type ("file" или "rule") и file_path. |
| Поле выходных данных | Тип | Описание |
|---|---|---|
permission | string | "allow" — продолжить, "deny" — заблокировать |
user_message | string (optional) | Сообщение, показываемое пользователю при отказе |
beforeTabFileRead
Вызывается перед тем, как Tab (встроенные дополнения) читает файл. Настройте редактирование или контроль доступа до того, как Tab получит доступ к содержимому файла.
Ключевые отличия от beforeReadFile:
- Срабатывает только для Tab, не для Agent
- Не содержит поля
attachments(Tab не использует вложения в промптах) - Позволяет применять отдельные политики к автономным операциям Tab
// Входные данные{ "file_path": "<absolute path>", "content": "<file contents>"}// Выходные данные{ "permission": "allow" | "deny"}afterTabFileEdit
Вызывается после того, как Tab (встроенные дополнения) вносит изменения в файл. Полезно для форматтеров и аудита кода, записанного Tab.
Ключевые отличия от afterFileEdit:
- Срабатывает только при использовании Tab, а не Agent
- Включает подробные сведения об изменениях:
range,old_lineиnew_lineдля точного отслеживания правок - Полезно для детального форматирования или анализа правок, внесённых Tab
// Входные данные{ "file_path": "<absolute path>", "edits": [ { "old_string": "<search>", "new_string": "<replace>", "range": { "start_line_number": 10, "start_column": 5, "end_line_number": 10, "end_column": 20 }, "old_line": "<line before edit>", "new_line": "<line after edit>" } ]}// Выходные данные{ // Выходные поля пока не поддерживаются}beforeSubmitPrompt
Вызывается сразу после нажатия пользователем кнопки отправки, но до запроса к бэкенду. Может отменить отправку.
// Входные данные{ "prompt": "<user prompt text>", "attachments": [ { "type": "file" | "rule", "file_path": "<absolute path>" } ]}// Выходные данные{ "continue": true | false, "user_message": "<message shown to user when blocked>"}| Поле выходных данных | Тип | Описание |
|---|---|---|
continue | boolean | Разрешает ли продолжить отправку промпта |
user_message | string (необязательно) | Сообщение, отображаемое пользователю при блокировке промпта |
afterAgentResponse
Вызывается после того, как агент завершил формирование сообщения ассистента.
// Входные данные{ "text": "<assistant final text>"}afterAgentThought
Вызывается после того, как Agent завершает блок мышления. Позволяет отслеживать ход рассуждений Agent.
// Входные данные{ "text": "<fully aggregated thinking text>", "duration_ms": 5000}// Выходные данные{ // Выходные поля пока не поддерживаются}| Поле | Тип | Описание |
|---|---|---|
text | string | Полный объединённый текст рассуждений завершённого блока |
duration_ms | number (optional) | Длительность блока рассуждений в миллисекундах |
stop
Вызывается при завершении цикла Agent. При необходимости может автоматически отправить следующее сообщение пользователя, чтобы продолжить итерации.
// Входные данные{ "status": "completed" | "aborted" | "error", "loop_count": 0}// Выходные данные{ "followup_message": "<message text>"}- Необязательное поле
followup_messageсодержит строку. Если оно задано и не пустое, Cursor автоматически отправит её как следующее сообщение пользователя. Это позволяет создавать циклические сценарии (например, выполнять итерации до достижения цели). - Поле
loop_countпоказывает, сколько раз хук stop уже автоматически отправлял следующее сообщение в этом диалоге (начиная с 0). По умолчанию для каждого скрипта разрешено не более 5 автоматических последующих сообщений; это ограничение можно настроить параметромloop_limit. Задайтеloop_limitзначениеnull, чтобы снять ограничение. То же ограничение действует для последующих сообщенийsubagentStop.
sessionStart
Вызывается при создании нового диалога в composer. Этот хук работает по принципу fire-and-forget: цикл Agent не ожидает и не требует блокирующего ответа. Используйте его, чтобы задать переменные среды для конкретной сессии или добавить дополнительный контекст.
// Входные данные{ "session_id": "<unique session identifier>", "is_background_agent": true | false, "composer_mode": "agent" | "ask" | "edit"}// Выходные данные{ "env": { "<key>": "<value>" }, "additional_context": "<context to add to conversation>"}| Поле входных данных | Тип | Описание |
|---|---|---|
session_id | string | Уникальный идентификатор этой сессии (такой же, как conversation_id) |
is_background_agent | boolean | Является ли эта сессия фоновой сессией Agent, а не интерактивной |
composer_mode | string (optional) | Режим, в котором запускается composer (например, "agent", "ask", "edit") |
| Поле выходных данных | Тип | Описание |
|---|---|---|
env | object (optional) | Переменные среды для этой сессии. Доступны при всех последующих выполнениях хуков |
additional_context | string (optional) | Дополнительный контекст, добавляемый в начальный системный контекст диалога |
Схема также принимает поля continue и user_message, но текущие вызывающие стороны не требуют их. Создание сессии не блокируется, даже если continue имеет значение false.
sessionEnd
Вызывается при завершении диалога в composer. Это хук типа fire-and-forget, полезный для логирования, аналитики или очистки. Ответ записывается в журнал, но не используется.
// Входные данные{ "session_id": "<unique session identifier>", "reason": "completed" | "aborted" | "error" | "window_close" | "user_close", "duration_ms": 45000, "is_background_agent": true | false, "final_status": "<status string>", "error_message": "<error details if reason is 'error'>"}// Выходные данные{ // Выходных полей нет — отправил и забыл}| Поле входных данных | Тип | Описание |
|---|---|---|
session_id | string | Уникальный идентификатор завершаемой сессии |
reason | string | Причина завершения сессии: "completed", "aborted", "error", "window_close" или "user_close" |
duration_ms | number | Общая продолжительность сессии в миллисекундах |
is_background_agent | boolean | Является ли сессия сессией фонового Agent |
final_status | string | Итоговый статус сессии |
error_message | string (optional) | Сообщение об ошибке, если reason имеет значение "error" |
preCompact
Вызывается перед сжатием или суммированием контекстного окна. Это наблюдательный хук: он не может блокировать или изменять процесс сжатия. Полезен для логирования сжатия или уведомления пользователей.
// Входные данные{ "trigger": "auto" | "manual", "context_usage_percent": 85, "context_tokens": 120000, "context_window_size": 128000, "message_count": 45, "messages_to_compact": 30, "is_first_compaction": true | false}// Выходные данные{ "user_message": "<message to show when compaction occurs>"}| Поле входных данных | Тип | Описание |
|---|---|---|
trigger | string | Причина сжатия: "auto" или "manual" |
context_usage_percent | number | Текущее использование контекстного окна в процентах (0–100) |
context_tokens | number | Текущее количество токенов в контекстном окне |
context_window_size | number | Максимальный размер контекстного окна в токенах |
message_count | number | Количество сообщений в диалоге |
messages_to_compact | number | Количество сообщений, которые будут суммированы |
is_first_compaction | boolean | Это первое сжатие в этом диалоге |
| Поле выходных данных | Тип | Описание |
|---|---|---|
user_message | string (optional) | Сообщение, показываемое пользователю при сжатии контекста |
workspaceOpen
Срабатывает при открытии рабочей области в Cursor и при каждом изменении папок рабочей области. Не срабатывает, если в окне нет папок рабочей области. Работает в приложении Cursor для компьютера и CLI.
// Входные данные{ "hook_event_name": "workspaceOpen", "cursor_version": "string", "workspace_roots": ["<absolute path>"], "user_email": "string | null"}// Выходные данные{ "pluginPaths": ["<absolute path>", "..."]}| Поле выходных данных | Тип | Описание |
|---|---|---|
pluginPaths | string[] (необязательно) | Абсолютные пути к каталогам плагинов, загружаемых для текущего рабочего пространства. |
Переменные среды
При выполнении скриптам хуков передаются переменные среды:
| Переменная | Описание | Всегда доступна |
|---|---|---|
CURSOR_PROJECT_DIR | Корневой каталог рабочего пространства | Да |
CURSOR_VERSION | Строка версии Cursor | Да |
CURSOR_USER_EMAIL | Email аутентифицированного пользователя | Если выполнен вход |
CURSOR_TRANSCRIPT_PATH | Путь к файлу транскрипта диалога | Если транскрипты включены |
CURSOR_CODE_REMOTE | Устанавливается в значение "true" при запуске в удалённом рабочем пространстве | Для удалённых рабочих пространств |
CLAUDE_PROJECT_DIR | Псевдоним каталога проекта (для совместимости с Claude) | Да |
Переменные среды уровня сессии, заданные хуками sessionStart, передаются при всех последующих запусках хуков в этой сессии.
Устранение неполадок
Как проверить, активны ли хуки
Во вкладке Hooks раздела Настроить и канале выходных данных Hooks можно отлаживать настроенные и выполненные хуки, а также просматривать ошибки.
Если хуки не работают
- Cursor отслеживает файлы
hooks.jsonи перезагружает их при сохранении. Если хуки по-прежнему не загружаются, перезапустите Cursor. - Проверьте правильность относительных путей к исходным файлам хуков:
- Для хуков проекта пути задаются относительно корня проекта (например,
.cursor/hooks/script.sh) - Для пользовательских хуков пути задаются относительно
~/.cursor/(например,./hooks/script.shилиhooks/script.sh)
- Для хуков проекта пути задаются относительно корня проекта (например,
Блокировка по коду выхода
Код выхода 2 командного хука блокирует действие (эквивалентно возврату permission: "deny"). Это соответствует поведению Claude Code для совместимости.
Хуки Enterprise и распространение
Облачное распространение и управление хуками для всей команды доступны в Enterprise.