Module 12 — Plugins et marketplaces : empaqueter et partager votre outillage
Les modules précédents ont bâti séparément ce qui fait la valeur de Claude Code dans une équipe : skills, sous-agents, hooks, serveurs MCP. Chaque brique vit dans son coin. Le module conclusif rassemble : un plugin est le paquetage unique qui regroupe tout, versionné, installable en une commande, partageable via un marketplace. C'est le format à privilégier dès qu'une équipe dépasse deux personnes.
Plugin ou configuration autonome ?
Restez sur .claude/ autonome quand le contenu est spécifique à un dépôt. Passez au plugin quand la brique est réutilisable entre projets, doit être versionnée indépendamment, doit s'installer chez d'autres équipes, ou groupe plusieurs composants (skill + sous-agent + hooks + serveur MCP).
Un plugin sait tout emballer : skills, sous-agents, workflows, hooks, serveurs MCP, serveurs LSP, monitors, thèmes, styles de sortie, exécutables. Il expose le tout sous un namespace (kiosque-tools:deploy) qui évite les collisions.
Anatomie d'un plugin
Un plugin est un dossier avec un manifeste unique au chemin .claude-plugin/plugin.json. Le reste des composants vit à la racine du plugin, pas dans .claude-plugin/. Une confusion fréquente : placer agents/ ou hooks/ dans .claude-plugin/ — Claude Code ne les trouve pas.
Structure de référence :
my-plugin/
├── .claude-plugin/
│ └── plugin.json # Manifeste (facultatif si tout est aux emplacements par défaut)
├── skills/ # <nom>/SKILL.md par skill
│ └── deploy/SKILL.md
├── commands/ # Skills en fichier .md plat (compatible ; préférer skills/)
├── agents/ # Sous-agents (.md avec frontmatter)
│ └── revieweur.md
├── workflows/ # Workflows dynamiques
├ ── hooks/
│ └── hooks.json # Hooks de plugin
├── .mcp.json # Serveurs MCP fournis par le plugin
├── .lsp.json # Serveurs LSP
├── monitors/monitors.json # Monitors d'arrière-plan
├── bin/ # Exécutables ajoutés au PATH quand le plugin est actif
└── settings.json # Paramètres par défaut (seules les clés `agent` et `subagentStatusLine` sont lues)
Un plugin qui n'expose qu'une seule skill peut poser SKILL.md directement à la racine du plugin, sans dossier skills/. Pour tout ce qui grossit, utilisez skills/<nom>/SKILL.md.
Le manifeste plugin.json
Seul name est obligatoire, et le manifeste lui-même est facultatif : sans lui, Claude Code découvre les composants aux emplacements par défaut et dérive le nom du dossier. Un manifeste minimal :
{
"name": "kiosque-tools",
"displayName": "Kiosque Tools",
"version": "1.0.0",
"description": "Outils internes Kiosque : revue, tests, déploiement.",
"author": { "name": "Équipe Kiosque", "email": "dev@kiosque.example" }
}
Extrait des champs documentés :
| Champ | Rôle |
|---|---|
name | Identifiant kebab-case, sert de namespace (kiosque-tools:deploy) |
displayName / description | Affichés dans /plugin |
version | Semver ; épingle l'installation |
author, homepage, repository, license, keywords | Métadonnées de découverte |
defaultEnabled | false = installe désactivé (opt-in) |
skills, commands, agents, workflows, hooks, mcpServers, lspServers | Chemins personnalisés vers les composants |
dependencies | Autres plugins requis, avec contraintes semver |
userConfig, channels | Configuration utilisateur, canaux de messagerie |
experimental.themes, experimental.monitors | Composants au schéma évolutif |
Les champs inconnus racine sont ignorés — utile pour cohabiter avec un package.json npm.
Trois variables d'environnement clés
${CLAUDE_PLUGIN_ROOT}— chemin absolu du dossier d'installation. Pour les scripts et binaires empaquetés.${CLAUDE_PLUGIN_DATA}— dossier persistant qui survit aux mises à jour (~/.claude/plugins/data/{id}/). Pour les dépendances installées à la première utilisation.${CLAUDE_PROJECT_DIR}— racine du projet.
Les trois sont exportées aux processus de hooks, MCP et LSP, et substituées dans le contenu des skills, agents, commandes de hooks/monitors, command/args/env d'un MCP stdio, url/headers d'un HTTP.
Développer, tester, recharger
Quatre commandes rythment le développement.
- Amorcer :
claude plugin init <nom>crée un plugin dans~/.claude/skills/<nom>/avec manifeste etSKILL.mdde démarrage, chargé à la session suivante. - Tester en local :
claude --plugin-dir ./mon-plugincharge le plugin pour la session. Cumulable pour plusieurs plugins. Si le nom entre en conflit avec un plugin installé, la copie locale prend précédence. - Recharger :
/reload-pluginsapplique les changements (skills, sous-agents, hooks, MCP, LSP) sans redémarrer.--forceaccepte l'invalidation du cache de prompt. - Valider :
claude plugin validate ./mon-plugin --stricten CI.
En session, /plugin ouvre le gestionnaire : onglets Installed, Discover, Errors, favoris (touche f), filtre par nom.
Marketplaces : trouver et diffuser
Un plugin s'installe rarement par --plugin-dir en production ; il vient d'un marketplace, catalogue de plugins qu'on ajoute une fois puis dont on installe les entrées à volonté.
Marketplaces officielles et ajout de sources
Deux marketplaces publiques maintenues par Anthropic : claude-plugins-official (enregistrée automatiquement à la première session interactive) et claude-community (soumissions tierces après revue, à ajouter avec /plugin marketplace add anthropics/claude-plugins-community).
Quatre sources d'ajout possibles :
/plugin marketplace add owner/repo # GitHub
/plugin marketplace add https://gitlab.com/entreprise/plugins.git # Git (https:// + .git)
/plugin marketplace add ./ma-marketplace # Chemin local
/plugin marketplace add https://exemple.com/marketplace.json # JSON distant
Raccourci : /plugin market. Cibler une branche : .../plugins.git#v1.0.0.
Installer un plugin
/plugin install kiosque-tools@ma-marketplace
Trois scopes proposés : User (tous vos projets), Project (partagé, ajouté à .claude/settings.json versionné), Local (vous seul). Depuis la v2.1.221, l'installation active parfois le plugin dans la session courante ; sinon l'invite précise Run /reload-plugins to activate.
Pour diffuser en interne, hébergez la marketplace dans un dépôt privé ; Claude Code utilise vos credentials Git pour cloner. Les administrateurs peuvent forcer une marketplace via managed settings (extraKnownMarketplaces).
Kiosque : le plugin kiosque-tools complet
L'équipe Kiosque consolide ce qu'elle a construit dans les modules 9 à 11 en un plugin unique, publié dans une marketplace privée kiosque/plugins-interne.
Structure du plugin
kiosque-tools/
├── .claude-plugin/
│ └── plugin.json
├── skills/
│ └── deploy/SKILL.md
├── agents/
│ ├── revieweur.md
│ └── testeur.md
├── hooks/
│ └── hooks.json
├── .mcp.json
├── bin/
│ └── format-python.sh
└── README.md
plugin.json
{
"name": "kiosque-tools",
"displayName": "Kiosque Tools",
"version": "1.0.0",
"description": "Outillage interne Kiosque : revue de code, tests, déploiement, accès GitHub et Postgres.",
"author": {
"name": "Équipe Kiosque",
"email": "dev@kiosque.example",
"url": "https://kiosque.example"
},
"homepage": "https://kiosque.example/docs/plugin",
"repository": "https://gitlab.kiosque.example/dev/kiosque-tools",
"license": "UNLICENSED",
"keywords": ["kiosque", "review", "deploy", "postgres", "github"],
"defaultEnabled": true
}
hooks/hooks.json
Les trois hooks du module 9, cette fois portables : ${CLAUDE_PLUGIN_ROOT} remplace ${CLAUDE_PROJECT_DIR} pour le script embarqué, et les scripts contre migrations/ et tests restent liés au projet.
{
"hooks": {
"PostToolUse": [
{ "matcher": "Edit|Write", "hooks": [
{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/bin/format-python.sh" }
]}
],
"PreToolUse": [
{ "matcher": "Edit|Write", "hooks": [
{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/protect-paths.sh" }
]}
],
"Stop": [
{ "hooks": [
{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/require-green-tests.sh", "timeout": 300 }
]}
]
}
}
Note : le formatage Python vit dans le plugin (bin/format-python.sh), commun à tous les projets Kiosque. Les hooks spécifiques au dépôt (protection des chemins, tests locaux) restent dans ${CLAUDE_PROJECT_DIR} — c'est la règle : ce qui varie par projet reste projet.
.mcp.json
Le serveur MCP du module 11 devient partie intégrante du plugin. Les secrets restent à l'extérieur, en ${VAR} :
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": { "Authorization": "Bearer ${GITHUB_MCP_TOKEN}" }
},
"postgres": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@bytebase/dbhub", "--dsn", "${KIOSQUE_DB_DSN}"]
}
}
}
Sous-agents et skill
agents/revieweur.md et agents/testeur.md reprennent les définitions du module 10, à ceci près qu'elles sont désormais namespaced en kiosque-tools:revieweur et kiosque-tools:testeur. Karim les invoque par @"kiosque-tools:revieweur (agent)".
skills/deploy/SKILL.md capitalise le déploiement récurrent :
---
description: Déploie la version courante de Kiosque sur l'environnement de recette.
---
# /kiosque-tools:deploy
Enchaîne les étapes de déploiement de recette :
1. Vérifie que la branche est propre (`git status --porcelain`).
2. Construit l'image Docker taguée sur le SHA court.
3. Pousse l'image vers `registry.kiosque.example`.
4. Met à jour le manifeste Kubernetes et relance le déploiement.
5. Attend le passage à `Ready` puis exécute la suite de fumée `make smoke`.
Utilise les serveurs MCP `github` et `postgres` déclarés par ce plugin pour vérifier
respectivement la conformité de la PR et la santé de la base de recette.
Publier et installer
Nadia commite kiosque-tools/ dans le dépôt gitlab.kiosque.example/dev/plugins-interne, avec un .claude-plugin/marketplace.json à la racine qui recense les plugins de l'équipe. Chaque développeur ajoute la marketplace une seule fois :
/plugin marketplace add https://gitlab.kiosque.example/dev/plugins-interne.git
/plugin install kiosque-tools@plugins-interne
Karim voit un résumé d'installation, choisit le scope User (il veut le plugin dans tous ses projets Kiosque). Si le message dit Run /reload-plugins to activate., il tape la commande. Depuis la session courante, /kiosque-tools:deploy, @"kiosque-tools:revieweur (agent)" et les hooks fonctionnent.
Un mois plus tard, l'équipe pousse la 1.1.0 avec un nouveau sous-agent. Nadia bumpe version, tague, pousse. Les collègues récupèrent la mise à jour à la prochaine session, ou immédiatement via /plugin marketplace update plugins-interne puis /reload-plugins.
Un plugin d'équipe idéal est agnostique du projet : ce qui fonctionne partout va dans le plugin, ce qui varie par dépôt reste dans le .claude/ du dépôt. Cette séparation évite l'anti-pattern « le plugin qui sait tout de Kiosque et ne marche nulle part ailleurs ».
En résumé
- Un plugin empaquette skills, sous-agents, workflows, hooks, serveurs MCP et LSP, monitors, thèmes et exécutables sous un namespace unique.
- Structure :
.claude-plugin/plugin.jsonpour le manifeste ; tout le reste à la racine du plugin, jamais dans.claude-plugin/. - Manifeste minimal :
name(kebab-case, sert de namespace). Champs utiles :displayName,version,description,defaultEnabled,dependencies. - Variables :
${CLAUDE_PLUGIN_ROOT}(installation),${CLAUDE_PLUGIN_DATA}(persistant),${CLAUDE_PROJECT_DIR}(projet). - Développement :
claude plugin init,--plugin-dirpour tester,/reload-pluginspour appliquer les changements,claude plugin validate --stricten CI. - Marketplaces : officielles (
claude-plugins-official,claude-community) ; sources personnalisées via/plugin marketplace add(GitHub, URL Git, chemin local,marketplace.jsondistant). - Installation :
/plugin install <plugin>@<marketplace>avec choix de scope User / Project / Local./pluginouvre le gestionnaire complet. - Pour Kiosque, un plugin
kiosque-toolsregroupe hooks portables, sous-agentsrevieweurettesteur, serveurs MCP GitHub et Postgres, et une skilldeploy— versionné dans une marketplace privée d'équipe.
Module suivant : Flux de travail quotidiens : explorer, corriger, tester, revoir, livrer — comment enchaîner tous ces outils dans une journée d'ingénierie type.