Configure seu primeiro hook
A forma mais rápida de criar um hook é através do menu interativo/hooks no Claude Code. Este passo a passo cria um hook de notificação de desktop, para que você seja alertado sempre que Claude estiver aguardando sua entrada em vez de observar o terminal.
Abra o menu de hooks
Digite
/hooks na CLI do Claude Code. Você verá uma lista de todos os eventos de hook disponíveis, mais uma opção para desabilitar todos os hooks. Cada evento corresponde a um ponto no ciclo de vida do Claude onde você pode executar código personalizado. Selecione Notification para criar um hook que dispara quando Claude precisa de sua atenção.Configure o matcher
O menu mostra uma lista de matchers, que filtram quando o hook dispara. Defina o matcher como
* para disparar em todos os tipos de notificação. Você pode restringi-lo depois alterando o matcher para um valor específico como permission_prompt ou idle_prompt.Adicione seu comando
Selecione
+ Add new hook…. O menu solicita um comando shell para executar quando o evento dispara. Hooks executam qualquer comando shell que você forneça, então você pode usar a ferramenta de notificação integrada da sua plataforma. Copie o comando para seu SO:- macOS
- Linux
- Windows (PowerShell)
Usa
osascript para disparar uma notificação nativa do macOS através do AppleScript:Escolha um local de armazenamento
O menu pergunta onde salvar a configuração do hook. Selecione
User settings para armazená-lo em ~/.claude/settings.json, que aplica o hook a todos os seus projetos. Você também pode escolher Project settings para limitá-lo ao projeto atual. Consulte Configurar local do hook para todos os escopos disponíveis.O que você pode automatizar
Hooks permitem executar código em pontos-chave do ciclo de vida do Claude Code: formatar arquivos após edições, bloquear comandos antes de executarem, enviar notificações quando Claude precisa de entrada, injetar contexto no início da sessão e muito mais. Para a lista completa de eventos de hook, consulte a referência de Hooks. Cada exemplo inclui um bloco de configuração pronto para usar que você adiciona a um arquivo de configuração. Os padrões mais comuns:- Receba notificações quando Claude precisa de entrada
- Formatar código automaticamente após edições
- Bloquear edições em arquivos protegidos
- Re-injetar contexto após compactação
- Auditar mudanças de configuração
Receba notificações quando Claude precisa de entrada
Receba uma notificação de desktop sempre que Claude terminar de trabalhar e precisar de sua entrada, para que você possa mudar para outras tarefas sem verificar o terminal. Este hook usa o eventoNotification, que dispara quando Claude está aguardando entrada ou permissão. Cada aba abaixo usa o comando de notificação nativo da plataforma. Adicione isto a ~/.claude/settings.json, ou use o passo a passo interativo acima para configurá-lo com /hooks:
- macOS
- Linux
- Windows (PowerShell)
Formatar código automaticamente após edições
Execute automaticamente Prettier em cada arquivo que Claude edita, para que a formatação permaneça consistente sem intervenção manual. Este hook usa o eventoPostToolUse com um matcher Edit|Write, para que execute apenas após ferramentas de edição de arquivo. O comando extrai o caminho do arquivo editado com jq e o passa para Prettier. Adicione isto a .claude/settings.json na raiz do seu projeto:
Os exemplos Bash nesta página usam
jq para análise JSON. Instale-o com brew install jq (macOS), apt-get install jq (Debian/Ubuntu), ou consulte downloads do jq.Bloquear edições em arquivos protegidos
Impeça que Claude modifique arquivos sensíveis como.env, package-lock.json ou qualquer coisa em .git/. Claude recebe feedback explicando por que a edição foi bloqueada, para que possa ajustar sua abordagem.
Este exemplo usa um arquivo de script separado que o hook chama. O script verifica o caminho do arquivo de destino contra uma lista de padrões protegidos e sai com código 2 para bloquear a edição.
Torne o script executável (macOS/Linux)
Scripts de hook devem ser executáveis para que Claude Code os execute:
Re-injetar contexto após compactação
Quando a janela de contexto do Claude fica cheia, a compactação resume a conversa para liberar espaço. Isto pode perder detalhes importantes. Use um hookSessionStart com um matcher compact para re-injetar contexto crítico após cada compactação.
Qualquer texto que seu comando escreve para stdout é adicionado ao contexto do Claude. Este exemplo lembra ao Claude as convenções do projeto e trabalho recente. Adicione isto a .claude/settings.json na raiz do seu projeto:
echo por qualquer comando que produza saída dinâmica, como git log --oneline -5 para mostrar commits recentes. Para injetar contexto em cada início de sessão, considere usar CLAUDE.md em vez disso. Para variáveis de ambiente, consulte CLAUDE_ENV_FILE na referência.
Auditar mudanças de configuração
Rastreie quando arquivos de configuração ou skills mudam durante uma sessão. O eventoConfigChange dispara quando um processo externo ou editor modifica um arquivo de configuração, para que você possa registrar mudanças para conformidade ou bloquear modificações não autorizadas.
Este exemplo anexa cada mudança a um log de auditoria. Adicione isto a ~/.claude/settings.json:
user_settings, project_settings, local_settings, policy_settings ou skills. Para bloquear uma mudança de entrar em vigor, saia com código 2 ou retorne {"decision": "block"}. Consulte a referência de ConfigChange para o esquema de entrada completo.
Como hooks funcionam
Eventos de hook disparam em pontos específicos do ciclo de vida do Claude Code. Quando um evento dispara, todos os hooks correspondentes executam em paralelo, e comandos de hook idênticos são automaticamente desduplicados. A tabela abaixo mostra cada evento e quando dispara:| Event | When it fires |
|---|---|
SessionStart | When a session begins or resumes |
UserPromptSubmit | When you submit a prompt, before Claude processes it |
PreToolUse | Before a tool call executes. Can block it |
PermissionRequest | When a permission dialog appears |
PostToolUse | After a tool call succeeds |
PostToolUseFailure | After a tool call fails |
Notification | When Claude Code sends a notification |
SubagentStart | When a subagent is spawned |
SubagentStop | When a subagent finishes |
Stop | When Claude finishes responding |
TeammateIdle | When an agent team teammate is about to go idle |
TaskCompleted | When a task is being marked as completed |
InstructionsLoaded | When a CLAUDE.md or .claude/rules/*.md file is loaded into context. Fires at session start and when files are lazily loaded during a session |
ConfigChange | When a configuration file changes during a session |
WorktreeCreate | When a worktree is being created via --worktree or isolation: "worktree". Replaces default git behavior |
WorktreeRemove | When a worktree is being removed, either at session exit or when a subagent finishes |
PreCompact | Before context compaction |
PostCompact | After context compaction completes |
Elicitation | When an MCP server requests user input during a tool call |
ElicitationResult | After a user responds to an MCP elicitation, before the response is sent back to the server |
SessionEnd | When a session terminates |
type que determina como ele executa. A maioria dos hooks usa "type": "command", que executa um comando shell. Três outros tipos estão disponíveis:
"type": "http": POST de dados de evento para uma URL. Consulte HTTP hooks."type": "prompt": avaliação LLM de turno único. Consulte Hooks baseados em prompt."type": "agent": verificação multi-turno com acesso a ferramentas. Consulte Hooks baseados em agente.
Ler entrada e retornar saída
Hooks se comunicam com Claude Code através de stdin, stdout, stderr e códigos de saída. Quando um evento dispara, Claude Code passa dados específicos do evento como JSON para stdin do seu script. Seu script lê esses dados, faz seu trabalho e diz ao Claude Code o que fazer a seguir através do código de saída.Entrada do hook
Cada evento inclui campos comuns comosession_id e cwd, mas cada tipo de evento adiciona dados diferentes. Por exemplo, quando Claude executa um comando Bash, um hook PreToolUse recebe algo assim em stdin:
UserPromptSubmit recebem o texto prompt em vez disso, hooks SessionStart recebem a source (startup, resume, clear, compact) e assim por diante. Consulte Campos de entrada comuns na referência para campos compartilhados e a seção de cada evento para esquemas específicos do evento.
Saída do hook
Seu script diz ao Claude Code o que fazer a seguir escrevendo para stdout ou stderr e saindo com um código específico. Por exemplo, um hookPreToolUse que quer bloquear um comando:
- Exit 0: a ação prossegue. Para hooks
UserPromptSubmiteSessionStart, qualquer coisa que você escrever para stdout é adicionada ao contexto do Claude. - Exit 2: a ação é bloqueada. Escreva um motivo para stderr, e Claude o recebe como feedback para que possa se ajustar.
- Qualquer outro código de saída: a ação prossegue. Stderr é registrado mas não mostrado ao Claude. Alterne o modo verboso com
Ctrl+Opara ver essas mensagens na transcrição.
Saída JSON estruturada
Códigos de saída lhe dão duas opções: permitir ou bloquear. Para mais controle, saia com 0 e imprima um objeto JSON para stdout em vez disso.Use exit 2 para bloquear com uma mensagem stderr, ou exit 0 com JSON para controle estruturado. Não misture: Claude Code ignora JSON quando você sai com 2.
PreToolUse pode negar uma chamada de ferramenta e dizer ao Claude por quê, ou escalar para o usuário para aprovação:
permissionDecision e cancela a chamada de ferramenta, depois alimenta permissionDecisionReason de volta ao Claude como feedback. Essas três opções são específicas para PreToolUse:
"allow": prosseguir sem mostrar um prompt de permissão"deny": cancelar a chamada de ferramenta e enviar o motivo ao Claude"ask": mostrar o prompt de permissão ao usuário normalmente
PostToolUse e Stop usam um campo decision: "block" de nível superior, enquanto PermissionRequest usa hookSpecificOutput.decision.behavior. Consulte a tabela de resumo na referência para uma análise completa por evento.
Para hooks UserPromptSubmit, use additionalContext em vez disso para injetar texto no contexto do Claude. Hooks baseados em prompt (type: "prompt") lidam com saída de forma diferente: consulte Hooks baseados em prompt.
Filtrar hooks com matchers
Sem um matcher, um hook dispara em cada ocorrência de seu evento. Matchers permitem restringir isso. Por exemplo, se você quer executar um formatador apenas após edições de arquivo (não após cada chamada de ferramenta), adicione um matcher ao seu hookPostToolUse:
"Edit|Write" é um padrão regex que corresponde ao nome da ferramenta. O hook dispara apenas quando Claude usa a ferramenta Edit ou Write, não quando usa Bash, Read ou qualquer outra ferramenta.
Cada tipo de evento corresponde a um campo específico. Matchers suportam strings exatas e padrões regex:
| Evento | O que o matcher filtra | Valores de matcher de exemplo |
|---|---|---|
PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest | nome da ferramenta | Bash, Edit|Write, mcp__.* |
SessionStart | como a sessão começou | startup, resume, clear, compact |
SessionEnd | por que a sessão terminou | clear, logout, prompt_input_exit, bypass_permissions_disabled, other |
Notification | tipo de notificação | permission_prompt, idle_prompt, auth_success, elicitation_dialog |
SubagentStart | tipo de agente | Bash, Explore, Plan ou nomes de agentes personalizados |
PreCompact | o que acionou a compactação | manual, auto |
SubagentStop | tipo de agente | mesmos valores que SubagentStart |
ConfigChange | fonte de configuração | user_settings, project_settings, local_settings, policy_settings, skills |
UserPromptSubmit, Stop, TeammateIdle, TaskCompleted, WorktreeCreate, WorktreeRemove | sem suporte a matcher | sempre dispara em cada ocorrência |
- Registrar cada comando Bash
- Corresponder ferramentas MCP
- Limpar no final da sessão
Corresponda apenas chamadas de ferramenta
Bash e registre cada comando em um arquivo. O evento PostToolUse dispara após o comando ser concluído, então tool_input.command contém o que foi executado. O hook recebe os dados do evento como JSON em stdin, e jq -r '.tool_input.command' extrai apenas a string de comando, que >> anexa ao arquivo de log:Configurar local do hook
Onde você adiciona um hook determina seu escopo:| Local | Escopo | Compartilhável |
|---|---|---|
~/.claude/settings.json | Todos os seus projetos | Não, local para sua máquina |
.claude/settings.json | Projeto único | Sim, pode ser commitado no repo |
.claude/settings.local.json | Projeto único | Não, gitignored |
| Configurações de política gerenciada | Organização inteira | Sim, controlado por admin |
Plugin hooks/hooks.json | Quando o plugin está habilitado | Sim, empacotado com o plugin |
| Skill ou agente frontmatter | Enquanto a skill ou agente está ativo | Sim, definido no arquivo do componente |
/hooks no Claude Code para adicionar, deletar e visualizar hooks interativamente. Para desabilitar todos os hooks de uma vez, use o toggle na parte inferior do menu /hooks ou defina "disableAllHooks": true no seu arquivo de configuração.
Hooks adicionados através do menu /hooks entram em vigor imediatamente. Se você editar arquivos de configuração diretamente enquanto Claude Code está em execução, as mudanças não entrarão em vigor até que você as revise no menu /hooks ou reinicie sua sessão.
Hooks baseados em prompt
Para decisões que exigem julgamento em vez de regras determinísticas, use hookstype: "prompt". Em vez de executar um comando shell, Claude Code envia seu prompt e os dados de entrada do hook para um modelo Claude (Haiku por padrão) para tomar a decisão. Você pode especificar um modelo diferente com o campo model se precisar de mais capacidade.
O único trabalho do modelo é retornar uma decisão sim/não como JSON:
"ok": true: a ação prossegue"ok": false: a ação é bloqueada. O"reason"do modelo é alimentado de volta ao Claude para que ele possa se ajustar.
Stop para perguntar ao modelo se todas as tarefas solicitadas estão completas. Se o modelo retornar "ok": false, Claude continua trabalhando e usa o reason como sua próxima instrução:
Hooks baseados em agente
Quando a verificação exige inspecionar arquivos ou executar comandos, use hookstype: "agent". Diferentemente de hooks de prompt que fazem uma única chamada LLM, hooks de agente geram um subagente que pode ler arquivos, pesquisar código e usar outras ferramentas para verificar condições antes de retornar uma decisão.
Hooks de agente usam o mesmo formato de resposta "ok" / "reason" que hooks de prompt, mas com um timeout padrão mais longo de 60 segundos e até 50 turnos de uso de ferramenta.
Este exemplo verifica que os testes passam antes de permitir que Claude pare:
HTTP hooks
Use hookstype: "http" para POST de dados de evento para um endpoint HTTP em vez de executar um comando shell. O endpoint recebe o mesmo JSON que um hook de comando receberia em stdin, e retorna resultados através do corpo da resposta HTTP usando o mesmo formato JSON.
HTTP hooks são úteis quando você quer que um servidor web, função em nuvem ou serviço externo manipule a lógica do hook: por exemplo, um serviço de auditoria compartilhado que registra eventos de uso de ferramenta em toda uma equipe.
Este exemplo posta cada uso de ferramenta para um serviço de logging local:
hookSpecificOutput apropriados. Códigos de status HTTP sozinhos não podem bloquear ações.
Valores de header suportam interpolação de variável de ambiente usando sintaxe $VAR_NAME ou ${VAR_NAME}. Apenas variáveis listadas no array allowedEnvVars são resolvidas; todas as outras referências $VAR permanecem vazias.
HTTP hooks devem ser configurados editando seu JSON de configuração diretamente. O menu interativo
/hooks suporta apenas adicionar hooks de comando.Limitações e solução de problemas
Limitações
- Hooks de comando se comunicam apenas através de stdout, stderr e códigos de saída. Eles não podem disparar comandos ou chamadas de ferramenta diretamente. HTTP hooks se comunicam através do corpo da resposta em vez disso.
- O timeout do hook é 10 minutos por padrão, configurável por hook com o campo
timeout(em segundos). - Hooks
PostToolUsenão podem desfazer ações já que a ferramenta já foi executada. - Hooks
PermissionRequestnão disparam em modo não-interativo (-p). Use hooksPreToolUsepara decisões de permissão automatizadas. - Hooks
Stopdisparam sempre que Claude termina de responder, não apenas na conclusão de tarefas. Eles não disparam em interrupções do usuário.
Hook não dispara
O hook está configurado mas nunca executa.- Execute
/hookse confirme que o hook aparece sob o evento correto - Verifique que o padrão do matcher corresponde ao nome da ferramenta exatamente (matchers são sensíveis a maiúsculas)
- Verifique que você está acionando o tipo de evento correto (por exemplo,
PreToolUsedispara antes da execução da ferramenta,PostToolUsedispara depois) - Se usar hooks
PermissionRequestem modo não-interativo (-p), mude paraPreToolUseem vez disso
Erro de hook na saída
Você vê uma mensagem como “PreToolUse hook error: …” na transcrição.- Seu script saiu com um código não-zero inesperadamente. Teste-o manualmente canalizando JSON de amostra:
- Se você vir “command not found”, use caminhos absolutos ou
$CLAUDE_PROJECT_DIRpara referenciar scripts - Se você vir “jq: command not found”, instale
jqou use Python/Node.js para análise JSON - Se o script não está executando em tudo, torne-o executável:
chmod +x ./my-hook.sh
/hooks mostra nenhum hook configurado
Você editou um arquivo de configuração mas os hooks não aparecem no menu.
- Reinicie sua sessão ou abra
/hookspara recarregar. Hooks adicionados através do menu/hooksentram em vigor imediatamente, mas edições manuais de arquivo exigem um recarregamento. - Verifique que seu JSON é válido (vírgulas finais e comentários não são permitidos)
- Confirme que o arquivo de configuração está no local correto:
.claude/settings.jsonpara hooks de projeto,~/.claude/settings.jsonpara hooks globais
Stop hook executa para sempre
Claude continua trabalhando em um loop infinito em vez de parar. Seu script de Stop hook precisa verificar se já acionou uma continuação. Analise o campostop_hook_active da entrada JSON e saia cedo se for true:
Validação JSON falhou
Claude Code mostra um erro de análise JSON mesmo que seu script de hook produza JSON válido. Quando Claude Code executa um hook, ele gera um shell que fornece seu perfil (~/.zshrc ou ~/.bashrc). Se seu perfil contiver instruções echo incondicionais, essa saída é adicionada ao seu JSON do hook:
$- contém flags de shell, e i significa interativo. Hooks executam em shells não-interativos, então o echo é pulado.
Técnicas de debug
Alterne o modo verboso comCtrl+O para ver a saída do hook na transcrição, ou execute claude --debug para detalhes de execução completos incluindo quais hooks corresponderam e seus códigos de saída.
Saiba mais
- Referência de Hooks: esquemas de eventos completos, formato de saída JSON, hooks assíncronos e hooks de ferramentas MCP
- Considerações de segurança: revise antes de implantar hooks em ambientes compartilhados ou de produção
- Exemplo de validador de comando Bash: implementação de referência completa