- 26 min de lecture
Mods Claude Code : ce qu'ils changent pour une équipe
Les mods de Claude Code ajoutent panneaux, commandes et règles sur les appels d'outils. Fonctionnement, cas d'usage, sécurité et gouvernance en équipe.
Les mods Claude Code sont souvent présentés comme une affaire d'interface : un panneau à côté de la conversation, un compteur près du spinner, une commande en plus. La description est exacte, mais elle laisse de côté ce qui compte pour une équipe. Un mod est du code qui s'exécute à l'intérieur de l'agent, avec les droits du développeur qui l'a installé, et qui peut approuver un appel d'outil avant que la moindre question ne soit posée.
La fonctionnalité est arrivée avec la version 2.1.287 du 1er octobre 2026 (« Added Claude Mods: plugins may now modify deeper behavior », dit le changelog) et elle est activée par défaut. Si votre équipe utilise Claude Code, elle peut donc déjà charger des mods. Cet article explique le mécanisme, dit quand un mod est le bon outil pour personnaliser Claude Code, et détaille ce qu'il faut encadrer sur les postes de développement.
Ce qu'est un mod Claude Code
Un mod est un plugin Claude Code dont le code est fait de gestionnaires d'événements écrits en JavaScript ou en TypeScript. Claude Code appelle l'un de ces gestionnaires chaque fois qu'un événement se produit : un appel d'outil, un prompt soumis, une partie de l'interface sur le point d'être dessinée. La documentation officielle des mods nomme ces gestionnaires des hooks, et chaque hook a trois possibilités :
- observer l'événement et le laisser suivre son cours ;
- le réécrire avant qu'il continue (modifier une commande, compléter un prompt, changer ce qui s'affiche) ;
- y répondre à la place de Claude Code, qui n'exécute alors pas son comportement habituel.
Le mot « hook » prête à confusion, parce que Claude Code en avait déjà. Les hooks historiques, que la documentation appelle désormais « settings hooks », sont une commande shell, une requête HTTP ou un prompt déclarés dans un fichier de réglages et lancés sur un événement du cycle de vie. Ils s'exécutent en dehors de Claude Code. Les hooks d'un mod sont des fonctions appelées à l'intérieur. Les deux coexistent : la page d'administration précise que rien n'est déprécié du côté des settings hooks.
Quelques repères pratiques :
- Versions : dans le terminal, il faut Claude Code v2.1.287 ou plus récent ; l'application de bureau embarque sa propre copie et prend les mods en charge à partir de la v2.1.286.
- Nom : « function hooks » était le nom de l'accès anticipé. Il n'en reste que la variable
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS, désormais ignorée : la mettre à0ne désactive plus rien. - Où ça s'exécute : les hooks tournent partout où le plugin se charge, y compris dans l'extension VS Code, avec
claude -p, l'Agent SDK et les sessions cloud. Le dessin, lui, n'apparaît que dans le terminal et dans l'onglet Code de l'application de bureau. Une session WSL de l'application de bureau ne charge aucun plugin, donc aucun mod.
Ce dernier point a une conséquence directe : un mod qui applique une règle (refuser une commande, journaliser un appel) agit aussi dans un pipeline d'intégration continue lancé avec claude -p, alors qu'un mod qui affiche un panneau n'y montre rien.
Ce qu'un mod peut construire : panneau, bandeau, statut, toast, commandes
Dessiner dans l'interface
Un mod dispose de plusieurs emplacements, décrits dans la page Draw in the interface :
- Un panneau (pane) : une barre latérale à côté de la conversation dans un terminal large en plein écran, sinon une zone encadrée au-dessus du prompt. Il s'ouvre avec
$.ui.open({ id }). - Un bandeau (band) au-dessus du prompt, partagé par tous les mods installés.
- Une ligne de statut sous le prompt avec
$.ui.status(text), préfixée par le nom du mod. Elle est distincte de la status line du réglagestatusLine, qui reste un mécanisme séparé. - Un toast avec
$.ui.toast(text), affiché quatre secondes par défaut.
Dans ces emplacements, un mod compose des éléments : onglets, boutons, champs de saisie, listes de choix, blocs de code et de diff, images. La galerie en montre le rendu.
Un mod peut aussi redessiner des parties existantes de Claude Code : la ligne d'un appel d'outil, le spinner, la boîte de dialogue dans laquelle Claude pose ses questions. Une exception est posée par la documentation : l'invite de permission ne peut pas être modifiée. Un mod ne peut donc pas changer ce qu'une demande d'autorisation vous montre.
Agir sur le comportement
L'interface n'est que la moitié du périmètre. Par l'API des mods, un mod peut :
- intervenir sur un appel d'outil ou une requête : le retenir le temps de poser une question à l'utilisateur, y répondre sans exécuter l'outil, l'approuver ou le refuser avant l'invite de permission, envoyer une requête à un autre modèle ;
- ajouter une commande
/commandequi exécute une fonction immédiatement, sans tour de modèle, même pendant que Claude travaille ; - ajouter des outils que Claude peut appeler, appeler un modèle, lancer des tâches de fond, échanger des messages entre sessions.
Plusieurs fonctions de Claude Code sont elles-mêmes des mods : la commande /diff, le chargement d'AGENTS.md, un garde de sécurité, la télémétrie, et « You should know », désactivé par défaut. Le code de quatre d'entre eux est public, ce qui en fait des exemples complets, tests compris.
Anthropic publie aussi trois exemples, fournis sans support : token-weather affiche une prévision de la fenêtre de contexte au-dessus du prompt, blast-radius retient une commande risquée comme un rm -rf ou un force push et montre ce qu'elle changerait, replay-theater ajoute une commande qui rejoue les modifications de fichiers du dernier tour.
Mod, hook, skill ou serveur MCP : lequel choisir dans Claude Code
Un plugin Claude Code peut contenir des mods, des settings hooks, des skills et des serveurs MCP. Ces quatre mécanismes se recoupent, et le mod est le plus puissant des quatre, donc le plus coûteux à relire et à maintenir. La documentation fournit un tableau comparatif, résumé ici.
Mod
- Ce que c'est : des fonctions, dans un plugin, que Claude Code appelle dans son propre processus.
- Ce qu'il peut changer : les appels d'outils, les prompts, les commandes, les tours, et ce que l'interface dessine.
- Ce qu'on écrit : du JavaScript ou du TypeScript.
- À choisir pour : un panneau, un bandeau, une commande sur mesure, ou la réécriture d'un événement.
Settings hook
- Ce que c'est : une commande shell, une requête HTTP ou un prompt lancés sur un événement du cycle de vie.
- Ce qu'il peut changer : le fait qu'un appel d'outil ou un prompt aboutisse, les arguments et le résultat d'un appel, le contexte ajouté pour Claude.
- Ce qu'on écrit : un script et une entrée dans
settings.json. - À choisir pour : bloquer, autoriser ou journaliser un événement avec un script que l'on a déjà.
Skill
- Ce que c'est : un fichier
SKILL.mdd'instructions que Claude lit. - Ce qu'elle peut changer : ce que Claude sait et fait.
- Ce qu'on écrit : du Markdown.
- À choisir pour : des consignes que l'on recolle sans cesse dans la conversation.
Serveur MCP
- Ce que c'est : un processus ou un service externe qui donne des outils à Claude.
- Ce qu'il peut changer : la liste des outils disponibles.
- Ce qu'on écrit : un serveur, dans le langage de son choix.
- À choisir pour : donner à Claude l'accès à un système externe.
Seul le mod peut dessiner dans l'interface.
En pratique, la règle à appliquer consiste à prendre le mécanisme le moins puissant qui répond au besoin :
- Le besoin est une consigne (conventions de code, procédure de revue, format de commit) : une skill suffit, et elle se relit comme un document.
- Claude doit atteindre un système (outil de tickets, base de données, API interne) : un serveur MCP, qui s'exécute hors de l'agent et dont les appels restent soumis aux règles de permission.
- Il faut bloquer ou autoriser une commande ou un chemin fixes : une règle de permission, sans code. La documentation le recommande elle-même pour ce cas.
- Il faut bloquer, autoriser ou journaliser avec un script existant : un settings hook.
- Il faut une interface, une commande sans tour de modèle, une décision qui dépend de l'état du moment (branche courante, valeur relevée par un autre hook) ou la réécriture d'un événement : un mod.
Quand un mod n'est pas le bon choix
- Pour une garantie de sécurité. Un hook qui refuse les pushs sur
mainen inspectant le texte de la commande reste un rappel adressé à Claude. La documentation le dit à propos de son propre exemple : pour bloquer ces pushs pour tout le monde, il faut protéger la branche chez l'hébergeur Git. - Quand la règle doit valoir pour des clients qui ne chargent pas le plugin. Un mod n'agit que là où il est chargé ; une session WSL de l'application de bureau, par exemple, n'en charge aucun.
- Quand personne ne maintiendra le code. L'API peut changer d'une version à l'autre, et un mod cassé ne provoque pas d'erreur visible : son hook est ignoré et la session continue.
Comment créer un mod Claude Code : trois fichiers et un rechargement à chaud
Les trois fichiers
Un mod tient en trois fichiers, décrits dans la page Create a mod :
garde-fou/
├── .claude-plugin/
│ └── plugin.json
└── hooks/
├── hooks.json
└── register.jsplugin.jsonest le manifeste commun à tout plugin Claude Code ;hooks.jsoncontient la clémodules, qui pointe vers le code. C'est cette clé qui fait du plugin un mod :
{
"description": "Module de hooks du garde-fou",
"modules": ["./register.js"]
}register.jsest le module de hooks. Il exporte une fonctionregister(on, options), et chaque appelon('evenement', filtre?, async ($, e, next) => …)enregistre un hook.
Il n'y a ni Node.js, ni bundler, ni étape de build : Claude Code charge directement les fichiers .js et .ts, en modules ES.
Un exemple : refuser les commandes destructrices
Ce module refuse toute commande shell qui contient un rm -r, un rm -rf ou un git push --force. Il est adapté de l'exemple de la page React to events :
const DESTRUCTIVE = /\brm\s+-rf?\b|\bgit\s+push\b.*--force/
export function register(on) {
on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
if (DESTRUCTIVE.test(e.command)) {
// Retour sans appeler next : la commande ne s'exécute pas, Claude lit le motif.
return { deny: "Commande destructrice refusée par la règle d'équipe. Proposer une alternative réversible." }
}
// Tout le reste poursuit vers les autres mods, le contrôle de permission, puis Bash.
return next(e)
}).catch(async ($, e, next) =>
// Sans ce gestionnaire, un garde qui plante ou dépasse son délai est ignoré et la commande s'exécute.
next.called ? next(e) : { deny: "Le garde-fou a échoué : la commande n'a pas été exécutée." },
)
}Trois arguments reviennent dans chaque hook :
$est l'API des mods, le seul moyen pour un hook d'agir hors de son propre code (dessiner, lire un fichier, lancer un processus, appeler un modèle) ;eest l'événement, sous forme de données figées : icie.commandcontient la commande shell ;nextpasse la main aux autres mods, puis au comportement de Claude Code, et renvoie le résultat.
Le deuxième argument de on, { tool: 'Bash' }, est un filtre : le hook ne s'exécute que pour les appels à Bash. Claude lit le texte de deny comme résultat de l'outil, d'où l'intérêt de le rédiger comme une consigne exploitable.
Deux détails de cet exemple concernent un responsable technique.
Un hook qui échoue laisse passer. Si un hook lève une exception, dépasse son délai ou renvoie un résultat mal formé avant d'avoir appelé next, Claude Code l'ignore et le gestionnaire suivant prend sa place : la commande s'exécute comme si le mod n'existait pas. Le .catch inverse ce comportement en refusant quand le garde n'a pas pu se prononcer. Tout mod dont le rôle est de bloquer devrait en avoir un, et la revue de code devrait le vérifier.
Une expression régulière a des angles morts. Celle-ci ne reconnaît pas git push -f, et la documentation signale la même limite sur l'exemple dont ce motif est repris. Un tel garde réduit les erreurs d'inattention de l'agent ; il ne remplace ni la protection de branche, ni les sauvegardes, ni des droits d'accès correctement réglés.
Un second exemple : une commande personnalisée qui lance le lint et les tests
Un mod ne sert pas qu'à bloquer. Celui-ci ajoute une commande /verif qui lance les vérifications du projet l'une après l'autre et s'arrête à la première qui échoue :
// Les vérifications du projet, dans l'ordre. À adapter à ses propres scripts.
const CHECKS = [
['pnpm', 'lint'],
['pnpm', 'test'],
]
export function register(on) {
on('session.start', async ($, e, next) => {
// immediate : la commande répond même pendant que Claude travaille.
await $.command.register({ name: 'verif', description: 'Lance le lint et les tests du projet', immediate: true })
return next(e)
})
on('command.run', { command: 'verif' }, async ($) => {
for (const argv of CHECKS) {
const label = argv.join(' ')
try {
// Le délai par défaut est de 30 secondes : cinq minutes laissent passer une suite de tests.
const run = await $.process.run(argv, { timeoutMs: 300_000 })
if (run.exitCode !== 0) {
$.ui.toast(label + ' a échoué')
// Le texte renvoyé s'affiche dans la conversation, et Claude le lit.
return { text: label + ' a échoué :\n' + (run.stdout + run.stderr).slice(-2000) }
}
} catch (error) {
// Programme introuvable, ou toujours en cours à l'expiration du délai.
return { text: label + " n'a pas abouti : " + error.message }
}
}
$.ui.toast('Lint et tests passent')
return { text: 'Lint et tests passent.' }
})
}Avec les deux mêmes fichiers de manifeste que le garde-fou, il s'essaie depuis la racine d'un projet avec claude --plugin-dir ./verif, puis /verif. La commande s'exécute sans tour de modèle. En cas d'échec, la fin de la sortie arrive dans la conversation : Claude la lit, et il suffit de lui demander de corriger sans rien recopier.
Sa limite principale tient à $.process.run : pas de shell (une liste d'arguments, donc ni && ni redirection), une sortie lue en une fois à la fin du programme, et un délai de dix minutes au plus. Pour une suite de tests longue ou un affichage au fil de l'eau, $.process.spawn diffuse la sortie. C'est aussi un mod qui lance des programmes : claude plugin validate le signale sur sa ligne calls:, ce qui en fait un bon exercice de relecture.
Rechargement à chaud et outillage
Un dossier chargé avec claude --plugin-dir ./garde-fou est surveillé : chaque enregistrement recharge le module, sans redémarrer la session. Chaque rechargement relance register, donc les variables du module repartent de zéro. Un état à conserver se range dans $.state.
L'outillage qui accompagne l'écriture :
- Des types générés pour la version installée. À chaque chargement, Claude Code écrit des fichiers de déclaration TypeScript dans
.claude-plugin/types/. La documentation demande de s'y fier plutôt qu'à ses propres pages en cas de désaccord, parce que les événements et les méthodes peuvent changer d'une version à l'autre. - Une analyse statique,
claude plugin validate, qui lit le manifeste et le code sans rien exécuter. Sur l'exemple ci-dessus, avec la version 2.1.295 :
❯ ./register.js hooks: tool.call{tool=Bash}
❯ ./register.js gating hook with .catch: tool.call{tool=Bash}
❯ ./register.js calls: nothing on $
✔ Validation passed- Des tests, lancés avec
claude plugin test, qui déclenchent les événements et vérifient la réponse des hooks sans session, sans authentification et sans réseau. Ils s'intègrent donc à une intégration continue classique.
Une fois écrit, un mod se distribue comme tout plugin : un dossier ou un .zip pour quelques personnes, une marketplace privée (un dépôt de l'équipe) pour un partage plus large, les réglages gérés pour toute une organisation, une marketplace publique pour tout le monde.
Demander le mod à Claude
L'autre voie consiste à décrire le mod dans une session : Claude s'appuie sur une skill intégrée, plugin-authoring, et écrit le mod dans ~/.claude/dev-mods/<id de session>/. Claude Code demande alors une fois, pour la session, s'il faut activer le rechargement à chaud ; le mod se charge à la fin du tour et se recharge à la fin de chaque tour qui le modifie. Un mod écrit ainsi ne vit que dans la session qui l'a créé : pour le conserver, il faut copier son dossier ailleurs.
Cette facilité a un revers pour une équipe : le code qui s'exécutera avec les droits du développeur a été écrit par l'agent. La relecture et le passage par claude plugin validate s'appliquent comme pour n'importe quel code tiers.
Trois usages des mods qui se justifient dans une équipe
Un garde-fou sur les commandes destructrices. C'est le premier exemple, ou sa variante qui pose la question au développeur avec $.ui.ask avant de laisser passer la commande. Par rapport à une règle de permission, il peut décider selon le contexte : branche courante, répertoire, valeur relevée par un autre hook.
Le suivi de la consommation de contexte. Un hook sur turn.step reçoit, pour chaque requête envoyée au modèle, les compteurs de tokens renvoyés par l'API, dont la part lue depuis le cache de prompt ; $.session.usage() donne le remplissage de la fenêtre de contexte, les limites de débit et le coût de la session (référence des mods). Affichées dans un bandeau, ces données rendent visible le moment où une session devient coûteuse ou approche de la compaction.
Une commande interne. C'est le modèle de /verif : une fonction exécutée sans tour de modèle, au résultat déterministe, pour ce que l'équipe fait à la main plusieurs fois par jour (lancer les vérifications, afficher l'état d'un environnement, ouvrir un panneau qui liste les appels d'outils de la session).
Ces trois cas ont un point commun : le mod sert un besoin identifié, son code tient en quelques dizaines de lignes, et quelqu'un dans l'équipe en est responsable. Au-delà, l'outillage d'agents relève d'un vrai projet d'intégration d'agents IA et automatisation, avec ses exigences de test et de maintenance.
Sécurité : ce qu'un mod peut atteindre sur un poste de développeur
La sécurité des mods Claude Code se résume à un fait : un mod n'est pas isolé. Il s'exécute avec les permissions de l'utilisateur. La section What a mod can reach liste ce qu'il peut faire une fois chargé :
- agir sur la machine : lire et écrire des fichiers partout où le compte utilisateur le peut, lancer des programmes, faire des requêtes réseau ;
- lire les secrets : variables d'environnement et fichiers de réglages, clés d'API comprises ;
- voir la session : chaque prompt envoyé, chaque appel d'outil ;
- modifier la session : réécrire un prompt ou un appel d'outil, soumettre un prompt comme si l'utilisateur l'avait tapé, envoyer un message à une autre session ;
- agir sans demander : approuver un appel d'outil avant que la question ne soit posée ;
- consommer le forfait ou la clé d'API en appelant un modèle.
Le sandboxing de Claude Code ne change rien à cette liste : il isole les commandes Bash lancées par Claude, et un processus démarré par un mod s'exécute en dehors.
Ce que deviennent les règles de permission
Pour comprendre ce qu'un mod peut contourner, il faut connaître l'ordre dans lequel un appel d'outil est traité.
Ordre simplifié de traitement d'un appel d'outil dans Claude Code, d'après la documentation des mods (les mods listés dans appendPlugins et les autres mods intégrés, placés après ceux de l'utilisateur, ne sont pas représentés).
Les hooks tool.check interviennent après les règles de permission et les settings hooks, et leur réponse peut remplacer la décision déjà prise. La page sur les permissions en tire quatre conséquences :
- Règles
ask: un mod peut approuver un appel qu'une règleaskaurait soumis à validation. - Hooks
PreToolUse: un mod peut approuver un appel qu'un hookPreToolUseavait bloqué, sauf si ce hook vient des réglages gérés. - Mode auto : un appel approuvé par un mod s'exécute sans passer par le classifieur.
- Règles
deny: sur une machine dotée de réglages gérés, ou pour un compte Team ou Enterprise, elles l'emportent par défaut sur le mod. Partout ailleurs, un mod peut approuver un appel qu'une règledenyrefuse.
Ce dernier point concerne directement les petites équipes : un développeur authentifié par clé d'API, sur une machine sans réglages gérés, n'a pas cette protection.
Par ailleurs, les règles deny portent sur les appels d'outils de Claude, pas sur les appels du mod lui-même. Avec Read(.env) refusé, un mod peut toujours lire ce fichier avec $.fs.read, ou lancer un programme qui le lit (page d'administration).
Relire un mod avant de l'installer
La contrepartie de ce périmètre est qu'il se lit sans exécuter le code. Un hook n'a pas d'autre moyen d'agir que l'API $, et Claude Code refuse de charger un mod dont l'usage de cette API échappe à l'analyse statique. La commande suivante liste donc tout ce qu'un mod écoute et appelle :
claude plugin validate ./un-mod ❯ ./register.js hooks: session.start, tool.call, ui.render{component=Pane}
❯ ./register.js calls: $.fs.read, $.http.fetch, $.store.set, $.ui.openSur la ligne calls:, les appels à regarder en priorité :
$.fs.read,$.fs.write: lecture et écriture de fichiers partout où l'utilisateur le peut ;$.process.run,$.process.spawn: lancement de programmes ;$.http.fetch: requêtes réseau ;$.env.get,$.settings.read: lecture de variables d'environnement et de réglages, qui peuvent contenir des clés d'API ;$.model.complete: appels de modèle facturés sur le forfait ou la clé de l'utilisateur ;$.prompt.submit: soumission d'un prompt, éventuellement présenté comme venant de l'utilisateur.
Sur la ligne hooks:, tool.call et prompt.submit signifient que le mod voit et peut modifier chaque appel d'outil et chaque prompt ; tool.check, qu'il peut approuver ou refuser un appel avant l'invite.
Un mod qui lit des fichiers et fait des requêtes réseau n'est pas suspect en soi, mais la combinaison $.fs.read et $.http.fetch suffit techniquement à faire sortir un fichier de la machine. C'est la lecture du code qui tranche, et validate indique où regarder.
Encadrer les mods Claude Code dans une équipe ou une entreprise
Pour qui déploie Claude Code en entreprise, la page Manage mods for your organization décrit l'état par défaut et les réglages disponibles.
Ce qui se passe sans aucun réglage
- Les mods sont activés. Un développeur peut en installer depuis toute marketplace autorisée, en charger un depuis un dossier avec
--plugin-dir, ou en faire écrire un par Claude. - Un garde intégré,
sec-default, se charge avant tout mod utilisateur si la machine a des réglages gérés ou si le compte est Team ou Enterprise. Il empêche un mod utilisateur de modifier ce que l'organisation gère : hooks gérés, prompt système, instructions gérées, réglages lus par les mods, outils des serveurs MCP gérés. - Tout le reste est permis : fichiers, processus, réseau, réécriture des prompts et des appels d'outils, approbation d'un appel avant l'invite.
Les niveaux de politique
Le niveau de restriction se choisit avec quelques réglages gérés :
- Aucun mod installé, settings hooks conservés :
allowManagedModsOnly, sans déployer de mod d'organisation. - Uniquement les mods de l'organisation :
allowManagedModsOnly, avec ses propres mods installés de façon à être reconnus comme tels. - Tout mod issu de marketplaces approuvées : les restrictions de marketplace existantes, plus
disableSideloadFlags, qui interdit--plugin-diret empêche de charger les mods écrits par Claude en session. Sa portée dépasse les mods : il rejette aussi--plugin-url,--agentset--mcp-config, un point à vérifier avant de l'activer si des scripts utilisent ces options. - Tout mod, sous le contrôle d'un mod de politique : un mod d'organisation placé en tête avec
prependPlugins. - Ni mods ni hooks :
disableAllHooks. Dans les réglages gérés, ce réglage coupe aussi les hooks gérés, donc un hookPreToolUsede l'organisation ne bloque plus rien.
allowManagedModsOnly est une option du garde intégré, lue uniquement dans les réglages gérés : un développeur ne peut pas la défaire dans ses propres fichiers.
{
"pluginConfigs": {
"cc-plugin-sec-default@builtin": {
"options": {
"allowManagedModsOnly": true
}
}
}
}Mods de l'organisation et mod de politique
Claude Code ne considère un mod comme celui de l'organisation que s'il est activé par les réglages gérés et chargé sur place depuis un répertoire local de la machine, désigné par un chemin absolu. Un plugin copié depuis GitHub, un dépôt git, une URL ou npm compte comme un mod utilisateur, même activé par les réglages gérés : allowManagedModsOnly le refuse et prependPlugins l'ignore. Une politique stricte suppose donc un outil de gestion de parc qui copie ce répertoire au même endroit sur chaque poste, avec des droits d'écriture réservés à un administrateur ; la console d'administration de claude.ai peut distribuer les clés, pas déposer le répertoire. Les conditions exactes figurent dans la page d'administration.
Placé dans prependPlugins, un mod de l'organisation peut contrôler les autres : il reçoit l'événement plugin.register chaque fois qu'un mod va se charger, avec la liste que claude plugin validate afficherait, et peut le refuser (par exemple tout mod utilisateur qui appelle $.process.run). Il peut aussi intercepter chaque appel de l'API par son nom, pour le journaliser ou le refuser. La documentation donne un exemple complet et deux réserves : un hook plugin.register qui échoue laisse le mod contrôlé se charger, sauf .catch qui refuse ; et une session peut tourner sans le mod de politique, après trois plantages du thread qui exécute les mods ou avec claude --safe-mode.
Lister et désactiver les mods
Pour savoir quels mods une session de terminal a chargés, la commande /plugin affiche sous ses onglets une ligne du type 1 mod active · first-mod, qui donne leur nombre et leurs noms. Les mods intégrés n'y figurent pas : ils sont listés dans l'onglet « Installed », sous « Built-in ».
Pour les désactiver côté utilisateur, trois niveaux : un mod depuis /plugin ; tous les mods installés pour une session avec claude --safe-mode ; tous durablement avec "disableAllHooks": true dans ~/.claude/settings.json, ce qui arrête aussi les settings hooks et la status line personnalisée. Aucun de ces réglages n'arrête les mods intégrés, qui ont chacun leur propre interrupteur.
Pour une équipe de quelques développeurs sans gestion de parc, la politique tient davantage à des conventions qu'à des réglages : une marketplace privée dans un dépôt de l'équipe, une revue de code obligatoire pour tout mod qui y entre, claude plugin validate dans l'intégration continue de ce dépôt, et une liste courte de mods admis. Choisir ce niveau de contrôle et l'articuler avec le reste de l'outillage de développement fait partie des sujets traités en conseil en architecture logicielle.
Limites actuelles des mods
- Une API qui bouge. La fonctionnalité a quelques jours. Neuf versions ont été publiées entre le 1er et le 8 octobre 2026, de la 2.1.287 à la 2.1.295, et le changelog montre des ajouts ou des corrections liés aux mods dans la plupart d'entre elles. Certaines corrections touchent les gardes eux-mêmes : la 2.1.295 corrige par exemple un cas où un hook recevait une entrée d'outil tronquée sans erreur, si bien qu'un garde pouvait laisser passer un contenu qu'il n'avait pas vu. Un mod doit indiquer la version avec laquelle il a été testé, et les postes ont intérêt à rester à jour.
- Des délais stricts. Un hook dispose de 10 secondes par événement (50 millisecondes pour
prompt.edit), hors temps passé dansnextou dans un appel de l'API ; au-delà, il est ignoré. - Des plafonds de taille. 4 Mio par fichier lu ou écrit avec
$.fs, 4 Mio au total pour$.store. - Un affichage borné. Les redessins sont plafonnés à 10 par seconde (30 dans le terminal pour certains emplacements), et un panneau qu'un mod ouvre de lui-même n'est placé qu'à partir de 144 colonnes de terminal.
- Un thread partagé. Les mods installés partagent un seul thread de travail. Un mod qui le bloque ou le fait planter est déchargé ; les autres mods de la session dépendent donc de la qualité du moins soigné d'entre eux (page de dépannage des mods).
- Des échecs discrets. Un mod défaillant ne casse pas la session : son hook est ignoré, et la raison n'apparaît que dans le journal de débogage (
claude --debug) hors session de développement. Un mod qui ne fait plus rien peut passer inaperçu. - Un dessin limité à deux surfaces. Le terminal et l'onglet Code de l'application de bureau.
Les chiffres viennent de la section Limits de la référence, donnée pour la v2.1.290 : ils sont à revérifier dans les fichiers de types de la version installée.
Ce qu'il faut retenir : critères de décision
Un mod étend Claude Code plus profondément que tout ce qui existait, et il le fait avec les droits du développeur. La décision de les autoriser se prend donc comme pour toute dépendance exécutable sur un poste qui détient du code source et des secrets.
Les questions à se poser avant d'en adopter un :
- Le besoin exige-t-il un mod ? Une consigne relève d'une skill, un accès à un système d'un serveur MCP, un blocage fixe d'une règle de permission ou d'un settings hook.
- Que dit
claude plugin validate? Quels événements le mod écoute-t-il, quels appels fait-il, et chacun se justifie-t-il par la fonction annoncée ? - S'il bloque quelque chose, que se passe-t-il quand il échoue ? Un garde sans
.catchlaisse passer. - Qui le maintient ? Avec une API qui change à chaque version, un mod sans responsable finit par cesser de fonctionner sans prévenir.
- Les postes ont-ils des réglages gérés ou un compte Team ou Enterprise ? Sinon, le garde intégré ne se charge pas et une règle
denyne résiste pas à un mod. - D'où viennent les mods autorisés ? Marketplace privée relue, liste fermée, ou politique
allowManagedModsOnly? - La règle visée doit-elle être garantie ? Dans ce cas, elle s'applique là où elle ne peut pas être contournée : protection de branche, droits d'accès, secrets hors du poste.
Une équipe qui répond à ces questions peut tirer parti des mods pour ce qu'ils apportent réellement : rendre visible ce que fait l'agent, lui poser des limites adaptées au contexte, et outiller ses propres pratiques sans attendre qu'une fonction arrive dans le produit.
Un sujet à creuser pour votre projet ?
Discutons de votre contexte technique et de vos enjeux.
Parlons de votre projet