Leitfaden zur Implementierung der MCP-Server-Authentifizierung: Verwendung der neuesten Spezifikation
Bietet wichtige Implementierungspunkte für die MCP-Server-Authentifizierung gemäß der Spezifikation vom 18.06.2025.
Vor einigen Tagen (18. Juni 2025) veröffentlichte das MCP (Model Context Protocol) Team die neueste Version der MCP-Spezifikation (2025-06-18). Dieses Update enthält eine entscheidende Änderung an der Authentifizierungsspezifikation. MCP-Server agieren nicht mehr als Authorization Server und geben keine Access Tokens mehr aus. Stattdessen nehmen sie Access Tokens entgegen und bieten ihre Ressourcen als Resource Server an.
Als einer der Maintainer von MCP Auth (einer Plug-and-Play Authentifizierungsbibliothek für MCP-Server) habe ich in diesem Projekt bereits Unterstützung für die neueste MCP-Auth-Spezifikation umgesetzt. Basierend auf meinen praktischen Erfahrungen zeige ich dir, wie du Authentifizierungsfunktionen für deinen MCP-Server implementierst, die mit der neuesten Spezifikation konform gehen.
Dieser Artikel hilft dir...
- zu verstehen, wie MCP-Authentifizierung nach der neuen Auth-Spezifikation funktioniert
- klarzustellen, was MCP-Server als Resource Server gemäß der MCP-Auth-Spezifikation umsetzen müssen
- Leitlinien zu geben, wie du Authentifizierungs-Support implementierst, der die neuesten Anforderungen der MCP-Auth-Spezifikation für deinen MCP-Server erfüllt
- häufig übersehene Punkte und Sicherheitsaspekte bei der Implementierung der MCP-Auth-Spezifikation zu erkennen
Beachte, dass dieser Artikel...
- grundlegende Kenntnisse zu JWT (JSON Web Token) voraussetzt. JWT-Struktur, Signaturprüfung und andere Basics werden nicht ausführlich behandelt. Für Details siehe Auth Wiki - JWT
- die diversen RFCs, von denen die MCP-Auth-Spezifikation abhängt, nicht tiefgehend behandelt. Es werden nur beispielhafte Umsetzungen gezeigt, die den RFC-Anforderungen entsprechen
- keine Details zur Implementierung und Interaktion von MCP-Client und Authorization behandelt. Diese werden meist von LLM-Clients und Authorization-Servern umgesetzt, die MCP laut Spezifikation unterstützen. MCP-Server-Entwickler müssen und können auf diese Implementierungen nicht einwirken. Für Details siehe OAuth Client und Authorization Server
- in allen Beispielen JWTs als Access Token-Format voraussetzt, da dies das marktweit gängigste Format ist. Für andere Tokentypen nutze die Dokumentation des jeweiligen Authorization Server Providers.
Wie funktioniert MCP-Authentifizierung?
Laut aktuellem MCP Auth Spec ist der Authentifizierungs-Ablauf in folgender Grafik dargestellt:
-
Der MCP-Client fordert Ressourcen vom MCP-Server unter
https://github-tools.com
an. Da der Nutzer noch nicht eingeloggt ist, enthält der HTTP-Authorization-Header kein Access Token für den Nutzer. -
Der MCP-Server findet kein Access Token im Authorization-Header der Clientanfrage und gibt einen HTTP 401 Fehler mit einem WWW-Authenticate-Header zurück. Dieser Header enthält die URL zu den Resource Metadaten des MCP-Servers (Wert im Feld
resource_metadata
). -
Der MCP-Client extrahiert den Wert von
resource_metadata
aus dem zurückgegebenen WWW-Authenticate-Header (z.B.https://github-tools.com/.well-known/oauth-protected-resource
). Dann fragt der Client die Resource Metadaten von der MCP Server-Adresse als Resource Server ab. Diese Metadaten enthalten Felder wieauthorization_servers
undscopes_supported
und helfen dem Client, herauszufinden, bei welchem Authorization Server er sich ein Token mit bestimmten Zugriffsrechten holen kann.
4-8. Der MCP-Client ruft basierend auf der Metadaten-URL des Authorization Servers die AS-Metadaten ab. Dann erfolgt eine OAuth 2.1-Authentifizierung beim Authorization Server, bis ein Access Token ausgegeben wird.
-
Der MCP-Client sendet die Ressourcennachfrage erneut an den Server und trägt dabei das erhaltene Access Token bei.
-
Der MCP-Server gibt nach erfolgreicher Token-Validierung die angeforderten Ressourcen zurück. Danach läuft die Kommunikation mit dem gültigen Token weiter.
Als nächstes erklären wir Schritt für Schritt, wie du den Authentifizierungsmechanismus des MCP-Servers nach diesem Flow implementierst.
Umgang mit unautorisierten Anfragen: 401-Fehler und WWW-Authenticate Header zurückgeben
Wie oben gezeigt: Wenn der MCP-Client eine Anfrage ohne Access Token an den MCP-Server sendet, antwortet der Server mit HTTP 401 Unauthorized und einem WWW-Authenticate
-Header, der die URL für die Resource Metadaten enthält.
Laut MCP Auth Spec Error Handling soll der MCP-Server nicht nur bei fehlenden Tokens, sondern auch bei ungültigen Access Tokens einen 401 Fehler mit WWW-Authenticate
-Header zurückgeben.
Aber wann und wie baut man diesen Header korrekt?
Nach RFC9728 Abschnitt 5.1 muss der WWW-Authenticate
-Header ein resource_metadata
-Parameter mit der Metadaten-URL enthalten.
Das Grundformat ist:
Bearer
steht dabei für das Authentifizierungsschema. Es signalisiert, dass für Ressourcen mit OAuth 2.0 Schutz ein Bearer Token benötigt wird (siehe: MDN Dokumentation). Der Wert im resource_metadata
-Parameter ist die vollständige URL zum Resource-Metadaten-Endpunkt deines MCP-Servers.
Der zugehörige Beispiel-Code sieht so aus:
Erhält der MCP-Client diesen 401-Fehler, wird er die MCP-Server-Resource-Metadaten unter resource_metadata
aus dem Header abrufen und sich anschließend am angegebenen Authorization Server ein entsprechendes Token besorgen.
Wir wissen nun, wann der Fehler-Header inkl. URL zu setzen ist – aber wie wird die Resource-Metadaten-URL aufgebaut und was genau steht eigentlich in diesen Metadaten? Darum geht es im nächsten Abschnitt.
Implementiere den Resource-Metadaten-Discovery-Mechanismus
Nach dem Flow fordert der Client nach einer 401-Antwort die Resource-Metadaten vom MCP-Server ab. Dieser muss daher ein Discovery-Mechanismus für Metadaten als Resource Server bereitstellen.
Ermittlung des URL-Pfads für den Metadaten-Endpunkt
Im OAuth-Kontext verwenden wir URLs als „Resource Identifier“. Laut RFC9728 müssen Resource Metadaten unter einem bestimmten /.well-known
-Pfad bereitgestellt werden.
Bietet dein MCP-Server (z. B. https://github-tools.com
) nur einen Service an, sollte der Endpunkt lauten:
Wenn du mehrere verschiedene MCP-Dienste auf einem Host anbietest, soll jeder Dienst einen eigenen Metadaten-Endpunkt haben – z. B. hat die Plattform https://api.acme-corp.com
diese Dienste:
https://api.acme-corp.com/github
- GitHub-Integrationsservicehttps://api.acme-corp.com/slack
- Slack-Integrationsservicehttps://api.acme-corp.com/database
- Datenbankabfrageservice
Die zugehörigen Metadaten-Endpunkte wären dann:
https://api.acme-corp.com/.well-known/oauth-protected-resource/github
https://api.acme-corp.com/.well-known/oauth-protected-resource/slack
https://api.acme-corp.com/.well-known/oauth-protected-resource/database
Vorteil: Jeder Dienst kann eigene Berechtigungs-Scopes und Authorization Server haben. Zum Beispiel:
- GitHub-Service nutzt den GitHub-OAuth-Server, benötigt die Scopes
github:read
,github:write
- Slack-Service nutzt Slack-OAuth, benötigt Scopes wie
slack:channels:read
,slack:messages:write
- Datenbank-Service nutzt einen internen Authorization Server, benötigt Scope
db:query
Daraus ergibt sich als Muster für Metadaten-URLs:
Man kann so anhand des Resource Identifiers die Adresse des passenden Metadaten-Endpunkts bestimmen:
Aufbau der Resource-Metadaten-Antwort
Nachdem der Endpunktpfad bestimmt ist, muss dieser eine JSON-Antwort gemäß RFC9728 liefern.
Kernfelder für die Implementierung sind:
Als erstes das Feld resource
, der Resource Identifier, identisch mit der MCP-Resource-Adresse.
Als nächstes das obligate Array authorization_servers
, das angibt, bei welchen Authorization Servern sich der Client ein Token holen darf/soll. Laut OAuth 2.0 Protected Resource Metadata (RFC 9728) ist das Feld optional, die MCP-Auth-Spezifikation verlangt es jedoch, damit der Client genau weiß, wo er sich autorisieren muss.
Das Feld scopes_supported
listet alle unterstützten Berechtigungen (Scopes).
Und schließlich bearer_methods_supported
, welches dem MCP-Client sagt, wie Tokens übergeben werden müssen: normalerweise ["header"]
für die Übergabe im HTTP-Authorization-Header.
Ein konkretes Beispiel für den MCP-Server https://github-tools.com
:
Diese Konfiguration informiert den Client darüber: Er will https://github-tools.com
ansprechen, muss sich bei https://auth.github-tools.com
autorisieren und kann die Scopes github:read
, github:write
, repo:admin
anfordern. Das Access Token muss im HTTP-Authorization-Header übertragen werden.
Für die meisten Szenarien reichen diese vier Felder aus. Für weitere Komplexität siehe RFC9728.
Validierung von Access Tokens
Nach Empfang eines Access Tokens wird dieses vom MCP-Server überprüft.
Worauf kommt es bei der Validierung an?
- Für Basis-Checks nutze die MCP-Server-Konfiguration und verlasse dich nicht nur auf Informationen aus dem Token.
- Prüfe, dass der "Audience" (aud) Eintrag im Token mit dem MCP-Server übereinstimmt, um sicherzustellen, dass das Token genau für diesen Server gedacht ist.
- Prüfe den Scope korrekt.
Verwende MCP-Server-Konfiguration für die Validierung von Access Tokens
Entwickler neigen dazu, sich beim Erhalt eines Access Tokens auf den im Token enthaltenen issuer
zu verlassen. Besonders, wenn in den Metadaten mehrere Authorization Server stehen, wie z. B.:
Es kann jedoch durch einen Angreifer ein böswilliger Authorization Server samt passendem Fake-Token aufgebaut werden. Nimmt der Server den issuer
direkt aus dem Token und vertraut ihm kritiklos, besteht die Gefahr, ein gefälschtes Token zu akzeptieren.
Daher gilt:
- Bei genau einem Authorization Server: Validierung sollte nur anhand des Backend-Eintrags geschehen
- Bei mehreren: Extrahiere den
issuer
aus dem nicht-signierten Token, prüfe, ob dieser in der MCP-Server-Konfiguration steht, und validiere nur dann gegen den jeweiligen Authorization Server. Unbekannte Issuer direkt ablehnen!
Natürlich sollte der Issuer streng geprüft werden.
Mit jose JWT-Library z. B.:
Prüfung der Audience
Im Abschnitt Token Audience Binding and Validation fordert die MCP-Auth-Spezifikation: Der Client muss beim Access Token Request an den Authorization Server als resource
-Parameter exakt die URL des anzuvisierenden Resource Servers angeben (z. B. https://github-tools.com
).
Bei Ausgabe des Tokens bindet der Authorization Server diesen Parameter an den Audience-Eintrag (aud
) im JWT.
Bei Prüfung eines eingehenden Access Tokens muss der MCP-Server daher genau prüfen: Der Wert im Feld aud
muss mit dem eigenen Resource Identifier übereinstimmen.
Am Beispiel https://github-tools.com
:
Diese Audience-Prüfung ist essenziell, um Missbrauch und Fehlakzeptanz von Fremd-Tokens zu verhindern.
Prüfung der Scopes
Einige MCP-Server verwalten interne Ressourcen mit verschiedenen Berechtigungsstufen pro Nutzer.
Deshalb: Nach Validierung des Tokens prüfe, ob der Scope das gewünschte Recht enthält, z. B.:
Nach der MCP-Auth-Spezifikation MUSS bei fehlendem Scope-Grant ein 403 Forbidden gesendet werden.
Fazit
Mit diesem Artikel solltest du in der Lage sein, Authentifizierungs-Features für deinen MCP-Server entsprechend der neuesten Spezifikation zu implementieren. Es gilt: Tokens sicher validieren, Metadaten konsistent konfigurieren und die Audience-Prüfung strikt umsetzen.
Wenn du einen MCP-Server entwickelst, probiere die MCP Auth Bibliothek. Sie bringt alle vorgestellten Features bereits mit und vereinfacht die Integration.
Fragen kannst du gerne auf GitHub diskutieren – arbeiten wir gemeinsam an einem sicheren und interoperablen MCP-Ökosystem.