Gli hooks sono comandi shell definiti dall’utente che si eseguono in punti specifici del ciclo di vita di Claude Code. Forniscono un controllo deterministico sul comportamento di Claude Code, garantendo che determinate azioni avvengano sempre piuttosto che affidarsi al modello linguistico per scegliere di eseguirle. Utilizzate gli hooks per applicare le regole del progetto, automatizzare attività ripetitive e integrare Claude Code con i vostri strumenti esistenti. Per decisioni che richiedono giudizio piuttosto che regole deterministiche, potete anche utilizzare hooks basati su prompt o hooks basati su agenti che utilizzano un modello Claude per valutare le condizioni. Per altri modi di estendere Claude Code, consultate skills per fornire a Claude istruzioni aggiuntive e comandi eseguibili, subagents per eseguire attività in contesti isolati, e plugins per pacchettizzare estensioni da condividere tra i progetti.Documentation Index
Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Configurare il vostro primo hook
Per creare un hook, aggiungete un bloccohooks a un file di impostazioni. Questa procedura crea un hook di notifica desktop, in modo da ricevere un avviso ogni volta che Claude sta aspettando il vostro input invece di guardare il terminale.
Aggiungere l'hook alle vostre impostazioni
Aprite Se il vostro file di impostazioni ha già una chiave Potete anche chiedere a Claude di scrivere l’hook per voi descrivendo quello che volete nella CLI.
~/.claude/settings.json e aggiungete un hook Notification. L’esempio sottostante utilizza osascript per macOS; consultate Ricevere una notifica quando Claude ha bisogno di input per i comandi Linux e Windows.hooks, aggiungete Notification come sibling delle chiavi di evento esistenti piuttosto che sostituire l’intero oggetto. Ogni nome di evento è una chiave all’interno del singolo oggetto hooks:Verificare la configurazione
Digitate
/hooks per aprire il browser degli hooks. Vedrete un elenco di tutti gli eventi hook disponibili, con un conteggio accanto a ogni evento che ha hook configurati. Selezionate Notification per confermare che il vostro nuovo hook appare nell’elenco. Selezionando l’hook vengono mostrati i suoi dettagli: l’evento, il matcher, il tipo, il file di origine e il comando.Cosa potete automatizzare
Gli hooks vi permettono di eseguire codice in punti chiave del ciclo di vita di Claude Code: formattare file dopo le modifiche, bloccare comandi prima che si eseguano, inviare notifiche quando Claude ha bisogno di input, iniettare contesto all’inizio della sessione, e altro ancora. Per l’elenco completo degli eventi hook, consultate il riferimento Hooks. Ogni esempio include un blocco di configurazione pronto all’uso che aggiungete a un file di impostazioni. I modelli più comuni:- Ricevere una notifica quando Claude ha bisogno di input
- Formattare automaticamente il codice dopo le modifiche
- Bloccare le modifiche ai file protetti
- Reiniettare il contesto dopo la compattazione
- Controllare le modifiche di configurazione
- Ricaricare l’ambiente quando la directory o i file cambiano
- Approvare automaticamente specifici prompt di autorizzazione
Ricevere una notifica quando Claude ha bisogno di input
Ricevete una notifica desktop ogni volta che Claude finisce di lavorare e ha bisogno del vostro input, in modo da poter passare ad altri compiti senza controllare il terminale. Questo hook utilizza l’eventoNotification, che si attiva quando Claude sta aspettando input o autorizzazione. Ogni scheda sottostante utilizza il comando di notifica nativo della piattaforma. Aggiungete questo a ~/.claude/settings.json:
- macOS
- Linux
- Windows (PowerShell)
Se nessuna notifica appare
Se nessuna notifica appare
osascript instrada le notifiche attraverso l’app Script Editor integrata. Se Script Editor non ha il permesso di notifica, il comando fallisce silenziosamente e macOS non vi chiederà di concederlo. Eseguite questo in Terminal una volta per far apparire Script Editor nelle vostre impostazioni di notifica:| Matcher | Si attiva quando |
|---|---|
permission_prompt | Claude ha bisogno che approviate un uso dello strumento |
idle_prompt | Claude ha finito e sta aspettando il vostro prossimo prompt |
auth_success | L’autenticazione si completa |
elicitation_dialog | Un server MCP apre un modulo di elicitazione |
elicitation_complete | Un modulo di elicitazione MCP viene inviato o chiuso |
elicitation_response | Una risposta di elicitazione MCP viene inviata al server |
/hooks e selezionate Notification per confermare che l’hook è registrato. Per lo schema completo dell’evento, consultate il riferimento Notification.
Formattare automaticamente il codice dopo le modifiche
Eseguite automaticamente Prettier su ogni file che Claude modifica, in modo che la formattazione rimanga coerente senza intervento manuale. Questo hook utilizza l’eventoPostToolUse con un matcher Edit|Write, quindi si esegue solo dopo gli strumenti di modifica dei file. Il comando estrae il percorso del file modificato con jq e lo passa a Prettier. Aggiungete questo a .claude/settings.json nella radice del vostro progetto:
Gli esempi Bash in questa pagina utilizzano
jq per l’analisi JSON. Installatelo con brew install jq (macOS), apt-get install jq (Debian/Ubuntu), o consultate i download di jq.Bloccare le modifiche ai file protetti
Impedite a Claude di modificare file sensibili come.env, package-lock.json, o qualsiasi cosa in .git/. Claude riceve un feedback che spiega perché la modifica è stata bloccata, in modo da poter adattare il suo approccio.
Questo esempio utilizza un file di script separato che l’hook chiama. Lo script controlla il percorso del file di destinazione rispetto a un elenco di modelli protetti ed esce con il codice 2 per bloccare la modifica.
Rendere lo script eseguibile (macOS/Linux)
Gli script degli hook devono essere eseguibili affinché Claude Code li esegua:
Reiniettare il contesto dopo la compattazione
Quando la finestra di contesto di Claude si riempie, la compattazione riassume la conversazione per liberare spazio. Questo può perdere dettagli importanti. Utilizzate un hookSessionStart con un matcher compact per reiniettare il contesto critico dopo ogni compattazione.
Qualsiasi testo che il vostro comando scrive su stdout viene aggiunto al contesto di Claude. Questo esempio ricorda a Claude le convenzioni del progetto e il lavoro recente. Aggiungete questo a .claude/settings.json nella radice del vostro progetto:
echo con qualsiasi comando che produce output dinamico, come git log --oneline -5 per mostrare i commit recenti. Per iniettare contesto all’inizio di ogni sessione, considerate di utilizzare CLAUDE.md invece. Per le variabili di ambiente, consultate CLAUDE_ENV_FILE nel riferimento.
Controllare le modifiche di configurazione
Tracciate quando i file di impostazioni o skills cambiano durante una sessione. L’eventoConfigChange si attiva quando un processo esterno o un editor modifica un file di configurazione, in modo da poter registrare le modifiche per la conformità o bloccare le modifiche non autorizzate.
Questo esempio aggiunge ogni modifica a un registro di controllo. Aggiungete questo a ~/.claude/settings.json:
user_settings, project_settings, local_settings, policy_settings, o skills. Per bloccare una modifica dall’avere effetto, uscite con il codice 2 o restituite {"decision": "block"}. Consultate il riferimento ConfigChange per lo schema di input completo.
Ricaricare l’ambiente quando la directory o i file cambiano
Alcuni progetti impostano variabili di ambiente diverse a seconda di quale directory siete. Strumenti come direnv lo fanno automaticamente nella vostra shell, ma lo strumento Bash di Claude non raccoglie quei cambiamenti da solo. L’accoppiamento di un hookSessionStart con un hook CwdChanged risolve questo. SessionStart carica le variabili per la directory in cui avviate, e CwdChanged le ricarica ogni volta che Claude cambia directory. Entrambi scrivono su CLAUDE_ENV_FILE, che Claude Code esegue come preambolo di script prima di ogni comando Bash. Aggiungete questo a ~/.claude/settings.json:
direnv allow una volta in ogni directory che ha un .envrc in modo che direnv sia autorizzato a caricarlo. Se utilizzate devbox o nix invece di direnv, lo stesso modello funziona con devbox shellenv o devbox global shellenv al posto di direnv export bash.
Per reagire a file specifici invece di ogni cambio di directory, utilizzate FileChanged con un matcher che elenca i nomi dei file da guardare, separati da |. Per costruire l’elenco di osservazione, questo valore viene diviso in nomi di file letterali piuttosto che valutato come regex. Consultate FileChanged per come lo stesso valore filtra anche quali gruppi di hook si eseguono quando un file cambia. Questo esempio guarda .envrc e .env nella directory di lavoro:
watchPaths, e i dettagli di CLAUDE_ENV_FILE.
Approvare automaticamente specifici prompt di autorizzazione
Saltate la finestra di dialogo di approvazione per le chiamate di strumenti che consentite sempre. Questo esempio approva automaticamenteExitPlanMode, lo strumento che Claude chiama quando finisce di presentare un piano e chiede di procedere, in modo da non essere richiesto ogni volta che un piano è pronto.
A differenza degli esempi di codice di uscita sopra, l’approvazione automatica richiede che il vostro hook scriva una decisione JSON su stdout. Un hook PermissionRequest si attiva quando Claude Code sta per mostrare una finestra di dialogo di autorizzazione, e restituire "behavior": "allow" la risponde per vostro conto.
Il matcher limita l’hook a ExitPlanMode solo, in modo che nessun altro prompt sia interessato. Aggiungete questo a ~/.claude/settings.json:
updatedPermissions con una voce setMode. Il valore mode è qualsiasi modalità di autorizzazione come default, acceptEdits, o bypassPermissions, e destination: "session" la applica solo per la sessione corrente.
bypassPermissions si applica solo se la sessione è stata avviata con modalità bypass già disponibile: --dangerously-skip-permissions, --permission-mode bypassPermissions, --allow-dangerously-skip-permissions, o permissions.defaultMode: "bypassPermissions" nelle impostazioni, e non disabilitato da permissions.disableBypassPermissionsMode. Non viene mai persistito come defaultMode.acceptEdits, il vostro hook scrive questo JSON su stdout:
.* o lasciare il matcher vuoto approverebbe automaticamente ogni prompt di autorizzazione, incluse le scritture di file e i comandi shell. Consultate il riferimento PermissionRequest per l’insieme completo di campi di decisione.
Come funzionano gli hooks
Gli eventi hook si attivano in punti specifici del ciclo di vita di Claude Code. Quando un evento si attiva, tutti gli hooks corrispondenti si eseguono in parallelo, e i comandi hook identici vengono automaticamente deduplicati. La tabella sottostante mostra ogni evento e quando si attiva:| Event | When it fires |
|---|---|
SessionStart | When a session begins or resumes |
Setup | When you start Claude Code with --init-only, or with --init or --maintenance in -p mode. For one-time preparation in CI or scripts |
UserPromptSubmit | When you submit a prompt, before Claude processes it |
UserPromptExpansion | When a user-typed command expands into a prompt, before it reaches Claude. Can block the expansion |
PreToolUse | Before a tool call executes. Can block it |
PermissionRequest | When a permission dialog appears |
PermissionDenied | When a tool call is denied by the auto mode classifier. Return {retry: true} to tell the model it may retry the denied tool call |
PostToolUse | After a tool call succeeds |
PostToolUseFailure | After a tool call fails |
PostToolBatch | After a full batch of parallel tool calls resolves, before the next model call |
Notification | When Claude Code sends a notification |
SubagentStart | When a subagent is spawned |
SubagentStop | When a subagent finishes |
TaskCreated | When a task is being created via TaskCreate |
TaskCompleted | When a task is being marked as completed |
Stop | When Claude finishes responding |
StopFailure | When the turn ends due to an API error. Output and exit code are ignored |
TeammateIdle | When an agent team teammate is about to go idle |
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 |
CwdChanged | When the working directory changes, for example when Claude executes a cd command. Useful for reactive environment management with tools like direnv |
FileChanged | When a watched file changes on disk. The matcher field specifies which filenames to watch |
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 che determina come si esegue. La maggior parte degli hooks utilizza "type": "command", che esegue un comando shell. Sono disponibili altri quattro tipi:
"type": "http": POST dei dati dell’evento a un URL. Consultate HTTP hooks."type": "mcp_tool": chiama uno strumento su un server MCP già connesso. Consultate MCP tool hooks."type": "prompt": valutazione LLM a turno singolo. Consultate Prompt-based hooks."type": "agent": verifica multi-turno con accesso agli strumenti. Gli agent hooks sono sperimentali e potrebbero cambiare. Consultate Agent-based hooks.
Combinare i risultati da più hooks
Quando più hooks corrispondono allo stesso evento, il comando di ogni hook si esegue fino al completamento prima che Claude Code unisca i risultati. Un hook che restituiscedeny non impedisce ai sibling hooks di eseguirsi. Non affidatevi al deny di un hook per sopprimere gli effetti collaterali in un altro hook.
Dopo che tutti gli hooks corrispondenti terminano, Claude Code combina i loro output. Per le decisioni di autorizzazione PreToolUse, la risposta più restrittiva vince: deny sostituisce ask, che sostituisce allow. Il testo da additionalContext viene mantenuto da ogni hook e passato a Claude insieme.
L’esempio sottostante registra due hooks PreToolUse su Bash. Il primo aggiunge ogni comando a un file di log e esce con 0. Il secondo esegue uno script che esce con 2 per negare quando il comando contiene rm -rf:
rm -rf /tmp/build, entrambi gli hooks si eseguono in parallelo. L’hook di logging scrive il comando a ~/.claude/bash.log e esce con 0, il che non riporta alcuna decisione. L’hook di guardrail esce con 2, il che nega la chiamata dello strumento. Il deny vince, quindi Claude Code blocca il comando e mostra a Claude lo stderr del guardrail. La voce di log viene comunque scritta perché l’hook di logging si è già eseguito.
Leggere l’input e restituire l’output
Gli hooks comunicano con Claude Code attraverso stdin, stdout, stderr e codici di uscita. Quando un evento si attiva, Claude Code passa i dati specifici dell’evento come JSON allo stdin del vostro script. Il vostro script legge quei dati, fa il suo lavoro, e dice a Claude Code cosa fare dopo tramite il codice di uscita.Input dell’hook
Ogni evento include campi comuni comesession_id e cwd, ma ogni tipo di evento aggiunge dati diversi. Ad esempio, quando Claude esegue un comando Bash, un hook PreToolUse riceve qualcosa di simile su stdin:
UserPromptSubmit ricevono il testo prompt invece, gli hook SessionStart ricevono la source (startup, resume, clear, compact), e così via. Consultate Campi di input comuni nel riferimento per i campi condivisi, e la sezione di ogni evento per gli schemi specifici dell’evento.
Output dell’hook
Il vostro script dice a Claude Code cosa fare dopo scrivendo su stdout o stderr e uscendo con un codice specifico. Ad esempio, un hookPreToolUse che vuole bloccare un comando:
- Exit 0: l’azione procede. Per gli hook
UserPromptSubmit,UserPromptExpansioneSessionStart, qualsiasi cosa scriviate su stdout viene aggiunta al contesto di Claude. - Exit 2: l’azione è bloccata. Scrivete un motivo su stderr, e Claude lo riceve come feedback in modo da poter adattarsi. Alcuni eventi non possono essere bloccati: per
SessionStart,Setup,Notificatione altri, exit 2 mostra stderr all’utente e l’esecuzione continua. Consultate exit code 2 behavior per evento per l’elenco completo. - Qualsiasi altro codice di uscita: l’azione procede. La trascrizione mostra un avviso
<hook name> hook errorseguito dalla prima riga di stderr; lo stderr completo va al debug log.
Output JSON strutturato
I codici di uscita vi danno due opzioni: consentire o bloccare. Per un controllo maggiore, uscite con 0 e stampate un oggetto JSON su stdout invece.Utilizzate exit 2 per bloccare con un messaggio stderr, o exit 0 con JSON per un controllo strutturato. Non mescolateli: Claude Code ignora JSON quando uscite con 2.
PreToolUse può negare una chiamata di strumento e dire a Claude perché, o escalarlo all’utente per l’approvazione:
"deny", Claude Code annulla la chiamata dello strumento e alimenta permissionDecisionReason di nuovo a Claude. Questi valori permissionDecision sono specifici per PreToolUse:
"allow": salta il prompt di autorizzazione interattivo. Le regole di negazione e richiesta, incluse le liste di negazione gestite dall’azienda, si applicano ancora"deny": annulla la chiamata dello strumento e invia il motivo a Claude"ask": mostra il prompt di autorizzazione all’utente come al solito
"defer", è disponibile in modalità non interattiva con il flag -p. Esce dal processo con la chiamata dello strumento preservata in modo che un wrapper SDK Agent possa raccogliere input e riprendere. Consultate Rinviare una chiamata di strumento per dopo nel riferimento.
Restituire "allow" salta il prompt interattivo ma non sostituisce le regole di autorizzazione. Se una regola di negazione corrisponde alla chiamata dello strumento, la chiamata viene bloccata anche quando il vostro hook restituisce "allow". Se una regola di richiesta corrisponde, l’utente viene comunque richiesto. Questo significa che le regole di negazione da qualsiasi ambito di impostazioni, incluse le impostazioni gestite, hanno sempre la precedenza sulle approvazioni degli hook.
Altri eventi utilizzano modelli di decisione diversi. Ad esempio, gli hook PostToolUse e Stop utilizzano un campo decision: "block" di livello superiore, mentre PermissionRequest utilizza hookSpecificOutput.decision.behavior. Consultate la tabella di riepilogo nel riferimento per una suddivisione completa per evento.
Per gli hook UserPromptSubmit, utilizzate additionalContext invece per iniettare testo nel contesto di Claude. Gli hooks basati su prompt (type: "prompt") gestiscono l’output diversamente: consultate Prompt-based hooks.
Filtrare gli hooks con i matcher
Senza un matcher, un hook si attiva su ogni occorrenza del suo evento. I matcher vi permettono di restringerlo. Ad esempio, se volete eseguire un formattatore solo dopo le modifiche ai file (non dopo ogni chiamata di strumento), aggiungete un matcher al vostro hookPostToolUse:
"Edit|Write" si attiva solo quando Claude utilizza lo strumento Edit o Write, non quando utilizza Bash, Read, o qualsiasi altro strumento. Consultate Matcher patterns per come i nomi semplici e le espressioni regolari vengono valutati.
Claude può anche creare o modificare file eseguendo comandi shell attraverso lo strumento
Bash. Se il vostro hook deve vedere ogni modifica ai file, come per la scansione di conformità o il logging di audit, aggiungete un hook Stop che scansiona l’albero di lavoro una volta per turno. Per una copertura per-chiamata invece, corrispondere anche a Bash e avere il vostro script elencare i file modificati e non tracciati con git status --porcelain.| Evento | Cosa filtra il matcher | Valori matcher di esempio |
|---|---|---|
PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDenied | nome dello strumento | Bash, Edit|Write, mcp__.* |
SessionStart | come è iniziata la sessione | startup, resume, clear, compact |
Setup | quale flag CLI ha attivato il setup | init, maintenance |
SessionEnd | perché è terminata la sessione | clear, resume, logout, prompt_input_exit, bypass_permissions_disabled, other |
Notification | tipo di notifica | permission_prompt, idle_prompt, auth_success, elicitation_dialog, elicitation_complete, elicitation_response |
SubagentStart | tipo di agente | general-purpose, Explore, Plan, o nomi di agenti personalizzati |
PreCompact, PostCompact | cosa ha attivato la compattazione | manual, auto |
SubagentStop | tipo di agente | stessi valori di SubagentStart |
ConfigChange | fonte di configurazione | user_settings, project_settings, local_settings, policy_settings, skills |
StopFailure | tipo di errore | rate_limit, authentication_failed, oauth_org_not_allowed, billing_error, invalid_request, server_error, max_output_tokens, unknown |
InstructionsLoaded | motivo del caricamento | session_start, nested_traversal, path_glob_match, include, compact |
Elicitation | nome del server MCP | i vostri nomi di server MCP configurati |
ElicitationResult | nome del server MCP | stessi valori di Elicitation |
FileChanged | nomi di file letterali da guardare (consultate FileChanged) | .envrc|.env |
UserPromptExpansion | nome del comando | i vostri nomi di skill o comando |
UserPromptSubmit, PostToolBatch, Stop, TeammateIdle, TaskCreated, TaskCompleted, WorktreeCreate, WorktreeRemove, CwdChanged | nessun supporto matcher | si attiva sempre su ogni occorrenza |
- Registrare ogni comando Bash
- Corrispondere agli strumenti MCP
- Pulire alla fine della sessione
Corrispondere solo alle chiamate dello strumento
Bash e registrare ogni comando in un file. L’evento PostToolUse si attiva dopo che il comando è completato, quindi tool_input.command contiene quello che è stato eseguito. L’hook riceve i dati dell’evento come JSON su stdin, e jq -r '.tool_input.command' estrae solo la stringa del comando, che >> aggiunge al file di log:Filtrare per nome dello strumento e argomenti con il campo if
Il campo
if richiede Claude Code v2.1.85 o successivo. Le versioni precedenti lo ignorano e eseguono l’hook su ogni chiamata corrispondente.if utilizza la permission rule syntax per filtrare gli hooks per nome dello strumento e argomenti insieme, in modo che il processo dell’hook si generi solo quando la chiamata dello strumento corrisponde, o quando un comando Bash è troppo complesso per essere analizzato. Questo va oltre il matcher, che filtra a livello di gruppo per nome dello strumento solo.
Ad esempio, per eseguire un hook solo quando Claude utilizza comandi git piuttosto che tutti i comandi Bash:
git *, o quando il comando è troppo complesso per essere analizzato in sottocomandi. Per comandi composti come npm test && git push, Claude Code valuta ogni sottocomando e attiva l’hook perché git push corrisponde. Il campo if accetta gli stessi modelli delle regole di autorizzazione: "Bash(git *)", "Edit(*.ts)", e così via. Per corrispondere a più nomi di strumenti, utilizzate handler separati ognuno con il suo valore if, o corrispondere a livello di matcher dove l’alternazione con pipe è supportata.
if funziona solo su eventi di strumenti: PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest e PermissionDenied. Aggiungerlo a qualsiasi altro evento impedisce all’hook di eseguirsi.
Configurare la posizione dell’hook
Dove aggiungete un hook determina il suo ambito:| Posizione | Ambito | Condivisibile |
|---|---|---|
~/.claude/settings.json | Tutti i vostri progetti | No, locale alla vostra macchina |
.claude/settings.json | Singolo progetto | Sì, può essere committato nel repo |
.claude/settings.local.json | Singolo progetto | No, gitignored |
| Impostazioni di policy gestite | Organizzazione intera | Sì, controllato dall’amministratore |
Plugin hooks/hooks.json | Quando il plugin è abilitato | Sì, raggruppato con il plugin |
| Skill o agente frontmatter | Mentre la skill o l’agente è attivo | Sì, definito nel file del componente |
/hooks in Claude Code per sfogliare tutti gli hooks configurati raggruppati per evento. Per disabilitare gli hooks, impostate "disableAllHooks": true nel vostro file di impostazioni. Gli hooks configurati nelle impostazioni gestite si eseguono comunque a meno che disableAllHooks non sia impostato anche lì.
Se modificate i file di impostazioni direttamente mentre Claude Code è in esecuzione, il file watcher normalmente raccoglie i cambiamenti degli hook automaticamente.
Hooks basati su prompt
Per decisioni che richiedono giudizio piuttosto che regole deterministiche, utilizzate gli hooktype: "prompt". Invece di eseguire un comando shell, Claude Code invia il vostro prompt e i dati di input dell’hook a un modello Claude (Haiku per impostazione predefinita) per prendere la decisione. Potete specificare un modello diverso con il campo model se avete bisogno di più capacità.
L’unico lavoro del modello è restituire una decisione sì/no come JSON:
"ok": true: l’azione procede"ok": false: ciò che accade dipende dall’evento:StopeSubagentStop: ilreasonviene alimentato di nuovo a Claude in modo che continui a lavorarePreToolUse: la chiamata dello strumento viene negata e ilreasonviene restituito a Claude come errore dello strumento, in modo che possa adattarsi e continuarePostToolUse,PostToolBatch,UserPromptSubmiteUserPromptExpansion: il turno termina e ilreasonappare nella chat come una riga di avviso
Stop per chiedere al modello se tutti i compiti richiesti sono completi. Se il modello restituisce "ok": false, Claude continua a lavorare e utilizza il reason come sua prossima istruzione:
Hooks basati su agenti
Quando la verifica richiede l’ispezione di file o l’esecuzione di comandi, utilizzate gli hooktype: "agent". A differenza degli hook di prompt che effettuano una singola chiamata LLM, gli hook di agenti generano un subagent che può leggere file, cercare codice e utilizzare altri strumenti per verificare le condizioni prima di restituire una decisione.
Gli hook di agenti utilizzano lo stesso formato di risposta "ok" / "reason" degli hook di prompt, ma con un timeout predefinito più lungo di 60 secondi e fino a 50 turni di utilizzo dello strumento.
Questo esempio verifica che i test passino prima di consentire a Claude di fermarsi:
HTTP hooks
Utilizzate gli hooktype: "http" per POST dei dati dell’evento a un endpoint HTTP invece di eseguire un comando shell. L’endpoint riceve lo stesso JSON che un hook di comando riceverebbe su stdin, e restituisce i risultati attraverso il corpo della risposta HTTP utilizzando lo stesso formato JSON.
Gli HTTP hooks sono utili quando volete che un server web, una funzione cloud o un servizio esterno gestisca la logica dell’hook: ad esempio, un servizio di controllo condiviso che registra gli eventi di utilizzo dello strumento in un team.
Questo esempio pubblica ogni utilizzo dello strumento a un servizio di registrazione locale:
hookSpecificOutput appropriati. I codici di stato HTTP da soli non possono bloccare le azioni.
I valori dell’intestazione supportano l’interpolazione delle variabili di ambiente utilizzando la sintassi $VAR_NAME o ${VAR_NAME}. Solo le variabili elencate nell’array allowedEnvVars vengono risolte; tutti gli altri riferimenti $VAR rimangono vuoti.
Per le opzioni di configurazione complete e la gestione delle risposte, consultate HTTP hooks nel riferimento.
Limitazioni e risoluzione dei problemi
Limitazioni
- Gli hook di comando comunicano solo attraverso stdout, stderr e codici di uscita. Non possono attivare comandi
/o chiamate di strumenti. Il testo restituito tramiteadditionalContextviene iniettato come un promemoria di sistema che Claude legge come testo semplice. Gli HTTP hooks comunicano attraverso il corpo della risposta invece. - I timeout dell’hook variano in base al tipo. Sovrascrivete per hook con il campo
timeoutin secondi.command,http,mcp_tool: 10 minuti.UserPromptSubmitriduce questi a 30 secondi.prompt: 30 secondi.agent: 60 secondi.
- Gli hook
PostToolUsenon possono annullare le azioni poiché lo strumento è già stato eseguito. - Gli hook
PermissionRequestnon si attivano in modalità non interattiva (-p). Utilizzate gli hookPreToolUseper le decisioni di autorizzazione automatizzate. - Gli hook
Stopsi attivano ogni volta che Claude finisce di rispondere, non solo al completamento dell’attività. Non si attivano su interruzioni dell’utente. Gli errori API attivano StopFailure invece. - Quando più hook PreToolUse restituiscono
updatedInputper riscrivere gli argomenti di uno strumento, l’ultimo a terminare vince. Poiché gli hook si eseguono in parallelo, l’ordine è non deterministico. Evitate di avere più di un hook che modifica l’input dello stesso strumento.
Hooks e modalità di autorizzazione
Gli hook PreToolUse si attivano prima di qualsiasi controllo della modalità di autorizzazione. Un hook che restituiscepermissionDecision: "deny" blocca lo strumento anche in modalità bypassPermissions o con --dangerously-skip-permissions. Questo vi permette di applicare una policy che gli utenti non possono aggirare cambiando la loro modalità di autorizzazione.
Il contrario non è vero: un hook che restituisce "allow" non aggira le regole di negazione dalle impostazioni. Gli hooks possono stringere le restrizioni ma non allentarle oltre quello che le regole di autorizzazione consentono.
Hook non si attiva
L’hook è configurato ma non si esegue mai.- Eseguite
/hookse confermate che l’hook appare sotto l’evento corretto - Controllate che il modello del matcher corrisponda esattamente al nome dello strumento (i matcher sono sensibili alle maiuscole)
- Verificate che state attivando il tipo di evento corretto (ad esempio,
PreToolUsesi attiva prima dell’esecuzione dello strumento,PostToolUsesi attiva dopo) - Se utilizzate gli hook
PermissionRequestin modalità non interattiva (-p), passate aPreToolUseinvece
Errore dell’hook nell’output
Vedete un messaggio come “PreToolUse hook error: …” nella trascrizione.- Il vostro script è uscito con un codice diverso da zero inaspettatamente. Testatelo manualmente inviando JSON di esempio:
- Se vedete “command not found”, utilizzate percorsi assoluti o
${CLAUDE_PROJECT_DIR}per fare riferimento agli script. Per evitare completamente le virgolette della shell, aggiungete"args": []per passare alla forma exec, che genera lo script direttamente senza una shell - Se vedete “jq: command not found”, installate
jqo utilizzate Python/Node.js per l’analisi JSON - Se lo script non si esegue affatto, rendetelo eseguibile:
chmod +x ./my-hook.sh
/hooks non mostra hook configurati
Avete modificato un file di impostazioni ma gli hooks non appaiono nel menu.
- Le modifiche ai file vengono normalmente raccolte automaticamente. Se non sono apparse dopo alcuni secondi, il file watcher potrebbe aver perso il cambiamento: riavviate la vostra sessione per forzare un ricaricamento.
- Verificate che il vostro JSON sia valido (le virgole finali e i commenti non sono consentiti)
- Confermate che il file di impostazioni è nella posizione corretta:
.claude/settings.jsonper gli hook del progetto,~/.claude/settings.jsonper gli hook globali
L’hook Stop si esegue per sempre
Claude continua a lavorare in un ciclo infinito invece di fermarsi. Il vostro script di hook Stop deve controllare se ha già attivato una continuazione. Analizzate il campostop_hook_active dall’input JSON e uscite presto se è true:
Convalida JSON non riuscita
Claude Code mostra un errore di analisi JSON anche se il vostro script di hook produce JSON valido. Quando Claude Code esegue un hook di comando in forma shell (uno senzaargs), genera sh -c su macOS e Linux o Git Bash su Windows per impostazione predefinita. Questa shell è non interattiva, ma Git Bash e alcune configurazioni (come BASH_ENV che punta a ~/.bashrc) comunque forniscono il vostro profilo. Se quel profilo contiene istruzioni echo incondizionate, l’output viene anteposto al vostro JSON dell’hook:
$- contiene i flag della shell, e i significa interattiva. Gli hooks si eseguono in shell non interattive, quindi l’echo viene saltato.
Tecniche di debug
La vista della trascrizione, attivata conCtrl+O, mostra un riepilogo di una riga per ogni hook che si è attivato: il successo è silenzioso, gli errori di blocco mostrano stderr, e gli errori non bloccanti mostrano un avviso <hook name> hook error seguito dalla prima riga di stderr.
Per i dettagli di esecuzione completi incluso quali hook hanno corrisposto, i loro codici di uscita, stdout e stderr, leggete il debug log. Avviate Claude Code con claude --debug-file /tmp/claude.log per scrivere in un percorso noto, quindi tail -f /tmp/claude.log in un altro terminale. Se avete avviato senza quel flag, eseguite /debug a metà sessione per abilitare la registrazione e trovare il percorso del log.
Ulteriori informazioni
- Riferimento Hooks: schemi di eventi completi, formato di output JSON, hooks asincroni e hooks di strumenti MCP
- Considerazioni sulla sicurezza: esaminate prima di distribuire gli hooks in ambienti condivisi o di produzione
- Esempio di validatore di comandi Bash: implementazione di riferimento completa