MCP vs. API für KI-Agenten: Der API-Katalog ist ein Verzeichnis, und die Wahl hängt davon ab, wer dazwischen sitzt
Ein API-Katalog konkurriert nicht mit einem MCP-Server, er kann ihn auflisten. Ist das geklärt, hängt die Wahl zwischen MCP und einer per OpenAPI beschriebenen HTTP-API davon ab, ob eine Host-Anwendung deinen Dienst für das Modell einbindet und ob schon jemand entschieden hat, dich dort einzubinden.
Inhalt
Diese Website hat einen API-Katalog unter /.well-known/api-catalog. Seit dem 8. Oktober steht darin an erster Stelle der MCP-Server der Website.
Dieser eine Eintrag hebelt die Frage aus, mit der die meisten Vergleiche „MCP vs. API“ beginnen. Ein API-Katalog und ein MCP-Server sind nicht zwei Antworten auf dasselbe Problem: Der Katalog ist ein Verzeichnis, und ein MCP-Server ist eines der Dinge, auf die ein Verzeichnis zeigen kann. Vergleicht man das, worauf der Katalog zeigt, bleibt eine echte Wahl. Meiner Einschätzung nach wird sie meist entlang der falschen Variable diskutiert. Das Protokoll zählt weniger als die Frage, ob eine Host-Anwendung deinen Dienst für das Modell einbindet und ob jemand schon entschieden hat, dich dort einzubinden. Beides ist am Ende dieselbe Bedingung, von zwei Seiten betrachtet.
Was ein RFC-9727-API-Katalog tut und was nicht
RFC 9727, ein Proposed Standard vom Juni 2025, definiert eine Well-Known-URI, die ein Linkset zurückgibt, ausgeliefert als application/linkset+json. Jeder Eintrag hat einen Anchor, also den Endpunkt, und daran hängende Relationen. service-desc zeigt auf eine maschinenlesbare Beschreibung, typischerweise eine OpenAPI-Datei. service-doc zeigt auf Dokumentation für Menschen. Das erklärte Ziel ist die automatische Erkennung der öffentlichen API-Endpunkte eines Anbieters.
Mehr tut er nicht. Der RFC sagt einem Client weder, wie er sich authentifiziert, noch, wie er etwas aufruft. Er beantwortet „was gibt es hier“ und überlässt das „wie“ dem, wohin die Links führen.
Das Format selbst stammt aus RFC 9264, und es hat ein Detail, das man leicht falsch macht: Der Relationstyp ist der Name des Members, und sein Wert ist ein Array von Zielen mit einem href. Hier sind die beiden Einträge dieser Website in dieser Form, gekürzt auf die zwei Relationen aus RFC 9727:
{
"linkset": [
{
"anchor": "https://max.nardit.com/mcp",
"service-desc": [{ "href": "https://max.nardit.com/.well-known/mcp/server-card.json" }],
"service-doc": [{ "href": "https://max.nardit.com/api-docs/mcp.md" }]
},
{
"anchor": "https://max.nardit.com/api/md",
"service-desc": [{ "href": "https://max.nardit.com/api-docs/openapi.json" }],
"service-doc": [{ "href": "https://max.nardit.com/api-docs/markdown-for-agents.md" }]
}
]
}So habe ich es nicht ausgeliefert. Der Katalog, den ich im April geschrieben habe, und der, der am 18. Oktober ausgeliefert wird, legt jeden Link in ein links-Array, als Objekt mit einem rel-Feld, einem Member, den RFC 9264 nicht definiert. Ein Parser, der sich an den RFC hält, findet Anchors ohne Relationen, die er kennt. Die Datei ist gültiges JSON, hat den richtigen Content-Type, und ein Mensch versteht sie beim ersten Lesen. Genau deshalb hat mich nichts darauf hingewiesen. Das Verzeichnis ist der billigste Teil des Ganzen und offenbar auch der, den man am leichtesten lautlos falsch macht.
Der zweite Anchor ist eine HTTP-API mit einer OpenAPI-3.1-Beschreibung. Der erste ist ein MCP-Server, dessen service-desc eine Server Card ist, in der Form eines früheren Vorschlags; dessen Nachfolger SEP-2127 ist inzwischen Final und empfiehlt einen anderen Ort für die Card. Dem Katalog ist egal, welches Protokoll hinter einem Anchor steckt. Deshalb vergleicht die Frage, ob ein API-Katalog statt MCP „reicht“, ein Verzeichnis mit einem seiner Einträge.
OpenAPI und MCP: was jedes dem Aufrufer übergibt
Die beiden Einträge sind auch nicht dieselben Daten in zwei Verpackungen. Die OpenAPI-Datei beschreibt eine Operation: Gib ihr einen Pfad, bekomm die Seite als Markdown zurück. Der MCP-Server bietet drei Read-only-Tools: Kontaktdaten, die Produktliste und eine Suche über Artikeltitel und Zusammenfassungen, die kanonische URLs liefert.
Eine OpenAPI-Beschreibung ist Lesestoff für den, der den Aufruf macht. Ein Skript oder ein Agent mit einem Fetch-Tool liest sie, baut den HTTP-Request selbst und parst, was zurückkommt. Die Runtime des Agenten wendet auf diesen Fetch trotzdem ihre eigenen Regeln an, aber es sind ihre Regeln für HTTP allgemein. Dein Dienst hat mit der Runtime nichts ausgehandelt, und niemand musste vorher etwas konfigurieren: Ein Agent, der den Katalog beim Browsen gefunden hat, kann die Markdown-API nutzen, ohne mehr zu können als einen GET-Request.
MCP übergibt dem Aufrufer etwas anderes: einen Host. Die Spezifikation 2026-07-28 nennt drei Rollen: Hosts (die LLM-Anwendungen), Clients (Konnektoren im Host) und Server. Der Server spricht mit dem Host, und der Host entscheidet, was beim Modell ankommt. Er bekommt deine Tool-Namen, Beschreibungen und Schemas als typisierte Liste und legt sie dem Modell vor, entweder alle auf einmal, was noch der Normalfall ist und die Token-Kosten verursacht, über die ich geschrieben habe, oder bei Bedarf, wenn der Host sie zurückstellt. Und der Host soll einen Menschen in die Schleife holen. Das Sicherheitsprinzip der Spezifikation für Tools ist kurz:
Tools represent arbitrary code execution and must be treated with
appropriate caution.
...
Hosts must obtain explicit user consent before invoking any toolDie Tools-Seite der Spezifikation ergänzt eine harte Regel für Annotations: Clients müssen sie als nicht vertrauenswürdig behandeln, sofern sie nicht von vertrauenswürdigen Servern kommen. Zum Feld daneben, der Beschreibung, sagt sie nichts ähnlich Klares, und ich habe argumentiert, dass die Beschreibung denselben Status wie jeder fremde Autor verdient.
Beide Wege laufen also über eine Agenten-Runtime. Der Unterschied ist, ob dein Dienst in sie eingebunden ist. Mit OpenAPI ist dein Dienst ein Dokument, das der Agent liest. Mit MCP ist er eine Reihe von Tools, die der Host akzeptiert hat, dem Modell vorlegt und mit seiner eigenen Zustimmungsregel steuert.
MCP 2026-07-28 hat den Server billig gemacht: Die Kosten liegen beim Host
Unter den Revisionen von 2025 begann jede Verbindung mit einem initialize-Handshake, der eine verbindungsgebundene Session aufbaute. HTTP-Session-IDs waren mit der Revision vom November 2025 schon optional, der Handshake nicht. Die aktuelle Spezifikation streicht ihn. Ihr Basisprotokoll nennt „stateless, self-contained requests“ mit Capability-Aushandlung pro Request, und beim Streamable-HTTP-Transport ist jede Nachricht ein HTTP-POST an einen einzigen Endpunkt, beantwortet mit einem JSON-Objekt oder einem Stream, der auf diesen Request beschränkt ist.
Der Server auf dieser Website ist ein einziger Route-Handler auf einer Serverless-Funktion. Er beantwortet POST, gibt auf GET 405 zurück, hält keine Sessions und braucht keine Authentifizierung, weil die Daten öffentlich sind. Den älteren initialize-Handshake beantwortet er trotzdem noch, wie es der Abschnitt der Spezifikation zur Abwärtskompatibilität beschreibt. Den Server zu schreiben ist nicht mehr der teure Teil.
Was nicht billiger wurde, liegt auf der Seite des Hosts. Jemand muss deinen Server finden und zulassen, von Hand in der Konfiguration eines Clients oder über eine Registry. Viele Hosts laden immer noch jede Definition vorab in den Kontext, und ob sie zurückgestellt werden, entscheidet der Host, nicht du. Die Prinzipien im Überblick sagen, der Host muss die Zustimmung einholen; die Tools-Seite schwächt das zu einem Menschen in der Schleife ab, der einen Aufruf ablehnen können sollte, und überlässt die Interaktion dem Host. In der Praxis ist das eine Abfrage beim ersten Aufruf, eine Allowlist pro Tool oder eine Bestätigung bei jedem Aufruf. Bei einer bereits freigegebenen, harmlosen Abfrage bringen wiederholte Rückfragen wenig. Wertlos sind sie selbst dann nicht: Mein Suchtool nimmt eine Freitext-Anfrage, und eine Anfrage kann etwas Privates aus der Session des Nutzers zu einem Server tragen, den er sich nie angesehen hat.
Wo „MCP für Agenten, REST für Code“ danebenliegt
Die übliche Einzeiler-Trennung sagt: MCP ist die Schnittstelle für KI-Agenten, eine REST-API die Schnittstelle für Programme. Beide Hälften gehen daneben.
Ein Agent mit einem Web-Fetch-Tool ist ein REST-Client. Er kann eine OpenAPI-Datei lesen oder einfach eine Seite mit Accept: text/markdown anfordern, und für öffentliche Inhalte ist das der kürzeste Weg überhaupt. Er braucht keine Konfiguration und trägt keine Tool-Liste von dir im Kontext. Wenn deine Aufrufer Agenten sind, die über die Suche oder einen Link hereinkommen, ist ein MCP-Server etwas, das sie nicht nutzen können, solange kein Host, der MCP spricht, ihn gefunden hat und sich mit ihm verbinden darf. Der Katalog kann auf den Server zeigen, und eine Server Card kann ihn beschreiben. Eine Verbindung stellt keins von beiden her.
Hier widerspreche ich einem Satz, den ich letzte Woche geschrieben habe. Beim Vergleich des MCP-Endpunkts mit In-Page-WebMCP-Tools nannte ich ihn den, den ein Agent heute erreichen kann. Gegenüber WebMCP stimmt das. Gegenüber einer Markdown-API, die gar keinen Client braucht, ist er der zweite Weg, nicht der erste.
MCP wiederum bedient eher Hosts als Agenten, und über sie die Menschen, die diese Hosts betreiben und entschieden haben, deinen Dienst anzubinden. Diese Entscheidung ist das, was MCP dir einbringt: Ist sie gefallen, stehen deine Tools in diesem Client bereit, ohne dass das Modell dich erst finden muss, typisiert und vom Host gesteuert. Das Publikum ist kleiner als „Agenten“ und verbindlicher.
Die Trennung, die ich verwenden würde, ist also nicht Agent gegen Code. Es ist ein Fremder gegen eine installierte Integration. Ein Fremder braucht einen lesbaren, auffindbaren Endpunkt. Eine installierte Integration kann sich einen Host in der Mitte leisten und hat echten Nutzen davon, sobald es ein Credential zu verwahren gibt oder eine Aktion, bei der sich Nachfragen lohnt.
WebMCP im offenen Tab: die dritte Tür und die, die diese Website am wenigsten braucht
Es gibt einen dritten Aufrufer: einen Agenten, der einen Browser-Tab steuert, in dem eine Seite Tools für die Session registrieren kann, in der sie schon läuft. Der oben verlinkte Beitrag beschreibt, wie die WebMCP-Registrierung jetzt funktioniert, einschließlich der Stelle, an der mein In-Page-Skript noch nach einem Objekt sucht, das der aktuelle Entwurf nicht mehr definiert. In einem aktuellen Browser stellt diese Tür also nichts bereit. Der Punkt hier ist enger. WebMCP passt, wenn der nützliche Zustand im Tab liegt: ein Warenkorb, ein halb ausgefülltes Formular, eine eingeloggte Ansicht. Eine öffentliche Website, die allen dieselbe Antwort gibt, hat keinen solchen Zustand.
Brauchst du einen MCP-Server? Die erste Frage
Bevor du ein Protokoll wählst, beantworte eine Frage: Wer hat schon entschieden, dich zu nutzen?
Lautet die ehrliche Antwort „noch niemand“, und deine Aufrufer wären Agenten, die dich beim Durchsuchen des Webs finden, dann bau zuerst den einfachen Weg. Mach die Inhalte über HTTP lesbar, beschreib sie mit OpenAPI, wenn es mehr als eine Operation gibt, und trag sie in einen API-Katalog ein, damit ein Crawler sieht, was es gibt. Agenten mit normalem HTTP-Zugriff können sie dann nutzen, ohne vorab ein Schema von dir zu laden; was sie abrufen, kostet sie trotzdem Kontext, aber erst, wenn sie es abrufen.
Gibt es Menschen oder Teams, die dich gezielt anbinden werden, in einem Client, den sie schon nutzen, beginnt MCP sich zu lohnen, und zwar umso mehr, je näher du an dem bist, was ein Host gut kann: ein Credential, das der Host für den Nutzer verwahrt, eine schreibende Aktion, bei der die Zustimmungsabfrage ihren Zweck erfüllt, oder ein Tool, zu dem die Arbeit so oft greift, dass es sich lohnt, es im Kontext zu halten.
Und wenn du beides baust, trag beides in den Katalog ein und prüf ihn dann mit einem Parser, der RFC 9264 folgt, nicht mit deinen eigenen Augen. Er ist das eine Teil, das vom Aufrufer nichts verlangt, und meiner hat einem strengen Parser sechs Monate lang nichts gesagt, bevor ich hingesehen habe.
01 / Diskussion
Hier gibt es keine Kommentarspalte. Diskussionen laufen auf X.
02 / Weitere Artikel
Claude Code Fork-Subagents in claude -p: was 2.1.302 für Headless-Runs geändert hat
Angeboten heißt nicht benutzt: Ein Modell im Headless-Modus wählt den Fork vielleicht nie, und die offizielle Doku beschreibt noch den alten Standard. Wie du prüfst, welchen Subagent deine Pipeline genutzt hat, warum ein Fork im Hintergrund einem Parser zwei Antworten liefert und wo sich das Abschalten lohnt.
Claude Code Review ist GA: die Review-Schichten drumherum und welche du ohne Team-Plan übernehmen kannst
Das meiste, was den Prozess des Claude-Code-Teams trägt, sind GitHub-Einstellungen und schriftliche Regeln, und die laufen auf jedem Plan. Was sich nicht übertragen lässt, ist die Herkunft der Regeln. Der Managed Service holt sie aus einem Branch, den der Pull Request nicht anfassen kann; ein lokales Review liest, was auf der Platte liegt, einschließlich einer Regeldatei, die der geprüfte Change gerade geändert hat.
Claude API OpenTelemetry: SDK und API tracen, ohne Tokens doppelt zu zählen
Die Input-Token-Zahl eines Spans enthält Cache-Reads und Cache-Writes bereits. Die Abfrage, die sich natürlich anfühlt, wenn du die Messages API kennst, zählt den gecachten Prefix deshalb doppelt. Setup für die SDK-Hälfte, getestet gegen einen lokalen Mock, die Console-Destination laut Doku und die Subtraktion, die dich zum ungecachten Input zurückbringt.