écrits/tutorial/2026/07
Tutorial8 juil. 2026·24 min

Plugins Claude Code : créez, testez et publiez votre propre marketplace de plugins

Apprenez à construire un plugin Claude Code complet avec commandes slash, sous-agents, skills, hooks et serveurs MCP — puis distribuez-le à toute votre équipe via une marketplace de plugins hébergée sur Git.

Claude Code s'est discrètement imposé comme l'agent de codage IA standard dans de nombreuses équipes d'ingénierie, et en 2026, les équipes les plus efficaces ne le configurent plus développeur par développeur. Elles empaquettent leurs commandes slash, sous-agents, skills, hooks et serveurs MCP dans des plugins, les publient sur une marketplace de plugins hébergée dans un simple dépôt Git, et les déploient pour tout le monde avec une seule entrée de configuration.

Dans ce tutoriel, vous allez construire de zéro un plugin de qualité production nommé team-toolkit, le tester localement, le publier sur GitHub sous forme de marketplace, puis l'activer automatiquement pour une équipe entière. À la fin, vous comprendrez chaque fichier du format de plugin et saurez exactement comment les pièces s'assemblent.

Prérequis

Avant de commencer, assurez-vous d'avoir :

  • Claude Code installé et authentifié (exécutez claude --version pour vérifier ; toute version 2.x prend en charge les plugins)
  • Node.js 20 ou plus récent
  • Un compte GitHub (ou tout hébergeur Git que votre équipe peut cloner)
  • Une familiarité de base avec les concepts de Claude Code comme les commandes slash et CLAUDE.md

Aucune expérience préalable des plugins n'est requise.

Ce que vous allez construire

Vous allez créer un plugin nommé team-toolkit qui regroupe cinq capacités :

  1. Une commande slash /team-toolkit:changelog qui rédige une entrée de changelog à partir des commits récents
  2. Un sous-agent code-auditor qui vérifie le code selon les conventions de votre équipe
  3. Un skill conventional-commits que Claude charge automatiquement lors de la rédaction de messages de commit
  4. Un hook qui exécute votre formateur après chaque modification de fichier
  5. Une configuration de serveur MCP embarquée pour accéder à un dossier de documentation partagé

Vous créerez ensuite un second dépôt qui servira de marketplace, afin que n'importe quel membre de votre équipe puisse installer le plugin en une seule commande.

Étape 1 : comprendre l'anatomie d'un plugin

Un plugin Claude Code n'est qu'un répertoire avec un manifeste. Chaque composant est optionnel — un plugin peut n'embarquer qu'un hook, que des commandes, ou tout à la fois. La structure complète ressemble à ceci :

team-toolkit/
├── .claude-plugin/
│   └── plugin.json        # Manifeste (obligatoire)
├── commands/              # Commandes slash (fichiers Markdown)
│   └── changelog.md
├── agents/                # Sous-agents (fichiers Markdown)
│   └── code-auditor.md
├── skills/                # Skills (dossiers avec SKILL.md)
│   └── conventional-commits/
│       └── SKILL.md
├── hooks/
│   └── hooks.json         # Gestionnaires d'événements
├── scripts/               # Scripts utilisés par les hooks
│   └── format.sh
└── .mcp.json              # Serveurs MCP embarqués

Deux règles comptent plus que tout le reste :

  • Le manifeste se trouve dans .claude-plugin/plugin.json — à l'intérieur du répertoire caché, pas à la racine du dépôt.
  • Les répertoires de composants (commands/, agents/, skills/, hooks/) se trouvent à la racine du plugin, pas dans .claude-plugin/.

Confondre ces deux règles est la cause la plus fréquente d'un plugin qui se charge mais dont les commandes n'apparaissent jamais.

Étape 2 : créer la structure et le manifeste

Créez l'arborescence et le manifeste :

mkdir -p team-toolkit/.claude-plugin
mkdir -p team-toolkit/commands team-toolkit/agents
mkdir -p team-toolkit/skills/conventional-commits
mkdir -p team-toolkit/hooks team-toolkit/scripts
cd team-toolkit

Créez maintenant .claude-plugin/plugin.json :

{
  "name": "team-toolkit",
  "description": "Noqta engineering conventions: changelog command, code auditor, commit skill, format-on-edit hook",
  "version": "1.0.0",
  "author": {
    "name": "Noqta Engineering",
    "email": "dev@noqta.tn"
  },
  "keywords": ["conventions", "review", "changelog"]
}

Seul name est strictement obligatoire, mais description et version apparaissent dans l'interface du gestionnaire de plugins : traitez-les donc comme obligatoires en pratique. Le name doit être en kebab-case sans espaces — il devient le préfixe d'espace de noms de chaque commande fournie par le plugin.

