Saltar al contenido
Claude Tutoriales

Hooks de Claude Code: reglas que el modelo no puede saltarse (guía con ejemplos)

Los hooks de Claude Code ejecutan tus propios comandos en momentos clave del trabajo del agente: bloquear comandos peligrosos, formatear al guardar, avisarte al terminar. Cómo configurarlos, ejemplos reales y los fallos habituales.

DesarrolloProductividad
TUTORIALES CLAUDE

Le dices a Claude Code, en tu CLAUDE.md, que nunca toque la carpeta migrations/ y que siempre pase el formateador antes de terminar. Funciona nueve veces de diez. La décima, en una sesión larga con mucho contexto, la instrucción se diluye y el cambio llega sin formatear, o peor, con una migración editada a mano. El problema no es el modelo: es que una instrucción en lenguaje natural es una petición, no una garantía.

Los hooks resuelven justo eso. Son comandos que defines tú y que Claude Code ejecuta en momentos concretos de su trabajo, sin preguntarle al modelo si le apetece. Si una regla no admite excepciones, no es una instrucción: es un hook.

Qué es un hook y cuándo se dispara

Un hook es un comando de shell asociado a un evento del ciclo de trabajo del agente. Cuando el evento ocurre, Claude Code ejecuta tu comando y le pasa por la entrada estándar un JSON con el contexto: qué herramienta se va a usar, con qué parámetros, en qué carpeta, etc. Los eventos que más se usan:

  • PreToolUse: justo antes de que Claude use una herramienta (ejecutar un comando, editar un archivo…). Puede bloquear la acción.
  • PostToolUse: justo después de que la herramienta termine bien. Ideal para formatear, ejecutar linters o tests rápidos.
  • UserPromptSubmit: cuando envías un prompt, antes de que Claude lo procese. Sirve para añadir contexto o validar.
  • Stop: cuando Claude termina de responder. Útil para notificaciones o comprobaciones finales.
  • SessionStart: al abrir o reanudar una sesión, para cargar contexto del proyecto.

La lista completa y los detalles de cada evento cambian con las versiones, así que conviene consultar la referencia oficial cuando vayas a configurar algo concreto.

Dónde se configuran

Los hooks viven en los archivos de configuración de Claude Code, bajo la clave hooks:

  • ~/.claude/settings.json: tus hooks personales, en todos los proyectos.
  • .claude/settings.json: los del proyecto, que se versionan y comparte todo el equipo.
  • .claude/settings.local.json: los tuyos para ese proyecto, sin subirlos al repositorio.

La estructura básica es siempre la misma: evento → lista de bloques con un matcher (a qué herramienta se aplica) → lista de comandos.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          { "type": "command", "command": "npx prettier --write \"$(jq -r '.tool_input.file_path')\"" }
        ]
      }
    ]
  }
}

Este primer ejemplo formatea con Prettier cada archivo que Claude edita o crea. El comando recibe el JSON por la entrada estándar y jq extrae la ruta del archivo. Así el formato queda siempre limpio, sin gastar una sola instrucción en pedírselo al modelo.

Ejemplo 1: bloquear comandos peligrosos

El caso estrella del evento PreToolUse. El hook recibe el comando que Claude quiere ejecutar y decide si lo deja pasar. La convención es sencilla: código de salida 0 deja continuar; código 2 bloquea la acción y el mensaje que escribas por la salida de error se devuelve a Claude, que lo lee y busca otra vía.

#!/usr/bin/env bash
# .claude/hooks/bloquear-peligrosos.sh
cmd=$(jq -r '.tool_input.command // empty')

if echo "$cmd" | grep -Eq 'rm -rf (/|~|\$HOME)|git push (-f|--force)|DROP TABLE'; then
  echo "Bloqueado por política del proyecto: comando destructivo. Propón una alternativa más segura." >&2
  exit 2
fi
exit 0

Y su registro en .claude/settings.json, limitado a la herramienta de shell:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/bloquear-peligrosos.sh" }
        ]
      }
    ]
  }
}

Fíjate en el mensaje de error: está escrito para Claude, no para ti. Un buen mensaje de bloqueo dice qué regla se ha incumplido y qué hacer en su lugar. Con eso, el agente rectifica en el mismo turno en vez de quedarse atascado o reintentar lo mismo.

Ejemplo 2: proteger archivos que no deben tocarse

Misma idea, aplicada a las herramientas de edición. Este hook impide modificar migraciones ya aplicadas y archivos de entorno:

#!/usr/bin/env bash
# .claude/hooks/proteger-archivos.sh
ruta=$(jq -r '.tool_input.file_path // empty')

case "$ruta" in
  */migrations/*|*.env|*.env.*)
    echo "Archivo protegido ($ruta). Las migraciones se crean nuevas, nunca se editan; los .env los gestiona una persona." >&2
    exit 2
    ;;
esac
exit 0

Se registra con "matcher": "Edit|Write" en PreToolUse. La regla que antes vivía como una frase en CLAUDE.md pasa a ser imposible de incumplir.

Ejemplo 3: avisarte cuando Claude termina

Con tareas largas, nadie quiere mirar la terminal. Un hook en Stop te avisa cuando el agente ha acabado. En macOS, por ejemplo:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          { "type": "command", "command": "osascript -e 'display notification \"Claude ha terminado\" with title \"Claude Code\"'" }
        ]
      }
    ]
  }
}

Es el hook más pequeño y probablemente el que más se agradece: lanzas la tarea, te pones con otra cosa y llega el aviso.

▶ Tres hooks, tres tipos de regla

Formatear al editar (PostToolUse): una tarea mecánica que no quieres pedir cada vez.

Bloquear comandos y archivos (PreToolUse): una barrera que evita el daño antes de que ocurra.

Notificar al terminar (Stop): una comodidad que te devuelve tiempo.

La mayoría de los equipos empieza por uno de estos tres y va añadiendo según aparecen los sustos.

Cómo crear tu primer hook, paso a paso

  1. Elige una regla que hayas tenido que repetirle a Claude más de dos veces. Esa es la candidata ideal.
  2. Decide el evento: ¿hay que impedir algo antes (PreToolUse), reaccionar después (PostToolUse) o avisar al final (Stop)?
  3. Escribe el comando como un script aparte en `.claude/hooks/` y pruébalo a mano, pasándole un JSON de ejemplo por la entrada estándar.
  4. Regístralo en `.claude/settings.local.json` con el `matcher` más estrecho posible (solo `Bash`, solo `Edit|Write`…).
  5. Observa una sesión real y revisa que se dispara cuando debe y que el mensaje de bloqueo ayuda a Claude a rectificar.
  6. Cuando funcione, súbelo a `.claude/settings.json` para que lo use todo el equipo y documenta en el README qué hace cada hook.

Los fallos más habituales

  • El matcher es demasiado amplio. Un hook que se ejecuta con cada herramienta ralentiza todo. Limítalo a lo que necesitas.
  • Hooks lentos. Se ejecutan en el camino crítico: si tardan segundos, cada acción de Claude los espera. Deja los tests largos para cuando termine, no para cada edición.
  • Mensajes de bloqueo crípticos. Si solo dices «prohibido», Claude insistirá o se quedará bloqueado. Explica la regla y la alternativa.
  • Scripts sin permiso de ejecución. Un chmod +x olvidado produce errores que parecen un fallo del hook y son del sistema.
  • Dependencias que no existen en otra máquina. Si tu hook usa jq o prettier, el resto del equipo también los necesita. Anótalo.
  • Olvidar que se ejecutan con tus permisos. Un hook es código que corre automáticamente en tu máquina. Trátalo como cualquier script que se ejecuta solo.

Pídele a Claude que te ayude a diseñar los tuyos

Nadie conoce tus sustos mejor que tú, pero Claude puede ayudarte a convertirlos en hooks bien hechos. Un buen punto de partida:

Diseña los hooks de mi proyecto
Quiero crear hooks de Claude Code para mi proyecto. Te cuento el contexto: [lenguaje y herramientas del proyecto], [carpetas o archivos que nunca deben modificarse], [comandos que nunca deben ejecutarse] y [tareas que repito tras cada cambio]. Propón una lista corta de hooks (máximo cinco) priorizados por riesgo evitado. Para cada uno dime: el evento más adecuado, el matcher más estrecho posible, el script completo y un JSON de ejemplo para probarlo a mano, y un mensaje de bloqueo escrito para que Claude sepa qué hacer en su lugar. Avísame de cualquier riesgo de seguridad o de lentitud que veas.

Conclusión

Los hooks no hacen a Claude más listo; hacen tu flujo de trabajo más fiable. Convierten las reglas que antes dependían de la memoria del modelo en comprobaciones que se ejecutan siempre. Empieza pequeño: un hook de formato, uno de protección de archivos y un aviso al terminar. Lo que ganas no es velocidad, sino algo más valioso: dejar de preocuparte por lo que el agente podría olvidar.

Si quieres seguir profundizando en cómo estructurar el trabajo con Claude, te recomendamos cómo elegir entre skills, MCP y subagentes y cómo crear tu primera skill.

Preguntas frecuentes

¿Qué es un hook en Claude Code?

Es un comando que tú defines y que Claude Code ejecuta automáticamente en un momento concreto: antes o después de usar una herramienta, al enviar un prompt, al terminar una respuesta o al empezar la sesión. Al ser código tuyo y no una instrucción al modelo, se ejecuta siempre.

¿En qué se diferencia un hook de poner la regla en CLAUDE.md?

CLAUDE.md es una instrucción que el modelo lee y normalmente cumple, pero puede olvidarla o interpretarla. Un hook es determinista: el comando se ejecuta o bloquea la acción sin depender de que el modelo recuerde nada. Para reglas que no admiten excepciones, usa hooks.

¿Puede un hook impedir que Claude ejecute un comando?

Sí. Un hook PreToolUse que termina con código de salida 2 bloquea la llamada a la herramienta y devuelve el mensaje de error a Claude para que cambie de estrategia.

¿Son seguros los hooks?

Se ejecutan con tus permisos de usuario, así que un hook mal escrito o copiado de una fuente dudosa puede hacer daño. Revisa cada comando antes de activarlo, evita pegar hooks de desconocidos y prueba primero en un proyecto sin datos importantes.

Fuentes y referencias

Contenido de la redacción de Skillsia, verificado con fuentes oficiales. Consulta nuestra política editorial. ¿Ves un error? Avísanos y lo corregimos.

Sigue leyendo