Vai al contenuto
Giallo

HTTP Hooks: controlli per Claude Code

Collega Claude Code a un controllo HTTP: POST JSON, risposte di decisione, allowlist e gestione errori. Esempio locale con dati sintetici.

Tempo di lettura: 11 min

Claude Code HTTP Hooks: evento, controllo e risultato nel workflow di sviluppo

Un HTTP hook di Claude Code invia il contesto di un evento a un endpoint con una richiesta POST JSON. Il servizio può eseguire un controllo e restituire il risultato previsto per quell’evento. È utile quando una regola è già disponibile in un servizio locale o condiviso, ma la decisione deve rispettare il contratto dei Hooks: uno status HTTP 403 o 500 non equivale da solo a un deny. Campi e risposte HTTP ufficiali.

Per bloccare una chiamata attraverso il percorso ordinario, il servizio deve rispondere con un JSON di decisione supportato in una risposta 2xx. Un errore di rete, un errore del server e un rifiuto della policy hanno significati differenti. La guida ai Claude Code Hooks descrive le alternative; qui il focus è rendere esplicito il confine fra servizio e decisione.

La documentazione è stata verificata il 9 ottobre 2026. Server e casi descritti sono esempi didattici con dati sintetici, non eseguiti in questa guida. Non inviano informazioni a un servizio pubblico e non rappresentano una policy completa per un’organizzazione.

In sintesi

  • L’input HTTP è il JSON dell’evento, inviato con POST.
  • Il servizio deve restituire il formato di decisione dell’evento selezionato.
  • Uno status di errore non costituisce automaticamente un rifiuto della tool call.
  • URL consentiti e variabili degli header richiedono configurazione esplicita.
  • La quantità di dati inviata deve essere proporzionata al controllo.

Quando HTTP è una scelta sensata?

HTTP può essere utile quando il team ha già una regola centralizzata o un servizio locale capace di verificarla. Per esempio, un controllo può conoscere l’elenco aggiornato di operazioni ammesse in un ambiente di prova. L’endpoint offre la stessa logica a più repository, mentre ciascun progetto decide quali eventi e tool gli passano davanti.

Se la regola è un confronto di un percorso e non deve essere condivisa, uno script locale può risultare più semplice. Introdurre un servizio comporta processo da avviare, porta, autenticazione, monitoraggio e gestione dell’indisponibilità. Questi elementi devono risolvere una necessità concreta, non essere aggiunti soltanto perché il termine webhook sembra più moderno.

Per una protezione locale dei percorsi, PreToolUse per file e comandi mostra l’alternativa. Per un controllo già offerto da uno strumento collegato, Hooks e MCP descrive un terzo percorso. La scelta parte da chi possiede la regola e dove sono i dati necessari.

Quale contratto deve rispettare l’endpoint?

Il servizio riceve l’oggetto dell’evento e deve verificare ciò che serve al suo compito: evento atteso, nome del tool, input necessario e schema dei dati. Non dovrebbe applicare in silenzio la stessa decisione a qualsiasi richiesta. Se il controllo riguarda PreToolUse, l’output di policy deve usare il contratto di quell’evento. HTTP response handling.

Una risposta positiva a livello HTTP significa che la richiesta è stata gestita. Il corpo può contenere una decisione che rifiuta l’operazione. Questa separazione rende osservabile la differenza fra “il servizio ha valutato e negato” e “il servizio non è riuscito a valutare”. Usare 403 per entrambi confonde il trasporto con la policy del hook.

Non inserire messaggi di debug prima del JSON di risposta. Il contenuto deve essere leggibile dal client e appartenere al contratto. Conserva i log tecnici separati, evitando copie dell’intero input se possono contenere prompt, percorsi personali o altri dati riservati.

Un server locale con una regola dimostrativa

Il seguente server Python 3 ascolta solo su 127.0.0.1. Nega una chiamata Write sul percorso dimostrativo esatto e restituisce un oggetto vuoto per gli altri input validi. Il confronto esatto è intenzionalmente limitato: non normalizza percorsi e non protegge una cartella reale. È uno snippet non eseguito, utile a mostrare il formato della risposta.

import json
from http.server import BaseHTTPRequestHandler, HTTPServer


class HookHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        if self.path != "/pre-tool-use":
            self.send_error(404)
            return
        try:
            length = int(self.headers.get("Content-Length", "0"))
            if length < 1 or length > 65536:
                raise ValueError("dimensione non consentita")
            event = json.loads(self.rfile.read(length))
            if not isinstance(event, dict):
                raise ValueError("oggetto richiesto")
        except (ValueError, json.JSONDecodeError):
            self.send_error(400)
            return
        output = {}
        raw = event.get("tool_input", {})
        if (
            event.get("hook_event_name") == "PreToolUse"
            and event.get("tool_name") == "Write"
            and isinstance(raw, dict)
            and raw.get("file_path") == "config/protected/demo.json"
        ):
            output = {
                "hookSpecificOutput": {
                    "hookEventName": "PreToolUse",
                    "permissionDecision": "deny",
                    "permissionDecisionReason": "Percorso dimostrativo protetto."
                }
            }
        payload = json.dumps(output).encode("utf-8")
        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(payload)))
        self.end_headers()
        self.wfile.write(payload)

    def log_message(self, format, *args):
        return


HTTPServer(("127.0.0.1", 8765), HookHandler).serve_forever()

Il limite del corpo e la porta sono scelte dell’esempio, non valori raccomandati per qualunque progetto. L’assenza di autenticazione è accettabile soltanto per questa dimostrazione locale isolata con dati fittizi; non trasformare lo snippet in un servizio condiviso esponendolo sulla rete.

Come registrare l’URL nel hook?

La registrazione seguente seleziona Write e invia la chiamata al servizio dimostrativo. Un valore di timeout esplicito rende la scelta leggibile, ma deve essere dimensionato e provato per il progetto. Il servizio va avviato separatamente. Esempio HTTP nella guida.

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "http",
            "url": "http://127.0.0.1:8765/pre-tool-use",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

Prima della prova nella sessione, invia al server una fixture locale con l’evento previsto e dati sintetici. Poi prova un percorso diverso e un input non valido. Infine osserva il comportamento con servizio spento. Nessuno di questi risultati è stato raccolto in questa guida: il lettore deve verificarli nella sua versione e nel suo ambiente.

Debug dei Hooks aiuta a distinguere una registrazione mancante da un endpoint non raggiungibile. Se il comando HTTP funziona fuori dalla sessione ma il hook non parte, controlla anche le allowlist dei settings.

Perché localhost può essere una macchina diversa?

localhost indica l’ambiente in cui gira il client, non sempre il portatile dell’utente. In un container, una sessione remota o un ambiente cloud, l’endpoint locale può trovarsi altrove. È necessario sapere dove viene eseguito Claude Code e dove è avviato il servizio, prima di cambiare porta o firewall.

Non aprire il server su tutte le interfacce soltanto per risolvere un problema di collegamento. Questo cambia il perimetro: altri processi o altre macchine potrebbero raggiungerlo. Un servizio di controllo condiviso richiede autenticazione, protezione del trasporto e una policy di accesso deliberata. La rete deve essere necessaria al workflow.

La prova deve descrivere l’ambiente: client sul computer, servizio nello stesso ambiente oppure servizio separato. Un errore di connessione non dimostra che la regola di policy sia sbagliata; dimostra che quel percorso di trasporto non è stato completato. Mantieni separati i due esiti anche nei messaggi del team.

Come gestire header e credenziali?

I campi HTTP consentono header con sostituzione di variabili ambiente e una lista allowedEnvVars. Le impostazioni possono inoltre restringere variabili e URL con httpHookAllowedEnvVars e allowedHttpHookUrls. Il controllo deve tenere conto delle policy effettivamente caricate, non soltanto del singolo file del progetto. Allowlist e header.

Non inserire un token reale nel JSON condiviso. Usa una credenziale dedicata, disponibile nell’ambiente appropriato, con un accesso limitato al servizio necessario. Non stamparla per verificare l’interpolazione. La prova può controllare che una richiesta sia autorizzata senza includere il valore nel log o nel testo della risposta.

