O que são hooks no Claude Code e que automações eles permitem?

hooks no Claude Code automatizando o fluxo de trabalho no editor
Resposta rápida

Hooks no Claude Code são comandos definidos por você que o editor executa automaticamente em pontos do ciclo de vida da sessão, como antes de usar uma ferramenta, depois de editar um arquivo ou quando a sessão começa. A graça é o determinismo: em vez de torcer pro modelo lembrar da regra, o evento acontece e o comando roda. A configuração vive em arquivos JSON de settings (.claude/settings.json no projeto, ~/.claude/settings.json no usuário) e tem três níveis: evento, matcher e handler. Dá pra formatar código, logar tudo, avisar sobre convenção e até bloquear alteração em arquivo sensível

Tem uma diferença absurda entre pedir "roda o formatador depois de editar" toda santa vez e o editor fazer isso sozinho, sem você abrir a boca

A primeira opção depende do modelo lembrar

A segunda é uma regra do projeto

E é exatamente aí que entram os hooks no Claude Code, a peça que faltava no acervo aqui do blog: a gente já falou de comandos e de MCP, mas nunca de hooks

Bora entender o que eles são e que tipo de automação eles destravam? 😀

Por que hooks importam: determinismo em vez de torcer para o modelo lembrar

Hooks são comandos definidos pelo usuário que o Claude Code executa automaticamente em pontos do ciclo de vida da sessão

A documentação oficial de hooks resume bem a ideia: em vez de depender do modelo decidir agir, você tem execução determinística disparada por evento

Se liga na diferença, porque ela é o post inteiro:

Quando você escreve a regra no prompt, o modelo AVALIA se aquilo se aplica agora

Às vezes aplica, às vezes o contexto encheu e ele passa batido

Quando a regra é um hook, o evento aconteceu, o comando rodou, fim

Não tem "será que ele lembrou?"

E tem um detalhe que muda o jogo pra quem trabalha em equipe: como a configuração mora num arquivo de settings dentro do projeto, aquela regra deixa de ser um hábito seu e vira parte do repositório

É o que transforma um monte de prompt solto em sistema

A convenção não depende mais de quem está digitando, ela é do projeto

Como um hook é montado: evento, matcher e handler

A configuração tem três níveis, e vale decorar nessa ordem: evento > matcher > handler

  • Evento: QUANDO o hook é considerado (antes da ferramenta, depois da ferramenta, no início da sessão e por aí vai)
  • Matcher: um grupo que FILTRA quando ele realmente dispara
  • Handler: o que efetivamente roda quando teve match

O exemplo oficial de formatação automática deixa isso bem claro

Ele usa um hook PostToolUse com matcher Edit|Write e um comando que extrai o caminho do arquivo com jq e passa pro Prettier:

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

Esse trecho vai no .claude/settings.json na raiz do projeto

E o matcher aqui é filtro por nome de ferramenta, aceitando alternância

Ou seja: Edit|Write dispara SÓ quando o Claude usa as ferramentas Edit ou Write

Se ele usar Bash, Read ou qualquer outra, o hook não roda

Tome cuidado com isso, é o erro clássico de quem monta o primeiro hook: escreve o matcher achando que ele filtra o arquivo ou a pasta, e depois fica se perguntando por que nada aconteceu

Quais eventos existem e o que cada momento permite automatizar

A referência oficial cita esta lista de eventos do ciclo de vida:

PreToolUse, PostToolUse, PostToolUseFailure, Notification, UserPromptSubmit, SessionStart, SessionEnd, Stop, SubagentStart, SubagentStop, PreCompact, PermissionRequest, Setup, TeammateIdle, TaskCompleted, ConfigChange, WorktreeCreate e WorktreeRemove

Se você já mexeu com lifecycle hooks em frameworks, a lógica é bem parecida: cada nome é um momento da vida da coisa, e você escolhe em qual deles quer se pendurar

Alguns têm comportamento próprio e merecem atenção:

PreToolUse dispara ANTES da chamada da ferramenta, e pode bloquear a chamada

Esse é o evento de guardrail na hora de mexer em ferramenta: é ali que dá pra impedir a ação antes dela acontecer

PostToolUse roda DEPOIS que a ferramenta já executou

Aqui não tem mais o que impedir, o que dá é reagir: formatar, logar, avisar

SessionStart dispara no início da sessão e aceita os matchers startup, resume, clear ou compact

PreCompact dispara antes da compactação de contexto, com os matchers manual ou auto

SessionEnd dispara quando a sessão termina, com os matchers clear, resume, logout, prompt_input_exit, bypass_permissions_disabled ou other

