Tutorial

Wie Agent Plugins einem AI-Coding-Agenten neue Fähigkeiten geben: Plugin-Manifest, Skills, MCP und das JSON nach der Installation

Ein Plugin macht das Modell nicht klüger. Der Client liest nur ein paar JSON-Dateien an festen Pfaden.

Die letzten beiden Texte klärten wie die Kiste aussieht und wann man sie nicht packt. Heute setzen wir voraus, dass ihr ein Plugin ausliefert. Die eigentliche Leserfrage: Nachdem Cursor, Claude Code oder Antigravity das Verzeichnis installiert haben — warum kann das Modell plötzlich Rechnungen abfragen und den Wochenbericht schreiben? Kein Gewichtsupdate, kein umgeschriebenes System-Prompt. Agent Plugins 1.0.0 ist klar: zuerst root-plugin.json lesen, dann skills/ und mcp.json an festen Orten finden. Das Google Cloud Developer Plugin läuft denselben Weg. Dieser Text geht die JSON-Hopps nach der Installation zu Ende und übergibt an MCP und JSON Schema.

Fünf Hopps, kein „das Modell hat gelernt“

„Der Agent hat automatisch eine Fähigkeit gewonnen“ klingt nach gelerntem Skill. Technisch sind es fünf Hopps, keiner ist optional. Hopp eins: Der Client setzt das Verzeichnis als Plugin-Wurzel; ein aufgelöster Pfad außerhalb der Wurzel wird verweigert, auch ein Symlink nach draußen. Hopp zwei: plugin.json lesen, geschlossenes Schema prüfen, name und Spez-Version nehmen. Scheitert dieser Hopp, fällt das ganze Paket — die Hopps drei bis fünf laufen nicht. Hopp drei: Existiert skills/, nur direkte Kinder mit einer regulären Datei namens genau SKILL.md; name und description kommen in den Kontext. Hopp vier: Existiert mcp.json, verbinden über jedes type, danach tools/list. Hopp fünf: Das Modell trifft Beschreibung oder Toolnamen, dann liest es den Skill-Body oder sendet tools/call.

Die Spezifikation definiert absichtlich nicht, wie der Installationsknopf aussieht. Der Google Developers Blog sagt es offen: Installation, Rechte, Sandbox und Bestätigungs-UX sind Sache jedes Clients. Agents CLI, Cursor und Claude Code dürfen drei Dialoge zeigen. Portabel sind Verzeichnis und zwei geschlossene JSON-Dateien. Im Review fragt man nicht „wo klickt der Nutzer?“, sondern „welche Objekte liegen jetzt im Speicher?“ Ohne Manifest keine späteren Hopps. Manifest ok, aber $schema in mcp.json weicht von plugin.json ab: MCP aus, Skills bleiben. Eine SKILL.md, die Agent Skills verfehlt: nur diesen Skill überspringen.

Horizontale Delegation liegt außerhalb dieser Pipeline. Wie der Rechnungs-Agent eines anderen Teams gefunden wird, ist eine Agent Card — siehe den A2A-Text. Heute geht es nur darum, wie dieser Coding-Agent eine Gruppe aus Skills und Tools wachsen lässt. Nennt „neue Fähigkeit“ ein Entdeckungsergebnis, dann seht euch das JSON jedes Hopps an.

Dieser Hopp JSON, das der Client jetzt hält Was das Modell tun kann
plugin.json lesenIdentität: name / version / $schemaNoch nichts — die Kiste ist nur gültig
skills/ durchlaufenSkill-Metadaten-Array (noch kein Body)Brief wählbar; Body bei Bedarf
MCP verbinden, dann tools/listToolnamen plus inputSchemaArgumente füllbar; noch nichts ausgeführt

Zuerst das Manifest: plugin.json ist der Identitätsvertrag