Étape 3 : ajouter une commande slash

Les commandes slash d'un plugin sont des fichiers Markdown dans commands/. Le nom du fichier devient le nom de la commande, préfixé par le plugin : commands/changelog.md devient /team-toolkit:changelog. Ce préfixage garantit que les commandes de votre plugin n'entrent jamais en collision avec celles d'un autre.

Créez commands/changelog.md :

---
description: Draft a changelog entry from recent commits
argument-hint: [version] [since-tag]
allowed-tools: Bash(git log:*), Bash(git diff:*), Read
---
 
Draft a changelog entry for version $1.
 
1. Run `git log --oneline $2..HEAD` to list commits since tag $2.
   If no tag argument was given, use the most recent tag.
2. Group the commits into Added, Changed, Fixed, and Removed sections
   following the Keep a Changelog format.
3. Rewrite each line as a user-facing sentence — drop internal refactor
   noise unless it affects behavior.
4. Output the entry as Markdown ready to paste into CHANGELOG.md.
   Do not modify any files.

Trois détails méritent attention :

  • argument-hint est ce que voient les utilisateurs lors de l'autocomplétion de la commande.
  • $1 et $2 reçoivent les arguments positionnels ; $ARGUMENTS recevrait la chaîne d'arguments entière.
  • allowed-tools pré-approuve des motifs d'outils spécifiques pour que la commande s'exécute sans demandes de permission — restreignez-le autant que possible.

Étape 4 : ajouter un sous-agent

Les sous-agents sont des assistants spécialisés dotés de leur propre prompt système, de restrictions d'outils et d'une fenêtre de contexte indépendante. Claude leur délègue automatiquement quand une tâche correspond à leur description, ou vous pouvez les invoquer explicitement.

Créez agents/code-auditor.md :

---
name: code-auditor
description: Reviews code changes against Noqta engineering conventions. Use proactively after significant edits or before committing.
tools: Read, Grep, Glob, Bash
model: inherit
---
 
You are a strict but pragmatic code auditor for a TypeScript/Next.js team.
 
When invoked:
1. Run `git diff HEAD` to see pending changes.
2. Check every changed file against these conventions:
   - No console.log in production code (a logger must be used)
   - No empty catch blocks
   - Files stay under 300 lines
   - Repeated logic is extracted into shared utilities
3. Report findings ordered by severity. For each finding include
   the file path, line number, and a concrete suggested fix.
4. If everything passes, say so explicitly and list what you checked.
 
Never modify files yourself. You are read-only by convention.

Le champ description est ce que Claude lit pour décider de déléguer — des formules comme « use proactively » influencent réellement le comportement de délégation. Définir model: inherit maintient le sous-agent sur le même modèle que la conversation principale ; vous pouvez aussi épingler un modèle spécifique comme haiku pour les vérifications mécaniques peu coûteuses.

Étape 5 : ajouter un skill

Les skills diffèrent des commandes sur un point fondamental : les commandes sont invoquées par l'utilisateur, les skills sont chargés par Claude lui-même quand la tâche correspond. Un skill est un dossier contenant un SKILL.md dont le frontmatter indique à Claude quand le charger.

Créez skills/conventional-commits/SKILL.md :

---
name: conventional-commits
description: Format git commit messages using the team's conventional commit standard. Use whenever writing, amending, or reviewing a commit message.
---
 
# Conventional Commits — Team Standard
 
## Format
 
    type(scope): subject
 
    body (optional)
 
    footer (optional)
 
## Types
 
feat, fix, docs, style, refactor, test, chore
 
## Rules
 
1. Subject in imperative mood, lowercase, no trailing period
2. Scope is the affected module: auth, api, ui, content, build
3. One logical change per commit — never batch unrelated edits
4. Reference issues in the footer: "Refs #123" or "Closes #123"
5. Body explains the why for any non-obvious change
 
## Examples
 
    feat(auth): add password reset flow
 
    fix(api): handle null values in user profile endpoint
 
    The endpoint returned 500 when optional fields were null.
    Added null checks with sensible defaults.
 
    Closes #456

Comme le skill est livré dans le plugin, chaque développeur qui installe team-toolkit obtient des conventions de commit identiques appliquées automatiquement — fini le copier-coller de directives dans le CLAUDE.md de chaque projet.

Étape 6 : ajouter un hook

Les hooks exécutent des commandes shell lors d'événements du cycle de vie — une automatisation déterministe qui ne dépend pas d'une décision du modèle. Nous allons formater les fichiers après chaque modification.

Créez hooks/hooks.json :

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh"
          }
        ]
      }
    ]
  }
}

Et le script dans scripts/format.sh :

