[Go to site: main page, start]

Skip to main content

Command Palette

Search for a command to run...

Personalizar

Hooks

Los hooks permiten observar, controlar y ampliar el bucle del agente mediante scripts personalizados. Define hooks en archivos hooks.json a nivel de proyecto o de usuario, o instálalos mediante plugins desde Personalizar. Los hooks son procesos que se ejecutan y se comunican mediante stdio usando JSON en ambas direcciones. Se ejecutan antes o después de etapas definidas del bucle del agente y pueden observar, bloquear o modificar su comportamiento.

Con los hooks, puedes:

  • Ejecutar formateadores después de las ediciones
  • Añadir analítica a los eventos
  • Analizar PII o secretos
  • Restringir operaciones de riesgo (p. ej., escrituras SQL)
  • Controlar la ejecución de subagentes (herramienta Task)
  • Inyectar contexto al inicio de la sesión

Categorías de hooks

Los hooks se dividen en tres categorías según el evento que los activa:

Hooks de Agent (Cmd+K/Agent Chat) se activan durante una sesión del agente:

  • sessionStart / sessionEnd - Gestión del ciclo de vida de la sesión
  • preToolUse / postToolUse / postToolUseFailure - Hooks genéricos para el uso de herramientas (se activan con todas las herramientas)
  • subagentStart / subagentStop - Ciclo de vida de los subagentes (herramienta Task)
  • beforeShellExecution / afterShellExecution - Controlan los comandos de shell
  • beforeMCPExecution / afterMCPExecution - Controlan el uso de herramientas MCP
  • beforeReadFile / afterFileEdit - Controlan el acceso a archivos y las ediciones
  • beforeSubmitPrompt - Validan las instrucciones antes de enviarlas
  • preCompact - Supervisan la compactación de la ventana de contexto
  • stop - Gestiona la finalización del agente
  • afterAgentResponse / afterAgentThought - Realizan un seguimiento de las respuestas del agente

Hooks de Tab (finalizaciones en línea) se activan en operaciones autónomas de Tab:

  • beforeTabFileRead - Controlan el acceso a archivos para las finalizaciones de Tab
  • afterTabFileEdit - Procesan las ediciones de Tab tras realizarlas

Hooks del ciclo de vida de la app se activan fuera de cualquier sesión del agente:

  • workspaceOpen - Se activa cuando Cursor abre un espacio de trabajo y cada vez que cambia una carpeta del espacio de trabajo. Puede devolver rutas de plugins adicionales que se cargarán para el espacio de trabajo actual.

Estas superficies de hooks independientes permiten aplicar distintas políticas a las operaciones autónomas de Tab, las operaciones de Agent dirigidas por el usuario y el inicio del espacio de trabajo.

Compatibilidad con agentes en la nube

Los agentes en la nube ejecutan hooks basados en comandos de tu repositorio. Si tienes hooks definidos en .cursor/hooks.json en la raíz de tu proyecto, los agentes en la nube los detectan y los ejecutan durante su trabajo.

En los planes Enterprise, los agentes en la nube también ejecutan hooks de equipo y hooks gestionados por la empresa configurados a través del Panel de control web.

Los agentes en la nube a veces comienzan en un entorno de solo lectura durante las primeras interacciones de exploración. Los hooks no se ejecutan durante esas interacciones. Se ejecutan una vez que el agente cuenta con un entorno con permisos de escritura.

Hooks compatibles

Los siguientes hooks se ejecutan en agentes en la nube:

HookCompatible
beforeShellExecution
afterShellExecution
beforeReadFile
afterFileEdit
preToolUse
postToolUse
postToolUseFailure
subagentStart
subagentStop
beforeSubmitPrompt
preCompact
afterAgentResponse
afterAgentThought
stop

Hooks no disponibles en agentes en la nube

Algunos hooks no se aplican a los agentes en la nube debido a diferencias en el entorno de ejecución:

HookMotivo
sessionStartSe pospone, ya que los agentes en la nube pueden iniciarse en un entorno de solo lectura. Los hooks no se cargan en ese entorno, por lo que un sessionStart en la nube se activaría demasiado tarde (después de la primera escritura), en lugar de al inicio real de la sesión.
sessionEndLos agentes en la nube no tienen un límite de sesión asociado a la duración del Editor. sessionEnd está vinculado a la sesión del IDE, no a un chat con un agente en la nube.
beforeMCPExecution / afterMCPExecutionSe pospone, ya que los agentes en la nube pueden iniciarse en un entorno de solo lectura, donde los hooks no se cargan y no está claro cuándo deben ejecutarse los hooks de MCP.
beforeTabFileRead / afterTabFileEditLas finalizaciones en línea de Tab son una función del IDE y no se ejecutan en agentes en la nube.
workspaceOpenEste es un hook del ciclo de vida del IDE y no se aplica a los agentes en la nube.

