SPONSORED / REPO SPOTLIGHT

Dans finestructure-ai/claude-plugin : un plugin Claude Code en sept fichiers

finestructure-ai/claude-plugin empaquette la plateforme applicative Fine Structure sous forme de plugin Claude Code et met à disposition /deploy, /fs-status et /fs-domain ainsi qu'un connecteur MCP hébergé qui fait le travail réel. Il vaut moins d'être lu pour ce qu'il déploie que pour ce qu'il montre du format de plugin : tout tient en markdown et en JSON, sous quatorze kilooctets, sans étape de build et sans sortie compilée.

THE REPOSITORY

finestructure-ai/claude-pluginSponsored

Open finestructure-ai/claude-plugin

Le dépôt entier tient en sept fichiers

Clonez-le et l'arborescence tient sur un seul écran :

.claude-plugin/
  plugin.json        686 B
  marketplace.json   507 B
commands/
  deploy.md          3.3 KB
  fs-domain.md       905 B
  fs-status.md       741 B
skills/
  fine-structure/
    SKILL.md         4.0 KB
LICENSE              MIT
README.md            2.3 KB

Pas de package.json, pas de fichier de verrouillage, pas de CI, pas de dist. Rien n'est compilé ni empaqueté, et il n'existe aucune version de ce dépôt dont le build puisse échouer. Si vous repoussiez l'écriture d'un plugin en supposant qu'il fallait une chaîne d'outils, voici la correction : le format est une convention de répertoires plus deux fichiers JSON, et le reste est de la prose.

plugin.json est un pointeur, pas un programme

Le manifeste porte les champs d'identité habituels (name, version 0.1.0, description, author, homepage, repository, license, keywords) puis un seul bloc qui accomplit tout le travail intéressant :

"mcpServers": {
  "finestructure": {
    "type": "http",
    "url": "https://finestructure.ai/api/mcp"
  }
}

Deux clés. Pas de command, pas d'args, pas d'env. Comparez avec la forme que prend la plupart des configurations MCP : un processus local (npx, uvx, un chemin vers un binaire), une liste d'arguments et une carte env contenant une clé d'API. Déclarer plutôt un point de terminaison streamable HTTP sort le serveur de la machine de l'utilisateur, et c'est pourquoi 105 outils (le nombre que donne le fichier skill) tiennent derrière un manifeste de 686 octets. Rien dans la version de Node ou de Python de l'utilisateur ne peut casser l'installation, et les changements côté serveur arrivent sans nouvelle version du plugin. La contrepartie est la reproductibilité : impossible de figer la surface d'outils depuis le client.

marketplace.json fait du dépôt son propre canal de distribution

Claude Code installe les plugins depuis des marketplaces et non depuis un registre de paquets, et un marketplace est un fichier JSON qui liste des plugins avec un chemin source. Le second fichier de .claude-plugin fait exactement cela, et son unique entrée de plugin porte "source": "./". Le dépôt est à la fois le plugin et le marketplace qui le sert, si bien que publier revient à un git push public :

/plugin marketplace add finestructure-ai/claude-plugin
/plugin install finestructure@finestructure

Les deux jetons identiques de la seconde ligne sont le nom du plugin chez le nom du marketplace, et ils se confondent parce que les deux s'appellent finestructure. Si vous reprenez cette disposition, donnez-leur des noms différents. Les instructions d'installation gagnent en clarté et vous gardez la place d'ajouter un second plugin plus tard.

Les commandes sont des gabarits de prompt avec du frontmatter

Chaque fichier de commands/ est du frontmatter YAML suivi de prose. deploy.md déclare un description et un argument-hint, les deux chaînes que l'utilisateur voit dans le sélecteur, puis déroule un arbre de décision numéroté : chercher à la racine du projet un .finestructure.json contenant un app_id, sinon appeler list_apps et chercher une correspondance de nom, sinon traiter le cas comme un premier déploiement et utiliser $ARGUMENTS comme nom d'application. fs-status.md pèse 741 octets et fait le travail d'une sous-commande CLI : résoudre l'application, appeler get_app_status, get_app_links et get_errors, puis résumer. fs-domain.md parcourt dans l'ordre add_custom_domain, get_domain_verification, check_domain_verification, get_domain_ssl_status et set_primary_domain.

