|
| 1 | +--- |
| 2 | +sidebar_position: 1 |
| 3 | +sidebar_label: Erste Schritte |
| 4 | +--- |
| 5 | + |
| 6 | +import TabItem from '@theme/TabItem'; |
| 7 | +import Tabs from '@theme/Tabs'; |
| 8 | + |
| 9 | +# Erste Schritte |
| 10 | + |
| 11 | +## Wähle einen kompatiblen OAuth 2.1- oder OpenID Connect-Anbieter \{#choose-a-compatible-oauth-2-1-or-openid-connect-provider} |
| 12 | + |
| 13 | +Die MCP-Spezifikation hat einige [spezifische Anforderungen](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization#1-3-standards-compliance) für die Autorisierung: |
| 14 | + |
| 15 | +- [OAuth 2.1 IETF DRAFT](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12) |
| 16 | +- OAuth 2.0 Authorization Server Metadata ([RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414)) |
| 17 | +- OAuth 2.0 Dynamic Client Registration Protocol ([RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591)) |
| 18 | + |
| 19 | +Während die letzten beiden nicht zwingend erforderlich sind, ist die erste notwendig, um eine sichere und konforme Implementierung zu gewährleisten. |
| 20 | + |
| 21 | +:::note |
| 22 | +Im neuen MCP-Entwurf wird RFC 8414 für Autorisierungsserver (Anbieter) verpflichtend sein. Wir werden die Dokumentation aktualisieren, sobald der neue Entwurf finalisiert ist. |
| 23 | +::: |
| 24 | + |
| 25 | +Du kannst die [Liste der MCP-kompatiblen Anbieter](./provider-list.mdx) prüfen, um zu sehen, ob dein Anbieter unterstützt wird. |
| 26 | + |
| 27 | +## Installiere MCP Auth SDK \{#install-mcp-auth-sdk} |
| 28 | + |
| 29 | +MCP Auth ist sowohl für Python als auch für TypeScript verfügbar. Lass uns wissen, wenn du Unterstützung für eine andere Sprache oder ein anderes Framework benötigst! |
| 30 | + |
| 31 | +<Tabs groupId="sdk"> |
| 32 | +<TabItem value="python" label="Python"> |
| 33 | + |
| 34 | +```bash |
| 35 | +pip install mcpauth |
| 36 | +``` |
| 37 | + |
| 38 | +Oder ein anderer Paketmanager deiner Wahl, wie pipenv oder poetry. |
| 39 | + |
| 40 | +</TabItem> |
| 41 | +<TabItem value="node" label="Node.js"> |
| 42 | + |
| 43 | +```bash |
| 44 | +npm install mcp-auth |
| 45 | +``` |
| 46 | + |
| 47 | +Oder ein anderer Paketmanager deiner Wahl, wie pnpm oder yarn. |
| 48 | + |
| 49 | +</TabItem> |
| 50 | +</Tabs> |
| 51 | + |
| 52 | +## Initialisiere MCP Auth \{#init-mcp-auth} |
| 53 | + |
| 54 | +Der erste Schritt ist die Initialisierung der MCP Auth-Instanz mit den Metadaten deines Anbieter-Autorisierungsservers. Wenn dein Anbieter eine der folgenden Spezifikationen unterstützt: |
| 55 | + |
| 56 | +- [OAuth 2.0 Authorization Server Metadata](https://datatracker.ietf.org/doc/html/rfc8414) |
| 57 | +- [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) |
| 58 | + |
| 59 | +kannst du die eingebaute Funktion verwenden, um die Metadaten abzurufen und die MCP Auth-Instanz zu initialisieren: |
| 60 | + |
| 61 | +<Tabs groupId="sdk"> |
| 62 | +<TabItem value="python" label="Python"> |
| 63 | + |
| 64 | +```python |
| 65 | +from mcpauth import MCPAuth |
| 66 | +from mcpauth.config import AuthServerType |
| 67 | +from mcpauth.utils import fetch_server_config |
| 68 | + |
| 69 | +mcp_auth = MCPAuth( |
| 70 | + server=fetch_server_config( |
| 71 | + '<auth-server-url>', |
| 72 | + type=AuthServerType.OIDC # oder AuthServerType.OAUTH |
| 73 | + ) |
| 74 | +) |
| 75 | +``` |
| 76 | + |
| 77 | +</TabItem> |
| 78 | +<TabItem value="node" label="Node.js"> |
| 79 | + |
| 80 | +```ts |
| 81 | +import { MCPAuth, fetchServerConfig } from 'mcp-auth'; |
| 82 | + |
| 83 | +const mcpAuth = new MCPAuth({ |
| 84 | + server: await fetchServerConfig('<auth-server-issuer>', { type: 'oidc' }), // oder 'oauth' |
| 85 | +}); |
| 86 | +``` |
| 87 | + |
| 88 | +</TabItem> |
| 89 | +</Tabs> |
| 90 | + |
| 91 | +Wenn du die Metadaten-URL oder Endpunkte manuell angeben musst, siehe [Weitere Möglichkeiten zur Initialisierung von MCP Auth](./configure-server/mcp-auth.mdx#other-ways). |
| 92 | + |
| 93 | +## Binde den Metadaten-Endpunkt ein \{#mount-the-metadata-endpoint} |
| 94 | + |
| 95 | +Um der aktuellen MCP-Spezifikation zu entsprechen, bindet MCP Auth den OAuth 2.0 Authorization Server Metadata-Endpunkt (`/.well-known/oauth-authorization-server`) in deinen MCP-Server ein: |
| 96 | + |
| 97 | +<Tabs groupId="sdk"> |
| 98 | +<TabItem value="python" label="Python"> |
| 99 | + |
| 100 | +```python |
| 101 | +from starlette.applications import Starlette |
| 102 | + |
| 103 | +app = Starlette(routes=[ |
| 104 | + mcp_auth.metadata_route(), |
| 105 | +]) |
| 106 | +``` |
| 107 | + |
| 108 | +</TabItem> |
| 109 | +<TabItem value="node" label="Node.js"> |
| 110 | + |
| 111 | +```ts |
| 112 | +import express from 'express'; |
| 113 | + |
| 114 | +const app = express(); |
| 115 | +app.use(mcpAuth.delegatedRouter()); |
| 116 | +``` |
| 117 | + |
| 118 | +</TabItem> |
| 119 | +</Tabs> |
| 120 | + |
| 121 | +Die URLs in den Metadaten bleiben unverändert, sodass die Rolle des Autorisierungsservers vollständig an den Anbieter delegiert wird. Du kannst den Metadaten-Endpunkt testen, indem du `/.well-known/oauth-authorization-server` in deinem MCP-Server aufrufst. |
| 122 | + |
| 123 | +### Warum nur der Metadaten-Endpunkt? \{#why-only-the-metadata-endpoint} |
| 124 | + |
| 125 | +Du wirst vielleicht sehen, dass die offiziellen SDKs einen Auth-Router bereitstellen, der Autorisierungsendpunkte wie `/authorize`, `/token` usw. einbindet. Hier ist der Grund, warum wir das nicht tun: |
| 126 | + |
| 127 | +1. Nur den Metadaten-Endpunkt einzubinden, ermöglicht es dir, die vollen Fähigkeiten deines Anbieters zu nutzen, ohne das Rad neu zu erfinden und unnötige Komplexität in deinen MCP-Server zu bringen. |
| 128 | +2. Es gibt außerdem Bestrebungen, die [Rolle des MCP-Servers zu einem Ressourcenserver zu verschieben](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/205) und OAuth 2.0 Protected Resource Metadata ([RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728)) zu verlangen. Das bedeutet, dass der MCP-Server **keine Autorisierungslogik mehr übernimmt** (einschließlich des Metadaten-Endpunkts), sondern nur noch als Ressourcenserver dient, der sich für Authentifizierung und Autorisierung auf den Anbieter verlässt. |
| 129 | + |
| 130 | +:::note |
| 131 | +Wir werden MCP Auth aktualisieren, um die neue MCP-Spezifikation zu unterstützen, sobald sie finalisiert ist. In der Zwischenzeit kannst du die aktuelle Version verwenden, die mit der aktuellen Spezifikation kompatibel ist. |
| 132 | +::: |
| 133 | + |
| 134 | +## Verwende das Bearer-Auth-Middleware \{#use-the-bearer-auth-middleware} |
| 135 | + |
| 136 | +Sobald die MCP Auth-Instanz initialisiert ist, kannst du das Bearer-Auth-Middleware anwenden, um deine MCP-Routen zu schützen: |
| 137 | + |
| 138 | +<Tabs groupId="sdk"> |
| 139 | +<TabItem value="python" label="Python"> |
| 140 | + |
| 141 | +```python |
| 142 | +from starlette.applications import Starlette |
| 143 | +from starlette.middleware import Middleware |
| 144 | +from starlette.routing import Mount |
| 145 | +from mcpauth import MCPAuth |
| 146 | +from mcp.server.fastmcp import FastMCP |
| 147 | + |
| 148 | +mcp = FastMCP() |
| 149 | +mcp_auth = MCPAuth( |
| 150 | + # Initialisiere mit deiner Auth-Server-Konfiguration |
| 151 | +) |
| 152 | +bearer_auth = mcp_auth.bearer_auth_middleware( |
| 153 | + "jwt", required_scopes=["read", "write"] |
| 154 | +) |
| 155 | + |
| 156 | +app = Starlette(routes=[ |
| 157 | + mcp_auth.metadata_route(), |
| 158 | + Mount( |
| 159 | + "/", |
| 160 | + app=mcp.sse_app(), |
| 161 | + middleware=[Middleware(bearer_auth)], |
| 162 | + ), |
| 163 | +]) |
| 164 | +``` |
| 165 | + |
| 166 | +</TabItem> |
| 167 | +<TabItem value="node" label="Node.js"> |
| 168 | + |
| 169 | +```ts |
| 170 | +import express from 'express'; |
| 171 | +import { MCPAuth } from 'mcp-auth'; |
| 172 | + |
| 173 | +const app = express(); |
| 174 | +const server = new McpServer(/* ... */); |
| 175 | +const mcpAuth = new MCPAuth({ |
| 176 | + /* ... */ |
| 177 | +}); |
| 178 | + |
| 179 | +app.use(mcpAuth.bearerAuth('jwt', { requiredScopes: ['read', 'write'] })); |
| 180 | +``` |
| 181 | + |
| 182 | +</TabItem> |
| 183 | +</Tabs> |
| 184 | + |
| 185 | +Im obigen Beispiel haben wir den Token-Typ `jwt` angegeben und die Berechtigungen `read` und `write` gefordert. Es wird automatisch das JWT (JSON Web Token) validieren und ein Objekt mit den Informationen des authentifizierten Benutzers befüllen. |
| 186 | + |
| 187 | +:::info |
| 188 | +Noch nie von JWT (JSON Web Token) gehört? Keine Sorge, du kannst die Dokumentation einfach weiterlesen – wir erklären es, wenn es nötig ist. Du kannst auch das [Auth Wiki](https://auth.wiki/jwt) für eine kurze Einführung besuchen. |
| 189 | +::: |
| 190 | + |
| 191 | +Weitere Informationen zur Bearer-Auth-Konfiguration findest du unter [Bearer-Auth konfigurieren](./configure-server/bearer-auth.mdx). |
| 192 | + |
| 193 | +## Auth-Informationen in deiner MCP-Implementierung abrufen \{#retrieve-the-auth-info-in-your-mcp-implementation} |
| 194 | + |
| 195 | +Sobald das Bearer-Auth-Middleware angewendet ist, kannst du auf die Informationen des authentifizierten Benutzers (oder der Identität) in deiner MCP-Implementierung zugreifen: |
| 196 | + |
| 197 | +<Tabs groupId="sdk"> |
| 198 | +<TabItem value="python" label="Python"> |
| 199 | + |
| 200 | +MCP Auth speichert die Informationen des authentifizierten Benutzers nach erfolgreicher Authentifizierung in einer Kontextvariablen, sobald das Bearer-Auth-Middleware angewendet wurde. Du kannst darauf in deinen MCP-Tool-Handlern wie folgt zugreifen: |
| 201 | + |
| 202 | +```python |
| 203 | +from mcp.server.fastmcp import FastMCP |
| 204 | + |
| 205 | +mcp = FastMCP() |
| 206 | +mcp_auth = MCPAuth( |
| 207 | + # Initialisiere mit deiner Auth-Server-Konfiguration |
| 208 | +) |
| 209 | + |
| 210 | +@mcp.tool() |
| 211 | +def add(a: int, b: int): |
| 212 | + """ |
| 213 | + Ein Tool, das zwei Zahlen addiert. |
| 214 | + Die Informationen des authentifizierten Benutzers sind im Kontext verfügbar. |
| 215 | + """ |
| 216 | + auth_info = mcp_auth.auth_info # Zugriff auf die Auth-Informationen im aktuellen Kontext |
| 217 | + if auth_info: |
| 218 | + print(f"Authentifizierter Benutzer: {auth_info.claims}") |
| 219 | + return a + b |
| 220 | +``` |
| 221 | + |
| 222 | +</TabItem> |
| 223 | +<TabItem value="node" label="Node.js"> |
| 224 | + |
| 225 | +Das zweite Argument des Tool-Handlers enthält das `authInfo`-Objekt, das die Informationen des authentifizierten Benutzers enthält: |
| 226 | + |
| 227 | +```ts |
| 228 | +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; |
| 229 | +import { z } from 'zod'; |
| 230 | + |
| 231 | +const server = new McpServer(/* ... */); |
| 232 | +server.tool('add', { a: z.number(), b: z.number() }, async ({ a, b }, { authInfo }) => { |
| 233 | + // Jetzt kannst du das `authInfo`-Objekt verwenden, um auf die authentifizierten Informationen zuzugreifen |
| 234 | +}); |
| 235 | +``` |
| 236 | + |
| 237 | +</TabItem> |
| 238 | +</Tabs> |
| 239 | + |
| 240 | +## Nächste Schritte \{#next-steps} |
| 241 | + |
| 242 | +Lies weiter, um ein End-to-End-Beispiel zu erfahren, wie du MCP Auth mit deinem MCP-Server integrierst und wie du den Auth-Flow in MCP-Clients handhabst. |
0 commit comments