Skip to main content
Un plugin Claude Code est construit à partir de composants, tels que des skills, des agents, des hooks et des serveurs MCP. Chaque composant a un dossier par défaut dans le plugin, une clé de manifeste optionnelle dans .claude-plugin/plugin.json qui remplace ou ajoute à ce dossier, et un nom que l’utilisateur voit. Pour chaque tableau complet des champs de clé, consultez la référence du manifeste. Utilisez cette page pour ajouter un composant à un plugin qui charge déjà. Après avoir ajouté un composant, exécutez /reload-plugins dans une session en cours ou démarrez une nouvelle session pour que Claude Code le charge. Pour vérifier le fichier du composant avant de le charger, exécutez claude plugin validate . dans votre shell à partir du répertoire du plugin.
Ces cas sont couverts sur d’autres pages :

Explorez le répertoire du plugin

L’explorateur montre un exemple de plugin, my-plugin, qui a un de chaque type de composant à son emplacement par défaut :
  • Une skill de révision et une commande about
  • Un sous-agent de révision de sécurité
  • Un hook qui formate les fichiers après que Claude les édite, et le dossier scripts/ qu’il appelle
  • Un moniteur de journal
  • Un style de sortie et un thème de couleur
  • Un workflow d’audit de route
  • Un exécutable hello-plugin
  • Les paramètres par défaut
  • Un serveur MCP local et un serveur de langage Go
Chaque fichier est le plus petit exemple valide de son format, là pour montrer la forme plutôt que d’être utile : une skill ou un agent réel porte des instructions complètes et souvent des fichiers de support, et un hook ou un moniteur réel fait un vrai travail. Les sections après l’explorateur utilisent les mêmes fichiers que leurs exemples et renvoient à des versions plus complètes. Sélectionnez un fichier ou un dossier pour lire à quoi il sert, voir ce qu’il contient, et trouver la section qui le couvre.

Ajouter chaque type de composant

Chaque section ci-dessous couvre un type de composant : où ses fichiers vont dans le plugin, un exemple qui valide, ce que l’utilisateur voit une fois que le plugin charge, et la clé de manifeste qui change l’emplacement par défaut. Ajoutez ceux dont votre plugin a besoin ; aucun n’est requis.

Skills

Une skill est un fichier SKILL.md que Claude peut charger quand sa description correspond à la tâche. L’utilisateur peut aussi l’exécuter comme une commande. Enregistrez chaque skill dans son propre répertoire sous skills/ :
Donnez au SKILL.md une description pour que Claude sache quand l’utiliser :
skills/review/SKILL.md
Après avoir chargé le plugin, /my-plugin:review exécute la skill. Le nom de la commande et qui peut l’invoquer suivent ces règles :
  • Nom de la commande : /<plugin>:<directory>, donc skills/review/SKILL.md dans my-plugin est /my-plugin:review. Si vous définissez name dans le frontmatter, il remplace le dernier segment et le préfixe du plugin reste. Consultez comment une skill obtient son nom de commande
  • Qui l’invoque : Claude, l’utilisateur, ou les deux, contrôlé par le frontmatter. Consultez Contrôler qui invoque une skill
Vous pouvez aussi placer des skills en dehors du répertoire par défaut skills/ :
  • Répertoires supplémentaires : listez-les dans la clé de manifeste skills. Ils s’ajoutent au scan skills/ par défaut plutôt que de le remplacer, contrairement à commands et agents
  • Une seule skill à la racine du plugin : sans répertoire skills/ et sans clé de manifeste skills, un SKILL.md à la racine du plugin charge comme une skill. Définissez name dans son frontmatter, car sinon une installation marketplace nomme la skill d’après son répertoire de cache plutôt que votre plugin
Pour inclure des instructions dans un plugin, écrivez-les comme une skill. Claude Code ne charge pas un CLAUDE.md à la racine du plugin, et claude plugin validate avertit CLAUDE.md at the plugin root is not loaded as project context. Pour les champs de frontmatter et les fichiers de support, consultez Skills.

Commandes