Le point de conception : aucun de ces fichiers n'appelle quoi que ce soit. Ils nomment des outils, fixent un ordre et décrivent quoi faire quand une étape échoue. L'exécution a lieu quand le modèle invoque des outils MCP. Une commande slash est un prompt versionné, donc la relire ne revient pas à se demander si la logique est juste, mais si l'instruction est ambiguë.

Les meilleures lignes sont les lignes négatives. deploy.md interdit les outils de suppression sauf demande explicite de l'utilisateur. fs-domain.md note que la propagation DNS prend de quelques minutes à quelques heures et demande de proposer un nouvel essai plus tard plutôt que de boucler sur la vérification. C'est une politique de reprise et des garde-fous écrits en phrases, et c'est précisément ce que les plugins naïfs oublient.

Skill contre command : traction contre poussée

skills/fine-structure/SKILL.md compte deux champs de frontmatter, name et description, et la description se lit comme une condition de déclenchement plutôt que comme un résumé : à utiliser dès que l'utilisateur veut déployer, créer ou mettre à jour une application, relier un domaine, gérer des données ou des secrets. Cette formulation est délibérée. Une commande part parce qu'un humain l'a tapée. Un skill part parce que le modèle a rapproché la description de ce qui se passe.

Le partage du contenu en découle. SKILL.md est un modèle mental, pas une liste de tâches : ce qu'est une application ici (pages JSX, composants partagés, schémas d'entités, aucun code serveur arbitraire), ce que sont les entités, quelles opérations consomment des crédits. Puis les flux de travail sous forme de chaînes d'outils, de get_app_files à read_app_file, write_app_file, validate_app et publish_app, avec des jeux de modifications pour les éditions multifichiers. Puis la sémantique des erreurs, la partie la plus dense par octet : une erreur d'authentification veut dire se reconnecter, une erreur de crédit veut dire recharger, et aucune des deux n'est réessayable. Un agent privé de ce savoir réessaie en boucle un échec non réessayable, et sur une plateforme facturée à l'usage cette boucle a un prix.

La règle pour votre propre plugin en sort nettement. Si un fichier de commande explique ce qu'est votre produit, ce paragraphe appartient au skill. Les commandes restent des procédures.

OAuth explique pourquoi le manifeste ne contient aucun secret

Le point de terminaison s'authentifie via OAuth 2.1 avec enregistrement dynamique du client, donc le premier appel d'outil ouvre une page de consentement dans le navigateur et le jeton atterrit dans le magasin d'identifiants de Claude Code, pas dans le dépôt. Un fork est sûr par construction, la révocation se fait côté serveur et non par une modification de configuration qui devrait atteindre chaque machine, et personne n'est prié de coller une clé à longue durée de vie dans un fichier situé à un commit imprudent d'un diff public.

Ce qu'il faut reprendre pour votre propre plugin

Des repères concrets, à peu près dans l'ordre de construction :

  • Commencez par .claude-plugin/plugin.json avec name, version et description. Tout le reste est optionnel.
  • Si vous exploitez un point de terminaison MCP hébergé, déclarez "type": "http" avec une url plutôt qu'une commande locale. Cela retire l'environnement d'exécution de l'utilisateur de votre surface de support.
  • Livrez marketplace.json dans le même dépôt avec "source": "./" tant que vous n'avez qu'un plugin, et donnez-lui un nom différent de celui du plugin.
  • Donnez à chaque commande un description et un argument-hint dans le frontmatter, rédigés comme des réponses aux questions à quoi cela sert et que faut-il taper ensuite.
  • Utilisez $ARGUMENTS plutôt que d'inventer une syntaxe positionnelle. Il n'y a pas d'analyseur, seulement une substitution.
  • Écrivez le corps des commandes comme des arbres de décision, outils nommés explicitement. "Si le fichier de configuration existe, lire app_id, sinon appeler list_apps" tient mieux qu'un paragraphe d'intentions.
  • Mettez la sémantique des échecs par écrit : quelles erreurs sont définitives, lesquelles sont réessayables, et quoi dire au lieu de réessayer.
  • Nommez vos outils destructeurs dans la prose et interdisez-les sauf demande.
  • Gardez le modèle du domaine dans SKILL.md et la procédure dans la commande. Une duplication entre les deux est un mauvais signe.
  • Testez avec /plugin marketplace add sur un chemin local ou sur votre fork avant d'envoyer qui que ce soit sur main.

