THE REPOSITORY
finestructure-ai/claude-pluginSponsored
Open finestructure-ai/claude-pluginDe hele repository is zeven bestanden
Kloon hem en de bestandsboom past op één scherm:
.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 KBGeen package.json, geen lockfile, geen CI, geen dist. Er wordt niets gecompileerd of gebundeld, en er bestaat geen versie van deze repository waarvan de build kan mislukken. Als je het schrijven van een plugin voor je uit schuift omdat je een toolchain veronderstelde, is dit de correctie: het formaat is een mapconventie plus twee JSON-bestanden, en de rest is proza.
plugin.json is een verwijzing, geen programma
Het manifest draagt de gebruikelijke identiteitsvelden (name, versie 0.1.0, description, author, homepage, repository, license, keywords) en daarna één blok dat al het interessante werk doet:
"mcpServers": {
"finestructure": {
"type": "http",
"url": "https://finestructure.ai/api/mcp"
}
}Twee sleutels. Geen command, geen args, geen env. Vergelijk dat met de vorm die de meeste MCP-configuraties aannemen: een lokaal proces (npx, uvx, een pad naar een binary), een argumentenlijst en een env-map met een API-sleutel. In plaats daarvan een streamable HTTP endpoint declareren haalt de server van de machine van de gebruiker af, en daarom staan 105 tools (het aantal dat het skill-bestand noemt) achter een manifest van 686 byte. Niets aan de Node- of Python-versie van de gebruiker kan de installatie breken, en wijzigingen aan de serverkant komen aan zonder nieuwe pluginrelease. De prijs is reproduceerbaarheid: je kunt het tooloppervlak niet aan de clientkant vastzetten.
marketplace.json maakt de repository zijn eigen distributiekanaal
Claude Code installeert plugins vanuit marketplaces en niet vanuit een pakketregister, en een marketplace is een JSON-bestand dat plugins opsomt met een bronpad. Het tweede bestand in .claude-plugin doet precies dat, en de enige plugin-invoer erin heeft "source": "./". De repository is tegelijk de plugin en de marketplace die hem uitserveert, dus publiceren is een publieke git push:
/plugin marketplace add finestructure-ai/claude-plugin
/plugin install finestructure@finestructureDe twee identieke tokens op de tweede regel zijn de pluginnaam bij de marketplacenaam, en ze botsen omdat beide finestructure heten. Kopieer je deze indeling, geef ze dan verschillende namen. De installatie-instructie wordt duidelijker en je houdt ruimte over om later een tweede plugin toe te voegen.
Commando's zijn promptsjablonen met frontmatter
Elk bestand in commands/ is YAML-frontmatter plus proza. deploy.md declareert een description en een argument-hint, de twee teksten die een gebruiker in de kiezer ziet, en legt daarna een genummerde beslisboom neer: kijk in de projectroot naar een .finestructure.json met een app_id, roep anders list_apps aan en zoek naar een naamovereenkomst, en behandel het anders als een eerste uitrol met $ARGUMENTS als appnaam. fs-status.md is 741 byte en doet het werk van een CLI-subcommando: bepaal de app, roep get_app_status, get_app_links en get_errors aan, vat samen. fs-domain.md loopt op volgorde langs add_custom_domain, get_domain_verification, check_domain_verification, get_domain_ssl_status en set_primary_domain.
Het ontwerppunt: geen van deze bestanden roept iets aan. Ze noemen tools, leggen een volgorde vast en beschrijven wat te doen als een stap mislukt. Uitvoering gebeurt wanneer het model MCP-tools aanroept. Een slash-commando is een prompt in versiebeheer, dus het reviewen ervan is niet de vraag of de logica klopt, maar de vraag of de instructie dubbelzinnig is.
De beste regels zijn de verbiedende. deploy.md verbiedt verwijdertools tenzij de gebruiker er expliciet om vroeg. fs-domain.md merkt op dat DNS-propagatie minuten tot uren duurt en zegt voor te stellen het later opnieuw te proberen in plaats van in een verificatielus te blijven hangen. Dat is een retrybeleid met vangrails, opgeschreven als zinnen, en precies dat laten naïeve plugins weg.
skill versus command: trekken versus duwen
skills/fine-structure/SKILL.md heeft twee frontmattervelden, name en description, en die description leest als een triggervoorwaarde in plaats van een samenvatting: gebruik dit wanneer de gebruiker een app wil uitrollen, aanmaken of bijwerken, een domein wil koppelen, of data of secrets wil beheren. Die formulering is bewust. Een commando vuurt omdat een mens het intypte. Een skill vuurt omdat het model de beschrijving matchte met wat er gaande is.
De inhoudsverdeling volgt daaruit. SKILL.md is een mentaal model, geen takenlijst: wat een app hier is (JSX-pagina's, gedeelde componenten, entiteitsschema's, geen willekeurige servercode), wat entiteiten zijn, welke handelingen credits kosten. Daarna workflows als toolketens, van get_app_files naar read_app_file naar write_app_file naar validate_app naar publish_app, met wijzigingssets voor bewerkingen over meerdere bestanden. Daarna de foutsemantiek, die per byte het zwaarst weegt: authenticatiefouten betekenen opnieuw verbinden, creditfouten betekenen bijvullen, en geen van beide is het opnieuw proberen waard. Een agent zonder die kennis herhaalt een onherstelbare fout in een lus, en op een platform met een meter heeft die lus een prijs.
De regel voor je eigen plugin volgt hier netjes uit. Legt een commandobestand uit wat je product is, dan hoort die alinea in de skill. Commando's blijven procedures.
OAuth is waarom het manifest geen geheimen bevat
Het endpoint authenticeert via OAuth 2.1 met dynamische clientregistratie, dus de eerste toolaanroep opent een toestemmingspagina in de browser en het token belandt in de credentialopslag van Claude Code, niet in de repository. Een fork is veilig van constructie, intrekken gebeurt aan de serverkant in plaats van via een configuratiewijziging die elke machine moet bereiken, en niemand wordt gevraagd een langlevende sleutel te plakken in een bestand dat één onoplettende commit van een publieke diff verwijderd is.
Wat je kunt overnemen voor je eigen plugin
Concrete aanwijzingen, ruwweg op bouwvolgorde:
- Begin met .claude-plugin/plugin.json met name, version en description. Al het andere is optioneel.
- Draai je een gehost MCP-endpoint, declareer dan "type": "http" met een url in plaats van een lokaal commando. Dat schrapt de runtime van de gebruiker uit je supportoppervlak.
- Zet marketplace.json in dezelfde repository met "source": "./" zolang je één plugin hebt, en geef het een andere naam dan de plugin.
- Geef elk commando een description en een argument-hint in de frontmatter, geschreven als antwoord op de vragen wat doet dit en wat typ ik erachter.
- Gebruik $ARGUMENTS in plaats van zelf een positionele syntaxis te verzinnen. Er is geen parser, alleen substitutie.
- Schrijf commandoteksten als beslisbomen met expliciet genoemde tools. "Als het configuratiebestand bestaat, lees app_id, roep anders list_apps aan" houdt beter stand dan een alinea over intenties.
- Zet de faalsemantiek op papier: welke fouten definitief zijn, welke te herhalen, en wat te zeggen in plaats van opnieuw proberen.
- Noem je destructieve tools in de tekst en verbied ze tenzij erom gevraagd wordt.
- Houd het domeinmodel in SKILL.md en de procedure in het commando. Duplicatie tussen die twee is een slecht teken.
- Test met /plugin marketplace add tegen een lokaal pad of je eigen fork voordat je iemand naar main stuurt.
Ruwe randen
Drie eerlijke, geen ervan fataal. Alles is Engels en het formaat biedt geen haakje om dat te verhelpen: er is geen locale-sleutel in de frontmatter, dus lokaliseren betekent gedupliceerde commandobestanden of de mismatch accepteren.
Het verhaal zonder API-sleutels heeft een sterretje. SKILL.md geeft toe dat de mediageneratietools buiten de OAuth-verbinding vallen en een statisch MCP-token met mediascopes nodig hebben, aangemaakt in de Studio van het platform en meegestuurd als bearer-header. De plugin gaat er goed mee om en zegt het model de afwezigheid uit te leggen in plaats van tegen een muur aan te blijven proberen, maar het is een tweede authenticatiepad, vastgeschroefd op een ontwerp waarvan het verkoopargument juist één pad is.
En het is versie 0.1.0 zonder changelog, tests of CI. Voor markdown valt dat te verdedigen, al zou een JSON-schemacontrole in een pre-commit hook de enige foutklasse vangen die installaties echt breekt, een misvormd manifest. De aanmelding voor de directory is op het moment van schrijven in behandeling, dus voorlopig installeer je via een verwijzing naar de repository.
Lees eerst de drie commandobestanden, dan SKILL.md, dan de twee JSON-bestanden. In die volgorde legt het formaat zichzelf uit: markdown bepaalt wat er moet gebeuren en in welke volgorde, de MCP-server bepaalt wat er werkelijk draait, en het manifest is de dunne naad ertussen.
QUESTIONS
Asked about this repository
- wat is de minimale bestandsstructuur voor een Claude Code plugin?
- Eén bestand: .claude-plugin/plugin.json met een name, version en description. Commando's, skills, agents en hooks zijn optionele lagen daarbovenop. finestructure-ai/claude-plugin is een handige maatstaf qua omvang, want het gebruikt meerdere van die lagen en komt toch op zeven bestanden en onder de veertien kilobyte, zonder buildstap.
- hoe werken slash-commando's in een Claude Code plugin?
- Een slash-commando is een markdown-bestand in commands/ waarvan de bestandsnaam de commandonaam wordt. De frontmatter levert een description en een argument-hint voor de kiezer, en de body is een prompt die het model krijgt wanneer het commando draait, met $ARGUMENTS vervangen door alles wat erachter stond. Het bestand voert zelf niets uit, dus het echte werk moet komen van tools die het model kan aanroepen, en daarom koppelt deze plugin commando's aan een MCP-server.
- heb ik een API-sleutel nodig om een MCP-server in een Claude Code plugin te gebruiken?
- Niet als de server OAuth spreekt. Dit manifest declareert alleen "type": "http" en een url, en het endpoint gebruikt OAuth 2.1 met dynamische clientregistratie, dus de autorisatie gebeurt in de browser en het token blijft in de credentialopslag van Claude Code. Het alternatief, een env-blok met een sleutel, werkt wel maar zet een langlevend geheim in een bestand dat gebruikers rondkopiëren. Eén kanttekening is hier zichtbaar: de mediatools vallen buiten die flow en hebben nog steeds een statisch token nodig.
- hoe maak ik van een GitHub-repository een Claude Code plugin marketplace?
- Voeg .claude-plugin/marketplace.json toe met een name, owner en plugins-array. Serveert het een plugin uit dezelfde repository, zet dan de source van die plugin op "./", precies wat deze repository doet. Gebruikers draaien vervolgens /plugin marketplace add owner/repo gevolgd door /plugin install plugin-name@marketplace-name. Er zit geen register en geen publicatiestap tussen een git push en een installeerbare plugin.
THE SPONSOR
The platform behind the endpoint
Fine Structure runs the hosted MCP server this plugin points at, and sponsors this publication.
finestructure.ai