Une commande est un seul fichier Markdown que l’utilisateur exécute par nom, comme /my-plugin:about.
Les commandes sont le format plus ancien, et les skills les remplacent pour les nouveaux travaux. Une skill s’exécute par nom de la même manière, et elle peut aussi porter des fichiers de support dans son répertoire. Gardez commands/ pour les fichiers que vous migrez depuis .claude/commands/.
Enregistrez une commande à commands/<file>.md et elle devient /<plugin>:<file>. Un sous-répertoire ajoute un segment, donc commands/db/migrate.md est /my-plugin:db:migrate. Les fichiers de commande prennent le même frontmatter que les skills.

Définir les commandes dans le manifeste

Vous n’en avez besoin que si vous voulez garder les fichiers de commande quelque part d’autre que commands/, ou pour définir une commande courte dans plugin.json sans fichier Markdown séparé. Définissez la clé de manifeste commands, et Claude Code la lit à la place de scanner commands/. La clé prend un chemin, un tableau de chemins, ou un objet qui mappe chaque nom de commande à soit un fichier source soit un content en ligne. Ce manifeste définit /my-plugin:about en ligne, sans fichier Markdown :
.claude-plugin/plugin.json
Chargez le plugin et exécutez /my-plugin:about dans la session pour confirmer qu’il a chargé. Pour la syntaxe complète de la clé, consultez commands.

Agents

Un sous-agent est un assistant séparé, avec ses propres instructions et fenêtre de contexte, que Claude peut déléguer une tâche. Chaque fichier Markdown sous agents/ en définit un :
agents/security-reviewer.md
Cet agent est nommé my-plugin:security-reviewer, et l’utilisateur peut l’invoquer explicitement avec @agent-my-plugin:security-reviewer. La forme du nom est <plugin>:<name>, où <name> provient du frontmatter, ou du nom du fichier quand il n’y en a pas. La clé de manifeste agents remplace le scan agents/.

Organiser les agents dans des sous-dossiers

Vous pouvez mettre les fichiers d’agent du plugin dans des sous-dossiers de agents/. Claude Code les charge récursivement et joint le nom du plugin, chaque nom de sous-dossier, et le nom du fichier avec des deux-points pour former le nom d’agent scopé. Par exemple, agents/review/security.md dans un plugin nommé my-plugin charge comme my-plugin:review:security. Deux paramètres changent ce nom :
  • Frontmatter name : il remplace seulement le nom du fichier, donc name: audit dans agents/review/security.md charge comme my-plugin:review:audit
  • Champ de manifeste agents : un fichier que vous listez là charge sans noms de sous-dossier, donc "agents": "./custom/review/security.md" charge comme my-plugin:security

Champs de frontmatter dans les agents du plugin

Le frontmatter d’un agent du plugin suit ces règles :
  • Champs supportés : name, description, model, effort, maxTurns, tools, disallowedTools, skills, memory, background, omitClaudeMd, isolation, color, et la clé cacheTtl de experimental. La seule valeur isolation valide est "worktree". Consultez champs de frontmatter supportés pour ce que chacun fait
  • Champs ignorés : permissionMode, hooks, mcpServers, et initialPrompt. Un fichier d’agent ne peut pas ajouter des hooks ou des serveurs MCP par lui-même, donc ajoutez-les comme plugin hooks et serveurs MCP à la place
  • Frontmatter qui ne s’analyse pas : l’agent charge quand même avec chaque champ ignoré. Il est nommé d’après le fichier, et sa description lit Agent from my-plugin plugin. Exécutez claude plugin validate dans votre shell pour trouver ces fichiers
Pour ce que chaque champ fait et les règles de précédence, consultez Sous-agents.

Hooks