E tem a regra dos subagentes, que confunde bastante:

Hooks de subagente rodam apenas enquanto aquele subagente está ativo, e são removidos quando ele termina

Além disso, o Claude Code converte um hook Stop em SubagentStop, que é o evento disparado quando o subagente conclui

Os cinco tipos de hook: command, http, prompt, mcp_tool e agent

O handler não precisa ser shell

Existem cinco tipos, e cada um abre uma categoria diferente de automação:

Tipo O que ele faz
command Roda um comando de shell
http Envia o JSON do evento como POST para uma URL
prompt Envia um prompt a um modelo Claude para avaliação de turno único
mcp_tool Chama uma ferramenta de um servidor MCP já conectado
agent Dispara um subagente que pode usar ferramentas como Read, Grep e Glob para verificar condições

Repara no salto de capacidade dessa lista

O command é o feijão com arroz e resolve a maior parte do que você quer

O http joga o evento pra fora da sua máquina, o que é a porta de entrada pra dashboard, webhook e integração

O prompt e o agent são o pulo do gato: você usa IA pra decidir se a condição bateu, em vez de tentar escrever essa lógica em if de bash

Um hook do tipo agent consegue abrir arquivo e vasculhar o projeto com Grep e Glob pra checar uma condição, o que é MUITO mais flexível que um grep cru

E o mcp_tool conecta o gatilho com o que você já plugou via MCP

Sobre tempo de execução: o campo timeout é opcional e tem padrão de 600 segundos para hooks command, 30 segundos para hooks prompt e 60 segundos para hooks agent

Faz sentido, né? Um script de build pode demorar, uma avaliação de turno único não deveria

Como o hook conversa com o Claude: stdin, exit code e bloqueio

Essa parte é a que mais gera dúvida, então vamos devagar

Em hooks do tipo command, o contrato é o mais unixzão possível: o script recebe o JSON do evento via stdin e devolve o resultado pelo exit code e pelo stdout

É por isso que o exemplo do Prettier começa com jq -r, ele está lendo o JSON que chegou pela entrada padrão

Agora os exit codes, que é onde mora o poder:

Exit code 2 é erro bloqueante

O Claude Code bloqueia a ação e o motivo escrito em stderr é mostrado ao Claude

O efeito varia por evento: em PreToolUse ele bloqueia a chamada da ferramenta, em UserPromptSubmit ele rejeita o prompt

Em PostToolUse o exit 2 não bloqueia, porque a ferramenta já rodou

Mas continua servindo pra uma coisa importante: o Claude enxerga o aviso escrito em stderr

É assim que você dá feedback automático de convenção sem travar o fluxo

No exit 0, o stderr vai só pro log de debug

Nunca pro transcript, e o Claude não vê esse conteúdo

Já me pareceu contraintuitivo, mas é a regra: se você quer que o Claude LEIA a mensagem, tem que sair com 2

E em PreToolUse ainda dá pra negar a ação de outro jeito, retornando permissionDecision igual a deny na saída JSON do hook

Que automações dá para montar com hooks

Agora que os pedaços estão na mesa, o sistema começa a tomar forma

A documentação cita estes casos de uso, e eu amarrei cada um ao evento e ao tipo que fazem sentido:

  1. Notificações: usar o evento Notification ou um handler http pra jogar o aviso onde você realmente olha
  2. Formatação automática após edição de arquivo: o clássico PostToolUse com matcher Edit|Write, exatamente o exemplo do Prettier lá de cima
  3. Logging para auditoria ou debug: um handler command gravando o JSON do evento, ou http mandando pra fora
  4. Feedback automático quando o código foge das convenções: PostToolUse saindo com exit 2 e a razão no stderr, pro Claude ler e corrigir
  5. Permissões customizadas pra bloquear alterações em arquivos ou diretórios sensíveis: PreToolUse com exit 2 ou com permissionDecision igual a deny

O item 5 é o que mais tranquiliza quem tem medo dos rm -rf da vida

E se você quer ver a receita completa desse caminho, tem um post aqui do blog sobre automatizar lint, formatação e bloqueios antes e depois do agente encostar no código

Onde os hooks ficam e quem vence quando há conflito

Hooks são definidos em arquivos JSON de settings, e existem dois lugares principais:

  • .claude/settings.json: hooks de PROJETO, versionado e compartilhado com o time
  • ~/.claude/settings.json: hooks PESSOAIS, que valem pra todo projeto

A escolha aqui não é técnica, é de intenção

Regra que vale pra qualquer um que abrir o repo? Vai no projeto

Mania sua, tipo notificação do seu jeito? Vai no seu