#!/usr/bin/env bash
# Reads the hook payload from stdin, formats the edited file if supported.
set -euo pipefail
 
payload=$(cat)
file_path=$(echo "$payload" | jq -r '.tool_input.file_path // empty')
 
if [[ -z "$file_path" ]]; then
  exit 0
fi
 
case "$file_path" in
  *.ts|*.tsx|*.js|*.jsx|*.json|*.css|*.md)
    if command -v prettier >/dev/null 2>&1; then
      prettier --write "$file_path" >/dev/null 2>&1 || true
    fi
    ;;
esac
 
exit 0

Rendez-le exécutable :

chmod +x scripts/format.sh

Le détail crucial est ${CLAUDE_PLUGIN_ROOT} — une variable d'environnement qui pointe vers l'emplacement d'installation du plugin à l'exécution. Ne codez jamais de chemins en dur dans les hooks d'un plugin ; le plugin sera installé à un endroit que vous ne contrôlez pas sur la machine de chaque utilisateur. Parmi les événements utiles au-delà de PostToolUse : PreToolUse (bloquer des actions avant leur exécution), UserPromptSubmit (injecter du contexte à chaque prompt), SessionStart et Stop.

Étape 7 : embarquer un serveur MCP

Les plugins peuvent livrer des configurations de serveurs MCP qui s'activent quand le plugin est activé. Créez .mcp.json à la racine du plugin :

{
  "mcpServers": {
    "team-docs": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "${CLAUDE_PLUGIN_ROOT}/docs"
      ]
    }
  }
}