Un hook exécute quelque chose automatiquement à un point du cycle de vie de Claude Code, comme après chaque édition de fichier : une commande shell, une requête HTTP, un appel d’outil MCP, une invite à un modèle, ou un sous-agent. Enregistrez les hooks du plugin dans hooks/hooks.json à la racine du plugin, sous une clé "hooks" de niveau supérieur, dans la même forme que l’objet hooks dans settings.json. Cela vous permet de copier un hook de paramètres existant inchangé. Ce hook exécute un script groupé après chaque Write ou Edit :
hooks/hooks.json
Enregistrez le script à scripts/format.sh et rendez-le exécutable. Chargez le plugin et demandez à Claude d’éditer un fichier. Un hook PostToolUse qui sort 0 ne montre rien dans la transcription, donc confirmez qu’il a exécuté avec journalisation de débogage ou par ce que le script lui-même change. Les hooks dans hooks/hooks.json et dans la clé de manifeste hooks chargent tous les deux. Pour chaque événement et sa charge utile, consultez Événements de hook.

Quand les hooks du plugin se déclenchent

Les hooks d’un plugin n’attendent pas qu’une des skills ou commandes du plugin soit utilisée. Claude Code les enregistre quand une session charge le plugin, et ils se déclenchent sur leurs événements à partir de là. Pour limiter quand un hook s’exécute, réduisez son matcher. Si un hook ne se déclenche jamais, consultez hooks qui ne se déclenchent pas.

Environnement, guillemets et correspondance des outils MCP

L’environnement du hook, les guillemets de ${CLAUDE_PLUGIN_ROOT}, et les matchers pour les outils MCP du plugin fonctionnent comme suit :
  • Environnement : chaque processus de hook reçoit CLAUDE_PLUGIN_ROOT et CLAUDE_PLUGIN_DATA dans son environnement, plus CLAUDE_PLUGIN_OPTION_<KEY> pour chaque valeur de configuration utilisateur, donc votre script peut les lire de là
  • Guillemets : quand command n’a pas args, il s’exécute via un shell, donc enveloppez le chemin ${CLAUDE_PLUGIN_ROOT} entre guillemets doubles, comme l’exemple hooks/hooks.json sous Hooks le fait, pour garder le chemin développé un mot shell. Quand vous passez args à la place, chaque élément est passé comme un argument sans shell et n’a besoin d’aucun guillemet. Consultez forme exec et forme shell
  • Correspondance des outils MCP du plugin : un outil d’un serveur MCP que ce plugin déclare est nommé mcp__plugin_<plugin>_<server>__<tool>, donc écrivez ce nom complet dans le matcher. Un matcher sur le nom du serveur seul ne se déclenche jamais. Consultez Correspondance des outils MCP

Serveurs MCP

Un serveur MCP donne à Claude des outils d’un système externe. Déclarez-le dans .mcp.json à la racine du plugin, dans la même forme qu’un .mcp.json de projet. Ce .mcp.json déclare un serveur nommé db :
.mcp.json
Vous pouvez aussi omettre le wrapper mcpServers et mettre db au niveau supérieur du fichier. Chargez le plugin et exécutez /mcp pour confirmer que le serveur apparaît comme plugin:my-plugin:db. claude plugin validate vérifie .mcp.json et signale une entrée de serveur que Claude Code supprimerait au moment du chargement comme une erreur. Nécessite Claude Code v2.1.281 ou ultérieur. Pour où une mauvaise entrée s’affiche au moment du chargement, consultez Serveurs MCP qui ne démarrent pas. La clé de manifeste mcpServers prend une carte de serveur en ligne, un chemin vers un fichier JSON, ou un tableau de ceux-ci. Quand un serveur de manifeste a le même nom qu’un dans .mcp.json, le serveur de manifeste le remplace.

Atteindre les utilisateurs sur claude.ai et Cowork

Un serveur stdio local, comme le serveur db sous Serveurs MCP, s’exécute dans Claude Code et dans une session Cowork qui s’exécute sur votre machine dans l’application Claude Desktop, mais pas sur claude.ai. Pour atteindre les utilisateurs là aussi, référencez un serveur distant par son URL https://, que claude.ai et Cowork offrent à l’utilisateur comme connecteur.

Noms de serveur, noms d’outils et rechargements