Der Client MUSS root-plugin.json lesen, bevor er Komponenten entdeckt. Der Dateiname ist nicht frei, Skills und MCP dürfen nicht ins Manifest inline. Das Schema ist geschlossen: nur $schema, name, version, description, author, homepage, repository, license, keywords, extensions. Extra-Top-Level-Keys MUSS er melden und ignorieren — das ist kein Ablehnungsgrund. Tödlich sind fehlende Pflichtfelder, falsche Typen oder ein illegales name: Paket ablehnen, nichts entdecken. Für 1.0.0 MUSS $schema https://agent-plugins.org/schemas/1.0.0/plugin.schema.json sein. Der Client wählt damit lokale Regeln und DARF beim Laden kein Schema aus dem Netz holen.

name ist ein Identifikator, kein Shop-Titel. Länge 1–64; nur Kleinbuchstaben, Ziffern, Bindestrich, Punkt; Anfang und Ende alphanumerisch; kein -- und kein ... My-Plugin und -start lehnen das ganze Paket ab. SemVer für version ist empfohlen, „sieht nicht nach SemVer aus“ ist kein Ablehnungsgrund. Das Author-Objekt darf nur name / email / url enthalten. Client-Privates gehört unter extensions.com.example.client oder in ein Reverse-Domain-Verzeichnis an der Wurzel. Keinen fünften Top-Level-Key für Hooks erfinden. Hooks oben in plugin.json ignoriert die Spez — eure IDE liest sie vielleicht zufällig, der nächste Client nicht.

Unten ein volles Manifest fürs Repo: mehr als das Zwei-Felder-Minimum, mit Metadaten für Menschen. Erst parsen und das offizielle Schema bestehen, dann über den Installationsknopf streiten. keywords helfen dem Katalog. description hilft Menschen bei der Installationsentscheidung. Sie hilft dem Modell nicht beim Tool-Wahl. Skills kommen aus der SKILL.md-Description, Tools aus tools/list. Eine Tool-Anleitung im Manifest lässt die Entdeckungsfläche leer.

{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "invoice-ops",
  "version": "1.2.0",
  "description": "Invoice query MCP plus the weekly-summary skill, shipped as one directory",
  "author": {
    "name": "Finance Platform",
    "url": "https://docs.example.com/invoice-ops"
  },
  "homepage": "https://docs.example.com/invoice-ops",
  "repository": "https://github.com/example/invoice-ops",
  "license": "MIT",
  "keywords": ["invoices", "weekly-summary", "mcp"]
}

Nach der Installation: der Fähigkeits-Snapshot im Client

Die Spez verlangt keinen Export „installierte Fähigkeiten“. Das Review muss trotzdem sehen, was nach der Installation im Speicher liegt. Faltet die fünf Hopps in ein Snapshot-JSON: Plugin-Identität, gefundene Skills (nur Metadaten), MCP-Verbindungsstatus, Tool-Verträge aus tools/list. Dieser Snapshot ist keine Instanz von plugin.schema.json — nicht mit dem Paket-Schema prüfen. Es ist euer CI-Fixture: Skill-Anzahl, Toolnamen, Pflichtfelder von inputSchema asserten. Installation ok, Snapshot falsch: Entdeckung oder Handshake kaputt. Das Modell hat nichts „nicht gelernt“.

„Automatisch gewonnen“ steht in diesem Objekt. skills[].loaded ist metadata, nicht body — etwa hundert Token beim Start, Body bei Bedarf. tools[] kommt nach dem Handshake von tools/list, nicht aus einer handgeschriebenen Liste in plugin.json. mcpServers[].status ist Laufzeit, nicht Paketvertrag. Leeres tools bei connected heißt: Handshake ok, Server hat nichts exponiert — den Server debuggen, nicht das Manifest. Umgekehrt, gültiges Manifest und null Skills im Snapshot: meist liegt SKILL.md eine Ebene zu tief.

Nach dem Google Cloud Developer Plugin sieht die Client-Seite gleich aus: Kisten-Identität, Metadaten des gcloud-Geländer-Skills, Tool-Liste des Developer-Knowledge-MCP. Nutzer sagen „der Agent kann jetzt Cloud-Docs suchen“. In den Daten ist tools um ein paar Einträge gewachsen. Snapshot gegen committed plugin.json / mcp.json diffen — wer Laufzeit zurück ins Paket schreibt, fällt sofort auf. Das ist Drift, kein Spez-Feld.

