Claude Code Hooks: qué son, cómo configurarlos y automatizar tareas
Los Claude Code Hooks permiten ejecutar automáticamente comandos, validaciones, llamadas HTTP, herramientas MCP o verificaciones con IA en momentos específicos del ciclo de trabajo. Puedes utilizarlos para bloquear comandos peligrosos, proteger archivos, ejecutar linters, lanzar tests después de editar, cargar contexto al iniciar una sesión y comprobar que una tarea esté realmente terminada.
¿Qué son los Hooks de Claude Code?
Los Hooks son automatizaciones
que Claude Code ejecuta
cuando ocurre un evento concreto.
Por ejemplo,
PreToolUse
se ejecuta antes de utilizar una herramienta,
PostToolUse
después de una ejecución correcta,
SessionStart
cuando comienza o se reanuda una sesión
y Stop
cuando Claude intenta terminar una respuesta.
Los Hooks pueden ejecutar
comandos locales,
endpoints HTTP,
herramientas MCP,
prompts de evaluación
o subagentes.
Qué puedes automatizar con Claude Code Hooks
Los Hooks permiten convertir reglas importantes en acciones automáticas en lugar de depender únicamente de instrucciones escritas en un prompt.
Bloquear acciones
Evita comandos, archivos u operaciones consideradas peligrosas.
Formatear código
Ejecuta Prettier, PHP CS Fixer u otras herramientas después de editar.
Ejecutar tests
Lanza automáticamente pruebas relacionadas después de cambios.
Inyectar contexto
Añade información dinámica al comenzar o reanudar sesiones.
Auditar
Registra comandos, cambios y eventos importantes.
Notificaciones
Recibe avisos cuando Claude necesita permiso o finaliza.
Evento → Matcher → Handler → Resultado
La arquitectura de Hooks se puede entender mediante cuatro pasos.
Ocurre un evento
Claude quiere usar una herramienta, iniciar una sesión o terminar.
Se evalúa el matcher
Claude Code determina si el Hook corresponde al evento.
Se ejecuta el handler
Un comando, HTTP, MCP, prompt o agente realiza la validación.
Por qué usar Hooks si ya existe CLAUDE.md
| Mecanismo | Función |
|---|---|
| CLAUDE.md | Le indica a Claude cómo debería trabajar |
| Skill | Define un procedimiento reutilizable |
| Permission | Controla acceso a herramientas |
| Hook | Ejecuta una regla automáticamente ante un evento |
Escribir
“no modifiques .env”
en CLAUDE.md
orienta a Claude.
Un Hook
PreToolUse
puede directamente
bloquear cualquier intento
de modificar ese archivo.
Dónde se configuran los Hooks
| Ubicación | Scope | Compartible |
|---|---|---|
~/.claude/settings.json |
Todos tus proyectos | No |
.claude/settings.json |
Proyecto | Sí |
.claude/settings.local.json |
Proyecto personal | No |
| Managed settings | Organización | Administrado |
hooks/hooks.json |
Plugin | Sí |
| Skill frontmatter | Desde que se invoca el Skill | Sí |
| Subagent frontmatter | Mientras corre el agente | Sí |
Principales eventos disponibles
Claude Code dispone actualmente de muchos eventos. Estos son algunos de los más útiles para desarrollo.
| Evento | Cuándo ocurre |
|---|---|
SessionStart |
Al comenzar, reanudar, limpiar o compactar una sesión |
UserPromptSubmit |
Antes de procesar el prompt del usuario |
UserPromptExpansion |
Cuando un comando o Skill expande un prompt |
PreToolUse |
Antes de ejecutar una herramienta |
PermissionRequest |
Cuando Claude necesita una decisión de permisos |
PostToolUse |
Después de una herramienta exitosa |
PostToolUseFailure |
Después de una herramienta que falla |
PostToolBatch |
Después de completar un lote de tools en paralelo |
Notification |
Cuando Claude Code genera una notificación |
SubagentStart |
Cuando comienza un subagente |
SubagentStop |
Cuando termina un subagente |
TaskCompleted |
Cuando una tarea se marca como completada |
Stop |
Cuando Claude intenta terminar su respuesta |
InstructionsLoaded |
Cuando se carga CLAUDE.md o una Rule |
ConfigChange |
Cuando cambia configuración durante la sesión |
FileChanged |
Cuando cambia un archivo vigilado |
CwdChanged |
Cuando cambia el working directory |
PreCompact |
Antes de compactar contexto |
PostCompact |
Después de compactar |
SessionEnd |
Cuando finaliza la sesión |
Cómo se configura un Hook
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "./scripts/check-code.sh"
}
]
}
]
}
}
Evento
PostToolUse
Matcher
Edit|Write
Handler
type: command
Acción
Ejecutar el script.
Tipos de Hooks disponibles
| Tipo | Función |
|---|---|
command |
Ejecuta un comando o script local |
http |
Envía el evento mediante HTTP POST |
mcp_tool |
Ejecuta una herramienta de un servidor MCP conectado |
prompt |
Pide a un modelo evaluar una condición |
agent |
Inicia un subagente para verificar una condición |
Anthropic recomienda preferir command Hooks para workflows de producción cuando una verificación determinista sea suficiente.
Ejecutar Hooks solo cuando corresponde
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "./check.sh"
}
]
}
]
}
}
El Hook se ejecutará únicamente para esas dos herramientas.
Un matcher
vacío,
omitido
o igual a
*
coincide
normalmente
con cualquier valor
del evento.
Filtrar herramientas con if
Los tool events permiten filtrar no solo el nombre de la herramienta, sino también sus argumentos.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(git push *)",
"command": "./validate-push.sh"
}
]
}
]
}
}
El filtro
if
se evalúa
antes de iniciar
el handler.
Bloquear una acción antes de ejecutarla
Este es uno de los usos más importantes de Hooks.
Bloquear comandos rm -rf
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(rm *)",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh"
}
]
}
]
}
}
Script para bloquear comandos destructivos
#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
if echo "$COMMAND" | grep -q 'rm -rf'; then
echo "Comando destructivo bloqueado" >&2
exit 2
fi
exit 0
Para la mayoría
de eventos
que permiten bloqueo,
el código
2
representa
un bloqueo explícito.
Aunque Unix
utiliza tradicionalmente
código 1
para errores,
en la mayoría
de Hooks
Claude Code
lo trata
como error no bloqueante.
Para una política
de enforcement,
utiliza
exit 2
o una decisión JSON.
Impedir que Claude modifique .env
#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
FILE_PATH="${FILE_PATH//\\//}"
PROTECTED_PATTERNS=(
".env"
"package-lock.json"
".git/"
)
for pattern in "${PROTECTED_PATTERNS[@]}"; do
if [[ "$FILE_PATH" == *"$pattern"* ]]; then
echo "Bloqueado: $FILE_PATH coincide con $pattern" >&2
exit 2
fi
done
exit 0
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/protect-files.sh"
}
]
}
]
}
}
Ejecutar un formatter después de editar
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
Formatear código es una tarea que no necesita razonamiento adicional del modelo.
Ejecutar PHP lint después de editar
#!/bin/bash
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if [[ "$FILE" == *.php ]]; then
php -l "$FILE"
fi
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/php-lint.sh"
}
]
}
]
}
}
Hook de validación para proyectos WordPress
Puedes utilizar un único script para ejecutar varias comprobaciones después de modificar PHP.
#!/bin/bash
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if [[ "$FILE" != *.php ]]; then
exit 0
fi
echo "Validando: $FILE"
php -l "$FILE" || exit 2
if command -v phpcs >/dev/null 2>&1; then
phpcs --standard=WordPress "$FILE"
fi
exit 0
Añade PHPStan, PHPUnit, WordPress Coding Standards o herramientas propias del proyecto.
Ejecutar Hooks largos de forma asíncrona
Una suite completa de tests puede tardar demasiado para bloquear cada edición.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/run-tests.sh",
"async": true
}
]
}
]
}
}
Cuando
async: true,
Claude Code
no espera
a que termine
el comando.
Como la acción
ya continuó,
decisiones como
deny
o
permissionDecision
dejan de tener efecto.
Inyectar información al comenzar una sesión
{
"hooks": {
"SessionStart": [
{
"matcher": "startup",
"hooks": [
{
"type": "command",
"command": "git log --oneline -5"
}
]
}
]
}
}
En
SessionStart,
texto simple
escrito a stdout
puede incorporarse
al contexto
que Claude ve.
Utiliza SessionStart para información dinámica. Para reglas estáticas, sigue utilizando CLAUDE.md.
Reinyectar información después de compactar
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo 'Recuerda: ejecuta PHPUnit antes de finalizar. No modifiques WordPress core.'"
}
]
}
]
}
}
Puede ser útil para restaurar información crítica que no quieres perder después de una compactación.
Comprobar que Claude realmente terminó
El evento
Stop
ocurre
cuando Claude
intenta finalizar
su respuesta.
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Evalúa si Claude puede terminar. Contexto: $ARGUMENTS. Comprueba si completó todas las tareas solicitadas, si quedan errores y si falta alguna verificación."
}
]
}
]
}
}
El modelo devuelve una decisión estructurada indicando si Claude puede terminar o debe continuar.
Prompt Hooks para decisiones semánticas
Cuando una regla no puede expresarse con Bash
Claude Code envía al modelo el input del Hook y tu instrucción. El modelo evalúa la condición y devuelve una decisión JSON.
| Situación | Mejor opción |
|---|---|
| Bloquear rm -rf | Command Hook |
| Validar formato | Command Hook |
| ¿La tarea parece realmente completa? | Prompt Hook |
| ¿Este cambio viola una regla conceptual? | Prompt o Agent Hook |
Utilizar un subagente para verificar antes de continuar
Un Prompt Hook solo evalúa la información que recibe. Un Agent Hook puede investigar el proyecto.
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "agent",
"prompt": "Verifica que todos los tests unitarios pasen. Ejecuta la suite y comprueba los resultados. $ARGUMENTS",
"timeout": 120
}
]
}
]
}
}
Los Agent Hooks pueden leer archivos, buscar código y utilizar herramientas, pero Anthropic los considera actualmente una capacidad experimental.
Ejecutar una herramienta MCP desde un Hook
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "mcp_tool",
"server": "security",
"tool": "security_scan",
"input": {
"file_path": "${tool_input.file_path}"
}
}
]
}
]
}
}
Puedes enviar automáticamente archivos modificados a analizadores, scanners o servicios expuestos por MCP.
Claude Code MCP →Enviar eventos de Claude Code a una API
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "http",
"url": "https://hooks.example.com/claude/code-change",
"timeout": 30,
"headers": {
"Authorization": "Bearer $HOOK_TOKEN"
},
"allowedEnvVars": [
"HOOK_TOKEN"
]
}
]
}
]
}
}
El endpoint recibe información sobre el evento y puede devolver el mismo formato de control estructurado utilizado por command Hooks.
Automatizar decisiones de permisos
Un Hook puede responder a determinadas solicitudes de permisos en tu nombre.
Aprobar automáticamente una acción conocida
{
"hookSpecificOutput": {
"hookEventName": "PermissionRequest",
"decision": {
"behavior": "allow"
}
}
}
No conviertas un PermissionRequest Hook en una aprobación general de cualquier acción. Limita cuidadosamente el matcher y las condiciones.
Recibir un aviso cuando Claude necesita atención
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{
"type": "command",
"shell": "powershell",
"command": "[System.Windows.Forms.MessageBox]::Show('Claude necesita aprobación','Claude Code')"
}
]
}
]
}
}
Entre ellos
permission_prompt,
idle_prompt,
eventos de autenticación,
MCP
y background agents.
Ejecutar Hooks directamente con PowerShell
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"shell": "powershell",
"command": "& \"$env:CLAUDE_PROJECT_DIR\\.claude\\hooks\\check.ps1\""
}
]
}
]
}
}
Claude Code
intenta utilizar
pwsh.exe
cuando PowerShell 7
está disponible
y puede utilizar
Windows PowerShell
como alternativa.
Aplicar Hooks a herramientas MCP
Las tools MCP aparecen dentro de los eventos como herramientas normales.
{
"hooks": {
"PreToolUse": [
{
"matcher": "mcp__github__.*",
"hooks": [
{
"type": "command",
"command": "./audit-github-action.sh"
}
]
}
]
}
}
Las herramientas MCP
siguen normalmente
el patrón:
mcp__servidor__herramienta.
Hooks empaquetados dentro de Plugins
my-plugin/
├── .claude-plugin/
│ └── plugin.json
├── hooks/
│ └── hooks.json
└── scripts/
└── format.sh
{
"description": "Automatic formatting",
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh",
"timeout": 30
}
]
}
]
}
}
Un Skill también puede registrar Hooks
---
name: secure-operations
description: Realiza tareas con validaciones de seguridad
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/security-check.sh"
---
Realiza la tarea solicitada
aplicando validaciones de seguridad.
Cuando el Skill se invoca, sus Hooks pueden permanecer registrados durante el resto de la sesión.
Hooks específicos para un subagente
También puedes restringir automatizaciones al periodo en que un agente está ejecutándose.
---
name: database-reviewer
description: Revisa consultas y estructura de base de datos
tools: Read, Grep, Glob, Bash
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./validate-db-command.sh"
---
Analiza la base de datos
sin realizar operaciones destructivas.
Los Hooks declarados en un subagente desaparecen cuando termina esa ejecución.
Control avanzado mediante respuestas estructuradas
Los exit codes no son la única forma de comunicarse con Claude Code.
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Las escrituras directas en producción están bloqueadas"
}
}
Dependiendo del evento, una respuesta JSON puede permitir, denegar, modificar input o proporcionar contexto adicional.
Qué información recibe un command Hook
{
"session_id": "abc123",
"cwd": "/home/user/project",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "npm test"
},
"tool_use_id": "toolu_..."
}
Todos comparten campos comunes, pero cada evento puede añadir información específica.
Auditar cambios de configuración
{
"hooks": {
"ConfigChange": [
{
"matcher": "project_settings|skills",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/audit-config.sh"
}
]
}
]
}
}
Permite registrar cambios a settings o Skills mientras una sesión está activa.
Reaccionar cuando cambia un archivo
{
"hooks": {
"FileChanged": [
{
"matcher": ".envrc|.env",
"hooks": [
{
"type": "command",
"command": "direnv export bash > \"$CLAUDE_ENV_FILE\""
}
]
}
]
}
}
FileChanged puede reaccionar a cambios realizados en disco por otras herramientas o procesos.
Mantener variables de entorno con CLAUDE_ENV_FILE
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "direnv export bash > \"$CLAUDE_ENV_FILE\""
}
]
}
],
"CwdChanged": [
{
"hooks": [
{
"type": "command",
"command": "direnv export bash > \"$CLAUDE_ENV_FILE\""
}
]
}
]
}
}
Si diferentes directorios requieren distintos entornos, Claude puede recargarlos al cambiar de carpeta.
Ver los Hooks configurados
/hooks
El menú permite inspeccionar eventos, matchers, tipo, archivo de origen y handler. Para modificar Hooks, edita settings o pídeselo a Claude.
Los Hooks ejecutan código automáticamente
Esta característica es precisamente lo que los hace tan potentes y lo que exige revisarlos cuidadosamente.
Revisa cualquier Hook incluido en repositorios de terceros.
Utiliza rutas absolutas o variables confiables.
Valida cualquier dato proveniente de stdin.
Evita interpolar directamente valores no confiables dentro de Bash.
Aplica mínimo privilegio a scripts y credenciales.
Mantén scripts sensibles bajo control de versiones.
Revisa Hooks HTTP y destinos remotos.
Utiliza Sandbox para reducir el impacto de comandos permitidos.
Hooks vs Permissions vs Sandbox
| Mecanismo | Función |
|---|---|
| Permissions | Decide qué herramientas o comandos puede solicitar Claude |
| Hooks | Aplica lógica personalizada alrededor de eventos |
| Sandbox | Limita técnicamente filesystem y red de los procesos |
Un entorno sólido puede combinar Permissions, Hooks y Sandbox en distintas capas de control.
Problemas frecuentes con Hooks
Usar exit 1 para bloquear: normalmente necesitas exit 2.
Script no ejecutable:
en macOS/Linux
recuerda
chmod +x.
Matcher incorrecto: el Hook nunca llega a ejecutarse.
Rutas relativas frágiles:
usa
${CLAUDE_PROJECT_DIR}
o
${CLAUDE_PLUGIN_ROOT}.
JSON inválido: Claude Code puede tratarlo como error no bloqueante.
Hook demasiado lento: cada ejecución añade latencia.
Usar async para bloquear: un Hook async ya no controla la acción.
Automatizar demasiado: no ejecutes una suite completa después de cada pequeño cambio si no es necesario.
Cómo depurar Hooks
claude --debug
Abre /hooks.
Confirma evento y matcher.
Ejecuta manualmente el script.
Comprueba permisos de ejecución.
Captura stdin temporalmente para estudiar el JSON.
Revisa el debug log.
Cómo diseñar buenos Hooks
Utiliza Hooks para tareas deterministas.
Filtra con matchers para evitar ejecuciones innecesarias.
Mantén PreToolUse rápido.
Ejecuta tests largos en background.
Devuelve mensajes claros cuando bloquees.
Utiliza Prompt Hooks solo cuando necesites evaluación semántica.
Usa Agent Hooks únicamente cuando sea necesario investigar archivos.
Combina Hooks con Permissions y Sandbox para defensa en profundidad.
Qué herramienta usar
Documentación oficial de Claude Code Hooks
Hooks Reference
Eventos, matchers, input/output, exit codes y tipos de Hooks.
Ver referencia oficial →Hooks Guide
Ejemplos prácticos de seguridad, formatting, notificaciones y automatización.
Ver guía oficial →Settings
Scopes, permisos y archivos de configuración.
Ver Settings →Guías relacionadas
FAQ sobre Claude Code Hooks
Respuestas sobre eventos, PreToolUse, PostToolUse, exit codes, seguridad y automatización.
Un Hook es una automatización que Claude Code ejecuta cuando ocurre un evento específico como utilizar una herramienta, iniciar una sesión, modificar un archivo o intentar terminar una tarea.
PreToolUse se ejecuta antes de que Claude utilice una herramienta. Puede utilizarse para validar, modificar o bloquear la operación.
PostToolUse se ejecuta después de que una herramienta termina correctamente. Es útil para formatting, linting, testing y validaciones posteriores.
En eventos que permiten bloqueo, un command Hook puede utilizar exit code 2. También puedes devolver una decisión JSON apropiada para el evento.
Normalmente no. Para la mayoría de eventos, exit code 1 se trata como un error no bloqueante. Para enforcement mediante código de salida, utiliza exit code 2.
Sí.
Puedes ejecutar
tests después
de Edit o Write.
Si la suite
tarda mucho,
un command Hook
puede utilizar
async: true.
Sí. Claude Code dispone de Prompt Hooks para evaluaciones de una sola llamada y Agent Hooks capaces de investigar mediante herramientas.
Sí.
El tipo
mcp_tool
puede ejecutar
una herramienta
de un servidor MCP
que ya esté conectado
a la sesión.
Sí.
Un Plugin
puede incluir
hooks/hooks.json
junto con scripts
y otros recursos.
Los Hooks se activan
cuando el Plugin
está habilitado.
Ejecuta
/hooks
dentro de Claude Code.
Actualmente
el navegador
permite inspeccionar Hooks,
pero las modificaciones
se realizan
en los archivos
de configuración
o pidiéndoselo a Claude.
Protege la ejecución de comandos con Claude Code Sandbox
Ya sabes cómo validar y automatizar acciones mediante Hooks. El siguiente paso es añadir aislamiento técnico para limitar qué partes del filesystem y de la red pueden alcanzar los comandos ejecutados por Claude Code.
Claude Code Sandbox →