Les noms du serveur, la substitution de variables, et le comportement de rechargement suivent ces règles :
  • Nom du serveur : plugin:<plugin>:<server>, donc le serveur db dans my-plugin est plugin:my-plugin:db dans /mcp. Utilisez la même forme pour nommer le serveur dans un hook mcp_tool
  • Noms d’outils : mcp__plugin_<plugin>_<server>__<tool>, donc un outil query sur ce serveur db est mcp__plugin_my-plugin_db__query. C’est le nom à utiliser dans les règles de permission et les matchers de hook
  • Substitution : ${CLAUDE_PLUGIN_ROOT} et les autres variables de chemin sont substituées dans command, args, et env. Aucun guillemet n’est nécessaire dans args, car chaque élément est passé comme un argument
  • Rechargement : quand l’utilisateur exécute /reload-plugins et que le rechargement s’applique, un serveur dont la configuration est inchangée garde sa connexion. Un serveur dont la configuration a changé se reconnecte, et un que vous avez supprimé se déconnecte

Inclure un serveur MCPB emballé

La clé mcpServers accepte aussi un serveur emballé comme un fichier MCPB, dont l’extension est .mcpb ou l’ancienne .dxt. Pointez la clé vers le fichier, comme un chemin à l’intérieur du plugin ou une URL https:// :
.claude-plugin/plugin.json
Le serveur prend son nom du name dans le manifeste du bundle. Pour les transports et l’authentification, consultez MCP.

Serveurs LSP

Un serveur LSP donne à Claude des diagnostics et une navigation de code pour une langue. Si un plugin officiel de code intelligence couvre déjà votre langue, installez celui-ci à la place d’en écrire un. Sinon, déclarez le serveur dans .lsp.json à la racine du plugin :
.lsp.json
Le fichier mappe chaque nom de serveur directement à sa configuration, sans objet wrapper autour de la carte. command est le nom du binaire, avec ses arguments dans args. extensionToLanguage a besoin d’au moins une extension, chacune commençant par .. claude plugin validate ne lit pas ce fichier. Quand une entrée est invalide, le fichier entier est ignoré au chargement et Invalid LSP server config for ".lsp.json" apparaît dans l’onglet Errors de /plugin. Votre plugin configure la connexion mais n’installe pas le binaire du serveur, et chaque extension de fichier obtient un serveur :
  • Binaire manquant : Claude Code démarre command par nom depuis le PATH de l’utilisateur. Quand le binaire n’est pas là, le serveur échoue à démarrer et claude --debug enregistre LSP server <name> failed to start
  • Conflits d’extension : quand deux serveurs activés revendiquent la même extension, le premier enregistré gère ces fichiers et l’autre n’est pas utilisé pour eux, que les serveurs proviennent d’un plugin ou de deux. L’onglet Errors de /plugin montre l’avertissement LSP server "<name>" is not used for <ext> files
La clé de manifeste lspServers prend la même carte en ligne, un chemin vers un fichier JSON, ou un tableau de ceux-ci, et ses serveurs s’ajoutent à ceux dans .lsp.json. Quand un serveur de manifeste a le même nom qu’un dans .lsp.json, le serveur de manifeste le remplace. Pour transport, les délais d’attente, les redémarrages, et les autres champs, consultez lspServers. Envoyez la sortie du journal à stderr, pas stdout. Claude Code lit le stdout d’un serveur comme des messages de protocole seulement, et accepte les en-têtes de message jusqu’à 64 KiB et un corps de message jusqu’à 32 MiB. Claude Code déconnecte un serveur qui dépasse l’une ou l’autre limite ou écrit une sortie non-protocole à stdout, et compte la déconnexion comme un crash pour restartOnCrash et maxRestarts. Quand vous exécutez avec --debug, Claude Code écrit une erreur nommant la cause au journal de débogage.

Exécutables

Les fichiers dans bin/ à la racine du plugin sont sur le PATH du shell de l’outil Bash tant que le plugin est activé, donc Claude peut les exécuter comme des commandes nues. Ajoutez un script exécutable :
bin/hello-plugin
Rendez-le exécutable avec chmod +x bin/hello-plugin et chargez le plugin. Quand vous demandez à Claude d’exécuter hello-plugin, le résultat de l’outil Bash montre la sortie du script. Les répertoires bin/ du plugin viennent après les entrées PATH de l’utilisateur, donc un plugin ne peut pas masquer git, ls, ou une autre commande système. claude.ai et Cowork n’installent pas un plugin qui a un répertoire bin/ de niveau supérieur, y compris un que vous distribuez via les paramètres d’organisation claude.ai.