Fuentes de configuración

Los agentes en la nube cargan hooks de estas fuentes:

  • Hooks de proyecto (.cursor/hooks.json en tu repo): Se cargan y ejecutan durante el trabajo del agente en la nube.
  • Hooks de equipo (Enterprise): Se distribuyen desde el panel de control y se ejecutan en agentes en la nube.
  • Hooks de Enterprise (Enterprise): Hooks gestionados en todo el sistema que se ejecutan en agentes en la nube.

Los hooks de nivel de usuario (~/.cursor/hooks.json) no están disponibles en los agentes en la nube. Las VM de los agentes en la nube no tienen acceso a la configuración de tu directorio personal local.

Limitaciones según el tipo de ejecución

Los agentes en la nube solo ejecutan hooks basados en comandos. Los hooks basados en prompts requieren una conexión de autenticación entre el hook y el bucle del agente, que no está disponible en el entorno de ejecución en la nube.

Inicio rápido

Crea un archivo hooks.json. Puedes crearlo a nivel de proyecto (<project>/.cursor/hooks.json) o en tu directorio personal (~/.cursor/hooks.json). Los hooks de proyecto solo se aplican a ese proyecto, mientras que los hooks del directorio personal se aplican globalmente.

Para crear hooks de usuario que se apliquen globalmente, crea ~/.cursor/hooks.json:

{  "version": 1,  "hooks": {    "afterFileEdit": [{ "command": "./hooks/format.sh" }]  }}

Crea el script del hook en ~/.cursor/hooks/format.sh:

#!/bin/bash# Lee la entrada, realiza alguna acción y termina con 0cat > /dev/nullexit 0

Hazlo ejecutable:

chmod +x ~/.cursor/hooks/format.sh

Cursor supervisa los archivos de configuración de hooks y los recarga automáticamente. El hook se ejecuta después de cada edición de archivo.

Tipos de hooks

Los hooks admiten dos tipos de ejecución: basada en comandos (predeterminada) y basada en prompts (evaluada por un LLM).

Hooks basados en comandos

Los hooks de comandos ejecutan scripts de shell que reciben datos JSON a través de stdin y devuelven datos JSON a través de stdout.

{  "hooks": {    "beforeShellExecution": [      {        "command": "./scripts/approve-network.sh",        "timeout": 30,        "matcher": "curl|wget|nc"      }    ]  }}

Comportamiento del código de salida:

  • Código de salida 0 - El hook se ejecutó correctamente; usa la salida JSON
  • Código de salida 2 - Bloquea la acción (equivale a devolver permission: "deny")
  • Otros códigos de salida - El hook falló; la acción continúa (por defecto, no se bloquea en caso de error)

Hooks basados en prompts

Los hooks basados en prompts usan un LLM para evaluar una condición en lenguaje natural. Sirven para aplicar políticas sin necesidad de escribir scripts personalizados.

{  "hooks": {    "beforeShellExecution": [      {        "type": "prompt",        "prompt": "Does this command look safe to execute? Only allow read-only operations.",        "timeout": 10      }    ]  }}

Funciones:

  • Devuelve una respuesta estructurada de { ok: boolean, reason?: string }
  • Usa un modelo rápido para evaluaciones ágiles
  • El marcador $ARGUMENTS se reemplaza automáticamente por el JSON de entrada del hook
  • Si no está $ARGUMENTS, la entrada del hook se añade automáticamente
  • Campo model opcional para anular el modelo de LLM predeterminado

Ejemplos

{  "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"      }    ]  }}

Hook de automatización stop en TypeScript

Elige TypeScript si necesitas JSON tipado, E/S de archivos persistente y llamadas HTTP en un mismo hook. Este hook stop basado en Bun registra en disco los recuentos de fallos por conversación, envía telemetría estructurada a una API interna y puede programar automáticamente un reintento cuando el agente falla dos veces seguidas.

{  "version": 1,  "hooks": {    "stop": [      {        "command": "bun run .cursor/hooks/track-stop.ts --stop"      }    ]  }}

Establece AGENT_TELEMETRY_URL con el endpoint interno que debe recibir los resúmenes de ejecución.

Hook de protección para manifiestos de Python

Python destaca cuando necesitas bibliotecas avanzadas de análisis. Este hook usa pyyaml para inspeccionar manifiestos de Kubernetes antes de ejecutar kubectl apply; Bash tendría dificultades para analizar de forma segura archivos YAML con varios documentos.

{  "version": 1,  "hooks": {    "beforeShellExecution": [      {        "command": "python3 .cursor/hooks/kube_guard.py"      }    ]  }}