Aspérités

Trois, honnêtement, aucune rédhibitoire. Tout est en anglais, et le format n'offre aucune prise pour y remédier : il n'y a pas de clé locale dans le frontmatter, donc localiser signifie dupliquer les fichiers de commande ou accepter le décalage.

L'argument du zéro clé d'API a un astérisque. SKILL.md reconnaît que les outils de génération de médias se situent hors de la connexion OAuth et exigent un jeton MCP statique avec des portées médias, créé dans le Studio de la plateforme et envoyé dans un en-tête bearer. Le plugin gère bien la chose, en demandant au modèle d'expliquer l'absence plutôt que de réessayer contre un mur, mais c'est un second chemin d'authentification greffé sur une conception dont l'argument de vente est de n'en avoir qu'un.

Et c'est une version 0.1.0 sans changelog, sans tests et sans CI. Pour du markdown c'est défendable, même si une vérification de schéma JSON dans un hook de pre-commit attraperait la seule classe d'erreur qui casse vraiment les installations, un manifeste mal formé. La soumission au répertoire est en cours d'examen à l'heure où ces lignes sont écrites, donc pour l'instant l'installation passe par la référence au dépôt.

Lisez d'abord les trois fichiers de commandes, puis SKILL.md, puis les deux fichiers JSON. Dans cet ordre le format s'explique de lui-même : le markdown décide de ce qui doit arriver et dans quel ordre, le serveur MCP décide de ce qui s'exécute vraiment, et le manifeste est la couture fine entre les deux.

QUESTIONS

Asked about this repository

quelle est la structure de fichiers minimale pour un plugin claude code ?
Un seul fichier : .claude-plugin/plugin.json avec un name, une version et une description. Les commandes, les skills, les agents et les hooks sont des couches optionnelles par-dessus. finestructure-ai/claude-plugin sert de repère de taille utile, car il utilise plusieurs de ces couches et totalise pourtant sept fichiers et moins de quatorze kilooctets, sans étape de build.
comment fonctionnent les commandes slash dans un plugin claude code ?
Une commande slash est un fichier markdown placé dans commands/ dont le nom de fichier devient le nom de la commande. Le frontmatter fournit un description et un argument-hint pour le sélecteur, et le corps est un prompt que le modèle reçoit à l'exécution, avec $ARGUMENTS remplacé par ce qui suivait. Le fichier n'exécute rien par lui-même, donc le travail réel doit venir d'outils que le modèle peut appeler, et c'est pourquoi ce plugin associe ses commandes à un serveur MCP.
faut-il une clé d'API pour utiliser un serveur MCP dans un plugin claude code ?
Pas si le serveur parle OAuth. Ce manifeste ne déclare que "type": "http" et une url, et le point de terminaison utilise OAuth 2.1 avec enregistrement dynamique du client, donc l'autorisation se fait dans le navigateur et le jeton reste dans le magasin d'identifiants de Claude Code. L'alternative, un bloc env contenant une clé, fonctionne mais place un secret à longue durée de vie dans un fichier que les utilisateurs recopient. Une réserve visible ici : les outils de médias sont hors de ce flux et réclament encore un jeton statique.
comment transformer un dépôt github en marketplace de plugins claude code ?
Ajoutez .claude-plugin/marketplace.json avec un name, un owner et un tableau plugins. S'il sert un plugin du même dépôt, mettez le source de ce plugin à "./", ce que fait ce dépôt. Les utilisateurs lancent ensuite /plugin marketplace add owner/repo puis /plugin install plugin-name@marketplace-name. Il n'y a ni registre ni étape de publication entre un git push et un plugin installable.

THE SPONSOR

The platform behind the endpoint

Fine Structure runs the hosted MCP server this plugin points at, and sponsors this publication.

finestructure.ai