Paramètres par défaut

Pour définir les paramètres par défaut qui s’appliquent tant que le plugin est activé, ajoutez un settings.json à la racine du plugin, ou mettez le même objet en ligne dans la clé de manifeste settings. Deux clés prennent effet, agent et subagentStatusLine, et toute autre clé est supprimée. Définissez agent pour exécuter l’un des propres agents du plugin comme le fil principal :
settings.json
Chargez le plugin et démarrez une session. Claude répond alors dans la conversation principale avec l’invite système et le modèle de l’agent security-reviewer. Pour tout ce que la clé contrôle, consultez le paramètre agent. Quand la même clé est définie à plus d’un endroit, ces règles décident quelle valeur s’applique :
  • Fichier sur manifeste : quand les deux existent et settings.json définit au moins une clé supportée, settings.json s’applique et le settings du manifeste est ignoré
  • Paramètres utilisateur sur paramètres par défaut du plugin : dans les sources de paramètres, les paramètres par défaut du plugin sont la couche la plus basse, donc un agent personnel de l’utilisateur dans ~/.claude/settings.json remplace le vôtre
  • Deux plugins définissent la même clé : la valeur du plugin chargé en dernier s’applique, et claude --debug enregistre overrides setting
Pour la forme subagentStatusLine, consultez lignes d’état du sous-agent.

Thèmes et styles de sortie

Un plugin peut inclure des thèmes de couleur et des styles de sortie. Les deux apparaissent dans les mêmes sélecteurs que ceux de l’utilisateur. Pour l’un ou l’autre, définir la clé de manifeste remplace le scan de dossier. Les thèmes du plugin sont en lecture seule, donc quand un utilisateur en édite un dans /theme, l’édition est enregistrée comme une copie dans son propre répertoire de thèmes. Ce thème recolore l’accent d’invite et le texte d’erreur sur le préréglage sombre :
themes/dracula.json

Canaux

Un canal permet à un système externe tel qu’une application de chat d’envoyer des messages dans une session. Dans un plugin, un canal est l’un des serveurs MCP plus une entrée channels qui se lie à lui et peut demander sa propre configuration. Ce manifeste lie un canal à un serveur telegram et demande un jeton de bot :
.claude-plugin/plugin.json
server doit correspondre à une clé dans mcpServers. Le userConfig par canal prend la même forme que la clé userConfig de niveau supérieur. Pour ce que le serveur doit implémenter et comment les utilisateurs activent un plugin de canal, consultez Empaqueter comme un plugin dans la référence des canaux. Pour le tableau des champs, consultez channels.

Moniteurs

Un moniteur est une commande shell qui s’exécute en arrière-plan pour toute la session. Ce qu’il imprime atteint Claude comme des notifications, donc Claude peut réagir à un journal ou à un changement d’état sans être demandé de le surveiller. Enregistrez les entrées dans monitors/monitors.json :
monitors/monitors.json
La commande s’exécute dans un shell, dans le répertoire de travail dans lequel la session a démarré. La commande d’un moniteur est limitée dans où elle démarre et ce qu’elle peut référencer :
  • Sessions interactives seulement : les moniteurs du plugin démarrent dans une session interactive et jamais en mode non-interactif avec le drapeau -p. Ils démarrent aussi seulement où l’outil Monitor est disponible
  • Pas de configuration utilisateur : command obtient les variables de chemin et ${ENV_VAR} de l’environnement, mais jamais ${user_config.*}. Un moniteur qui en référence un ne démarre pas, et les processus de moniteur ne reçoivent pas non plus CLAUDE_PLUGIN_OPTION_<KEY>
  • Désactivation en cours de session : si vous désactivez un plugin en cours de session, Claude Code n’arrête pas les moniteurs qui s’exécutent déjà. Ils s’arrêtent quand la session se termine