Un token non rende corretto l’endpoint. Serve anche sapere quali richieste accetta, quali dati conserva e chi può cambiare la policy. Per approfondire il livello organizzativo consulta Mods per team e sicurezza: l’autorizzazione di un componente e il confine di esecuzione sono questioni separate.

Errori HTTP e deny: quale differenza deve vedere il team?

La tabella distingue esiti spesso confusi. Serve a progettare i test del servizio, non a presumere il comportamento di una versione che non è stata provata. La risposta di decisione deve essere coerente con l’evento e con il contratto corrente. Output dei Hooks.

Esito Significato Prova da raccogliere
2xx con JSON di deny valido Il servizio ha valutato e rifiutato Decisione e mancata esecuzione del tool
2xx con oggetto senza decisione Nessuna decisione della policy Flusso dei permessi successivo
500 Errore del servizio Comportamento del hook e del tool
Connessione rifiutata Endpoint non disponibile Esito tecnico e azione osservata
JSON non valido Contratto di risposta rotto Errore di parsing e comportamento
Timeout Valutazione non conclusa nei tempi Effetto nella versione usata
Un contratto di controllo
Diagramma illustrativo: Un contratto di controllo. Le frecce rappresentano collegamenti e controlli del processo; non risultati misurati.

La nuova opzione onFailure: "block" è annunciata per command e HTTP nella release 2.1.295 dell’8 ottobre 2026. Questa verifica conferma l’introduzione, ma non lo schema completo per ogni evento e le sue interazioni; per questo non viene inventato uno snippet che la usi. Prima di affidare una barriera vincolante a tale comportamento, consulta e prova la versione installata. Release ufficiale.

Quali dati inviare a una policy condivisa?

Il corpo contiene il contesto dell’evento. La prima domanda è se un servizio condiviso abbia davvero bisogno di quel materiale. Per decidere una categoria di operazione può bastare un identificatore; per analizzare un file potrebbe servire altro. Non trasmettere automaticamente transcript, contenuti di clienti o credenziali a un servizio soltanto perché è tecnicamente raggiungibile.

Definisci anche la conservazione. Log del proxy, errori applicativi e strumenti di osservazione possono trattenere il corpo oltre la risposta. Un endpoint controllato dall’azienda rimane un luogo in cui gestire accessi e dati. Non chiamarlo “interno” come sinonimo di “senza rischio”.

AI e sicurezza dei dati offre il contesto per questa scelta. Se il controllo può restare locale, il vantaggio è un perimetro più piccolo; se deve essere condiviso, documenta la necessità e il dato minimo. La progettazione del hook include questo percorso informativo, non soltanto l’URL.

Due servizi di controllo per PMI italiane

Esempio ipotetico, non testato: una software house di Bergamo vuole applicare la stessa policy a diversi repository di prova. Un servizio conosce le categorie di operazioni consentite. Il team prepara fixture sintetiche per decisione positiva, deny e indisponibilità. Prima di collegarlo al lavoro reale documenta quali campi riceve, come autentica il client e cosa succede durante un guasto. Non considera un HTTP 500 una prova di blocco.

Esempio ipotetico, non testato: un laboratorio tecnico di Reggio Emilia usa un controllo locale per un importatore di dati fittizi. Claude Code e il servizio girano sullo stesso computer. Il laboratorio prova il percorso protetto dimostrativo e un percorso ordinario, poi spegne il servizio per osservare l’errore. La demo non usa dati di produzione e non viene esposta sulla rete per comodità.

In entrambi i casi la policy deve avere un proprietario. Cambiare il servizio può modificare contemporaneamente il comportamento di molti progetti. La distribuzione di una nuova versione richiede prove e una strategia per identificare quale regola ha valutato una determinata chiamata.

Come evitare una dipendenza fragile dal servizio?

Un controllo condiviso può diventare un punto di indisponibilità. Definisci timeout, limite dei dati, comportamento d’errore e diagnosi. Non aggiungere retry automatici illimitati: possono duplicare lavoro e rendere più difficile capire se il servizio ha ricevuto la prima richiesta. Per controlli che modificano qualcosa, il problema della ripetizione è ancora più delicato.

