Ir al contenido
Mastering Claude

Inicio / Extender: habilidades, MCP, subagentes, hooks, plugins

Extender: habilidades, MCP, subagentes, hooks, plugins11 minApplication

Los eventos de hook, del disparo al mensaje

PreToolUse puede impedir que una llamada se produzca, PostToolUse ya solo puede reaccionar después de los hechos, y la decisión de un hook pasa por campos JSON precisos, nunca por una frase escrita en la salida estándar.

Un hook PreToolUse se ejecuta antes de que la herramienta se active: su decisión puede impedir que la llamada se produzca. Un hook PostToolUse se ejecuta después, una vez que la herramienta ya se ha lanzado: su decisión ya no puede impedir nada, solo reaccionar. Esta diferencia de momento determina lo que un hook puede razonablemente hacer en cada evento, y explica por qué un mismo mecanismo de bloqueo no se comporta de la misma manera según el evento que lo porte.

Una treintena de eventos, del arranque al fin de sesión

La documentación oficial enumera una treintena de eventos del ciclo de vida, desde SessionStart y UserPromptSubmit hasta PreCompact, WorktreeCreate o SessionEnd. Cada uno cubre un momento preciso: un archivo que cambia, un cambio de modelo, un subagente que arranca o termina, una instrucción en curso de expansión. Un automatismo deseado, presentado en la lección anterior como la traducción mecánica de una regla que se esperaba ver seguida, siempre se declara sobre uno de esos eventos precisos, nunca sobre una intención general.

El plazo de expiración depende del tipo de hook, no solo del evento

Un hook de tipo command, http o mcp_tool dispone por defecto de seiscientos segundos para responder. Tres eventos rebajan ese plazo a treinta segundos, UserPromptSubmit, PreModelSwitch y PostModelSwitch, y uno solo lo reduce a diez segundos, MessageDisplay. Un hook de tipo prompt conserva un plazo fijo de treinta segundos, un hook de tipo agent un plazo fijo de sesenta segundos, sea cual sea el evento que lo dispare. SessionEnd funciona de otra manera: el conjunto de sus hooks comparte un presupuesto de un segundo y medio, ampliable hasta sesenta segundos solo si un hook declara explícitamente un plazo más largo.

Lo que realmente llega al modelo: campos JSON, no texto libre

Un hook no comunica su decisión escribiendo una frase en la salida estándar. Devuelve un objeto JSON cuyo campo hookSpecificOutput.permissionDecision lleva el valor allow o deny, acompañado de un permissionDecisionReason que explica la elección, y el campo hookEventName retoma el nombre exacto del evento que lo disparó. Para añadir información sin bloquear nada, hookSpecificOutput.additionalContext inserta texto que el modelo leerá como si viniera de otra parte de la conversación.

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Commande destructive detectee dans le motif teste"
  }
}

El código de salida del script también cuenta, con independencia del JSON: un código de salida 2 bloquea la acción incluso si el cuerpo JSON afirmaba allow. Esta regla sufre excepciones nombradas, PermissionRequest, StopFailure fuera de una secuencia terminal, PermissionDenied, y sobre todo PostToolUse y PostToolUseFailure, donde el código 2 se vuelve no bloqueante y se limita a mostrarse a Claude vía el error estándar: lógico, ya que la herramienta ya ha terminado de ejecutarse cuando se dispara ese hook.

Diferir en lugar de decidir

El campo permissionDecision documenta dos valores, allow y deny. Para devolver la decisión al flujo de permisos habitual en lugar de forzarla, un hook no escribe ningún tercer valor en ese campo: sale con el código 0 sin reportar decisión, y la llamada sigue su camino normal de aprobación, como si ese hook concreto no hubiera tenido nada que decir al respecto.

Figure 1

Plazo de expiración según el tipo de hook y el evento

Plazo de expiración por defectoTipo de hook implicadoPlazo por defectoParticularidad
Hook command, http o mcp_tool ordinariocommand, http, mcp_tool600 segundosSe aplica a la mayoría de los eventos del ciclo de vida
UserPromptSubmit, PreModelSwitch, PostModelSwitchcommand, http, mcp_tool30 segundosEstos tres eventos rebajan el plazo normalmente fijado en 600 segundos
MessageDisplaycommand, http, mcp_tool10 segundosEl plazo más corto de todos los eventos documentados
SessionEndTodos los tipos combinados1,5 segundos para el conjunto de los hooks del eventoAmpliable hasta 60 segundos si un hook declara explícitamente un plazo más largo
Hook de tipo promptprompt30 segundosPlazo propio del tipo, independiente del evento que lo dispara
Hook de tipo agentagent60 segundosPlazo propio del tipo, independiente del evento que lo dispara
La tabla cruza el tipo de hook con su plazo por defecto, y aísla los eventos que rebajan ese plazo o que siguen una regla aparte como SessionEnd.
Figure 2

Del evento a la decisión transmitida al modelo

01
Evento disparado
Una herramienta está a punto de ejecutarse, o acaba de hacerlo, según el evento registrado.
02
Hook ejecutado
El arnés lanza el comando, la llamada HTTP, la herramienta MCP, la instrucción o el agente declarado para ese evento.
03
Decisión emitida en JSON
hookSpecificOutput.permissionDecision lleva allow o deny, acompañado de permissionDecisionReason, y hookEventName retoma el nombre del evento.
04
Contexto añadido o acción bloqueada
additionalContext enriquece lo que ve el modelo, o la llamada se cancela antes de producirse si el evento es PreToolUse.
05
Código de salida 2 como red de seguridad
Bloquea la acción incluso si el JSON dice allow, salvo para los eventos que no lo respetan, como PostToolUse donde solo se muestra a Claude vía stderr.
La secuencia sitúa el momento en que PreToolUse todavía puede impedir la llamada, y aquel en que PostToolUse ya solo puede constatar lo que acaba de ocurrir.
Calíbralo tú mismo

Un desarrollador configura un hook PostToolUse que devuelve un código de salida 2 después de cada llamada de la herramienta Bash. Después lanza un comando Bash desde Claude Code y observa que el comando se ejecuta hasta el final.

Escribe en una frase lo que esta situación establece, y en una frase lo que no establece.

Lo que hay que recordar
  • PreToolUse puede impedir que se produzca una llamada de herramienta, PostToolUse ya solo puede reaccionar una vez que la herramienta ya se ha lanzado.
  • El plazo por defecto de seiscientos segundos para un hook command, http o mcp_tool baja a treinta segundos en tres eventos y a diez segundos en uno solo.
  • La decisión de un hook pasa por el campo hookSpecificOutput.permissionDecision, con los valores confirmados allow y deny, nunca por una frase escrita en la salida estándar.
  • Un código de salida 2 bloquea la acción incluso cuando el JSON afirma allow, salvo en una lista de eventos nombrados donde se convierte en un simple mensaje mostrado a Claude.
  • Para diferir al flujo de permisos habitual en lugar de forzar allow o deny, un hook sale con el código 0 sin reportar decisión, no existe un tercer valor escrito en permissionDecision.
Hazlo ahora

Escribe un hook PreToolUse mínimo que salga con el código 0 sin escribir nada en su salida estándar, decláralo sobre un evento anodino, y confirma que la llamada sigue su camino normal de aprobación en lugar de ser forzada.

Verificar en la fuente

Cada afirmación datable de esta lección remite aquí al texto público que la respalda. Una fuente que no se abre no prueba nada.