Cet exemple expose un dossier docs/ livré dans le plugin lui-même — pratique pour les architecture decision records ou les références d'API que toute l'équipe devrait pouvoir interroger. En déploiement réel, vous pointerez plus souvent vers un serveur MCP interne (passerelle de base de données, gestionnaire de tickets, API d'observabilité). La même règle s'applique : utilisez ${CLAUDE_PLUGIN_ROOT} pour tout chemin relatif, et des variables d'environnement pour les secrets — ne codez jamais d'identifiants en dur dans .mcp.json.

Créez un fichier de départ pour que le dossier existe :

mkdir -p docs
echo "# Team Engineering Docs" > docs/README.md

Étape 8 : tester le plugin localement

Avant de publier quoi que ce soit, validez la structure. Claude Code embarque un validateur :

claude plugin validate .

Corrigez toute erreur de manifeste ou de schéma signalée. Testez ensuite le comportement réel avec une marketplace locale. Le schéma le plus propre consiste à garder les plugins dans un dépôt de marketplace dès le premier jour, alors mettez cela en place maintenant :

cd ..
mkdir -p noqta-claude-plugins/.claude-plugin
mv team-toolkit noqta-claude-plugins/plugins/team-toolkit

Attendez avant de créer le manifeste de la marketplace — c'est l'étape 9. Pour un test local rapide, vous pouvez ajouter directement le répertoire de la marketplace :

claude
# puis dans la session :
/plugin marketplace add ./noqta-claude-plugins
/plugin install team-toolkit@noqta-claude-plugins

Redémarrez la session quand on vous le demande, puis vérifiez chaque composant :

  1. Tapez /team-toolkit:changelog 1.2.0 — la commande doit apparaître dans l'autocomplétion et s'exécuter.
  2. Demandez « vérifie mes modifications en attente pour des violations de conventions » — Claude doit déléguer à code-auditor.
  3. Demandez à Claude de committer quelque chose — le skill conventional-commits doit façonner le message.
  4. Modifiez n'importe quel fichier TypeScript — Prettier doit s'exécuter automatiquement via le hook.
  5. Exécutez /mcp — le serveur team-docs doit être listé et connecté.

Si un composant n'apparaît pas, lancez claude --debug et observez la sortie de chargement des plugins au démarrage ; elle nomme chaque manifeste analysé et toute erreur rencontrée.

Étape 9 : créer la marketplace et publier

Une marketplace est n'importe quel dépôt Git contenant .claude-plugin/marketplace.json. Créez noqta-claude-plugins/.claude-plugin/marketplace.json :

{
  "name": "noqta-claude-plugins",
  "owner": {
    "name": "Noqta Engineering",
    "email": "dev@noqta.tn"
  },
  "metadata": {
    "description": "Internal Claude Code plugins for the Noqta team",
    "version": "1.0.0"
  },
  "plugins": [
    {
      "name": "team-toolkit",
      "source": "./plugins/team-toolkit",
      "description": "Team conventions: changelog command, code auditor, commit skill, format-on-edit hook",
      "version": "1.0.0",
      "category": "productivity"
    }
  ]
}

Le champ source accepte un chemin relatif (le plugin vit dans ce dépôt), une référence GitHub ou une URL Git — une marketplace peut donc aussi agréger des plugins d'autres dépôts. Validez et poussez :

cd noqta-claude-plugins
claude plugin validate .
git init && git add -A
git commit -m "feat: add team-toolkit plugin and marketplace manifest"
gh repo create noqta/claude-plugins --private --source . --push

Toute personne ayant accès peut maintenant l'installer :

/plugin marketplace add noqta/claude-plugins
/plugin install team-toolkit@noqta-claude-plugins

Pour les mises à jour : incrémentez version dans plugin.json et dans l'entrée de la marketplace, poussez, et les utilisateurs récupèrent les changements avec /plugin marketplace update noqta-claude-plugins.

Étape 10 : déployer pour toute l'équipe

La vraie force, c'est le déploiement automatique. Dans n'importe quel dépôt, committez un fichier .claude/settings.json qui déclare la marketplace et active le plugin :

{
  "extraKnownMarketplaces": {
    "noqta-claude-plugins": {
      "source": {
        "source": "github",
        "repo": "noqta/claude-plugins"
      }
    }
  },
  "enabledPlugins": {
    "team-toolkit@noqta-claude-plugins": true
  }
}

Désormais, chaque développeur qui ouvre ce dépôt avec Claude Code reçoit une seule invite pour faire confiance à la marketplace, puis le plugin s'installe et s'active tout seul. L'onboarding d'un nouveau coéquipier passe d'une page wiki d'étapes de configuration à un simple git clone.

Tester votre implémentation

Parcourez cette liste pour confirmer que tout fonctionne de bout en bout :

  • claude plugin validate . passe dans le dépôt du plugin comme dans celui de la marketplace
  • /plugin affiche team-toolkit comme installé et activé
  • /team-toolkit:changelog 1.0.0 produit un brouillon de changelog groupé
  • Le sous-agent code-auditor apparaît dans /agents
  • Modifier un fichier .ts déclenche Prettier (vérifiez que le formatage du fichier change)
  • /mcp liste team-docs comme connecté
  • Un clone frais d'un dépôt contenant le .claude/settings.json de l'étape 10 propose d'installer le plugin

Dépannage

Les commandes n'apparaissent pas après l'installation. Vérifiez la structure des répertoires : plugin.json dans .claude-plugin/, mais commands/ à la racine du plugin. Redémarrez Claude Code après l'installation — les composants s'enregistrent au démarrage de la session.

Le hook ne se déclenche jamais. Vérifiez que format.sh est exécutable (chmod +x) et que vous avez utilisé ${CLAUDE_PLUGIN_ROOT} plutôt qu'un chemin relatif. Lancez claude --debug pour voir les journaux d'enregistrement et d'exécution des hooks.

Le serveur MCP ne se connecte pas. Exécutez /mcp pour voir l'erreur. La cause la plus fréquente est une commande absente du PATH dans l'environnement où s'exécute Claude Code — préférez npx -y package-name aux binaires installés globalement.

L'ajout de la marketplace échoue avec une erreur de manifeste. Le fichier doit se trouver exactement dans .claude-plugin/marketplace.json, et chaque chemin source doit exister relativement à la racine du dépôt. claude plugin validate . détecte les deux cas.

Le plugin fonctionne chez vous mais pas chez vos collègues. C'est presque toujours un chemin codé en dur ou une dépendance manquante (comme jq ou prettier) sur leur machine. Les hooks doivent se dégrader proprement — notez comment format.sh sort avec le code 0 quand Prettier est absent.

Prochaines étapes

  • Ajoutez une commande /team-toolkit:release qui enchaîne le brouillon de changelog avec l'incrément de version et le tag
  • Livrez votre runbook de déploiement comme second skill pour que la réponse aux incidents se charge à la demande
  • Explorez notre guide sur la rédaction de fichiers SKILL.md efficaces pour affiner les descriptions de skills
  • Construisez un serveur MCP personnalisé en TypeScript et embarquez-le dans le plugin
  • Comparez avec le Claude Agent SDK quand vous avez besoin d'agents programmatiques plutôt que d'outillage interactif

Conclusion

Vous avez construit un plugin Claude Code complet — commande slash, sous-agent, skill, hook et serveur MCP embarqué — vous l'avez validé, publié via une marketplace hébergée sur Git, et câblé le déploiement automatique en équipe via les paramètres du dépôt. La force du format de plugin tient au fait que chaque pièce est du simple Markdown ou JSON dans un dépôt versionné : l'outillage IA de votre équipe évolue désormais par pull requests, revue de code et releases, comme n'importe quel autre logiciel. Commencez petit avec une commande et un hook, puis faites grandir la boîte à outils à mesure que les conventions se consolident.