{"meta":{"title":"Plug-In-Verzeichnisse","intro":"Ein Plug-In ist ein Verzeichnis, das SDK-Erweiterungen – Fähigkeiten, Hooks, MCP-Server, benutzerdefinierte Agents und LSP-Konfiguration – hinter einem einzigen Manifest gebündelt. Wenn Sie auf das SDK in einem Plug-In-Verzeichnis verweisen, wird alles geladen, was das Plug-In beiträgt, sodass Sie wiederverwendbare Funktionspakete versenden können, ohne die Kabel pro Erweiterung in jeder Hostanwendung zu schreiben.","product":"GitHub Copilot","breadcrumbs":[{"href":"/de/copilot","title":"GitHub Copilot"},{"href":"/de/copilot/how-tos","title":"Vorgehensweisen"},{"href":"/de/copilot/how-tos/copilot-sdk","title":"Copilot SDK"},{"href":"/de/copilot/how-tos/copilot-sdk/features","title":"Funktionen"},{"href":"/de/copilot/how-tos/copilot-sdk/features/plugin-directories","title":"Plug-In-Verzeichnisse"}],"documentType":"article"},"body":"# Plug-In-Verzeichnisse\n\nEin Plug-In ist ein Verzeichnis, das SDK-Erweiterungen – Fähigkeiten, Hooks, MCP-Server, benutzerdefinierte Agents und LSP-Konfiguration – hinter einem einzigen Manifest gebündelt. Wenn Sie auf das SDK in einem Plug-In-Verzeichnis verweisen, wird alles geladen, was das Plug-In beiträgt, sodass Sie wiederverwendbare Funktionspakete versenden können, ohne die Kabel pro Erweiterung in jeder Hostanwendung zu schreiben.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\nIn diesem Handbuch wird die Struktur des Plug-in-Ordners erläutert, wie Sie ein Plug-in aus einem Verzeichnis laden, wann Plug-in-Verzeichnisse im Vergleich zur Registrierung einzelner Erweiterungen verwendet werden sollten und wie Plug-in-Sets deterministisch gemacht werden.\n\n## Wann Plugin-Verzeichnisse verwendet werden sollten\n\nVerwenden Sie ein Plug-In-Verzeichnis, wenn Sie folgendes möchten:\n\n* **Verteilen Sie ein Bündel von Fähigkeiten** als Einheit — z. B. ein „TypeScript Reviewer“-Paket mit einer Fähigkeit, einem `preToolUse` Hook, der die Linting-Regeln erzwingt, und einem benutzerdefinierten Agenten, der den Reviewer ausführt.\n* **Anbieterfunktionspakete in ein Repository** , sodass jeder Klon der Hostanwendung die gleichen Erweiterungen deterministisch lädt.\n* **Entwickeln Sie ein Plug-In lokal** , bevor Sie es auf einem Marketplace veröffentlichen.\n* **Überschreiben oder Erweitern** eines marketplace-installierten Plug-Ins mit einem lokalen Auschecken zu Testzwecken.\n\nWenn Sie nur einen einzelnen MCP-Server, einen einzelnen Hook oder einen einzelnen benutzerdefinierten Agent hinzufügen müssen, können Sie ihn inline über die SDK-Konfiguration (`mcpServers`, , `hooks``customAgents`) registrieren. Plug-In-Verzeichnisse sind am nützlichsten, sobald Sie drei oder mehr verwandte Erweiterungen haben, die zusammen ausgeliefert werden.\n\n## Plugin-Ordnerstruktur\n\nDie Copilot CLI durchsucht jedes Plug-In-Verzeichnis nach einem `plugin.json`-Manifest oder einer `SKILL.md` im Stammverzeichnis. Ein minimales Plug-In sieht wie folgt aus:\n\n```text\nmy-plugin/\n├── plugin.json              # manifest (required unless using SKILL.md only)\n├── SKILL.md                 # optional: top-level skill\n├── hooks.json               # optional: hooks config\n├── .mcp.json                # optional: MCP server config\n├── agents/                  # optional: custom agents (one .md file per agent)\n│   └── code-reviewer.md\n└── skills/                  # optional: additional skills\n    └── lint-fix/\n        └── SKILL.md\n```\n\nDas Manifest kann sich auch unter `.github/plugin.json` oder `.github/plugin/plugin.json` befinden, sodass Plugins in einem vorhandenen Repository liegen können, ohne dessen Stammverzeichnisstruktur zu ändern. Jedes Subsystem (Hooks, MCP, LSP, Skills, Agents) verfügt über einen eigenen Loader und ist optional – ein Plugin benötigt nur die Teile, die es beisteuert.\n\nDas vollständige Manifestschema finden Sie in der Laufzeitdokumentation, auf die im Schrägstrichbefehl `/plugin` Ihrer CLI verwiesen wird.\n\n## Laden eines Plug-In-Verzeichnisses aus dem SDK\n\nPlug-In-Verzeichnisse werden geladen, indem `--plugin-dir <path>` an die Copilot CLI übergeben werden, wenn das SDK sie spawns. Jede Sprache macht dies über die Extra-Args-Option der Laufzeitverbindung verfügbar. Das Flag kann wiederholt werden, um mehrere Plug-ins zu laden.\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient, RuntimeConnection } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient({\n  connection: RuntimeConnection.forStdio({\n    args: [\n      \"--plugin-dir\", \"./plugins/code-reviewer\",\n      \"--plugin-dir\", \"./plugins/lint-fix\",\n    ],\n  }),\n});\n\nawait client.start();\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n<!-- docs-validate: wrap-async -->\n\n```python\nfrom copilot import CopilotClient, StdioRuntimeConnection\n\nclient = CopilotClient(\n    connection=StdioRuntimeConnection(\n        args=(\n            \"--plugin-dir\", \"./plugins/code-reviewer\",\n            \"--plugin-dir\", \"./plugins/lint-fix\",\n        ),\n    ),\n)\nawait client.start()\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\nclient := copilot.NewClient(&copilot.ClientOptions{\n    Connection: copilot.StdioConnection{\n        Args: []string{\n            \"--plugin-dir\", \"./plugins/code-reviewer\",\n            \"--plugin-dir\", \"./plugins/lint-fix\",\n        },\n    },\n})\nif err := client.Start(ctx); err != nil {\n    return err\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\nusing GitHub.Copilot;\n\nawait using var client = new CopilotClient(new CopilotClientOptions\n{\n    Connection = RuntimeConnection.ForStdio(args: new[]\n    {\n        \"--plugin-dir\", \"./plugins/code-reviewer\",\n        \"--plugin-dir\", \"./plugins/lint-fix\",\n    }),\n});\n\nawait client.StartAsync();\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n```java\nvar options = new CopilotClientOptions()\n    .setCliArgs(new String[] {\n        \"--plugin-dir\", \"./plugins/code-reviewer\",\n        \"--plugin-dir\", \"./plugins/lint-fix\",\n    });\n\nvar client = new CopilotClient(options);\nclient.start().get();\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\nuse github_copilot_sdk::{Client, ClientOptions};\n\nlet client = Client::start(\n    ClientOptions::new().with_extra_args([\n        \"--plugin-dir\", \"./plugins/code-reviewer\",\n        \"--plugin-dir\", \"./plugins/lint-fix\",\n    ]),\n)\n.await?;\n```\n\n</div>\n\n</div>\n\n> Im obigen Beispiel wird eine Stdio-Laufzeitverbindung verwendet– der Standardwert, wenn das SDK die CLI bündelt. Wenn Sie über eine URL (`forUri` / `ForUri`) eine Verbindung zu einer externen Laufzeit herstellen, übergeben Sie `--plugin-dir` beim Starten an den langlebigen CLI-Server; das SDK leitet `--plugin-dir` nicht an Laufzeiten weiter, die es nicht selbst gestartet hat.\n\n## Vertrauenswürdige Host-gebündelte Plug-In-Verzeichnisse\n\nAnwendungen, die ihre eigenen vertrauenswürdigen Plug-Ins versenden, können sie als Clientstartoption registrieren. Das SDK sendet die vollständige geordnete Menge nach dem Herstellen der Verbindung und der Überprüfung des Protokolls, bevor `start` zurückkehrt oder eine Sitzung erstellt werden kann. Pfade müssen absolut sein; wenn die Option nicht gesetzt oder leer ist, erfolgt kein RPC-Aufruf.\n\nDie entsprechende Option in jedem SDK lautet:\n\n| SDK                  | Startoption                                           |\n| -------------------- | ----------------------------------------------------- |\n| Node.js / TypeScript | `builtinPluginDirectories: string[]`                  |\n| Python               | `builtin_plugin_directories=[...]`                    |\n| Go                   | `BuiltinPluginDirectories: []string{...}`             |\n| .NET                 | `BuiltinPluginDirectories = [...]`                    |\n| Java                 | `.setBuiltinPluginDirectories(List.of(Path.of(...)))` |\n| Rust                 | `.with_builtin_plugin_directories([...])`             |\n\nDies ist eine Vertrauensgrenze für Plugins, die gebündelt und von der Hostanwendung gesteuert werden. Es unterscheidet sich von `--plugin-dir`einem CLI-Prozessstartargument zum expliziten Laden gewöhnlicher Plug-In-Verzeichnisse. Die Startoption funktioniert auch beim Herstellen einer Verbindung mit einer vorhandenen Laufzeit, da sie über JSON-RPC und nicht als Prozessargument weitergeleitet wird.\n\n## Was ein Plug-In beitragen kann\n\nDas Laden eines Plug-In-Verzeichnisses macht seine Erweiterungen für jede vom Client erstellte Sitzung sichtbar. Die Laufzeit führt von Plug-ins bereitgestellte Erweiterungen mit allem zusammen, was Sie inline registrieren:\n\n| Plugin leistet einen Beitrag                  | Für Sitzung sichtbar als                                             |\n| --------------------------------------------- | -------------------------------------------------------------------- |\n| Fähigkeiten (`SKILL.md`, `skills/*/SKILL.md`) | Elemente in `session.skills.list()`; injizierbar nach Name           |\n| Benutzerdefinierte Agenten (`agents/*.md`)    | Verteilbar über das `task(agent_type=...)` Tool                      |\n| Hooks (`hooks.json`)                          | Wird zusammen mit Hooks ausgelöst, die über das SDK registriert sind |\n| MCP-Server (`.mcp.json`)                      | Werkzeuge und Ressourcen, die über `session.mcp.*` erreichbar sind   |\n| LSP-Server (`.lsp.json`)                      | Initialisiert über `session.lsp.initialize(...)`                     |\n\nPlug-in-Agents sind erstklassige Sub-Agents in [Flottenmodus](/de/copilot/how-tos/copilot-sdk/features/fleet-mode): Ein übergeordneter Agent kann sie über `agent_type` aufrufen, und die Laufzeit löst die Hooks `subagentStart` / `subagentStop` für sie wie bei jedem anderen Sub-Agenten aus.\n\n## Plugin-Verzeichnis vs. Marketplace-Plugins\n\nDie Laufzeitumgebung bietet zwei Möglichkeiten, Plugins zu installieren, und beide sehen für eine Sitzung gleich aus:\n\n* **Marketplace-/Direct-Repo-Plugins** werden dauerhaft über den Slash-Befehl der CLI `/plugin` oder die zugrunde liegende Nutzereinstellung `installedPlugins` installiert. Sie sind *global verfügbar* – jede Sitzung, die mit derselben Benutzerkonfiguration ausgeführt wird, hat Zugriff darauf, und sie werden bei den Regeln zur Plug-in-Erkennung berücksichtigt.\n* **`--plugin-dir` Plugins** sind *explizit und kurzlebig* – sie gelten nur für den CLI-Prozess, den Sie mit dieser Kennzeichnung gestartet haben. Sie haben Vorrang vor ambient discovery und werden gegen Marketplace-Einträge mit demselben Cachepfad dedupliziert, sodass dasselbe Plug-In nicht zweimal geladen wird, wenn beide Oberflächen darauf verweisen.\n\nFür SDK-basierte Anwendungen ist `--plugin-dir` in der Regel die richtige Wahl: Es hält den Plug-In-Satz unter der Kontrolle Ihrer Anwendung, anstatt vom benutzerspezifischen Zustand des jeweiligen Rechners abzuhängen.\n\n## Deterministisches Erstellen von Plug-in-Sets\n\nWenn auf der Hostmaschine möglicherweise andere Plugins installiert sind (aus dem Marketplace oder eigene), setzen Sie `COPILOT_PLUGIN_DIR_ONLY=true` in den Umgebungsvariablen der Laufzeitumgebung, um die automatische Erkennung von Plugins zu unterdrücken. Nur die Verzeichnisse, die Sie über `--plugin-dir` übergeben, werden geladen.\n\n<details open>\n<summary>\n<strong>Node.js / TypeScript</strong></summary>\n\n```typescript\nprocess.env.COPILOT_PLUGIN_DIR_ONLY = \"true\";\n\nconst client = new CopilotClient({\n  connection: RuntimeConnection.forStdio({\n    args: [\"--plugin-dir\", \"./plugins/code-reviewer\"],\n  }),\n});\nawait client.start();\n```\n\n</details>\n\nVerwenden Sie dies in CI, in Headless-Serverbereitstellungen und überall, wo Sie einen reproduzierbaren Plug-In-Satz wünschen, der nicht von der Benutzerkonfiguration des Hosts abhängt.\n\n## Prüfen, welche Plug-Ins geladen wurden\n\nSobald eine Sitzung erstellt wurde, führen Sie die aktiven Plug-Ins auf, um zu bestätigen, dass ein Verzeichnis richtig aufgenommen wurde:\n\n<details open>\n<summary>\n<strong>Node.js / TypeScript</strong></summary>\n\n```typescript\nconst plugins = await session.rpc.plugins.list();\nfor (const plugin of plugins.plugins) {\n  console.log(`${plugin.name} (${plugin.enabled ? \"enabled\" : \"disabled\"})`);\n}\n```\n\n</details>\n\nPlugins, die über `--plugin-dir` geladen werden, erscheinen in dieser Liste, wobei ihr Cachepfad auf das von Ihnen angegebene Verzeichnis gesetzt ist. Marketplace-Installationen werden mit ihrer Registrierungsquelle markiert.\n\n## Troubleshooting\n\n* **\"keine plugin.json oder SKILL.md in \\<dir> gefunden\"** – das Verzeichnis ist vorhanden, gilt aber nicht als Plugin. Fügen Sie ein `plugin.json` Manifest im Stammverzeichnis (oder unter `.github/`) hinzu, oder fügen Sie eine oberste Ebene `SKILL.md`ein.\n* **Plug-In geladen, aber Agents/Fähigkeiten nicht sichtbar** - stellen Sie sicher, dass das Plug-In-Manifest die Agents/Fähigkeiten deklariert, die es beiträgt, oder verwenden Sie das implizite Layout (`agents/*.md`, `skills/*/SKILL.md`). Rufen Sie dann auf `session.rpc.skills.reload()` , um Änderungen ohne Neustart zu übernehmen.\n* **Doppelte Hooks werden ausgeführt** – die Laufzeit dedupliziert anhand von `cache_path`, aber nur, wenn auf dasselbe Verzeichnis sowohl als Marketplace-Installation als auch als `--plugin-dir` verwiesen wird. Wenn zwei verschiedene Verzeichnisse dasselbe Plug-In enthalten, werden beide geladen. Entfernen Sie eine oder verwenden Sie `COPILOT_PLUGIN_DIR_ONLY=true`.\n* **`--plugin-dir` wird bei der Verbindung mit einer externen Laufzeit ignoriert** – das SDK leitet zusätzliche Argumente nur weiter, wenn es die CLI selbst startet. Für externe Laufzeiten (`forUri`/`ForUri`) übergeben Sie `--plugin-dir` in der Befehlszeile, mit der der Laufzeitserver gestartet wird.\n\n## Verwandte Themen\n\n* [Angepasste Agents und Orchestrierung von Unteragenten](/de/copilot/how-tos/copilot-sdk/features/custom-agents): Agenten schreiben, die im `agents/`Ordner des Plug-ins enthalten sind.\n* [Benutzerdefinierte Fähigkeiten](/de/copilot/how-tos/copilot-sdk/features/skills): Wie `SKILL.md` Dateien geladen werden, und die Regeln für die Reihenfolge der Fähigkeiten.\n* [Arbeiten mit Hooks](/de/copilot/how-tos/copilot-sdk/features/hooks): Von einem Plugin definierte Hooks werden zusammen mit den vom SDK registrierten Hooks ausgelöst.\n* [Verwenden von MCP-Servern mit dem GitHub Copilot SDK](/de/copilot/how-tos/copilot-sdk/features/mcp): Von Plugins bereitgestellte MCP-Server werden auf die gleiche Weise wie Inline-Registrierungen integriert.\n* [Flottenmodus](/de/copilot/how-tos/copilot-sdk/features/fleet-mode): Von Plugins bereitgestellte Agenten können als Sub-Agenten eingesetzt werden."}