Marketplace d'equipe
Publier tes plugins sur un depot Git pour que ton equipe les installe en une commande, avec des versions maitrisees et une gouvernance claire.
Temps de lecture : 12 min | Niveau : Avance
Ce que tu sauras faire apres
- Ecrire un fichier
marketplace.jsonvalide avec ses champs obligatoires. - Choisir la bonne source pour chaque plugin du catalogue.
- Heberger la marketplace sur un depot Git, public ou prive.
- Publier une nouvelle version sans casser les installations existantes.
- Renommer ou retirer un plugin sans perdre tes utilisateurs.
1. Ce qu'est une marketplace
Une marketplace est un dossier ou un depot qui contient un fichier .claude-plugin/marketplace.json. Ce fichier liste tes plugins et dit ou aller chercher chacun.
C'est un catalogue, pas une boutique hebergee. Le catalogue peut vivre dans un depot prive, il peut lister autant de plugins que tu veux, et un administrateur peut l'imposer sur toutes les machines.
marketplace-equipe/
├── .claude-plugin/
│ └── marketplace.json
└── plugins/
├── boite-a-outils-data/
│ └── .claude-plugin/plugin.json
└── conventions-sql/
└── .claude-plugin/plugin.jsonLa racine de la marketplace est le dossier qui contient .claude-plugin/. Ici, c'est marketplace-equipe/. Retiens-le : tous les chemins relatifs des entrees partent de la.
2. Le fichier marketplace.json
La forme minimale
{
"name": "marketplace-equipe",
"description": "Plugins Claude Code de l'equipe data",
"owner": {
"name": "Equipe Data"
},
"plugins": [
{
"name": "boite-a-outils-data",
"source": "./plugins/boite-a-outils-data",
"description": "Revue SQL, documentation dbt, audit de pipeline"
}
]
}Trois champs sont obligatoires : name, owner et plugins.
Les champs de premier niveau
| Champ | Type | Role |
|---|---|---|
name | string | Identifiant de la marketplace. Pas d'espaces, pas de / ni de \, pas de .., et pas . tout court. C'est ce que les gens tapent apres @ |
owner | object | Mainteneur. name obligatoire, email et url optionnels |
plugins | array | Les entrees de plugins. Chaque entree est validee separement, donc une entree invalide ne casse pas tout le catalogue |
description | string | Description montree aux utilisateurs. claude plugin validate avertit si elle manque |
version | string | Version du manifeste de marketplace |
metadata.pluginRoot | string | Dossier sous lequel les noms nus de plugins se resolvent. Demande Claude Code v2.1.239 ou plus recent |
renames | object | Ancien nom de plugin vers son nom actuel, ou null si retire. Demande Claude Code v2.1.193 ou plus recent |
forceRemoveDeletedPlugins | boolean | Si true, un plugin retire de plugins est desinstalle chez les utilisateurs |
allowCrossMarketplaceDependenciesOn | array de strings | Marketplaces dont les plugins peuvent etre installes comme dependances |
Les champs d'une entree de plugin
name et source sont obligatoires. Une entree accepte en plus tous les champs de plugin.json.
| Champ | Role |
|---|---|
name | Identifiant que les gens tapent avant @ pour installer |
source | Ou Claude Code va chercher le plugin |
description | La ligne affichee a cote du plugin dans /plugin |
version | Version du plugin. Si plugin.json la fixe aussi, plugin.json gagne et la validation avertit |
category | Categorie libre pour ranger le catalogue |
tags | Etiquettes libres pour la recherche |
displayName | Nom lisible affiche dans l'interface |
defaultEnabled | Si le plugin demarre actif. La valeur de l'entree l'emporte sur plugin.json |
dependencies | Plugins qui doivent etre actifs |
strict | Defaut true. Decide ce qui se passe si l'entree declare des composants (commands, agents, skills, hooks, outputStyles, themes) alors que le plugin a deja son plugin.json. Avec true, les composants de l'entree s'ajoutent au manifeste. Avec false, c'est un conflit et le plugin ne se charge pas. Le plus simple : ne declare aucun composant dans l'entree |
3. Choisir la source de chaque plugin
| Type | Quand l'utiliser | Valeur minimale |
|---|---|---|
| Chemin relatif | Les fichiers du plugin sont dans le dossier de la marketplace | "./plugins/boite-a-outils-data" |
github | Le plugin est un depot GitHub a lui seul | { "source": "github", "repo": "mon-org/boite-a-outils-data" } |
git-subdir | Le plugin est un sous-dossier d'un autre depot, par exemple un monorepo | { "source": "git-subdir", "url": "mon-org/monorepo", "path": "tools/boite-a-outils-data" }. Ici url accepte une URL git complete ou le raccourci GitHub owner/repo |
url | Un depot Git par URL, sur n'importe quel hote | { "source": "url", "url": "https://gitlab.example.com/data/plugin.git" } |
archive | Un zip telecharge en HTTPS. Utile pour les collegues qui n'ont pas de compte sur ton hote Git. Demande Claude Code v2.1.224 ou plus recent | { "source": "archive", "url": "https://...zip", "sha256": "..." } |
npm | Un paquet npm | { "source": "npm", "package": "...", "version": "..." } |
command | Un dossier produit par une commande lancee sur la machine de l'utilisateur. Chaque utilisateur doit accepter la commande avant qu'elle ne tourne. Demande Claude Code v2.1.229 ou plus recent | { "source": "command", "command": "..." } |
Les sources github, url et git-subdir partagent deux champs d'epinglage :
ref: une branche ou un tag. Par defaut, la branche par defaut du depot.sha: un SHA de commit complet, 40 caracteres minuscules. Si tu metsrefetsha, Claude Code sort lesha.
{
"name": "boite-a-outils-data",
"source": {
"source": "github",
"repo": "mon-org/boite-a-outils-data",
"ref": "v2.0.0",
"sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
}
}Deux regles qui cassent la plupart des premiers essais
Regle 1 — Les chemins relatifs partent de la racine de la marketplace. ./plugins/boite-a-outils-data designe <racine>/plugins/boite-a-outils-data, meme si le fichier marketplace.json est dans <racine>/.claude-plugin/. N'utilise pas .. pour sortir : claude plugin validate refuse avec un message commencant par Path contains "..".
Regle 2 — Le nom d'entree et le nom du manifeste doivent etre identiques. Un plugin de marketplace a deux noms : le name de son entree dans marketplace.json, et le name de son propre plugin.json.
| Nom | Ou il sert |
|---|---|
| Nom d'entree | L'identifiant d'installation <entree>@<marketplace>, ce qu'affiche claude plugin list, la cle ecrite dans enabledPlugins |
| Nom du manifeste | Le prefixe des skills du plugin, et le nom que prend claude plugin details |
Quand les deux different et que quelqu'un installe par le nom du manifeste, Claude Code repond Plugin "<manifest-name>" not found in marketplace "<marketplace>".
Le piege de la marketplace servie par URL
Si tes utilisateurs ajoutent ta marketplace comme une simple URL de marketplace.json, Claude Code ne telecharge que ce fichier. Une entree dont la source est un chemin relatif echoue alors a l'installation, avec un message qui contient its marketplace entry path does not stay inside the marketplace directory.
Donne dans ce cas a chaque entree une source autonome, github ou archive, ou heberge la marketplace dans un depot Git pour que Claude Code clone tout l'arbre.
4. La boucle complete, du local au depot 🔁
Etape 1 — Construire en local
mkdir -p marketplace-equipe/.claude-plugin marketplace-equipe/plugins
cp -r boite-a-outils-data marketplace-equipe/plugins/
claude plugin validate ./marketplace-equipe/plugins/boite-a-outils-dataCette derniere commande verifie que le plugin est valide la ou il est maintenant, pour qu'une erreur suivante parle bien de la marketplace et pas du plugin.
Etape 2 — Ecrire et valider le catalogue
Ecris marketplace-equipe/.claude-plugin/marketplace.json, puis :
claude plugin validate ./marketplace-equipeLa derniere ligne doit afficher ✔ Validation passed.
Ce que la validation attrape :
- Les erreurs de syntaxe JSON.
- Les champs obligatoires manquants, par exemple
owner: Invalid input. - Un nom de marketplace avec des espaces, ou qui imite une marketplace officielle Anthropic.
- Une
sourcerelative contenant... - Les champs inconnus, signales en avertissements.
Ce qu'elle n'attrape pas, et qui te tombe dessus plus tard :
- Un
repoou unpathfaux dans une source distante. L'erreur sort a l'installation. - Un chemin relatif vers un dossier inexistant. La validation passe, puis l'installation echoue avec
Source path does not exist: <chemin>.
Etape 3 — Enregistrer et installer chez toi
claude plugin marketplace add ./marketplace-equipe
claude plugin install boite-a-outils-data@marketplace-equipe
claude plugin list
claude plugin details boite-a-outils-dataLa premiere commande affiche ✔ Successfully added marketplace: marketplace-equipe (declared in user settings).
L'identifiant d'installation est le name de l'entree, un @, et le name de la marketplace.
Etape 4 — Pousser sur Git
Une fois que l'installation locale fonctionne, pousse le dossier de la marketplace sur ton hote Git. C'est tout : la publication n'a pas de formulaire.
Etape 5 — Ce que tes collegues tapent
| Hote | La commande a leur donner |
|---|---|
| GitHub | /plugin marketplace add mon-org/marketplace-equipe |
| GitLab, Bitbucket, GitHub Enterprise Server | /plugin marketplace add https://gitlab.example.com/data/marketplace-equipe.git |
marketplace.json heberge | /plugin marketplace add https://plugins.example.com/marketplace.json |
| Dossier sur un partage reseau | /plugin marketplace add /Volumes/partage/claude-plugins |
Puis l'installation :
claude plugin install boite-a-outils-data@marketplace-equipeOu en une seule commande dans une session, a partir de Claude Code v2.1.275 :
/plugin install boite-a-outils-data --marketplace mon-org/marketplace-equipeEnvoie toujours l'URL complete pour un hote autre que GitHub. Le raccourci
owner/reposignifie toujours github.com.
Etape 6 — Enregistrer la marketplace pour tout un depot
Pour que chaque personne qui travaille sur un depot ait la marketplace automatiquement, lance une fois depuis la racine du depot :
claude plugin marketplace add mon-org/marketplace-equipe --scope projectPuis commite le .claude/settings.json que la commande a ecrit. Claude Code enregistre alors la marketplace pour chaque collegue qui a accepte la boite de dialogue de confiance du dossier.
5. Versionner ⚙️
C'est le point ou les equipes se plantent le plus souvent.
Un utilisateur recoit une nouvelle copie d'un plugin uniquement quand la version calculee change. Cette version vient d'abord de plugin.json, puis de l'entree de la marketplace.
Tu as donc deux strategies, et une seule a choisir :
| Strategie | Ce que tu fais | Consequence |
|---|---|---|
| Versionner | Incremente version dans plugin.json a chaque publication | Les utilisateurs restent sur leur copie en cache tant que la chaine ne change pas |
| Suivre les commits | Omets version dans plugin.json et dans l'entree | La version devient le SHA du commit ; chaque commit est une nouvelle version. Pour les sources github, url et git-subdir, ce SHA est raccourci a 12 caracteres. Pour une entree en chemin relatif dans une marketplace hebergee sur Git, c'est le SHA du commit du dossier installe. Si ni le plugin ni la marketplace ne sont dans un depot Git, la version vaut unknown |
Erreur classique : fixer
"version": "1.0.0"puis pousser vingt commits sans y toucher. Tes collegues ne recoivent rien, etclaude plugin updateleur repond<name> is already at the latest version (1.0.0).
Ne mets pas version aux deux endroits. Si tu le fais, Claude Code utilise la valeur de plugin.json sans prevenir, et claude plugin validate signale l'ecart avec Entry declares version "<a>" but <path>/plugin.json says "<b>".
Cas particulier : la marketplace en dossier local
Un plugin charge sur place depuis une marketplace ajoutee comme dossier local n'est pas controle par version. Il charge tes fichiers courants a chaque demarrage de session, quoi que dise sa chaine de version. C'est pratique en developpement, trompeur en production.
Tenir les utilisateurs sur une version
Une marketplace sert une seule version de chaque plugin a la fois. Tu figes donc par ce que pointe l'entree :
refetshasur l'entree du plugin, pour une sourcegithub,urlougit-subdir.#<ref>sur la commande d'ajout :mon-org/marketplace-equipe#stabledonne cette branche ou ce tag du catalogue.
Canaux de publication
Claude Code n'a pas de notion de canal de publication. Pour offrir une voie stable et une voie anticipee, heberge deux marketplaces dont les entrees pointent vers des ref differents du meme plugin, et donne a chacun celle qu'il veut.
{
"name": "data-stable",
"owner": { "name": "Equipe Data" },
"plugins": [
{ "name": "boite-a-outils-data", "source": { "source": "github", "repo": "mon-org/boite-a-outils-data", "ref": "stable" } }
]
}Le second catalogue est identique, avec "name": "data-latest" et "ref": "latest". Les deux name doivent differer : Claude Code identifie une marketplace par son nom, donc un utilisateur ne peut pas en avoir deux du meme nom enregistrees. Donne aussi aux deux ref des versions differentes, ou omets version partout pour que le SHA les distingue.
6. Renommer et retirer sans casser 🧹
Le name d'un plugin est son identifiant. Les utilisateurs le referencent dans enabledPlugins, donc le changer casse toutes les installations existantes.
Pour changer seulement l'etiquette affichee, mets displayName dans plugin.json et laisse name tranquille.
Si le renommage est inevitable : la carte renames
Ajoute une cle renames au premier niveau de marketplace.json. Elle associe chaque ancien nom a son nom actuel, ou a null quand le plugin a disparu.
{
"name": "marketplace-equipe",
"owner": { "name": "Equipe Data" },
"plugins": [
{ "name": "boite-a-outils-data", "source": "./plugins/boite-a-outils-data" }
],
"renames": {
"outils-data": "boite-a-outils-data",
"vieux-linter-sql": null
}
}Ce que voit l'utilisateur apres ton push :
- Entree renommee : le plugin se charge sous son nouveau nom. Claude Code reecrit l'ancienne cle en nouvelle dans
enabledPluginsetpluginConfigs, aux scopes user, project et local. Le messageRenamed to "<nouveau-nom>" in the "marketplace-equipe" marketplaces'affiche une fois. - Entree a
null: la cle est retiree de ces memes scopes, avec le messageRemoved from the "marketplace-equipe" marketplace. - Plugin active par des managed settings : il se charge bien sous son nouveau nom, mais Claude Code ne peut pas reecrire les managed settings. L'avis revient a chaque session tant qu'un administrateur n'a pas corrige
enabledPluginsla-bas.
Un cas pratique a connaitre : pour une marketplace ajoutee depuis un depot Git ou une URL, un plugin renomme affiche Plugin "<nom>" not cached at <chemin> tant que l'utilisateur n'a pas lance une fois /plugin install <nouveau-nom>@marketplace-equipe dans une session. Previens tes collegues.
Cette migration automatique demande Claude Code v2.1.193 ou plus recent.
Traite renames comme un historique en ajout seul. Garde les anciennes entrees meme apres la migration de tout le monde. Quand tu renommes une seconde fois, ajoute une deuxieme entree au lieu de modifier la premiere : Claude Code suit la chaine depuis le nom le plus ancien.
Apres chaque edition de la carte, lance claude plugin validate . : la commande refuse une chaine qui boucle ou qui n'aboutit ni a null ni a un nom present dans plugins.
Desinstaller vraiment un plugin retire
Sans champ dedie, un plugin retire du catalogue reste installe chez tes utilisateurs et signale Plugin "<name>" not found in marketplace. Pour qu'il soit desinstalle, ajoute "forceRemoveDeletedPlugins": true au premier niveau du catalogue.
A chaque demarrage de session, Claude Code compare alors ce que l'utilisateur a installe depuis ta marketplace avec les entrees et la carte renames, desinstalle ce qui n'est ni liste ni renomme aux scopes user, project et local, et affiche les plugins concernes sous un en-tete Flagged dans /plugin, avec le statut Removed from marketplace.
Une exception : un plugin installe uniquement par des managed settings d'entreprise reste en place.
7. Gouvernance 🏛️
Marketplace privee : ce que chaque personne doit avoir
Claude Code n'a aucun jeton Git a lui, et marketplace.json n'a aucun champ pour en porter un. Il lance git sur la machine de l'utilisateur avec les invites desactivees et se repose sur les identifiants deja presents.
| Protocole | Ce que la machine doit avoir |
|---|---|
| SSH | Une cle qui fonctionne sans demande de passphrase, par exemple chargee dans ssh-agent. L'hote deja present dans known_hosts |
| HTTPS | Un identifiant deja stocke par le credential helper. Sur GitHub : gh auth login puis gh auth setup-git |
Raccourci GitHub owner/repo | Claude Code teste la cle SSH, puis clone en SSH si ca marche, en HTTPS sinon. CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1 force HTTPS |
Imposer la marketplace a toute une entreprise
Un administrateur passe par les managed settings, les reglages qu'aucun utilisateur ne peut surcharger. Deux cles vont ensemble : extraKnownMarketplaces enregistre la marketplace sur chaque machine, et enabledPlugins nomme les plugins a installer et activer.
{
"extraKnownMarketplaces": {
"marketplace-equipe": {
"source": { "source": "github", "repo": "mon-org/marketplace-equipe" },
"autoUpdate": true
}
},
"enabledPlugins": {
"boite-a-outils-data@marketplace-equipe": true,
"conventions-sql@marketplace-equipe": true
}
}Une fois les reglages arrives sur une machine, Claude Code enregistre la marketplace et installe les deux plugins au demarrage de la session suivante. Desactiver l'un d'eux a son propre scope ne l'empeche pas de se charger : les managed settings l'emportent sur tous les autres scopes. Pour bloquer un plugin partout, mets-le a false dans le enabledPlugins managed.
Restreindre ce que les gens peuvent installer
| Cle | Ce qu'elle fait |
|---|---|
strictKnownMarketplaces | Liste blanche de sources de marketplaces. [] bloque tout, y compris la marketplace officielle. Alias : allowedMarketplaces |
blockedMarketplaces | Liste noire de sources, verifiee avant la liste blanche |
disableSideloadFlags | Rejette --plugin-dir, --plugin-url et la variable CLAUDE_CODE_PLUGIN_DIRS au demarrage |
pluginTrustMessage | Ajoute ton texte a l'avertissement de confiance affiche par /plugin avant une installation |
Exemple typique, qui autorise la marketplace officielle et la tienne, enregistre les deux, active un plugin et refuse le chargement par drapeau :
{
"strictKnownMarketplaces": [
{ "source": "github", "repo": "anthropics/claude-plugins-official" },
{ "source": "github", "repo": "mon-org/*" },
{ "source": "skills-dir" }
],
"extraKnownMarketplaces": {
"claude-plugins-official": {
"source": { "source": "github", "repo": "anthropics/claude-plugins-official" }
},
"marketplace-equipe": {
"source": { "source": "github", "repo": "mon-org/marketplace-equipe" }
}
},
"enabledPlugins": {
"boite-a-outils-data@marketplace-equipe": true
},
"disableSideloadFlags": true
}L'entree { "source": "skills-dir" } est importante : sans elle, des qu'une liste blanche est posee, les plugins ranges dans ~/.claude/skills/ cessent de se charger.
Ce qu'une marketplace ne peut pas faire
A savoir avant de le chercher pendant une heure :
- Activer l'auto-update pour tes utilisateurs : aucun champ de
marketplace.jsonne le fait. Chaque utilisateur l'active dans/plugin, onglet Marketplaces, ou un administrateur poseautoUpdatedans les managed settings. - Installer un plugin sans que l'utilisateur le demande : aucun champ d'entree ne le fait. Seul
enabledPluginsen managed settings le fait pour un parc. - Montrer des entrees differentes a des utilisateurs differents : les entrees n'ont pas de champ d'audience. Heberge des marketplaces separees.
- Marquer un plugin comme deprecie : il n'y a pas d'etat de depreciation. Retire l'entree, mappe son nom vers
nulldansrenames, et pose eventuellementforceRemoveDeletedPlugins. - Porter des identifiants Git : aucun champ ne porte de jeton. Seule exception, une source
archivetelechargee en HTTPS : son entree peut porter desheaders, ou unheadersHelperqui genere le jeton a la demande.
8. Template a copier-coller 📋
Prompt pour faire generer et verifier ton catalogue.
Contexte : je suis [DEV / DATA ENGINEER / DATA ANALYST] dans une equipe de [NOMBRE] personnes.
Je veux publier une marketplace de plugins Claude Code pour mon equipe.
Informations :
- nom de la marketplace (kebab-case, sans espace) : [NOM_MARKETPLACE]
- proprietaire : [NOM_PROPRIETAIRE] / [EMAIL_OPTIONNEL]
- hebergement : [GITHUB mon-org/le-depot | GITLAB https://... | DOSSIER PARTAGE /chemin]
- depot prive ? [OUI / NON]
- plugins a lister :
1. [NOM_PLUGIN_1] — ou sont ses fichiers : [DANS LA MARKETPLACE sous ./plugins/... | DEPOT GITHUB mon-org/... | SOUS-DOSSIER DE MONOREPO ...]
2. [NOM_PLUGIN_2] — ...
- strategie de version : [JE VERSIONNE avec plugin.json | JE SUIS LES COMMITS sans champ version]
Produis exactement :
1. Le fichier .claude-plugin/marketplace.json complet, avec uniquement des champs reels.
Choisis le bon type de source pour chaque plugin et justifie ton choix en une ligne.
2. Les commandes shell exactes pour valider, enregistrer en local et installer, dans l'ordre.
3. Le message a envoyer a mes collegues : la commande d'ajout de marketplace
et la commande d'installation, plus ce qu'ils doivent avoir sur leur machine
si le depot est prive.
4. Un rappel de la regle de version qui s'applique a ma strategie, en deux phrases.
Contraintes : ne mets jamais version a la fois dans plugin.json et dans l'entree.
Garde le nom d'entree identique au nom du manifeste de chaque plugin.
Les chemins relatifs partent de la racine de la marketplace, jamais de .claude-plugin/.
Reponds en francais.A retenir
- Une marketplace est un dossier avec
.claude-plugin/marketplace.json;name,owneretpluginssont obligatoires. - Les chemins relatifs des entrees partent de la racine de la marketplace, pas de
.claude-plugin/, et..est refuse. - Garde le
namede l'entree identique aunameduplugin.json, sinon l'installation par le nom du manifeste echoue. - Choisis une strategie de version : incrementer
versiona chaque publication, ou l'omettre partout pour suivre les commits. Jamais les deux endroits a la fois. - Pour renommer ou retirer un plugin, passe par la carte
renameset traite-la comme un historique en ajout seul. - L'auto-update est desactive par defaut pour ta marketplace ; seul un utilisateur ou un administrateur l'active.
- Une marketplace privee ne porte aucun identifiant : chaque machine doit deja avoir ses credentials Git en place.
Sources
- Create a marketplace — Claude Code
- Host and maintain a marketplace — Claude Code
- Marketplace reference — Claude Code
- Publish and distribute a plugin — Claude Code
- Manage Claude Code plugins for your organization
- Plugin loading reference — Claude Code
- anthropics/claude-plugins-official - code d'exemple sur le fichier
marketplace.json:.claude-plugin/marketplace.json, avec les sourcesgit-subdirepinglees parrefetshaet la carterenames - wshobson/agents - code d'exemple sur le versionnage d'un catalogue :
.claude-plugin/marketplace.json, plus de 90 entrees avecversion,licenseetcategory - ivan-magda/claude-code-plugin-template - code d'exemple sur la CI d'une marketplace d'equipe :
.github/workflows/validate-plugins.yml