Instala PyYAML (por ejemplo, pip install pyyaml) en todos los entornos donde se ejecuten tus scripts de hooks para que la importación del analizador funcione correctamente.

Integraciones con socios

Colaboramos con proveedores del ecosistema que han desarrollado compatibilidad con hooks para Cursor. Estas integraciones incluyen análisis de seguridad, gobernanza, gestión de secretos y más.

Gobernanza y visibilidad de MCP

partnerDescripción
MintMCPCree un inventario completo de servidores MCP, supervise los patrones de uso de las herramientas y analice las respuestas para detectar datos confidenciales antes de que lleguen al modelo de IA.
Oasis SecurityAplique políticas de mínimo privilegio a las acciones de los agentes de IA y mantenga registros de auditoría completos en todos los sistemas de la empresa.
RunlayerEncapsule las herramientas MCP e intégrelas con su intermediario MCP para centralizar el control y la visibilidad de las interacciones entre agentes y herramientas.

Seguridad del código y mejores prácticas

partnerDescripción
CorridorObtén comentarios en tiempo real sobre la implementación del código y las decisiones de diseño de seguridad mientras escribes código.
SemgrepAnaliza automáticamente el código generado por IA en busca de vulnerabilidades y recibe comentarios en tiempo real para regenerarlo hasta resolver las vulnerabilidades de seguridad.

Seguridad de las dependencias

partnerDescripción
Endor LabsIntercepta la instalación de paquetes y analiza dependencias maliciosas para evitar ataques a la cadena de suministro antes de que lleguen a tu base de código.

Seguridad de los agentes

partnerDescripción
SnykSupervisa en tiempo real las acciones de los agentes con Evo Agent Guard para detectar y prevenir problemas como la inyección de prompts y las llamadas a herramientas peligrosas.

Gestión de secretos

PartnerDescripción
1PasswordVerifica que los archivos de entorno de 1Password Environments estén correctamente montados antes de ejecutar comandos de shell, lo que permite acceder a secretos justo a tiempo sin escribir credenciales en el disco.

Para más información sobre nuestros partners de hooks, consulta la publicación del blog Hooks para equipos de seguridad y plataforma.

Configuración

Define hooks en un archivo hooks.json. La configuración puede existir en varios niveles. Se ejecutan todos los hooks coincidentes de cada fuente; cuando las respuestas entran en conflicto, prevalecen las fuentes de mayor prioridad durante la fusión:

~/.cursor/├── hooks.json└── hooks/    ├── audit.sh    └── block-git.sh
  • Enterprise (gestionado por MDM en todo el sistema):
    • macOS: /Library/Application Support/Cursor/hooks.json
    • Linux/WSL: /etc/cursor/hooks.json
    • Windows: C:\\ProgramData\\Cursor\\hooks.json
  • Equipo (distribuido desde Cloud, solo para Enterprise):
    • Se configura en el Panel de control web y se sincroniza automáticamente con todos los miembros del equipo
  • Proyecto (específico del proyecto):
    • <project-root>/.cursor/hooks.json
    • Los hooks de proyecto se ejecutan en cualquier espacio de trabajo de confianza y se incluyen en el control de versiones junto con el proyecto
  • Usuario (específico del usuario):
    • ~/.cursor/hooks.json

Orden de prioridad (de mayor a menor): Enterprise → Equipo → Proyecto → Usuario

El objeto hooks asigna nombres de hooks a arrays de definiciones de hooks. Actualmente, cada definición admite una propiedad command que puede ser una cadena de shell, una ruta absoluta o una ruta relativa. El directorio de trabajo depende del origen del hook:

  • Hooks de proyecto (.cursor/hooks.json en un repositorio): Se ejecutan desde la raíz del proyecto
  • Hooks de usuario (~/.cursor/hooks.json): Se ejecutan desde ~/.cursor/
  • Hooks de Enterprise (configuración de todo el sistema): Se ejecutan desde el directorio de configuración de Enterprise
  • Hooks de equipo (distribuidos desde Cloud): Se ejecutan desde el directorio de hooks gestionados

Para los hooks de proyecto, usa rutas como .cursor/hooks/script.sh (relativas a la raíz del proyecto), no ./hooks/script.sh (que buscaría <project>/hooks/script.sh).

Archivo de configuración

Este ejemplo muestra un archivo de hooks a nivel de usuario (~/.cursor/hooks.json). Para los hooks a nivel de proyecto, cambia rutas como ./hooks/script.sh por .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" }]  }}