{
  "plugin": {
    "name": "invoice-ops",
    "version": "1.2.0",
    "spec": "1.0.0"
  },
  "skills": [
    {
      "name": "write-weekly-summary",
      "description": "Turn invoice query results into the weekly summary finance reads. Use when the user asks for a week-end report.",
      "path": "skills/write-weekly-summary/SKILL.md",
      "loaded": "metadata"
    }
  ],
  "mcpServers": [
    {
      "id": "invoice-tools",
      "type": "streamable-http",
      "status": "connected"
    }
  ],
  "tools": [
    {
      "name": "query_invoices",
      "server": "invoice-tools",
      "inputSchema": {
        "type": "object",
        "required": ["week"],
        "properties": {
          "week": { "type": "string", "pattern": "^[0-9]{4}-W[0-9]{2}$" },
          "status": { "type": "string", "enum": ["open", "paid", "overdue"] }
        }
      }
    }
  ]
}

Skill-Hopp: Frontmatter wird zur Entdeckungsfläche

Agent Plugins schreibt SKILL.md nicht neu. Eine Entdeckungsregel: ein direktes Kind von skills/ mit einer regulären Datei namens genau SKILL.md. Versteckt unter skills/deploy/extra/SKILL.md bleibt unsichtbar. Ein Skill, der Agent Skills verfehlt, MUSS übersprungen werden; andere Skills und MCP laden weiter. In den Kontext kommen Frontmatter-name und description plus Pfad, damit Body, scripts/ und references/ später nachgeladen werden.

Die Description muss sagen, was sie tut und wann. invoice-ops-skill-v2 oder ein Ich-Slogan machen die Entdeckungsfläche zu null — Kiste installiert, Modell wählt nie, Nutzer schimpfen aufs Plugin. Kaputt ist der Brief. scripts/ heißt weiter „mit der vorhandenen Shell ausführen“; Argumente sind argv, keine erstklassigen Tools aus tools/list. Keine Skriptnamen in tools[] des Snapshots. Stehen sie dort, hat jemand eine Skill-Anlage als MCP verbucht.

Den Body bei Bedarf zu laden, schont das Fenster. loaded: metadata im Snapshot fängt die Regression, ein ganzes Runbook ins System-Prompt zu kippen. Ein vom Brief gesprengtes Fenster ist Client-Ladepolitik, kein Plugin-Formatfehler. Die Spez garantiert nur, dass der Skill gefunden werden kann. Wie er Modell und Nutzer gezeigt wird, bleibt clientseitig.

MCP-Hopp: verbinden, dann tools/list

mcp.json MUSS an der Wurzel liegen. Nicht inline in plugin.json, nicht auf einem anderen Kernpfad. Top-Level nur $schema und mcpServers. $schema auf https://agent-plugins.org/schemas/1.0.0/mcp.schema.json pinnen und mit der Spez-Version im Manifest abgleichen. Abweichung schaltet nur MCP dieses Plugins ab. Jeder Server MUSS type explizit setzen: stdio, streamable-http oder optionales Legacy-sse. Transport nicht aus der Objektform raten. Eine streamable-http-url MUSS absolut http/https sein; außerhalb von Loopback https. headers sind sichtbare Paketdaten, kein Geheimfach.

Die Entdeckungsfläche nach dem Connect ist tools/list. Die Paketdatei sagt wohin. Der Tool-Vertrag sagt, ob die Arguments dieses Hopps legal sind. inputSchema nicht nach plugin.json kopieren, name / version nicht nach inputSchema. Auth-Fehler ist Verbindungsfehler dieses Servers, nicht illegale Plugin-Konfig — die Spez definiert keine portablen OAuth-Felder; Credentials bleiben in der Client-Laufzeit. Drahtprotokoll: Was ist MCP.

Unten ein portables Remote-MCP-Fragment. Keine API-Keys in Repo-Fixtures. Nach dem Connect tools/list in tools[] des Snapshots gießen. Handshake-Fehler überspringt nur diesen Server; andere Server und Skills laufen weiter. Diese Fehlergrenze steht in der Spez, nicht auf einem Produktplakat.

