Définir un hook
Mis à jour le 29 juillet 2026
Définir un hook
Créer un hook revient à répondre à quatre questions, dans l’ordre. Vous choisissez d’abord le type : PreToolUse si votre code doit s’exécuter avant l’appel d’outil, PostToolUse s’il doit s’exécuter après. Ce choix n’est pas une simple affaire de chronologie, puisque les hooks PreToolUse peuvent empêcher l’exécution alors que les PostToolUse ne le peuvent pas ; dès lors que votre objectif est d’interdire quelque chose, la question est déjà tranchée.
Vous déterminez ensuite les outils à surveiller, en spécifiant exactement lesquels doivent déclencher votre hook. Vient alors l’écriture de la commande proprement dite : un script qui reçoit les données de l’appel d’outil via l’entrée standard (stdin). Reste enfin à renvoyer du feedback, et c’est le code de sortie de votre commande qui indique à Claude s’il doit autoriser ou bloquer l’opération. Un hook n’est donc pas un programme compliqué : il lit du JSON, décide, et sort avec le bon code.
Les outils disponibles
Choisir les outils à surveiller suppose de savoir lesquels existent. Claude Code fournit plusieurs outils intégrés que vous pouvez surveiller avec des hooks, mais plutôt que de vous fier à une liste figée, demandez directement à Claude :
Liste tous les outils disponibles
C’est particulièrement utile car les outils disponibles peuvent changer quand vous ajoutez des serveurs MCP personnalisés. Un hook écrit il y a trois mois pour surveiller les lectures de fichiers peut être devenu incomplet du jour où un serveur MCP a apporté sa propre manière d’accéder au disque. Reposer la question avant d’écrire un matcher coûte dix secondes et vous épargne un angle mort dont vous ne soupçonneriez même pas l’existence.
Structure des données d’un appel d’outil
Quand votre commande hook s’exécute, Claude envoie des données JSON via l’entrée standard :
{
"session_id": "2d6a1e4d-6...",
"transcript_path": "/Users/sg/...",
"hook_event_name": "PreToolUse",
"tool_name": "Read",
"tool_input": {
"file_path": "/code/projet/.env"
}
}
Votre commande lit ce JSON depuis stdin, l’analyse, puis décide d’autoriser ou bloquer l’opération. Prenez le temps d’examiner la structure : hook_event_name vous rappelle à quel moment du cycle vous vous trouvez, tool_name identifie l’outil que Claude s’apprête à utiliser, et tool_input contient les arguments de cet appel. C’est dans ce dernier objet que se loge l’information sur laquelle vous allez réellement statuer — ici, un chemin de fichier qui pointe vers un .env.
Codes de sortie et flux de contrôle
Le dialogue en retour est volontairement minimaliste. Votre script ne renvoie pas une réponse structurée : il sort, et son code de sortie tient lieu de verdict.
| Code | Signification |
|---|---|
| 0 | Tout est OK — l’appel d’outil peut continuer |
| 2 | Bloquer l’appel d’outil (hooks PreToolUse uniquement) |
Quand vous sortez avec le code 2, tout message écrit sur la sortie d’erreur standard (stderr) sera envoyé à Claude comme feedback. Cette précision change beaucoup de choses en pratique. Un blocage muet laisse Claude devant un échec inexpliqué, qu’il tentera souvent de contourner en réessayant autrement, parfois par un chemin encore moins souhaitable. Un blocage accompagné d’un message sur stderr — expliquant que le fichier est protégé et, si besoin, indiquant quoi faire à la place — lui donne de quoi ajuster son plan et poursuivre la tâche par une autre voie.
Cas d’utilisation courant
Le cas classique est d’empêcher Claude de lire des fichiers sensibles comme les fichiers .env. L’exercice semble trivial jusqu’au moment où l’on réalise qu’il existe plusieurs portes d’entrée : comme les outils Read et Grep peuvent tous deux accéder au contenu des fichiers, surveiller le seul Read laisserait une recherche de motif afficher exactement ce que vous vouliez cacher. Vous voudriez donc surveiller les deux types d’outils et vérifier s’ils essaient d’accéder à des chemins de fichiers restreints.
C’est un réflexe à généraliser : avant d’écrire un hook de protection, demandez-vous par quels outils différents la même information pourrait sortir, et couvrez-les tous dans votre matcher. La leçon suivante implémente précisément ce hook, de la configuration au test.