Qué son los Hooks
Los hooks son comandos shell, endpoints HTTP o prompts LLM que se ejecutan automáticamente en puntos específicos del ciclo de vida de Claude Code. Permiten automatizar acciones como formateo después de ediciones, linting antes de commits, o bloqueo de comandos peligrosos.
Los 16 eventos
| Evento | Cuándo se dispara |
|---|---|
SessionStart | Al iniciar o reanudar una sesión |
SessionEnd | Al terminar una sesión |
UserPromptSubmit | Al enviar un prompt, antes de que Claude lo procese |
PreToolUse | Antes de ejecutar una herramienta. Puede bloquearla |
PostToolUse | Después de que una herramienta se ejecuta exitosamente |
PostToolUseFailure | Después de que una herramienta falla |
PermissionRequest | Cuando aparece un diálogo de permisos |
Notification | Cuando Claude Code envía una notificación |
SubagentStart | Cuando se lanza un sub-agente |
SubagentStop | Cuando un sub-agente termina |
Stop | Cuando Claude termina de responder |
TeammateIdle | Cuando un teammate del agent team va a quedar inactivo |
TaskCompleted | Cuando una tarea se marca como completada |
ConfigChange | Cuando cambia un archivo de configuración |
WorktreeCreate | Cuando se crea un worktree |
WorktreeRemove | Cuando se elimina un worktree |
PreCompact | Antes de la compactación de contexto |
Configuración
Los hooks se definen en archivos de settings JSON:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/block-rm.sh"
}
]
}
]
}
}
Tres niveles de anidación
- Evento: qué punto del ciclo (
PreToolUse,Stop, etc.) - Matcher group: filtro de cuándo se dispara
- Hook handler: qué ejecutar cuando coincide
Ubicaciones
| Ubicación | Alcance |
|---|---|
~/.claude/settings.json | Global |
.claude/settings.json | Proyecto (commiteable) |
.claude/settings.local.json | Proyecto (local) |
| Frontmatter de skill/agent | Durante uso del componente |
Matcher patterns
El campo matcher es un regex que filtra cuándo se dispara el hook:
| Evento | Qué filtra el matcher | Ejemplos |
|---|---|---|
PreToolUse, PostToolUse | Nombre de herramienta | Bash, Edit|Write, mcp__.* |
SessionStart | Cómo inició | startup, resume, clear |
SessionEnd | Por qué terminó | clear, logout, other |
Notification | Tipo de notificación | permission_prompt, idle_prompt |
SubagentStart/Stop | Tipo de agente | Explore, Plan, nombres custom |
ConfigChange | Fuente del cambio | user_settings, project_settings |
Eventos sin soporte de matcher (siempre se disparan): UserPromptSubmit, Stop, TeammateIdle, TaskCompleted, WorktreeCreate, WorktreeRemove.
Tipos de hook handler
Command (shell)
{
"type": "command",
"command": ".claude/hooks/lint.sh"
}
Recibe JSON en stdin, puede retornar JSON en stdout.
HTTP
{
"type": "http",
"url": "https://mi-servidor.com/hooks/pre-tool"
}
Recibe JSON como body del POST.
Prompt (LLM)
{
"type": "prompt",
"prompt": "Verifica que el código editado siga las convenciones del proyecto"
}
Ejecuta un prompt LLM como parte del hook.
Exit codes
| Código | Significado |
|---|---|
0 | Éxito, continuar normalmente |
2 | Error — se muestra al usuario y bloquea la acción |
| Otro | Error genérico |
JSON de entrada (stdin)
Para PreToolUse:
{
"session_id": "abc-123",
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf /tmp/build"
}
}
JSON de salida (stdout)
Para bloquear una herramienta:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Comando destructivo bloqueado"
}
}
Ejemplo: Auto-format después de editar
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx prettier --write \"$CLAUDE_TOOL_INPUT_FILE_PATH\""
}
]
}
]
}
}
Variables de entorno en hooks
Claude Code expone variables de entorno al contexto del hook:
CLAUDE_SESSION_ID— ID de la sesiónCLAUDE_TOOL_NAME— Nombre de la herramientaCLAUDE_TOOL_INPUT_*— Inputs de la herramienta (comoFILE_PATH,COMMAND)
Siguiente: MCP Servers