La clé de manifeste experimental.monitors prend le même tableau en ligne ou un chemin vers un fichier JSON, et est lue à la place de monitors/monitors.json. Pour le déclencheur when et les autres champs, consultez monitors.

Demander à l’utilisateur des valeurs de configuration

Déclarez les valeurs dont votre plugin a besoin de l’utilisateur dans la clé de manifeste userConfig, pour que les utilisateurs ne modifient pas settings.json eux-mêmes. Chaque option apparaît dans une boîte de dialogue avec son title comme étiquette et sa description en dessous. Définissez "sensitive": true pour un jeton ou un mot de passe. La boîte de dialogue masque alors l’entrée, et la valeur est stockée dans un stockage sécurisé plutôt que dans settings.json. Ce manifeste demande un point de terminaison et un jeton :
.claude-plugin/plugin.json

Quand la boîte de dialogue de configuration apparaît

La boîte de dialogue n’apparaît que dans l’interface interactive /plugin. Elle s’ouvre pour toute option qui n’est pas encore définie quand l’utilisateur fait l’une des choses suivantes :
  • Installe le plugin dans /plugin
  • Exécute /plugin install <plugin>@<marketplace> à l’intérieur d’une session
  • Active le plugin à partir de l’onglet Installed dans /plugin
Pour ouvrir la même boîte de dialogue à tout moment, l’utilisateur exécute /plugin configure <plugin>@<marketplace>. La commande shell claude plugin install ne demande jamais les valeurs userConfig. Pour définir les valeurs à partir du shell, passez chacune comme --config KEY=VALUE. Quand les options restent non définies, la commande imprime une ligne userConfig options not yet set qui nomme les deux façons de les définir. La boîte de dialogue userConfig ne s’affiche jamais cite la ligne. Pour les champs d’option, où chaque valeur est stockée, comment un composant référence une valeur enregistrée, et quels champs rejettent ${user_config.*}, consultez Configuration utilisateur.

Référencer les chemins du plugin et stocker les données

Vous ne savez pas où votre plugin sera installé, donc référencez ses fichiers et données via ces variables plutôt que des chemins fixes. Ils sont substitués dans le contenu des skills, commandes et agents, dans les commandes des hooks et moniteurs, et dans les configurations des serveurs MCP et LSP. Ils sont aussi exportés aux processus des hooks, MCP et LSP :
  • ${CLAUDE_PLUGIN_ROOT} : le répertoire d’installation du plugin. Chaque version a son propre répertoire de cache, donc le chemin change quand le plugin se met à jour. N’écrivez pas d’état là
  • ${CLAUDE_PLUGIN_DATA} : un répertoire qui survit aux mises à jour, pour node_modules, les environnements virtuels, et les caches. Il se résout en ~/.claude/plugins/data/<id>/ et est créé quand d’abord référencé
  • ${CLAUDE_PROJECT_DIR} : la racine du projet, la même valeur que les hooks reçoivent
Dans le chemin du répertoire de données, <id> est l’identifiant du plugin avec chaque caractère autre que les lettres, les chiffres, _, et - remplacé par -, donc my-plugin@my-marketplace devient my-plugin-my-marketplace. Sur Windows, les chemins substitués utilisent des barres obliques avant pour qu’un shell ne lise pas les barres obliques arrière comme des échappements.

Installer les dépendances dans le répertoire de données

Pour un plugin installé depuis la marketplace, Claude Code installe automatiquement les dépendances de package Node.js éligibles quand il met en cache le plugin, donc vous n’aurez peut-être pas besoin de les installer vous-même. Quand vous le faites, ce hook SessionStart installe node_modules dans ${CLAUDE_PLUGIN_DATA} à la première exécution et à nouveau après une mise à jour qui change package.json :
hooks/hooks.json
Après la première session, ~/.claude/plugins/data/<id>/node_modules existe. Un serveur MCP peut alors définir NODE_PATH à ${CLAUDE_PLUGIN_DATA}/node_modules dans son env. Pour quels champs substituent quelle variable, consultez Variables d’environnement.

Étapes suivantes