
Hooks de Claude Code: la guía definitiva para automatizar tu agente
Los hooks de Claude Code ejecutan tus comandos automáticamente en eventos del ciclo de vida — valida, aplica linting, bloquea o registra actividad sin tener que estar pendiente. Los eventos, la configuración, cinco recetas prácticas, la trampa del código de salida y cómo usar Claude Code sin configuración previa.
Los hooks de Claude Code son comandos definidos por el usuario que se ejecutan automáticamente en puntos específicos del ciclo de vida de Claude Code — antes de una llamada a una herramienta, después de una edición, al iniciar una sesión, cuando Claude termina un turno — para que puedas validar, formatear, registrar o bloquear acciones sin tener que estar pendiente cada vez. Son la diferencia entre un agente de codificación con IA que sugiere y uno que sigue tus reglas de forma determinista. Esta guía explica qué son los hooks, cada evento en el que pueden dispararse, cómo configurarlos, cinco recetas prácticas que puedes copiar, el detalle del código de salida que hace tropezar a todo el mundo, y cómo aprovechar todo el poder de Claude Code sin ninguna configuración local.
¿Qué son los hooks de Claude Code?
Un hook es un manejador — un comando de shell, un endpoint HTTP, una llamada a una herramienta MCP, o incluso un prompt de modelo — que Claude Code ejecuta automáticamente cuando ocurre un evento en particular. El manejador recibe una entrada estructurada (por stdin para hooks de tipo comando, o como cuerpo POST para hooks HTTP), puede inspeccionar lo que está sucediendo, tomar una acción y, opcionalmente, devolver una decisión que cambia lo que Claude hace a continuación.
Esa última parte es lo que hace que los hooks sean poderosos y no solo convenientes. Un hook no es solo una notificación — puede bloquear una llamada a una herramienta, reescribir la entrada o salida de una herramienta, inyectar contexto adicional, o detener a Claude por completo. En otras palabras, los hooks convierten a Claude Code de un asistente inteligente en uno programable que aplica las reglas de tu equipo de forma determinista, no solo cuando el modelo resulta recordarlas.
Cuándo se disparan los hooks: el ciclo de vida
Los hooks se enganchan a eventos, y Claude Code expone muchos de ellos. Se agrupan por cadencia: algunos se disparan una vez por sesión, otros una vez por turno, y otros en cada llamada a una herramienta.
Dónde se disparan los hooks a lo largo de una sesión de Claude Code — desde SessionStart hasta SessionEnd.
Los eventos que usarás con más frecuencia:
SessionStart/SessionEnd— una vez cuando comienza o termina una sesión. Ideal para cargar contexto (issues abiertos, información de la rama, variables de entorno) o para limpieza.UserPromptSubmit— se dispara cuando envías un prompt, antes de que Claude lo procese. Puedes filtrar o ampliar el prompt.PreToolUse— antes de cualquier llamada a una herramienta. Aquí es donde bloqueas acciones peligrosas.PostToolUse(yPostToolUseFailure) — después de que una llamada a una herramienta tiene éxito (o falla). El lugar para hacer linting, formateo y verificación.Stop/StopFailure— cuando Claude termina de responder, o el turno finaliza con un error.Notification— cuando Claude Code emite una notificación (útil para alertas de escritorio).
Más allá de eso, Claude Code también dispara hooks para subagentes (SubagentStart/SubagentStop), tareas (TaskCreated/TaskCompleted), compactación de contexto (PreCompact/PostCompact), cambios de directorio de trabajo (CwdChanged), cambios de archivos en disco (FileChanged), carga de instrucciones (InstructionsLoaded), y más. La amplitud es justamente el punto: casi cualquier momento en el bucle del agente es un lugar donde puedes adjuntar una política.
Los cinco tipos de manejadores de hooks
Un evento de hook puede activar cinco tipos diferentes de manejador, lo cual es lo que hace flexible al sistema:
command— ejecuta un comando de shell; lee la entrada por stdin, señala decisiones mediante el código de salida y stdout.http— envía por POST el JSON del evento a una URL y lee la respuesta JSON.mcp_tool— llama a una herramienta en un servidor MCP conectado.prompt— una evaluación de modelo de un solo turno que devuelve una decisión JSON de sí/no (útil para comprobaciones difusas).agent— genera un subagente (experimental).
Para la mayoría de los equipos, los hooks de tipo command hacen el 90% del trabajo — un script de shell es suficiente para hacer linting, bloquear o registrar.
Cómo configurar un hook
Los hooks residen en archivos de configuración (la documentación oficial de hooks de Claude Code es la referencia canónica), y dónde los coloques controla su alcance:
| Ubicación | Alcance |
|---|---|
~/.claude/settings.json | Todos tus proyectos |
.claude/settings.json | Un proyecto (se puede confirmar en el repositorio — compartible con tu equipo) |
.claude/settings.local.json | Un proyecto, solo local (en gitignore) |
| Configuración de políticas administradas | A nivel de organización (administrador) |
La estructura se anida en tres niveles: elige un evento, agrega un grupo de matcher, luego define los manejadores. Los matchers deciden a qué llamadas de herramientas se aplica un hook — "*" (u omitirlo) coincide con todo, un simple Edit|Write coincide con esas herramientas exactas, y cualquier cosa más compleja se trata como una expresión regular. (Las herramientas MCP coinciden con el patrón mcp__<server>__<tool>.)
Aquí tienes un hook PostToolUse que ejecuta una verificación de linting después de cada edición:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "/path/to/lint-check.sh" }]
}
]
}
}Cinco recetas prácticas de hooks
Estos son los patrones a los que los equipos recurren primero:
- Hacer linting o formateo después de cada edición. Un hook
PostToolUseemparejado conEdit|Writeque ejecuta tu formateador o linter, para que el código del agente siempre cumpla con tus reglas de estilo. - Bloquear comandos destructivos. Un hook
PreToolUseemparejado conBashque inspecciona el comando y bloquearm -rfy similares antes de que lleguen a ejecutarse. - Notificaciones de escritorio. Un hook
Notificationque te avisa cuando Claude necesita atención o termina una tarea larga. - Registro de auditoría. Un hook
PostToolUse(o dirigido a MCP) que registra cada llamada a una herramienta para cumplimiento normativo — qué se ejecutó, cuándo, y con qué argumentos. - Cargar el contexto del proyecto al iniciar. Un hook
SessionStartque trae los issues abiertos, la rama actual, o variables de entorno para que el agente comience cada sesión ya orientado.
Cinco recetas comunes de hooks y los eventos a los que se adjuntan.
El detalle del código de salida
Este es el detalle que hace tropezar a todo el mundo, así que interiorízalo: para los hooks de tipo command, solo el código de salida 2 bloquea. La salida 0 significa éxito (y stdout se analiza en busca de cualquier decisión JSON). La salida 2 es un error bloqueante — su stderr se retroalimenta a Claude. Cualquier otro código, incluyendo la salida 1, es un error no bloqueante — Claude continúa.
Así que si escribes un hook de "bloquear esto" y haces exit 1, no bloqueará — la acción procede. Para realmente aplicar una política desde un hook de comando, usa exit 2. (Los hooks de comando también pueden devolver un control más rico como JSON en stdout — permissionDecision: "deny" para PreToolUse, updatedInput para reescribir argumentos, additionalContext para inyectar información, y continue: false para detener a Claude por completo.)
Un ejemplo trabajado: bloquear rm -rf
Construyamos de principio a fin la protección contra comandos destructivos, porque muestra cada pieza en movimiento. Primero, la configuración — un hook PreToolUse emparejado con Bash:
{ "hooks": { "PreToolUse": [{ "matcher": "Bash",
"hooks": [{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard.sh" }] }] } }Luego el script, guard.sh. Claude Code envía el evento como JSON por stdin, incluyendo la entrada de la herramienta; el script lo lee, verifica el comando, y decide:
#!/usr/bin/env bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command // ""')
if echo "$cmd" | grep -Eq 'rm +-rf|mkfs'; then
echo "Blocked: destructive command refused by policy." >&2
exit 2 # exit 2 blocks — exit 1 would NOT
fi
exit 0La línea decisiva es exit 2. Devuelve 0 y el comando se ejecuta; devuelve 1 y — contraintuitivamente — aun así se ejecuta como un error no bloqueante; solo exit 2 bloquea y retroalimenta tu mensaje de stderr a Claude para que entienda por qué. Haz que el script sea ejecutable, súbelo bajo .claude/hooks/, y a partir de ahí cada llamada a Bash pasará por tu protección — para todo tu equipo, ya que el settings.json del proyecto es compartible. Para una garantía sólida en lugar de una red de mejor esfuerzo, combínalo con las reglas de permisos de Claude Code; como red de seguridad determinista y versionada, este hook ya cumple su función.
Cuando los hooks no son la respuesta
Los hooks son para políticas deterministas y repetibles — "siempre hacer linting después de una edición", "nunca ejecutar rm -rf". Son la herramienta equivocada para cosas que requieren criterio (usa el modelo o un hook de tipo prompt para decisiones difusas) y para garantías de seguridad estrictas (usa el sistema de permisos, ya que los filtros if de los hooks de comando fallan de forma abierta). Tampoco abuses de los hooks: cada hook de comando ejecuta un proceso con un tiempo de espera, y una maraña de hooks lentos agrega latencia a cada llamada a una herramienta. Mantenlos rápidos, pocos, y enfocados en las reglas que realmente importan.
Notas de seguridad que vale la pena conocer
Algunas realidades que la documentación deja explícitas:
- El filtro
iffalla de forma abierta. Si usas el campoifpara acotar un hook a una regla de permiso y el comando no se puede analizar, el hook se ejecuta de todos modos. Para una aplicación estricta de permitir/denegar, usa el sistema de permisos de Claude Code, no los hooks. - Los hooks se ejecutan sin una terminal de control — no pueden pedir información por
/dev/tty. UsasystemMessageo la salida restringidaterminalSequencepara mensajes dirigidos al usuario. - Stdout debe estar limpio. Solo el objeto de decisión JSON debe estar en stdout; una salida perdida de un perfil de shell puede romper el análisis.
- Trata el contexto inyectado con cuidado.
additionalContextdebe escribirse como declaraciones factuales, no como comandos imperativos, para funcionar bien con las defensas contra inyección de prompts.
Los hooks son ingeniería de harness en miniatura
Dando un paso atrás, los hooks son un ejemplo concreto de una idea más amplia: el modelo no es todo el agente — el sistema que lo rodea también lo es. Los hooks son parte del harness que hace confiable a un agente de codificación, junto al bucle, las herramientas, la memoria y el sandbox. (Profundizamos en ese modelo mental en harness engineering.) Cuando escribes un bloqueo PreToolUse o un linter PostToolUse, estás haciendo ingeniería de harness — moldeando el comportamiento del agente de forma determinista en lugar de esperar que el modelo se comporte bien.
Ese enfoque también te dice cuándo vale la pena el esfuerzo de usar hooks: cualquier regla que de otro modo tendrías que recordarle al agente cada vez es candidata para un hook.
Usa todo el poder de Claude Code sin configuración local
Los hooks residen en la CLI de Claude Code, lo que significa que necesitas tenerla instalada y configurada para usarlos — una barrera para cualquiera que no esté configurado en una terminal, e imposible para compañeros de equipo que no son desarrolladores. Si quieres las capacidades de agente de Claude Code sin gestionar una instalación local, puedes ejecutar Claude Code en tu navegador en Happycapy: ejecuta Claude Code en un sandbox en la nube gestionado donde el harness — el bucle, las herramientas, la memoria y el aislamiento a los que se conectan los hooks — ya está configurado para ti. Describes una tarea y observas al agente trabajar en un escritorio visual, sin necesidad de una terminal.
Piénsalo así: los hooks permiten a los usuarios avanzados ajustar manualmente el harness de Claude Code; Happycapy le da a todos un harness gestionado desde el primer momento. Si has querido poner a Claude Code a trabajar pero la configuración de la CLI te ha detenido, comienza gratis en happycapy.ai y ejecuta una tarea real en tu navegador hoy mismo.
Preguntas frecuentes
P: ¿Qué son los hooks de Claude Code?
Son manejadores definidos por el usuario — comandos de shell, endpoints HTTP, llamadas a herramientas MCP, o prompts de modelo — que Claude Code ejecuta automáticamente en eventos del ciclo de vida como antes de una llamada a una herramienta (PreToolUse), después de una edición (PostToolUse), o al inicio de una sesión. Pueden validar, formatear, registrar, bloquear o reescribir acciones.
P: ¿Qué eventos de hooks admite Claude Code?
Muchos — incluyendo SessionStart/SessionEnd, UserPromptSubmit, PreToolUse, PostToolUse (y PostToolUseFailure), Stop/StopFailure, Notification, eventos de subagentes y tareas, y eventos de compactación. Se disparan una vez por sesión, una vez por turno, o en cada llamada a una herramienta.
P: ¿Cómo hago que un hook bloquee una llamada a una herramienta?
Para hooks de comando, sal con el código 2 — solo la salida 2 bloquea (la salida 1 no). Para PreToolUse, también puedes devolver JSON con permissionDecision: "deny". Para una aplicación estricta, prefiere el sistema de permisos de Claude Code, ya que el filtro if del hook falla de forma abierta.
P: ¿Dónde configuro los hooks de Claude Code?
En archivos de configuración: ~/.claude/settings.json (todos los proyectos), .claude/settings.json (un proyecto, compartible), o .claude/settings.local.json (solo local). Eliges un evento, agregas un matcher, y defines manejadores.
P: ¿Puedo usar los hooks de Claude Code sin instalar la CLI?
Los hooks en sí requieren la CLI de Claude Code. Si tu objetivo es usar Claude Code sin configuración local, ejecútalo en un sandbox de navegador gestionado como Happycapy, que proporciona el agente y su harness listos para usar — ideal cuando no quieres instalar y configurar la CLI tú mismo.
P: ¿Cuál es un buen primer hook para agregar?
Un linter PostToolUse emparejado con Edit|Write — ejecuta tu formateador después de cada cambio de código, para que la salida del agente siempre cumpla con tus reglas de estilo. Es de bajo riesgo e inmediatamente útil.
Guías relacionadas
- How Claude Code Review Actually Works: Diffs, Hooks, and What the Agent Catches
- Build Autonomous Agents with the Claude Code SDK: A Practical Developer's Guide
- Claude Code Web: How to Run Claude Code in Your Browser (No Install)
- Claude Code vs GitHub Copilot: Autonomous Agent or In-Editor Assistant?