Una prova di indisponibilità utile prima del team

In un ambiente con soli dati sintetici, esegui una chiamata prevista mentre il servizio è spento. Osserva errore tecnico, messaggio della sessione e comportamento del tool. Ripeti con risposta lenta e JSON non valido. La policy deve descrivere questi esiti, oltre al caso in cui tutto funziona.

Gli errori comuni sono URL sul computer sbagliato, token nei settings, risposta di deny con status di errore, logging completo degli input e una presunta modalità di blocco mai provata. Per i controlli dopo un’azione, PostToolUse ricorda un altro limite: il servizio non annulla una modifica già effettuata.

Come riconoscere la versione della policy che ha risposto?

Un servizio centrale può cambiare mentre i repository mantengono la stessa configurazione del hook. Il team deve poter sapere quale versione della regola ha valutato una richiesta. Può conservare questo dato in un log sintetico interno o nel risultato previsto dal proprio contratto, senza aggiungere campi arbitrari che Claude Code interpreti come decisioni.

Prima di una nuova distribuzione, ripeti le fixture positive, negative e di guasto. Confronta anche l’esito di una richiesta gestita dalla versione precedente: una modifica della policy può rendere una chiamata prima consentita soggetta a review. La differenza deve essere deliberata e comprensibile ai progetti coinvolti.

Un identificatore di versione non richiede conservare il corpo completo della richiesta. Per la diagnosi possono bastare categoria di operazione, esito e versione della regola, secondo la policy del servizio. Separare questi metadati dal contenuto riduce la quantità di informazioni replicate e rende più semplice leggere ciò che è cambiato.

Come portare HTTP Hooks in un’applicazione mantenibile?

Conserva insieme contratto, fixture, policy dei dati e procedura di avvio. Identifica la versione del servizio e della configurazione di Claude Code usata nelle prove. La decisione deve essere leggibile da chi mantiene il software, senza dover dedurre il significato da una riga di log generica.

Un servizio dedicato ha senso quando risolve una regola condivisa; Mods di Claude offre un confronto con altre forme di personalizzazione. Non aggiungere HTTP per sostituire una semplice funzione locale senza una necessità di rete o di responsabilità centrale.

Per costruire un controllo collegato a un gestionale, il percorso di software su misura può includere contratto, autorizzazioni e prove dei guasti. Il risultato da raggiungere è una decisione verificabile, con dati necessari e un comportamento conosciuto anche quando il servizio non risponde.

Metodo e fonti delle guide di Giallo Studio

Come lo applichiamo in azienda

Risorse correlate

Servizi di consulenza AI e automazione dei processi

FAQ

Come riceve i dati un HTTP hook?

Claude Code invia il contesto dell’evento con una richiesta POST JSON. Il servizio risponde secondo il formato previsto per quell’evento.

Un HTTP 403 equivale a deny?

No. Uno status di errore non è da solo una decisione di rifiuto. Il percorso ordinario usa una risposta 2xx con il JSON di decisione supportato.

Posso usare localhost?

Sì, se il servizio è raggiungibile dall’ambiente in cui gira Claude Code. In un container, desktop remoto o ambiente cloud localhost può indicare una macchina diversa.

Come gestire i token degli header?

Usa variabili ambiente consentite dalla configurazione e un segreto dedicato con accesso limitato. Non inserirlo nei file condivisi o nei log del hook.

La nuova opzione onFailure è già documentata?

L’introduzione per command e HTTP è confermata dalla release 2.1.295. In questa verifica non è stato confermato lo schema completo per ogni evento; serve una prova sulla versione usata.

Quali dati inviare a un controllo condiviso?

Soltanto quelli necessari alla decisione. Non inviare automaticamente prompt, transcript o codice di clienti quando la policy può usare informazioni meno sensibili.

Applichiamolo

Trasformiamo la guida in un primo flusso live.

Raccontaci quale processo vuoi alleggerire: valutiamo fattibilità, ritorno e primo step operativo.