Capability-Design: Tools und Resources mit enger Wirkung
Ein universelles run_api kann jeden Backend-Endpunkt treffen, eine Resource leakt temporäre Dateipfade und ein Status-Tool liefert 80 MiB Logs. Alles ist technisch erreichbar — nichts davon ist eine belastbare Capability.
Lehrtext · 10 Abschnitte · zuletzt geprüft: 2026-09-04
Eine Capability ist eine kuratierte Außensicht
Ein MCP-Server ist kein automatischer Spiegel seiner REST-Endpunkte, Tabellen und Admin-Skripte. Er veröffentlicht eine absichtlich kleine Außensicht für einen probabilistischen Aufrufer. Ein Modell wählt anhand von Namen, Beschreibung und Schema; es kennt weder interne Konventionen noch die stillen Voraussetzungen eines menschlichen Operators. Deshalb muss die Capability die fachliche Absicht ausdrücken und gefährliche Freiheitsgrade entfernen.
- Backend-Oberfläche
- Für bekannte Entwickler; oft technisch, breit und historisch gewachsen
- MCP-Capability
- Für Host und Modell; fachlich benannt, eng validiert und erklärbar
- Policy-Grenze
- Autorisiert Wirkung unabhängig von Beschreibung und Modellwahl
Beginne das Design mit realen Aufgaben und Missbrauchsgrenzen. Welche Nutzerfrage soll beantwortet werden, welche Wirkung ist maximal nötig, welche Identität trägt sie und welches Ergebnis braucht der nächste Schritt? Erst danach werden bestehende Endpunkte zugeordnet. Wer mit einer API-Liste startet, veröffentlicht fast zwangsläufig deren historische Schnitte. Eine kleine Capability darf intern mehrere Aufrufe bündeln, solange sie eine kohärente Fachoperation bleibt und keine neue Entscheidung versteckt. Nachteil: Die Übersetzung kann Backendfunktionen zunächst unzugänglich lassen; Erweiterung folgt nachgewiesenem Bedarf statt vorsorglicher Vollständigkeit.
Tool oder Resource folgt aus der Kontrollrichtung
Ein Tool ist modellgesteuert: Das Modell kann eine parametrisierte Operation auswählen. Eine Resource ist anwendungsgesteuert: Der Host wählt adressierbaren Kontext und liest ihn. Lesen gegen ein Backend ist nicht automatisch Resource. Soll das Modell mit Suchparametern eine Abfrage initiieren, kann ein lesendes Tool richtig sein. Soll der Host ein bekanntes Runbook unter stabiler URI in den Kontext legen, ist eine Resource näher am gewünschten Kontrollmodell.
tickets/searchmit Status und Team- Tool: Modell initiiert eine parametrisierte Suche
runbook://payments/timeout- Resource: Host liest eine bekannte Kontextentität
restart_service- Tool: angeforderte Operation mit sichtbarer Wirkung
cmdb://acme/services/billing- Resource: adressierbarer Zustand für Kontext
Kurzcheck
Ein Host kennt die URI eines freigegebenen Runbooks und soll dessen Inhalt gezielt in den Kontext legen. Welche Grundform passt?
- Eine Resource mit stabiler URI
- Ein universelles Shell-Tool
- Ein Prompt ohne Resource-Bezug
Treffer. Richtig. Der Host kontrolliert die Auswahl eines adressierbaren Kontextobjekts.
Manche Fähigkeiten brauchen beide Formen. Eine Resource beschreibt einen Change, ein Tool genehmigt ihn. Das ist kein Duplikat: Lesen und Wirkung haben verschiedene Kontroll- und Autorisierungsgrenzen. Nachteil: Mehr Einträge erhöhen Discovery- und Dokumentationsaufwand. Kombiniere sie trotzdem nicht zu einer Mehrzweckfähigkeit, wenn dadurch Zustimmung oder Datenfluss unklar werden.
Auch Kosten können die Kontrollform verändern. Das Lesen einer bereits erzeugten Logresource ist erwartbar nebenwirkungsarm. Eine minutenlange Aggregation, die Compute verbraucht und einen persistenten Export anlegt, ist eine Operation, selbst wenn ihr Ergebnis nur gelesen wird. Ein sinnvolles Muster ist create_log_export plus Ergebnis-URI: Das Tool macht Auslösung, Parameter und Kosten sichtbar; die Resource macht das fertige Artefakt adressierbar. Der zweistufige Ablauf kostet einen zusätzlichen Call, verhindert aber, dass Hosts vermeintlich billiges Kontextlesen ungefragt vervielfachen.
Tools werden nach Aufgaben geschnitten, nicht nach Endpunkten
Ein Modell trifft zuverlässiger, wenn ein Tool eine verständliche Aufgabe kapselt. get_deployment_status darf intern drei APIs abfragen und Fehler übersetzen. Drei rohe Tools für Datenbank-ID, Queue-Job und Deployment-API zwingen dagegen Host und Modell, die heutige interne Orchestrierung nachzubauen. Jede Backend-Umstellung wird dann zur externen Vertragsänderung.
Tool-Granularität — Der Umfang einer veröffentlichten Operation: zu fein erzwingt fragile Aufrufketten, zu grob versteckt Entscheidungen und erweitert die Wirkung.
- Benenne die fachliche Aufgabe und ihr Ergebnis.
- Halte zusammen, was atomar oder mit gemeinsamer Fehlerbehandlung ausgeführt werden muss.
- Trenne Schritte, wenn dazwischen Nutzerzustimmung oder neue Information nötig ist.
- Veröffentliche keine universelle Pass-through-Schnittstelle für beliebige Backend-Befehle.
Deployment prüfen statt drei APIs spiegeln
Szenario
Ein Server ermittelt Rolloutstatus aus Orchestrator, Monitoring und Change-System.
Anforderungen
- Stabile Deployment-Referenz
- dokumentiertes Statusmodell
- kontrollierte Diagnosefelder
Schritte
get_deployment_statusnimmt die fachliche Referenz- Server ruft interne Systeme auf
- Server normalisiert Fehler und Status
- Host erhält einen stabilen Output-Vertrag
Merksatz: Kapselung verschiebt Komplexität an die Stelle, die Backendwissen und Autorität besitzt.
Zu grob ist die Gegenrichtung. Ein manage_customer, das abhängig von optionalen Feldern sucht, anlegt, sperrt oder löscht, zwingt das Modell zu impliziter Moduswahl und macht Freigaben unverständlich. Getrennte Tools können unterschiedliche Rechte, Beschreibungen und Approval-Stufen tragen. Atomare Fachoperationen dürfen trotzdem mehrere technische Schritte enthalten. Die Grenze liegt dort, wo eine neue Nutzerentscheidung, andere Berechtigung oder eigenständig behandelbare Wirkung beginnt. Preis: Mehr Tools vergrößern die Kandidatenmenge; der Host muss sie nach Aufgabenkontext kuratieren.
Name, Beschreibung und Input-Schema arbeiten zusammen
Die aktuelle Spezifikation verlangt für ein Tool name, description und ein valides inputSchema. Der Name identifiziert, die Beschreibung erklärt Zweck und relevante Grenzen, das Schema begrenzt Form und Werte. Kein Feld kann die anderen ersetzen. execute mit perfektem Schema bleibt semantisch unklar; delete_backup mit freiem Objekt bleibt gefährlich offen.
- Name
- Stabile, unterscheidbare Aufgabe; innerhalb des Servers eindeutig
- Beschreibung
- Wann nutzen, Wirkung, wichtige Ausschlüsse und Ergebnis
inputSchema- Zulässige Argumente, Pflichtfelder, Typen und Wertebereiche
outputSchema- Optionale prüfbare Form von
structuredContent
Toolnamen sollen kurz, case-sensitive und innerhalb eines Servers eindeutig sein. Aggregierende Hosts können trotzdem Namenskollisionen zwischen Servern sehen; der selbst gemeldete Servername ist dafür keine sichere globale ID. Beschreibungen gehören in einen Review, weil sie die Modellauswahl beeinflussen. Sie sind aber keine Policy. Der Server validiert jedes Argument und autorisiert die konkrete Operation auch dann, wenn das Modell exakt die dokumentierte Form liefert.
Beschreibungen brauchen positive und negative Abgrenzung, wenn Nachbartools ähnlich wirken. Bei draft_customer_email und send_customer_email genügt nicht zweimal eine Paraphrase des Namens. Die Beschreibung des Entwurfs sagt, dass keine Nachricht versendet wird; die Versandbeschreibung nennt die externe Wirkung und erforderliche Freigabe. Konkrete Enums, Formate und Bounds gehören ins Schema, nicht nur in Prosa. Umgekehrt gehört die fachliche Bedeutung eines Feldes nicht ausschließlich in ein Regex. Gute Auswahl entsteht aus konsistentem Namen, Beschreibung und Schema; Widersprüche machen den Vertrag für Modell und Mensch ratbar.
Output, Fehler und Annotations bleiben untrusted
Toolresultate können content und structuredContent enthalten. Wenn outputSchema veröffentlicht ist, muss die strukturierte Ausgabe dazu passen; Clients sollen sie validieren. Struktur ist jedoch kein Wahrheitsbeweis. Ein kompromittiertes Backend kann schema-valide falsche Daten oder manipulative Texte liefern. Der Host behandelt Resultate daher als externe Eingabe, bevor er sie an das Modell oder ein weiteres Tool weitergibt.
Protokollfehler und Tool-Ausführungsfehler haben unterschiedliche Adressaten. Eine unbekannte Methode oder malformed Request gehört in einen JSON-RPC-Fehler. Ein fachlich ungültiges Datum oder abgelehnter Geschäftsfall kann als Toolresultat mit isError: true zurückkommen, damit das Modell die Argumente korrigiert. Diese Trennung gehört zum Capability-Design: Ein Modell kann nur auf Fehler reagieren, die in einer für es nutzbaren Form vorliegen.
Annotations wie readOnlyHint, destructiveHint oder idempotentHint helfen bei Anzeige und Risikoerklärung. Der Client muss sie als unvertrauenswürdig behandeln, solange der Server nicht vertrauenswürdig ist. Selbst dann bleiben sie Hinweise, keine Autorisierung. Ein Tool darf seine eigene Gefährlichkeit nicht verbindlich klassifizieren.
Ein Tool ohne Parameter braucht trotzdem ein objektförmiges inputSchema. type: object akzeptiert zusätzliche Properties; mit additionalProperties: false wird ausdrücklich nur das leere Objekt akzeptiert. Diese kleine Differenz zeigt, warum Defaultverhalten Teil des Designs ist. Für strukturierte Ausgaben beschreibt outputSchema die erwartete Form; der Server muss structuredContent daran halten, der Client soll validieren. Für Abwärtskompatibilität empfiehlt die Spezifikation zusätzlich serialisierten Textinhalt. Das verdoppelt Darstellung, verbessert aber die Nutzbarkeit älterer oder rein textorientierter Konsumenten.
Resource-URIs sind fachliche Identitäten
Eine Resource wird über eine URI adressiert. Diese URI sollte eine fachliche Entität stabil benennen und nicht den heutigen Speicherort leaken. cmdb://acme/services/billing kann denselben Service meinen, egal ob die Daten aus PostgreSQL, einem Graph Store oder einer API kommen. file:///tmp/export-8472.json bindet den Host dagegen an eine temporäre Datei, Cleanup-Regeln und lokale Pfade.
Resource Template — Eine mit RFC 6570 beschriebene URI-Form für parametrisierte Resources, etwa cmdb://{tenant}/services/{service}.
- Stabile Identität
- Fachobjekt und dokumentierte Lesesemantik bleiben gleich
- Template-Variable
- Erlaubte Variabilität ist sichtbar und vervollständigbar
mimeType- Hilft bei Darstellung und Verarbeitung, ist aber nur Metadatum
- Autorisierung
- Prüft jede konkrete URI unabhängig von ihrer syntaktischen Gültigkeit
Ein eigenes URI-Schema kostet Dokumentation und Migration. Dafür löst es Identität von Deploymentdetails. Nutze HTTPS nicht automatisch nur deshalb, weil der Backendinhalt aus dem Netz stammt. MCP-Resource-URIs sind Vertragsschlüssel; ob und wie der Server Daten lädt, bleibt seine Implementierung.
Stabil bedeutet nicht unveränderlich. Wird ein Dokument fachlich ersetzt, kann dieselbe URI die aktuelle Fassung bezeichnen, wenn genau das dokumentierte Modell ist. Muss ein Audit eine konkrete Fassung wiederfinden, braucht die Version eine eigene stabile Identität oder Metadatum mit unveränderlichem Abruf. Der Server darf diese Semantik nicht aus einem Dateipfad ableiten, den niemand außerhalb kennt. Plane außerdem Löschung und Nichtfund als Vertragsfälle: Ein unbekannter oder nicht erlaubter Bezeichner darf keine internen Pfade, Tenantnamen oder Existenzunterschiede verraten.
Templates begrenzen Auswahl, ersetzen aber keine Policy
Resource Templates machen variable Segmente sichtbar. Sie helfen Hosts, mögliche URIs zu konstruieren und Argumente zu vervollständigen. Ein Template inventory://{tenant}/hosts/{name} sagt jedoch nicht, welche Tenantwerte der aktuelle Aufrufer verwenden darf. Der Server muss die aufgelöste URI gegen die Autorisierung dieses Requests prüfen.
resources/list, resources/templates/list und resources/read sind cachebar und liefern ttlMs sowie cacheScope. Eine öffentliche Cache-Scope ist nur korrekt, wenn der Inhalt wirklich zwischen Nutzern und Tokens geteilt werden darf. Bei mandantenspezifischen Listen oder Reads ist private die sichere Semantik. TTL beschreibt erwartete Frische und ist weder Berechtigungsdauer noch Unveränderlichkeitsgarantie.
RFC 6570 beschreibt, wie Variablen expandiert werden; es definiert nicht ihre Domäne. Der MCP-Server dokumentiert daher, welche Werte sinnvoll sind, und validiert nach Expansion. Completion kann Werte vorschlagen, ist aber weder vollständige Aufzählung noch Berechtigungsnachweis. Ein Client darf einen vorgeschlagenen Tenant nicht als freigegeben behandeln. Ebenso darf der Server aus einer korrekt expandierten URI keine Identität des Nutzers ableiten. Syntaktische Konstruktion, fachliche Existenz und Autorisierung bleiben drei getrennte Prüfungen mit bewusst gleichförmigen Fehlern, wo Existenz vertraulich ist.
Antwortgröße ist Teil der Capability
Eine Resource, die ein 80-MiB-Log liefert, kann protokollkonform und trotzdem unbrauchbar sein. Der eigentliche Konsument ist häufig ein begrenztes Kontextfenster. Ebenso schadet ein Tool, das tausende Treffer ohne Cursor oder Auswahlkriterium zurückgibt. Größe, Pagination, Filter und Zusammenfassung sind daher Capability-Entscheidungen, nicht spätere Performance-Tweaks.
- Biete stabile Filter und begrenzte Trefferzahlen statt freier Vollabzüge.
- Verweise auf Resources, wenn ein Toolresultat umfangreichen Kontext nur adressieren soll.
- Nutze
outputSchemafür maschinenlesbare Kerndaten und knappen Text für das Modell. - Gib klare Trunkierungs- oder Pagination-Signale statt still abgeschnittener Wahrheit.
Kleine Antworten sparen Tokens und Latenz, können aber entscheidende Details verbergen. Die richtige Grenze folgt aus der Aufgabe: Statusübersicht zuerst, gezielte Detail-Resource danach. Ein willkürliches globales Zeichenlimit ist einfacher, macht aber fachlich zusammengehörige Daten unvollständig. Der Vertrag muss deshalb Auswahl und Nachladen ermöglichen.
Der Server sollte Größenlimits nicht nur dokumentieren, sondern durchsetzen. Filter, limit, Cursor und gezielte Detail-URIs begrenzen Arbeit vor der Materialisierung. Stilles Abschneiden ist gefährlich, weil ein Modell Vollständigkeit annehmen kann. Gib stattdessen nextCursor, eine klare Trunkierungsangabe oder einen Link zum nächsten Detail zurück. Auch eingebettete Resources in Toolresultaten zählen zum Kontextbudget. Nachteil: Mehrstufiges Nachladen kann zusätzliche Modellrunden erzeugen; der Gewinn ist ein sichtbarer, steuerbarer Vollständigkeitsvertrag statt zufälliger Tokenüberschreitung.
Ein Legacy-Wrapper übernimmt Verantwortung
Beim Anbinden eines Altsystems entsteht ein neuer öffentlicher Vertrag. Der Wrapper darf interne IDs, breite Servicekonten, zustandsbehaftete Transaktionen und rohe Fehlermeldungen nicht ungefiltert durchreichen. Er übersetzt eine fachliche Operation, validiert Argumente, bindet Identität, begrenzt Wirkung und normalisiert Fehler. Sonst wird aus einer historisch gewachsenen Admin-API eine modellgesteuerte Fernbedienung.
Alte Job-API kontrolliert veröffentlichen
Szenario
Die API akzeptiert freien Jobnamen, interne Server-ID und ein privilegiertes Servicekonto.
Anforderungen
- Erlaubte Jobtypen als Enum
- fachliche Zielreferenz
- serverseitige Tenant- und Rechteprüfung
- normalisierte Ergebnisform
Schritte
- Backendoperationen inventarisieren
- nur benötigte Fachaufgabe wählen
- freie Parameter durch enge Domänenwerte ersetzen
- Servicekonto hinter Policy und Audit halten
- rohe Fehler in dokumentierte Klassen übersetzen
Merksatz: Der Wrapper ist Sicherheits- und Semantikgrenze, nicht bloß Protokolladapter.
Diese Übersetzung kostet Entwicklungsarbeit und kann nicht jede exotische Backendfunktion sofort abdecken. Genau das ist ihr Wert. Eine enge Capability macht bewusste Lücken sichtbar; ein generisches call_legacy_api tarnt unbegrenzte Wirkung als Flexibilität.
Technische Konten des Wrappers brauchen dieselbe Enge wie der veröffentlichte Vertrag. Ein schmales Tool vor einem Konto mit Vollzugriff begrenzt nur den vorgesehenen Codepfad; ein Implementierungsfehler oder neues Pass-through-Feld kann die breite Berechtigung wieder freilegen. Nutze nach Möglichkeit getrennte Downstream-Rechte pro Aufgabenklasse, prüfe Objekt- und Tenantbezug serverseitig und protokolliere die fachliche Operation statt nur den technischen Endpunkt. Nachteil: Zusätzliche Konten und Policyregeln erhöhen Provisionierungsaufwand. Sie machen die behauptete Wirkfläche jedoch auch auf der letzten durchsetzbaren Ebene wahr.
Neun Entscheidungen prüfen die Oberfläche
Im Check schneidest du Tools nach Aufgaben, stabilisierst Resource-URIs, verbesserst Beschreibung und Schema, wählst Templates, trennst Tool von Resource, begrenzt die sichtbare Toolmenge und Antwortgröße, kapselst ein Legacy-Backend und weist eine generische Pass-through-Fähigkeit zurück. Nutze dabei vier Fragen: Wer initiiert? Welche fachliche Bedeutung bleibt stabil? Welche Wirkung und Datenmenge sind maximal möglich? Welche Backenddetails dürfen sich ändern, ohne Hosts zu brechen?
Beurteile jede Option auch gegen ihren Preis. Ein aufgabenorientiertes Tool verschiebt Orchestrierung in den Server. Eine stabile URI erzeugt einen langfristigen Namensvertrag. Kleine Resources verlangen gezieltes Nachladen. Hostseitige Toolprofile brauchen Pflege. Enge Datenbankrechte begrenzen spontane Ad-hoc-Abfragen. Diese Kosten sind kein Argument für eine universelle Oberfläche; sie zeigen, welche Verantwortung die sichere Wahl tatsächlich übernimmt. Wenn eine Lösung nur deshalb einfach wirkt, weil sie Validierung, Auswahl oder Autorisierung an Modell und Nutzer weitergibt, ist die Komplexität nicht verschwunden, sondern an eine schwächere Grenze gewandert.
Jetzt anwenden
Diesen Stoff gibt es als Modul mit bewerteten Entscheidungs-Checks — dieselbe Einführung, danach die Übungen.
Zum Modul →Quellen & Aktualität8 Primärquellen · zuletzt geprüft:
- 01Model Context Protocol Specification 2026-07-28 — Architecture
- 02Model Context Protocol Specification 2026-07-28 — Tools
- 03Model Context Protocol Specification 2026-07-28 — Resources
- 04Model Context Protocol Specification 2026-07-28 — Caching
- 05JSON Schema Validation Draft 2020-12
- 06RFC 6570 — URI Template
- 07rfc-editor.org/rfc/rfc3986
- 08modelcontextprotocol.io/specification/2026-07-…urity_best_practices