{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
  "mcpServers": {
    "invoice-tools": {
      "type": "streamable-http",
      "url": "https://billing.example.com/mcp"
    }
  }
}
Fehler Was stirbt Was weiterlebt
Großbuchstaben in plugin.json nameDas ganze Paket; keine KomponentenNichts
mcp.json $schema weicht vom Manifest abAlles MCP dieses PluginsSkills laden weiter
Eine SKILL.md hat kaputtes FrontmatterDieser eine SkillAndere Skills + MCP

Unabhängiges Scheitern, Fixtures in JSONVue

Mindestens vier Review-Fixtures: das legale plugin.json oben, der Fähigkeits-Snapshot, ein portables mcp.json, ein query_invoices-Arguments-Objekt. Das erste MUSS offizielles plugin.schema.json bestehen. Das zweite euer Snapshot-Schema oder Struktur-Asserts — das Paket-Schema nicht darüberstülpen. Das dritte mcp.schema.json. Das vierte das Tool-inputSchema. Vier JSON-Dateien, vier Jobs: Identität, Inventar, Verbindung, Aufruf.

Zwei Negative dazu: name auf Invoice-Ops; type an einem mcp.json-Eintrag streichen. Ersteres MUSS das Paket ablehnen. Letzteres überspringt nur diesen Server. Behandelt CI ein unbekanntes Top-Level-Feld als fatal, seid ihr strenger als der Client — die Spez sagt: melden, ignorieren, weiterladen. Kein Geheimnis in committed Fixtures.

Im Browser reicht:JSON formatieren, um zu sehen, ob Manifest, Snapshot und mcp.json parsen;JSON-Schema prüfen, um $schema, name, mcpServers und inputSchema zu prüfen;JSON Diff, um Laufzeit zurück ins Paket zu fangen. Nichts verlässt die Maschine. Weiterlesen:MCP und JSON Schema, Plugins-Überblick, und wann man packt.

Verwandt: Google Agent Plugins 2026, Skills vs MCP vs Plugins, MCP und JSON Schema, Was ist MCP.

FAQ

Feintuned die Plugin-Installation das Modell?

Nein. Die Gewichte bleiben. Der Client gewinnt ein Identitätsobjekt, Skill-Metadaten und Tool-Verträge aus tools/list. Es „kann“, weil die Entdeckungsfläche wuchs, nicht weil das Modell Rechnungswesen lernte.

Kann ich die Tool-Liste in plugin.json schreiben und mcp.json weglassen?

Nein. Das Manifest darf keine Komponenten inline und keine Entdeckungspfade ändern. Die Tool-Liste kommt nach dem Handshake von tools/list. Oben in plugin.json wird sie ignoriert. Unter extensions gilt sie nur für einen Client und verschwindet beim nächsten.

Kann ich den Snapshot mit offiziellem plugin.schema.json prüfen?

Nein. Das offizielle Schema beschreibt Kisten-Identität. Der Snapshot ist clientseitig zusammengebautes Inventar: Laufzeit-status und Tool-inputSchema. Eigenes Snapshot-Schema oder CI-Asserts auf die Felder, die zählen.

Install-UX unterscheidet sich. Ist das Plugin trotzdem portabel?

Das Paket ist portabel. Die Installation muss es nicht sein. Die Spez schließt Installation, Rechte und Sandbox bewusst aus. Client wechseln: Verzeichnis und zwei geschlossene JSON-Dateien bleiben. Bestätigungsdialog und Enterprise-Policy dürfen sich unterscheiden.

Fazit und nächste Schritte

2026 schrumpft „ein Plugin gibt dem Coding-Agenten automatisch Fähigkeiten“ auf einen Satz: Neue Fähigkeit ist Entdeckung, kein Gewicht. Nach fünf Hopps liegen Identität, Skill-Metadaten und Tool-Verträge im Speicher. Ein Hopp fehlt — Nutzer melden „installiert, kann trotzdem nicht“.

Ausliefern in dieser Reihenfolge: plugin.json durchs offizielle Schema; skills/ und mcp.json gehen; Snapshot-Fixture einfrieren; ersten tools/call gegen inputSchema prüfen. Die vier Verträge in JSONVue lassen. Kiste: Plugins-Text. Packen oder nicht: Entscheidungs-Text. Draht: MCP-Texte.