Los hooks de Agent (sessionStart, sessionEnd, preToolUse, postToolUse, postToolUseFailure, subagentStart, subagentStop, beforeShellExecution, afterShellExecution, beforeMCPExecution, afterMCPExecution, beforeReadFile, afterFileEdit, beforeSubmitPrompt, preCompact, stop, afterAgentResponse, afterAgentThought) se aplican a las operaciones de Cmd+K y Agent Chat. Los hooks de Tab (beforeTabFileRead, afterTabFileEdit) se aplican específicamente a las finalizaciones en línea de Tab. El hook del ciclo de vida de la aplicación (workspaceOpen) se activa al abrir un espacio de trabajo y cuando cambian las carpetas del espacio de trabajo, independientemente de cualquier sesión del agente.

Opciones de configuración global

OpciónTipoPredeterminadoDescripción
versionnúmero1Versión del esquema de configuración

Opciones de configuración por script

OpciónTipoPredeterminadoDescripción
commandstringobligatorioRuta o comando del script
type"command""prompt""command"
timeoutnumbervalor predeterminado de la plataformaTiempo de espera de ejecución en segundos
loop_limitnumbernull5
failClosedbooleanfalseCuando es true, los errores del hook (bloqueo, tiempo de espera o JSON no válido) bloquean la acción en lugar de permitir que continúe. Útil para hooks críticos para la seguridad.
matcherobject-Criterios de filtro que determinan cuándo se ejecuta el hook

Configuración de matchers

Los matchers permiten filtrar cuándo se ejecuta un hook. El campo al que se aplica cada matcher depende del hook:

{  "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: El matcher se aplica al tipo de subagente (p. ej., explore, shell, generalPurpose). Úsalo para ejecutar hooks solo cuando se inicie un tipo específico de subagente. El ejemplo anterior ejecuta validate-explore.sh solo para subagentes de exploración o de shell.
  • beforeShellExecution: El matcher se aplica a la cadena del comando de shell. Úsalo para ejecutar hooks solo cuando el comando coincida con un patrón (p. ej., llamadas de red o eliminación de archivos). El ejemplo anterior ejecuta approve-network.sh solo cuando el comando contiene curl, wget o nc .

Matchers disponibles por hook:

  • preToolUse / postToolUse / postToolUseFailure: Filtra por tipo de herramienta. Los valores incluyen Shell, Read, Write, Grep, Delete, Task y herramientas MCP con el formato MCP:<tool_name>.
  • subagentStart / subagentStop: Filtra por tipo de subagente (generalPurpose, explore, shell, etc.).
  • beforeShellExecution / afterShellExecution: Filtra por el texto del comando de shell; el matcher se aplica a la cadena completa del comando.
  • beforeReadFile: Filtra por tipo de herramienta (TabRead, Read, etc.).
  • afterFileEdit: Filtra por tipo de herramienta (TabWrite, Write, etc.).
  • beforeSubmitPrompt: Se aplica al valor UserPromptSubmit.
  • stop: Se aplica al valor Stop.
  • afterAgentResponse: Se aplica al valor AgentResponse.
  • afterAgentThought: Se aplica al valor AgentThought.

Distribución en equipos

Los hooks pueden distribuirse a los miembros del equipo mediante hooks de proyecto (a través del control de versiones), herramientas de MDM o el sistema de distribución en la nube de Cursor.

Hooks de proyecto (control de versiones)

Los hooks de proyecto son la forma más sencilla de compartir hooks con tu equipo. Coloca un archivo hooks.json en <project-root>/.cursor/hooks.json y súbelo a tu repositorio. Cuando los miembros del equipo abren el proyecto en un espacio de trabajo de confianza, Cursor carga y ejecuta automáticamente los hooks de proyecto.

Los agentes en la nube también cargan estos hooks de proyecto cuando trabajan en tu repositorio en la nube.

Los hooks de proyecto:

  • Se almacenan en el control de versiones junto con tu código
  • Se cargan automáticamente para todos los miembros del equipo en espacios de trabajo de confianza
  • Pueden ser específicos del proyecto (p. ej., para aplicar estándares de formato a una base de código concreta)
  • Requieren un espacio de trabajo de confianza para ejecutarse (por seguridad)

Distribución mediante MDM

Distribuye hooks en toda tu organización mediante herramientas de gestión de dispositivos móviles (MDM). Coloca el archivo hooks.json y los scripts de hooks en los directorios de destino de cada máquina.

Directorio de inicio del usuario (distribución por usuario):

  • ~/.cursor/hooks.json
  • ~/.cursor/hooks/ (para scripts de hooks)

Directorios globales (distribución para todo el sistema):

  • macOS: /Library/Application Support/Cursor/hooks.json
  • Linux/WSL: /etc/cursor/hooks.json
  • Windows: C:\\ProgramData\\Cursor\\hooks.json

Nota: La distribución mediante MDM está totalmente gestionada por tu organización. Cursor no implementa ni gestiona archivos a través de tu solución MDM. Asegúrate de que tu equipo interno de TI o seguridad se encargue de la configuración, la implementación y las actualizaciones conforme a las políticas de tu organización.

Distribución en la nube (solo Enterprise)

Los equipos Enterprise pueden usar la distribución nativa en la nube de Cursor para sincronizar automáticamente los hooks con todos los miembros del equipo. Configure los hooks en el Panel de control web. Cursor entrega automáticamente los hooks configurados a todas las máquinas cliente cuando los miembros del equipo inician sesión.

La distribución en la nube ofrece:

  • Sincronización automática con todos los miembros del equipo (cada treinta minutos)
  • Selección por sistema operativo para hooks específicos de cada plataforma
  • Gestión centralizada desde el panel de control

Los administradores de Enterprise pueden crear, editar y gestionar hooks de equipo desde el panel de control sin necesidad de acceder a máquinas individuales.

Contacte con ventas para obtener la distribución de hooks en la nube para Enterprise.

Referencia

Esquema común

Entrada (todos los hooks)

Todos los hooks reciben un conjunto básico de campos, además de los campos específicos de cada hook:

{  "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"}
CampoTipoDescripción
conversation_idstringID estable de la conversación a lo largo de varias interacciones
generation_idstringLa generación actual, que cambia con cada mensaje del usuario
modelstringSlug del modelo heredado configurado para el composer que activó el hook
model_idstring (optional)ID estructurado del modelo seleccionado, cuando está disponible
model_paramsarray (optional)Parámetros del modelo seleccionado, como thinking, contexto o esfuerzo. Cada elemento tiene un id y un value.
hook_event_namestringEl hook que se está ejecutando
cursor_versionstringVersión de la aplicación Cursor (p. ej., "1.7.2")
workspace_rootsstring[]Lista de carpetas raíz del espacio de trabajo (normalmente solo una, pero los espacios de trabajo multirraíz pueden tener varias)
user_emailstringnullDirección de correo electrónico del usuario autenticado, si está disponible
transcript_pathstringnullRuta al archivo de transcripción de la conversación principal (null si las transcripciones están desactivadas)

Eventos de hooks

preToolUse

Se invoca antes de ejecutar cualquier herramienta. Es un hook genérico que se activa con todos los tipos de herramientas (Shell, Read, Write, MCP, Task, etc.). Usa matchers para filtrar herramientas específicas.

// Entrada{  "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..."}// Salida{  "permission": "allow" | "deny",  "user_message": "<message shown in client when denied>",  "agent_message": "<message sent to agent when denied>",  "updated_input": { "command": "npm ci" }}
Campo de salidaTipoDescripción
permissionstring"allow" para permitir la acción, "deny" para bloquearla. "ask" se acepta en el esquema, pero actualmente no se aplica para preToolUse.
user_messagestring (opcional)Mensaje que se muestra al usuario cuando se deniega la acción
agent_messagestring (opcional)Mensaje que se envía al agente cuando se deniega la acción
updated_inputobjeto (opcional)Entrada de la herramienta modificada para usar en su lugar

postToolUse

Se invoca tras ejecutar correctamente una herramienta. Útil para auditorías, analítica e inyectar contexto.

// Entrada{  "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" }  ]}// Salida{  "updated_mcp_tool_output": { "modified": "output" },  "additional_context": "Test coverage report attached."}
Campo de entradaTipoDescripción
durationnumberTiempo de ejecución en milisegundos
tool_outputstringPayload de resultado de la herramienta serializado como JSON (no texto sin procesar de la terminal)
Campo de salidaTipoDescripción
updated_mcp_tool_outputobjeto (opcional)Solo para herramientas MCP: reemplaza la salida de la herramienta que ve el modelo
additional_contextstring (opcional)Contexto adicional inyectado en la conversación después del resultado de la herramienta

postToolUseFailure

Se llama cuando una herramienta falla, se agota el tiempo de espera o se rechaza. Útil para el seguimiento de errores y la lógica de recuperación.

// Entrada{  "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}// Salida{  // Actualmente no se admiten campos de salida}
Campo de entradaTipoDescripción
error_messagestringDescripción del error
failure_typestringTipo de error: "error", "timeout" o "permission_denied"
durationnumberTiempo transcurrido en milisegundos hasta que se produjo el error
is_interruptbooleanIndica si este error se debió a una interrupción o cancelación del usuario

subagentStart

Se invoca antes de iniciar un subagente (herramienta Task). Puede permitir o denegar la creación de subagentes.

// Entrada{  "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"}// Salida{  "permission": "allow" | "deny",  "user_message": "<message shown when denied>"}
Campo de entradaTipoDescripción
subagent_idstringIdentificador único de esta instancia de subagente
subagent_typestringTipo de subagente: generalPurpose, explore, shell, etc.
taskstringDescripción de la tarea asignada al subagente
parent_conversation_idstringID de conversación de la sesión del agente principal
tool_call_idstringID de la llamada a herramienta que activó el subagente
subagent_modelstringModelo que usará el subagente
is_parallel_workerbooleanIndica si este subagente se ejecuta como worker paralelo
git_branchstring (optional)Rama de Git en la que operará el subagente, si corresponde
Campo de salidaTipoDescripción
permissionstring"allow" para continuar, "deny" para bloquear. "ask" no es compatible con subagentStart y se trata como "deny".
user_messagestring (optional)Mensaje que se muestra al usuario cuando se deniega el subagente

subagentStop

Se llama cuando un subagente finaliza, presenta errores o se cancela. Puede activar acciones de seguimiento.

// Entrada{  "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"}// Salida{  "followup_message": "<auto-continue with this message>"}
Campo de entradaTipoDescripción
subagent_typestringTipo de subagente: generalPurpose, explore, shell, etc.
statusstring"completed", "error" o "aborted"
taskstringDescripción de la tarea asignada al subagente
descriptionstringBreve descripción del propósito del subagente
summarystringResumen de la salida del subagente
duration_msnumberTiempo de ejecución en milisegundos
message_countnumberNúmero de mensajes intercambiados durante la sesión del subagente
tool_call_countnumberNúmero de llamadas a herramientas realizadas por el subagente
loop_countnumberNúmero de veces que un seguimiento de subagentStop ya se ha activado para este subagente (empieza en 0)
modified_filesstring[]Archivos modificados por el subagente
agent_transcript_pathstringnullRuta al archivo de transcripción propio del subagente (independiente de la conversación principal)
Campo de salidaTipoDescripción
followup_messagestring (optional)Continúa automáticamente con este mensaje. Solo se procesa cuando status es "completed".

El campo followup_message permite flujos en bucle en los que la finalización de un subagente activa la siguiente iteración. Los mensajes de seguimiento están sujetos al mismo límite de bucle configurable que el hook stop (5 de forma predeterminada, configurable mediante loop_limit).

beforeShellExecution / beforeMCPExecution

Se ejecuta antes de que se ejecute cualquier comando de shell o herramienta MCP. Devuelve una decisión de permiso.

// entrada de beforeShellExecution{  "command": "<full terminal command>",  "cwd": "<current working directory>",  "sandbox": false}// entrada de beforeMCPExecution{  "tool_name": "<tool name>",  "tool_input": "<json params>"}// Además, una de estas opciones:{ "url": "<server url>" }// O:{ "command": "<command string>" }// Salida{  "permission": "allow" | "deny" | "ask",  "user_message": "<message shown in client>",  "agent_message": "<message sent to agent>"}

afterShellExecution

Se activa después de ejecutar un comando de shell; resulta útil para auditorías o para recopilar métricas de la salida del comando.

// Entrada{  "command": "<full terminal command>",  "output": "<full terminal output>",  "duration": 1234,  "sandbox": false}
CampoTipoDescripción
commandstringEl comando de terminal completo que se ejecutó
outputstringLa salida completa capturada de la terminal
durationnumberDuración en milisegundos de la ejecución del comando de shell (no incluye el tiempo de espera de aprobación)
sandboxbooleanIndica si el comando se ejecutó en un entorno aislado

afterMCPExecution

Se activa después de ejecutar una herramienta MCP; incluye los parámetros de entrada de la herramienta y el resultado completo en JSON.

// Entrada{  "tool_name": "<tool name>",  "tool_input": "<json params>",  "result_json": "<tool result json>",  "duration": 1234}
CampoTipoDescripción
tool_namestringNombre de la herramienta MCP ejecutada
tool_inputstringCadena de parámetros JSON pasada a la herramienta
result_jsonstringCadena JSON de la respuesta de la herramienta
durationnumberDuración en milisegundos de la ejecución de la herramienta MCP (no incluye el tiempo de espera de aprobación)

afterFileEdit

Se activa después de que el agente edite un archivo; resulta útil para formateadores o para contabilizar el código escrito por el agente.

// Entrada{  "file_path": "<absolute path>",  "edits": [{ "old_string": "<search>", "new_string": "<replace>" }]}

beforeReadFile

Se ejecuta antes de que el agente lea un archivo. Úsalo para controlar el acceso e impedir que se envíen archivos confidenciales al modelo.

// Entrada{  "file_path": "<absolute path>",  "content": "<file contents>",  "attachments": [    {      "type": "file" | "rule",      "file_path": "<absolute path>"    }  ]}// Salida{  "permission": "allow" | "deny",  "user_message": "<message shown when denied>"}
Campo de entradaTipoDescripción
file_pathstringRuta absoluta del archivo que se está leyendo
contentstringContenido completo del archivo
attachmentsarrayArchivos adjuntos de contexto asociados a la instrucción. Cada entrada tiene un type ("file" o "rule") y un file_path.
Campo de salidaTipoDescripción
permissionstring"allow" para continuar, "deny" para bloquear
user_messagestring (opcional)Mensaje que se muestra al usuario cuando se deniega

beforeTabFileRead

Se invoca antes de que Tab (completaciones en línea) lea un archivo. Activa la redacción o el control de acceso antes de que Tab acceda al contenido del archivo.

Diferencias clave respecto a beforeReadFile:

  • Solo se activa con Tab, no con agente
  • No incluye el campo attachments (Tab no usa archivos adjuntos en las instrucciones)
  • Útil para aplicar políticas diferentes a las operaciones autónomas de Tab
// Entrada{  "file_path": "<absolute path>",  "content": "<file contents>"}// Salida{  "permission": "allow" | "deny"}

afterTabFileEdit

Se llama después de que Tab (completaciones en línea) edite un archivo. Es útil para formateadores o para auditar código escrito por Tab.

Diferencias clave con afterFileEdit:

  • Solo lo activa Tab, no agente
  • Incluye información detallada sobre la edición: range, old_line y new_line para realizar un seguimiento preciso de los cambios
  • Útil para formatear o analizar en detalle las ediciones de Tab
// Entrada{  "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>"    }  ]}// Salida{  // Actualmente no se admiten campos de salida}

beforeSubmitPrompt

Se llama justo después de que el usuario pulsa Enviar, pero antes de la solicitud al backend. Puede impedir el envío.

// Entrada{  "prompt": "<user prompt text>",  "attachments": [    {      "type": "file" | "rule",      "file_path": "<absolute path>"    }  ]}// Salida{  "continue": true | false,  "user_message": "<message shown to user when blocked>"}
Campo de salidaTipoDescripción
continuebooleanIndica si se permite continuar con el envío de la instrucción
user_messagestring (opcional)Mensaje que se muestra al usuario cuando se bloquea la instrucción

afterAgentResponse

Se invoca después de que el agente haya completado un mensaje del asistente.

// Entrada{  "text": "<assistant final text>"}

afterAgentThought

Se llama cuando el agente termina un bloque de razonamiento. Útil para observar su proceso de razonamiento.

// Entrada{  "text": "<fully aggregated thinking text>",  "duration_ms": 5000}// Salida{  // Actualmente no se admiten campos de salida}
CampoTipoDescripción
textstringTexto de razonamiento agregado completo del bloque finalizado
duration_msnumber (optional)Duración en milisegundos del bloque de razonamiento

stop

Se ejecuta cuando finaliza el ciclo del agente. Opcionalmente, puede enviar automáticamente un mensaje de seguimiento del usuario para continuar iterando.

// Entrada{  "status": "completed" | "aborted" | "error",  "loop_count": 0}
// Salida{  "followup_message": "<message text>"}
  • El followup_message opcional es una cadena. Si se proporciona y no está vacío, Cursor lo enviará automáticamente como el siguiente mensaje del usuario. Esto permite flujos en bucle (p. ej., iterar hasta alcanzar un objetivo).
  • El campo loop_count indica cuántas veces el hook stop ya ha activado un mensaje de seguimiento automático para esta conversación (comienza en 0). El límite predeterminado es de 5 mensajes de seguimiento automáticos por script, configurable mediante la opción loop_limit. Establece loop_limit en null para eliminar el límite. El mismo límite se aplica a los mensajes de seguimiento de subagentStop.

sessionStart

Se invoca cuando se crea una nueva conversación de composer. Este hook se ejecuta de forma fire-and-forget; el bucle del agente no espera ni exige una respuesta bloqueante. Úsalo para configurar variables de entorno específicas de la sesión o inyectar contexto adicional.

// Entrada{  "session_id": "<unique session identifier>",  "is_background_agent": true | false,  "composer_mode": "agent" | "ask" | "edit"}
// Salida{  "env": { "<key>": "<value>" },  "additional_context": "<context to add to conversation>"}
Campo de entradaTipoDescripción
session_idstringIdentificador único de esta sesión (igual que conversation_id)
is_background_agentbooleanIndica si se trata de una sesión de agente en segundo plano o de una sesión interactiva
composer_modestring (opcional)El modo en el que se inicia composer (p. ej., "agent", "ask", "edit")
Campo de salidaTipoDescripción
envobjeto (opcional)Variables de entorno que se deben establecer para esta sesión. Están disponibles para todas las ejecuciones posteriores de hooks
additional_contextstring (opcional)Contexto adicional que se debe añadir al contexto inicial del sistema de la conversación

sessionEnd

Se llama cuando finaliza una conversación de composer. Este hook fire-and-forget es útil para tareas de registro, analítica o limpieza. La respuesta se registra, pero no se utiliza.

// Entrada{  "session_id": "<identificador de sesión único>",  "reason": "completed" | "aborted" | "error" | "window_close" | "user_close",  "duration_ms": 45000,  "is_background_agent": true | false,  "final_status": "<cadena de estado>",  "error_message": "<detalles del error si reason es 'error'>"}
// Salida{  // Sin campos de salida: se envía y se olvida}
Campo de entradaTipoDescripción
session_idstringIdentificador único de la sesión que está finalizando
reasonstringCómo finalizó la sesión: "completed", "aborted", "error", "window_close" o "user_close"
duration_msnumberDuración total de la sesión en milisegundos
is_background_agentbooleanIndica si se trató de una sesión de un agente en segundo plano
final_statusstringEstado final de la sesión
error_messagestring (optional)Mensaje de error si el motivo es "error"

preCompact

Se llama antes de que se produzca la compactación o resumido de la ventana de contexto. Es un hook de observación que no puede bloquear ni modificar el comportamiento de la compactación. Resulta útil para registrar cuándo se produce la compactación o notificar a los usuarios.

// Entrada{  "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}
// Salida{  "user_message": "<message to show when compaction occurs>"}
Campo de entradaTipoDescripción
triggerstringQué desencadenó la compactación: "auto" o "manual"
context_usage_percentnumberUso actual de la ventana de contexto como porcentaje (0-100)
context_tokensnumberNúmero actual de tokens de la ventana de contexto
context_window_sizenumberTamaño máximo de la ventana de contexto en tokens
message_countnumberNúmero de mensajes de la conversación
messages_to_compactnumberNúmero de mensajes que se resumirán
is_first_compactionbooleanIndica si esta es la primera compactación de la conversación
Campo de salidaTipoDescripción
user_messagestring (optional)Mensaje que se mostrará al usuario cuando se produzca la compactación

workspaceOpen

Se activa una vez cuando Cursor abre un espacio de trabajo y de nuevo cada vez que cambia una carpeta del espacio de trabajo. Se omite cuando la ventana no tiene ninguna carpeta de espacio de trabajo. Se ejecuta en la aplicación de escritorio de Cursor y en la CLI.

// Entrada{  "hook_event_name": "workspaceOpen",  "cursor_version": "string",  "workspace_roots": ["<absolute path>"],  "user_email": "string | null"}// Salida{  "pluginPaths": ["<absolute path>", "..."]}
Campo de salidaTipoDescripción
pluginPathsstring[] (opcional)Rutas absolutas a los directorios de plugins que se cargarán para el espacio de trabajo actual.

Variables de entorno

Los scripts de hook reciben variables de entorno al ejecutarse:

VariableDescripciónSiempre presente
CURSOR_PROJECT_DIRDirectorio raíz del espacio de trabajo
CURSOR_VERSIONCadena de versión de Cursor
CURSOR_USER_EMAILCorreo electrónico del usuario autenticadoSi ha iniciado sesión
CURSOR_TRANSCRIPT_PATHRuta del archivo de transcripción de la conversaciónSi las transcripciones están activadas
CURSOR_CODE_REMOTESe establece en la cadena "true" al ejecutarse en un espacio de trabajo remotoPara espacios de trabajo remotos
CLAUDE_PROJECT_DIRAlias del directorio del proyecto (compatibilidad con Claude)

Las variables de entorno con alcance de sesión de los hooks sessionStart se փոխանցen a todas las ejecuciones posteriores de hooks dentro de esa sesión.

Solución de problemas

Cómo confirmar que los hooks están activos

Hay una pestaña Hooks en Personalizar y un canal de salida de Hooks para depurar los hooks configurados y ejecutados, y consultar errores.

Si los hooks no funcionan

  • Cursor supervisa los archivos hooks.json y los recarga al guardarlos. Si los hooks siguen sin cargarse, reinicia Cursor.
  • Comprueba que las rutas relativas sean correctas para el código fuente de tu hook:
    • Para los hooks de proyecto, las rutas son relativas a la raíz del proyecto (p. ej., .cursor/hooks/script.sh)
    • Para los hooks de usuario, las rutas son relativas a ~/.cursor/ (p. ej., ./hooks/script.sh o hooks/script.sh)

Bloqueo por código de salida

El código de salida 2 de los hooks de comando bloquea la acción (equivale a devolver permission: "deny"). Esto coincide con el comportamiento de Claude Code para garantizar la compatibilidad.

Hooks de Enterprise y distribución

La distribución en la nube y la gestión de hooks para todo el equipo están disponibles en Enterprise.

Contact Sales