E quando os dois falam da mesma coisa, vale a precedência de settings: o arquivo de settings de um projeto pode sobrescrever o do usuário, e settings gerenciados (managed) têm a maior precedência e não podem ser sobrescritos

A ordem é: managed > projeto > usuário

Detalhe importante pra quem trabalha em empresa com política definida: hooks definidos em managed settings continuam rodando a menos que disableAllHooks também esteja definido ali

E se você usa o Claude Code na web, se liga nisso: sessões na nuvem não leem o ~/.claude/settings.json local

Ali os hooks vêm do repositório e dos settings gerenciados pelo servidor da organização

Ou seja, aquele hook pessoal que você ama simplesmente não existe naquele ambiente

O comando /hooks: o que ele mostra e o que ele não faz

O comando /hooks abre o navegador de hooks

Ele lista os eventos disponíveis com a contagem de hooks configurados em cada um, e ao selecionar um hook aparecem evento, matcher, tipo, arquivo de origem e comando

Aquele campo de arquivo de origem é ouro puro quando você não faz ideia de onde veio um hook que está disparando

Mas tem o aviso central: o menu /hooks é somente leitura

Pra adicionar, alterar ou remover um hook é preciso editar o JSON de settings diretamente ou pedir a alteração ao Claude

Remover é apagar a entrada no arquivo de settings, não tem botão

E uma boa notícia pra não ficar reiniciando à toa: se os arquivos de settings forem editados com o Claude Code aberto, o file watcher normalmente já pega as mudanças de hooks automaticamente

Conclusão

O conceito cabe numa linha: o evento acontece, o Claude Code executa o que você definiu, sem depender do modelo lembrar

Evento define quando, matcher filtra o que dispara, handler é o que roda

E os cinco tipos (command, http, prompt, mcp_tool e agent) fazem esse gatilho ir de um shell simples até um subagente vasculhando o projeto

Próximo passo concreto, bem de boa:

  1. Roda /hooks na sua sessão pra ver o que já existe hoje (talvez tenha coisa vinda do projeto que você nem sabia)
  2. Cria um PostToolUse simples de formatação no .claude/settings.json do projeto, copiando o exemplo do Prettier
  3. Edita um arquivo e vê se rodou

Se o hook não disparar, o suspeito número 1 é sempre o matcher: confere se a ferramenta usada foi mesmo Edit ou Write

Depois que isso engatar, junta com o que já rolou por aqui sobre comandos e MCP

Comando é o atalho que você chama, MCP é a ferramenta que você pluga, hook é o gatilho que dispara sozinho

Os três juntos é onde a coisa vira sistema de verdade… 🙂

até o próximo post!

Perguntas frequentes

O que são hooks no Claude Code?

São comandos definidos pelo usuário que o Claude Code executa automaticamente em pontos do ciclo de vida da sessão. A diferença pro prompt é o determinismo: em vez de depender do modelo decidir agir, o evento acontece e o comando roda.

Quais tipos de hook existem além de rodar um comando de shell?

São cinco tipos: command (roda comando de shell), http (envia o JSON do evento como POST para uma URL), prompt (envia um prompt a um modelo Claude para avaliação de turno único), mcp_tool (chama uma ferramenta de um servidor MCP já conectado) e agent (dispara um subagente que pode usar ferramentas como Read, Grep e Glob para verificar condições).

Qual a diferença entre configurar um hook em .claude/settings.json e em ~/.claude/settings.json?

O .claude/settings.json fica no projeto, é versionado e compartilhado com o time. Já o ~/.claude/settings.json é pessoal e vale pra todo projeto que você abrir. Na precedência, managed settings vem em primeiro lugar, depois o settings do projeto sobrescreve o do usuário.

Hooks de subagente continuam ativos depois que o subagente termina?

Não. Hooks de subagente rodam apenas enquanto aquele subagente está ativo e são removidos quando ele termina. Vale reparar também que, dentro de um subagente, o Claude Code converte um hook Stop em SubagentStop, o evento disparado quando ele conclui.

Dá pra bloquear uma ferramenta perigosa antes dela executar usando hooks no Claude Code?

Dá, e é justamente o papel do PreToolUse, que dispara antes da chamada da ferramenta e pode impedi-la. Isso acontece com exit code 2, que bloqueia a ação e mostra o motivo escrito em stderr pro Claude, ou retornando permissionDecision igual a deny na saída JSON do hook.

Qual é o timeout padrão de um hook?

O campo timeout é opcional. O padrão é de 600 segundos para hooks command, 30 segundos para hooks prompt e 60 segundos para hooks agent.



Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares