claude-code-notifier
cómo funciona guías preguntas frecuentes
◐Español
English العربية Deutsch Español Français עברית Italiano 日本語 한국어 Nederlands Polski Português (Brasil) Русский Türkçe Tiếng Việt 简体中文 繁體中文
Empezar
Todas las guías

El Stop hook de Claude Code: ejecuta algo cuando Claude termina

Actualizado el 31 de octubre de 2026 · 6 min de lectura
en esta página 01Cuándo se dispara Stop y cuándo no 02El Stop hook más sencillo 03Qué recibe el hook 04Muestra el último mensaje de Claude en la notificación 05Hacer que Claude siga 06Notificaciones también para los fallos 07Dónde encaja Claude Code Notifier 08Preguntas frecuentes

El hook Stop de Claude Code ejecuta un comando cada vez que el agente principal de Claude termina de responder, así que es el sitio ideal para enviar una notificación de "listo", registrar el resultado o lanzar comprobaciones. No se ejecuta si interrumpes a Claude, y un turno que termina con un error de la API dispara StopFailure en su lugar. El hook recibe el mensaje final de Claude en last_assistant_message y puede devolver decision: "block" con un reason para que Claude continúe en vez de parar.

01Cuándo se dispara Stop y cuándo no

Stop se dispara al final de cada turno, no solo cuando se completa una tarea entera. Claude Code no tiene noción de "la tarea"; solo sabe que Claude ha dejado de responder y te está esperando. Una pregunta corta genera un Stop, y un refactor de dos horas también.

No se dispara:

  • cuando pulsas Esc o interrumpes el turno de cualquier otra forma;
  • cuando el turno termina por un error de la API, como un rate limit, sobrecarga o fallo de autenticación. Para esos casos Claude Code dispara StopFailure, con un campo error que puedes usar para filtrar (rate_limit, overloaded, server_error y otros);
  • cuando termina un subagente. Para eso está SubagentStop.

Stop no admite matchers, así que cualquier matcher que añadas se ignora y el hook se ejecuta en cada turno.

02El Stop hook más sencillo

Añade esto a ~/.claude/settings.json para ejecutar un comando cada vez que Claude termine. Este reproduce un sonido en macOS:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "afplay /System/Library/Sounds/Glass.aiff"
          }
        ]
      }
    ]
  }
}

Para comandos de notificaciones de escritorio en Mac, Windows y Linux, consulta cómo recibir una notificación cuando Claude Code termina. El resto de esta guía trata de lo que puedes hacer con el input y el output del hook.

03Qué recibe el hook

Además de los campos comunes (session_id, transcript_path, cwd, permission_mode, hook_event_name), un hook Stop recibe:

CampoQué contiene
last_assistant_messageEl texto de la respuesta final de Claude en este turno
stop_hook_activetrue si Claude ya está continuando porque un Stop hook lo bloqueó
background_tasksTareas que siguen en ejecución, como shells en segundo plano o subagentes
session_cronsReactivaciones programadas en esta sesión, por ejemplo con /loop

Usa last_assistant_message en lugar de leer el archivo de transcript. El transcript se escribe de forma asíncrona y puede que aún no contenga el mensaje final cuando se ejecuta el hook.

background_tasks y session_crons te indican si la sesión ha terminado de verdad o solo está en pausa hasta que el trabajo en segundo plano la reactive. Un script de notificación puede comprobar que ambos estén vacíos antes de decir "terminado".

04Muestra el último mensaje de Claude en la notificación

Este script (macOS y Linux, necesita jq) muestra el comienzo de la respuesta de Claude y no dice nada si aún hay trabajo en segundo plano:

#!/bin/bash
# ~/.claude/hooks/notify-done.sh
input=$(cat)

# Skip if background tasks are still in flight
busy=$(jq '(.background_tasks // []) | length' <<<"$input")
[ "$busy" -gt 0 ] && exit 0

msg=$(jq -r '(.last_assistant_message // "Claude has finished")
             | gsub("\\s+"; " ") | .[0:140]' <<<"$input")

if command -v osascript >/dev/null 2>&1; then
  osascript -e 'on run argv' \
            -e 'display notification (item 1 of argv) with title "Claude has finished"' \
            -e 'end run' "$msg"
elif command -v notify-send >/dev/null 2>&1; then
  notify-send "Claude has finished" "$msg"
fi
exit 0

Guárdalo, ejecuta chmod +x ~/.claude/hooks/notify-done.sh y apunta el hook a él:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify-done.sh" }]
      }
    ]
  }
}

El script siempre sale con 0. Esto es importante: en Stop, el código de salida 2 significa "no pares", así que un script de notificación que saliera con 2 por error mantendría a Claude trabajando.

05Hacer que Claude siga

Stop es uno de los eventos que pueden bloquear. Bloquear una parada significa que Claude continúa con el turno, usando tu motivo como su siguiente instrucción. Puedes hacerlo de dos formas:

  • sal con 2 y Claude recibirá tu stderr como motivo; o
  • sal con 0 e imprime JSON:
{
  "decision": "block",
  "reason": "The test suite is failing. Run npm test, fix the failures, then finish."
}

Si el hook da indicaciones en lugar de informar de un error, hookSpecificOutput.additionalContext también mantiene la conversación, pero el transcript lo marca como feedback del Stop hook en vez de como error del hook:

{
  "hookSpecificOutput": {
    "hookEventName": "Stop",
    "additionalContext": "Please run the test suite before finishing"
  }
}

Cómo evitar un bucle infinito

Un Stop hook que siempre bloquee nunca dejaría parar a Claude. Hay dos cosas que te protegen:

  1. stop_hook_active vale true cuando Claude ya está continuando por un Stop hook. Compruébalo y sal antes.
  2. Claude Code termina el turno de todos modos cuando los Stop hooks han bloqueado ocho veces seguidas sin ninguna llamada a herramientas entre medias. La variable de entorno CLAUDE_CODE_STOP_HOOK_BLOCK_CAP permite subir ese límite.

Aquí tienes un hook que hace que Claude arregle los tests que fallan una vez y luego lo deja parar:

#!/bin/bash
# ~/.claude/hooks/tests-must-pass.sh
input=$(cat)
[ "$(jq -r '.stop_hook_active' <<<"$input")" = "true" ] && exit 0

if ! npm test --silent >/dev/null 2>&1; then
  jq -nc '{decision: "block", reason: "npm test is failing. Fix the failures, then finish."}'
fi
exit 0

Los hooks se ejecutan en el directorio de trabajo de la sesión, así que npm test se ejecuta en tu proyecto. Haz que las comprobaciones sean rápidas: por defecto, un hook de comando puede ejecutarse hasta 600 segundos y Claude lo espera.

Si solo quieres que Claude siga trabajando hacia un objetivo sin escribir un script, el comando integrado /goal de Claude Code configura por ti un Stop hook limitado a la sesión.

06Notificaciones también para los fallos

Como los errores de la API se saltan Stop, una alerta de "terminado" no te avisará de que Claude se rindió por un límite de uso. Añade el mismo script en StopFailure si quieres enterarte. Su salida y su código de salida se ignoran, así que solo sirve para notificar o registrar. En StopFailure, last_assistant_message contiene el texto del error, como "API Error: Rate limit reached".

07Dónde encaja Claude Code Notifier

Un Stop hook que llama a un servicio de push es una forma perfectamente válida de saber que Claude ha terminado mientras estás fuera. Si quieres montarlo tú mismo, la guía de ntfy es un buen punto de partida.

Claude Code Notifier usa el mismo hook Stop, con una diferencia: puede devolver algo. Su herramienta de línea de comandos gratuita, ccn, funciona en Mac, Windows y Linux y muestra por sí sola una notificación de escritorio. Con la app de iPhone o Android emparejada, recibes un push de "Claude ha terminado" en cuanto acaba un turno, y puedes escribir la siguiente instrucción en el móvil. ccn la devuelve desde el hook Stop como la siguiente instrucción de Claude, así que la sesión continúa sin que estés al teclado. Si has escrito en los últimos 30 segundos, no se espera al móvil. Es independiente y no lo ha creado Anthropic. Consulta alejarte de las tareas largas para ese flujo de trabajo y la página de ccn para instalarlo.

08Preguntas frecuentes

¿El Stop hook se ejecuta cuando Claude termina toda la tarea o después de cada respuesta?

Después de cada respuesta. Stop se dispara cada vez que el agente principal termina de responder, sea cual sea el tamaño de la petición. Revisa background_tasks y session_crons en la entrada si necesitas saber si aún queda trabajo programado.

¿Por qué no se disparó mi Stop hook?

Puede que interrumpieras el turno, lo que se salta Stop, o que terminara con un error de la API, que dispara StopFailure en su lugar. Si no, comprueba que /hooks muestra tu hook y que el script es ejecutable. La lista de comprobación para solucionar problemas cubre el resto.

¿Por qué Claude sigue trabajando después de que se ejecute mi Stop hook?

Tu hook está bloqueando la parada, ya sea saliendo con código 2 o imprimiendo decision: "block". Asegúrate de que un hook que solo notifica siempre salga con 0, y de que cualquier hook que bloquee compruebe primero stop_hook_active.

¿Cómo obtengo la respuesta final de Claude en el hook?

Lee last_assistant_message del JSON que llega por stdin, por ejemplo con jq -r '.last_assistant_message'. No dependas de transcript_path: puede que el archivo aún no contenga el último mensaje cuando se dispara Stop.

¿Qué diferencia hay entre Stop y SubagentStop?

Stop es para el agente principal. SubagentStop se dispara cuando termina un subagente, filtra por tipo de agente y admite los mismos campos de bloqueo. Una alerta de "Claude ha terminado" va en Stop.

Claude Code Notifier Recibe un push en el móvil cuando Claude Code termina o te necesita, y aprueba, deniega o responde desde ahí. La herramienta de línea de comandos ccn es gratis en Mac, Windows y Linux.
Descargar para iOS Descargar para Android Instalar ccn

Guías relacionadas

  • Cómo recibir una notificación cuando Claude Code terminaUsa un Stop hook para "ha terminado" y un Notification hook para "necesita tu respuesta". Configuraciones listas para copiar en Mac, Windows y Linux, además de avisos en el móvil.
  • Los hooks de Claude Code explicados: cada evento y para qué sirveQué son los hooks de Claude Code, dónde van en settings.json, cómo funcionan los matchers, la entrada y los códigos de salida, y para qué sirve cada evento de hook.
  • El Notification hook de Claude Code: cuándo se dispara y cómo usarloCuándo se dispara el Notification hook de Claude Code, qué significan permission_prompt e idle_prompt, qué entrada recibe y por qué espera antes de dispararse.
  • Deja Claude Code trabajando y vete: un flujo de trabajoUna rutina práctica para tareas largas de Claude Code: mantén el ordenador despierto, elimina prompts innecesarios, recibe avisos en el móvil y responde desde ahí.
claude-code-notifier

Claude Code Notifier es una aplicación independiente de terceros. No está afiliada, respaldada ni patrocinada por Anthropic, PBC. "Claude" y "Claude Code" son marcas comerciales de Anthropic, PBC.

apps App para iOS App para Android ccn para macOS, Windows y Linux Todas las guías
legal Política de privacidad Condiciones del servicio Otros idiomas © 2026 touchtap. Todos los derechos reservados. TouchTap Ltd está registrada en Inglaterra y Gales, número de empresa 13942589.