Zum Hauptinhalt springen

Tutorial: Baue einen Todo-Manager

In diesem Tutorial bauen wir einen Todo-Manager-MCP-Server mit Benutzer-Authentifizierung (Authentifizierung) und Autorisierung (Autorisierung).

Nach Abschluss dieses Tutorials hast du:

  • ✅ Ein grundlegendes Verständnis, wie du rollenbasierte Zugangskontrolle (RBAC) in deinem MCP-Server einrichtest.
  • ✅ Einen MCP-Server, der persönliche Todo-Listen verwalten kann.
hinweis

Bevor du beginnst, empfehlen wir dir dringend, zuerst das Who am I Tutorial durchzugehen, falls du mit dem MCP-Server und OAuth 2 nicht vertraut bist.

Überblick

Das Tutorial umfasst folgende Komponenten:

  • MCP-Server: Ein einfacher MCP-Server, der die offiziellen MCP-SDKs verwendet, um Anfragen zu bearbeiten, mit einem integrierten Todo-Service zur Verwaltung der Todo-Einträge der Benutzer.
  • MCP Inspector: Ein visuelles Test-Tool für MCP-Server. Es agiert auch als OAuth / OIDC-Client, um den Autorisierungsfluss zu starten und Zugangstokens abzurufen.
  • Autorisierungsserver: Ein OAuth 2.1- oder OpenID Connect-Anbieter, der Benutzeridentitäten verwaltet und Zugangstokens ausstellt.

Hier ist ein Überblicksdiagramm der Interaktion zwischen diesen Komponenten:

Verstehe deinen Autorisierungsserver

Zugangstokens mit Berechtigungen (Scopes)

Um rollenbasierte Zugangskontrolle (RBAC) in deinem MCP-Server zu implementieren, muss dein Autorisierungsserver das Ausstellen von Zugangstokens mit Berechtigungen (Scopes) unterstützen. Berechtigungen repräsentieren die Rechte, die einem Benutzer gewährt wurden.

Logto bietet RBAC-Unterstützung über seine API-Ressourcen (gemäß RFC 8707: Resource Indicators for OAuth 2.0) und Rollenfunktionen. So richtest du es ein:

  1. Melde dich bei der Logto Console (oder deiner selbst gehosteten Logto Console) an.

  2. Erstelle API-Ressource und Berechtigungen:

    • Gehe zu "API-Ressourcen"
    • Erstelle eine neue API-Ressource namens "Todo Manager"
    • Füge folgende Berechtigungen hinzu:
      • create:todos: "Neue Todo-Einträge erstellen"
      • read:todos: "Alle Todo-Einträge lesen"
      • delete:todos: "Beliebigen Todo-Eintrag löschen"
  3. Erstelle Rollen (empfohlen für einfachere Verwaltung):

    • Gehe zu "Rollen"
    • Erstelle eine "Admin"-Rolle und weise alle Berechtigungen zu (create:todos, read:todos, delete:todos)
    • Erstelle eine "User"-Rolle und weise nur die Berechtigung create:todos zu
  4. Berechtigungen zuweisen:

    • Gehe zu "Benutzer"
    • Wähle einen Benutzer aus
    • Du kannst entweder:
      • Rollen im Tab "Rollen" zuweisen (empfohlen)
      • Oder direkt Berechtigungen im Tab "Berechtigungen" zuweisen

Die Berechtigungen werden im scope-Anspruch des JWT-Zugangstokens als durch Leerzeichen getrennte Zeichenkette enthalten sein.

Tokens validieren und Berechtigungen prüfen

Wenn dein MCP-Server eine Anfrage erhält, muss er:

  1. Die Signatur und das Ablaufdatum des Zugangstokens validieren
  2. Die Berechtigungen aus dem validierten Token extrahieren
  3. Prüfen, ob das Token die erforderlichen Berechtigungen für die angeforderte Operation enthält

Wenn ein Benutzer z. B. einen neuen Todo-Eintrag erstellen möchte, muss sein Zugangstoken die Berechtigung create:todos enthalten. So funktioniert der Ablauf:

Dynamische Client-Registrierung

Die dynamische Client-Registrierung ist für dieses Tutorial nicht erforderlich, kann aber nützlich sein, wenn du die MCP-Client-Registrierung mit deinem Autorisierungsserver automatisieren möchtest. Siehe Ist Dynamic Client Registration erforderlich? für weitere Details.

Verstehe RBAC im Todo-Manager

Zu Demonstrationszwecken implementieren wir ein einfaches rollenbasiertes Zugangskontrollsystem (RBAC) in unserem Todo-Manager-MCP-Server. Das zeigt dir die Grundprinzipien von RBAC bei überschaubarer Implementierung.

hinweis

Auch wenn dieses Tutorial RBAC-basierte Berechtigungsverwaltung demonstriert, ist es wichtig zu wissen, dass nicht alle Authentifizierungsanbieter die Berechtigungsverwaltung über Rollen implementieren. Manche Anbieter haben eigene Mechanismen zur Verwaltung von Zugangskontrolle und Berechtigungen.

Tools und Berechtigungen

Unser Todo-Manager-MCP-Server stellt drei Haupttools bereit:

  • create-todo: Einen neuen Todo-Eintrag erstellen
  • get-todos: Alle Todos auflisten
  • delete-todo: Ein Todo anhand der ID löschen

Um den Zugriff auf diese Tools zu steuern, definieren wir folgende Berechtigungen:

  • create:todos: Erlaubt das Erstellen neuer Todo-Einträge
  • delete:todos: Erlaubt das Löschen bestehender Todo-Einträge
  • read:todos: Erlaubt das Abfragen und Abrufen aller Todo-Einträge

Rollen und Berechtigungen

Wir definieren zwei Rollen mit unterschiedlichen Zugriffsrechten:

Rollecreate:todosread:todosdelete:todos
Admin
User
  • User: Ein normaler Benutzer, der Todo-Einträge erstellen und nur seine eigenen Todos ansehen oder löschen kann
  • Admin: Ein Administrator, der alle Todo-Einträge erstellen, ansehen und löschen kann, unabhängig vom Eigentümer

Ressourcenbesitz

Obwohl die obige Berechtigungstabelle die explizit zugewiesenen Berechtigungen pro Rolle zeigt, gibt es ein wichtiges Prinzip des Ressourcenbesitzes zu beachten:

  • Benutzer haben nicht die Berechtigungen read:todos oder delete:todos, können aber trotzdem:
    • Ihre eigenen Todo-Einträge lesen
    • Ihre eigenen Todo-Einträge löschen
  • Admins haben volle Berechtigungen (read:todos und delete:todos) und können:
    • Alle Todo-Einträge im System ansehen
    • Jeden Todo-Eintrag löschen, unabhängig vom Eigentümer

Das demonstriert ein häufiges Muster in RBAC-Systemen, bei dem der Besitz einer Ressource implizite Berechtigungen für eigene Ressourcen gewährt, während administrative Rollen explizite Berechtigungen für alle Ressourcen erhalten.

Mehr erfahren

Um tiefer in RBAC-Konzepte und Best Practices einzutauchen, sieh dir Mastering RBAC: A Comprehensive Real-World Example an.

Autorisierung in deinem Anbieter konfigurieren

Um das oben beschriebene Zugangskontrollsystem zu implementieren, musst du deinen Autorisierungsserver so konfigurieren, dass er die benötigten Berechtigungen unterstützt. So geht es bei verschiedenen Anbietern:

Logto bietet RBAC-Unterstützung über seine API-Ressourcen und Rollenfunktionen. So richtest du es ein:

  1. Melde dich bei der Logto Console (oder deiner selbst gehosteten Logto Console) an.

  2. Erstelle API-Ressource und Berechtigungen:

    • Gehe zu "API-Ressourcen"
    • Erstelle eine neue API-Ressource namens "Todo Manager" und verwende https://todo.mcp-server.app (zu Demo-Zwecken) als Indikator.
    • Erstelle folgende Berechtigungen:
      • create:todos: "Neue Todo-Einträge erstellen"
      • read:todos: "Alle Todo-Einträge lesen"
      • delete:todos: "Beliebigen Todo-Eintrag löschen"
  3. Erstelle Rollen (empfohlen für einfachere Verwaltung):

    • Gehe zu "Rollen"
    • Erstelle eine "Admin"-Rolle und weise alle Berechtigungen zu (create:todos, read:todos, delete:todos)
    • Erstelle eine "User"-Rolle und weise nur die Berechtigung create:todos zu
    • Wechsle auf der Detailseite der "User"-Rolle zum Tab "Allgemein" und setze die "User"-Rolle als "Standardrolle".
  4. Benutzerrollen und Berechtigungen verwalten:

    • Für neue Benutzer:
      • Sie erhalten automatisch die "User"-Rolle, da wir sie als Standardrolle gesetzt haben
    • Für bestehende Benutzer:
      • Gehe zu "Benutzerverwaltung"
      • Wähle einen Benutzer aus
      • Weise dem Benutzer Rollen im Tab "Rollen" zu
Programmatische Rollenverwaltung

Du kannst auch die Management API von Logto verwenden, um Benutzerrollen programmatisch zu verwalten. Das ist besonders nützlich für automatisierte Benutzerverwaltung oder beim Erstellen von Admin-Panels.

Beim Anfordern eines Zugangstokens wird Logto die Berechtigungen im scope-Anspruch des Tokens basierend auf den Rollenberechtigungen des Benutzers einfügen.

Nach der Konfiguration deines Autorisierungsservers erhalten Benutzer Zugangstokens mit ihren gewährten Berechtigungen. Der MCP-Server nutzt diese Berechtigungen, um zu bestimmen:

  • Ob ein Benutzer neue Todos erstellen darf (create:todos)
  • Ob ein Benutzer alle Todos (read:todos) oder nur seine eigenen sehen darf
  • Ob ein Benutzer beliebige Todos (delete:todos) oder nur seine eigenen löschen darf

MCP-Server einrichten

Wir verwenden die offiziellen MCP-SDKs, um unseren Todo-Manager-MCP-Server zu erstellen.

Neues Projekt erstellen

mkdir mcp-server
cd mcp-server
uv init # Oder verwende `pipenv` oder `poetry`, um eine neue virtuelle Umgebung zu erstellen

MCP-SDK und Abhängigkeiten installieren

pip install "mcp[cli]" starlette uvicorn

Oder ein anderer Paketmanager deiner Wahl, wie uv oder poetry.

MCP-Server erstellen

Erstelle zunächst einen einfachen MCP-Server mit den Tool-Definitionen:

Erstelle eine Datei namens todo-manager.py und füge folgenden Code hinzu:

from typing import Any
from mcp.server.fastmcp import FastMCP
from starlette.applications import Starlette
from starlette.routing import Mount

mcp = FastMCP("Todo Manager")

@mcp.tool()
def create_todo(content: str) -> dict[str, Any]:
    """Neues Todo erstellen."""
    return {"error": "Nicht implementiert"}

@mcp.tool()
def get_todos() -> dict[str, Any]:
    """Alle Todos auflisten."""
    return {"error": "Nicht implementiert"}

@mcp.tool()
def delete_todo(id: str) -> dict[str, Any]:
    """Todo anhand der ID löschen."""
    return {"error": "Nicht implementiert"}

app = Starlette(
    routes=[Mount('/', app=mcp.sse_app())]
)

Starte den Server mit:

uvicorn todo_manager:app --host 0.0.0.0 --port 3001

MCP-Server inspizieren

MCP Inspector klonen und starten

Jetzt, da der MCP-Server läuft, können wir den MCP Inspector verwenden, um zu prüfen, ob das whoami-Tool verfügbar ist.

Aufgrund der aktuellen Implementierung haben wir den MCP Inspector geforkt, um ihn flexibler und skalierbarer für Authentifizierung und Autorisierung zu machen. Wir haben auch einen Pull Request an das Original-Repository eingereicht, um unsere Änderungen einzubringen.

Um den MCP Inspector zu starten, verwende folgenden Befehl (Node.js wird benötigt):

git clone https://github.com/mcp-auth/inspector.git
cd inspector
npm install
npm run dev

Öffne dann deinen Browser und gehe zu http://localhost:6274/ (oder eine andere im Terminal angezeigte URL), um den MCP Inspector zu nutzen.

MCP Inspector mit dem MCP-Server verbinden

Prüfe vor dem Fortfahren folgende Konfiguration im MCP Inspector:

  • Transporttyp: Setze auf SSE.
  • URL: Setze auf die URL deines MCP-Servers. In unserem Fall sollte das http://localhost:3001/sse sein.

Jetzt kannst du auf die Schaltfläche "Connect" klicken, um zu sehen, ob der MCP Inspector eine Verbindung zum MCP-Server herstellen kann. Wenn alles in Ordnung ist, solltest du im MCP Inspector den Status "Connected" sehen.

Checkpoint: Todo-Manager-Tools ausführen

  1. Klicke im oberen Menü des MCP Inspectors auf den Tab "Tools".
  2. Klicke auf die Schaltfläche "List Tools".
  3. Du solltest die Tools create-todo, get-todos und delete-todo auf der Seite sehen. Klicke darauf, um die Tool-Details zu öffnen.
  4. Du solltest rechts die Schaltfläche "Run Tool" sehen. Klicke darauf und gib die erforderlichen Parameter ein, um das Tool auszuführen.
  5. Du solltest das Tool-Ergebnis mit der JSON-Antwort {"error": "Nicht implementiert"} sehen.

MCP Inspector erster Start

Mit deinem Autorisierungsserver integrieren

Für diesen Abschnitt gibt es einige Überlegungen:

Die Issuer-URL deines Autorisierungsservers

Dies ist normalerweise die Basis-URL deines Autorisierungsservers, z. B. https://auth.example.com. Manche Anbieter haben einen Pfad wie https://example.logto.app/oidc, prüfe daher die Dokumentation deines Anbieters.

Wie du die Metadaten des Autorisierungsservers abrufst
  • Wenn dein Autorisierungsserver dem OAuth 2.0 Authorization Server Metadata oder OpenID Connect Discovery entspricht, kannst du die eingebauten MCP Auth-Utilities verwenden, um die Metadaten automatisch abzurufen.
  • Wenn dein Autorisierungsserver diesen Standards nicht entspricht, musst du die Metadaten-URL oder Endpunkte manuell in der MCP-Server-Konfiguration angeben. Prüfe die Dokumentation deines Anbieters für die spezifischen Endpunkte.
Wie du den MCP Inspector als Client in deinem Autorisierungsserver registrierst
  • Wenn dein Autorisierungsserver Dynamic Client Registration unterstützt, kannst du diesen Schritt überspringen, da der MCP Inspector sich automatisch als Client registriert.
  • Wenn dein Autorisierungsserver Dynamic Client Registration nicht unterstützt, musst du den MCP Inspector manuell als Client in deinem Autorisierungsserver registrieren.
Verstehe die Token-Anfrageparameter

Beim Anfordern von Zugangstokens von verschiedenen Autorisierungsservern wirst du verschiedene Ansätze zur Angabe der Zielressource und Berechtigungen sehen. Hier sind die Hauptmuster:

  • Ressourcenindikator-basiert:

    • Verwendet den Parameter resource, um die Ziel-API anzugeben (siehe RFC 8707: Resource Indicators for OAuth 2.0)
    • Häufig in modernen OAuth 2.0-Implementierungen
    • Beispielanfrage:
      {
        "resource": "https://todo.mcp-server.app",
        "scope": "create:todos read:todos"
      }
    • Der Server stellt Tokens aus, die speziell an die angeforderte Ressource gebunden sind
  • Audience-basiert:

    • Verwendet den Parameter audience, um den beabsichtigten Token-Empfänger anzugeben
    • Ähnlich wie Ressourcenindikatoren, aber mit anderer Semantik
    • Beispielanfrage:
      {
        "audience": "todo-api",
        "scope": "create:todos read:todos"
      }
  • Rein scope-basiert:

    • Verwendet ausschließlich Scopes ohne resource/audience-Parameter
    • Traditioneller OAuth 2.0-Ansatz
    • Beispielanfrage:
      {
        "scope": "todo-api:create todo-api:read openid profile"
      }
    • Nutzt oft vorangestellte Scopes, um Berechtigungen zu namespacen
    • Häufig in einfacheren OAuth 2.0-Implementierungen
Best Practices
  • Prüfe die Dokumentation deines Anbieters auf unterstützte Parameter
  • Manche Anbieter unterstützen mehrere Ansätze gleichzeitig
  • Ressourcenindikatoren bieten bessere Sicherheit durch Audience-Beschränkung
  • Nutze Ressourcenindikatoren, wenn verfügbar, für bessere Zugangskontrolle

Auch wenn jeder Anbieter eigene Anforderungen hat, führen dich die folgenden Schritte durch die Integration des MCP Inspectors und MCP Servers mit anbieter-spezifischen Konfigurationen.

MCP Inspector als Client registrieren

Die Integration des Todo-Managers mit Logto ist unkompliziert, da es sich um einen OpenID Connect-Anbieter handelt, der Ressourcenindikatoren und Scopes unterstützt. So kannst du deine Todo-API mit https://todo.mcp-server.app als Ressourcenindikator absichern.

Da Logto Dynamic Client Registration noch nicht unterstützt, musst du den MCP Inspector manuell als Client in deinem Logto-Tenant registrieren:

  1. Öffne deinen MCP Inspector, klicke auf die Schaltfläche "OAuth Configuration". Kopiere den Redirect URL (auto-populated)-Wert, z. B. http://localhost:6274/oauth/callback.
  2. Melde dich bei der Logto Console (oder deiner selbst gehosteten Logto Console) an.
  3. Navigiere zum Tab "Anwendungen", klicke auf "Anwendung erstellen". Klicke unten auf der Seite auf "App ohne Framework erstellen".
  4. Fülle die Anwendungsdetails aus und klicke dann auf "Anwendung erstellen":
    • Wähle einen Anwendungstyp: "Single-page application"
    • Anwendungsname: z. B. "MCP Inspector"
  5. Im Bereich "Einstellungen / Redirect URIs" füge den kopierten Redirect URL (auto-populated)-Wert ein. Klicke dann unten auf "Änderungen speichern".
  6. Im oberen Bereich siehst du den Wert "App ID". Kopiere ihn.
  7. Gehe zurück zum MCP Inspector und füge den "App ID"-Wert im Bereich "OAuth Configuration" unter "Client ID" ein.
  8. Gib den Wert {"scope": "create:todos read:todos delete:todos", "resource": "https://todo.mcp-server.app"} im Feld "Auth Params" ein. Dadurch enthält das von Logto zurückgegebene Zugangstoken die erforderlichen Berechtigungen für den Zugriff auf den Todo-Manager.

MCP Auth einrichten

In deinem MCP-Server-Projekt musst du das MCP Auth SDK installieren und so konfigurieren, dass es die Metadaten deines Autorisierungsservers verwendet.

Installiere zuerst das mcpauth-Paket:

pip install mcpauth

Oder ein anderer Paketmanager deiner Wahl, wie uv oder poetry.

MCP Auth benötigt die Metadaten des Autorisierungsservers zur Initialisierung. Je nach Anbieter:

Die Issuer-URL findest du auf der Anwendungsdetailseite in der Logto Console im Bereich "Endpoints & Credentials / Issuer endpoint". Sie sieht etwa so aus: https://my-project.logto.app/oidc.

Aktualisiere die todo-manager.py, um die MCP Auth-Konfiguration einzubinden:

from mcpauth import MCPAuth
from mcpauth.config import AuthServerType
from mcpauth.utils import fetch_server_config

auth_issuer = '<issuer-endpoint>'  # Ersetze durch deinen Issuer-Endpunkt
auth_server_config = fetch_server_config(auth_issuer, type=AuthServerType.OIDC)
mcp_auth = MCPAuth(server=auth_server_config)

Aktualisiere die todo-manager.py, um die MCP Auth-Konfiguration einzubinden:

from mcpauth import MCPAuth
from mcpauth.config import AuthServerType
from mcpauth.utils import fetch_server_config

auth_issuer = '<issuer-endpoint>'  # Ersetze durch deinen Issuer-Endpunkt
auth_server_config = fetch_server_config(auth_issuer, type=AuthServerType.OIDC)
mcp_auth = MCPAuth(server=auth_server_config)

MCP-Server aktualisieren

Wir sind fast fertig! Jetzt aktualisieren wir den MCP-Server, um die MCP Auth-Route und Middleware-Funktion anzuwenden und die berechtigungsbasierte Zugangskontrolle für die Todo-Manager-Tools basierend auf den Benutzerberechtigungen zu implementieren.

@mcp.tool()
def create_todo(content: str) -> dict[str, Any]:
    """Neues Todo erstellen."""
    return (
        mcp_auth.auth_info.scopes
        if mcp_auth.auth_info # Wird durch die Bearer-Auth-Middleware befüllt
        else {"error": "Nicht authentifiziert"}
    )

# ...

bearer_auth = Middleware(mcp_auth.bearer_auth_middleware("jwt"))
app = Starlette(
    routes=[
        # Metadaten-Route hinzufügen (`/.well-known/oauth-authorization-server`)
        mcp_auth.metadata_route(),
        # MCP-Server mit Bearer-Auth-Middleware schützen
        Mount('/', app=mcp.sse_app(), middleware=[bearer_auth]),
    ],
)

Als Nächstes implementieren wir die spezifischen Tools.

Zuerst erstellen wir einen einfachen Todo-Service, der grundlegende CRUD-Operationen für die Verwaltung von Todo-Einträgen im Speicher bereitstellt.

# service.py

"""
Ein einfacher Todo-Service zu Demonstrationszwecken.
Verwendet eine In-Memory-Liste zur Speicherung der Todos.
"""

from datetime import datetime
from typing import List, Optional, Dict, Any
import random
import string

class Todo:
"""Repräsentiert einen Todo-Eintrag."""

    def __init__(self, id: str, content: str, owner_id: str, created_at: str):
        self.id = id
        self.content = content
        self.owner_id = owner_id
        self.created_at = created_at

    def to_dict(self) -> Dict[str, Any]:
        """Todo in ein Dictionary für die JSON-Serialisierung umwandeln."""
        return {
            "id": self.id,
            "content": self.content,
            "ownerId": self.owner_id,
            "createdAt": self.created_at
        }

class TodoService:
"""Ein einfacher Todo-Service zu Demonstrationszwecken."""

    def __init__(self):
        self._todos: List[Todo] = []

    def get_all_todos(self, owner_id: Optional[str] = None) -> List[Dict[str, Any]]:
        """
        Alle Todos abrufen, optional gefiltert nach owner_id.

        Args:
            owner_id: Falls angegeben, nur Todos dieses Benutzers zurückgeben

        Returns:
            Liste von Todo-Dictionaries
        """
        if owner_id:
            filtered_todos = [todo for todo in self._todos if todo.owner_id == owner_id]
            return [todo.to_dict() for todo in filtered_todos]
        return [todo.to_dict() for todo in self._todos]

    def get_todo_by_id(self, todo_id: str) -> Optional[Todo]:
        """
        Ein Todo anhand seiner ID abrufen.

        Args:
            todo_id: Die ID des abzurufenden Todos

        Returns:
            Todo-Objekt, falls gefunden, sonst None
        """
        for todo in self._todos:
            if todo.id == todo_id:
                return todo
        return None

    def create_todo(self, content: str, owner_id: str) -> Dict[str, Any]:
        """
        Ein neues Todo erstellen.

        Args:
            content: Der Inhalt des Todos
            owner_id: Die ID des Benutzers, dem dieses Todo gehört

        Returns:
            Dictionary-Darstellung des erstellten Todos
        """
        todo = Todo(
            id=self._generate_id(),
            content=content,
            owner_id=owner_id,
            created_at=datetime.now().isoformat()
        )
        self._todos.append(todo)
        return todo.to_dict()

    def delete_todo(self, todo_id: str) -> Optional[Dict[str, Any]]:
        """
        Ein Todo anhand seiner ID löschen.

        Args:
            todo_id: Die ID des zu löschenden Todos

        Returns:
            Dictionary-Darstellung des gelöschten Todos, falls gefunden, sonst None
        """
        for i, todo in enumerate(self._todos):
            if todo.id == todo_id:
                deleted_todo = self._todos.pop(i)
                return deleted_todo.to_dict()
        return None

    def _generate_id(self) -> str:
        """Eine zufällige ID für ein Todo generieren."""
        return ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))

Dann bestimmen wir in der Tool-Schicht, ob Operationen basierend auf den Benutzerberechtigungen erlaubt sind:

# todo-manager.py

from typing import Any, Optional
from mcpauth.errors import MCPAuthBearerAuthError

def assert_user_id(auth_info: Optional[dict]) -> str:
    """Benutzer-ID aus den Auth-Informationen extrahieren und validieren."""
    subject = auth_info.get('subject') if auth_info else None
    if not subject:
        raise ValueError('Ungültige Auth-Informationen')
    return subject

def has_required_scopes(user_scopes: list[str], required_scopes: list[str]) -> bool:
    """Prüfen, ob der Benutzer alle erforderlichen Berechtigungen hat."""
    return all(scope in user_scopes for scope in required_scopes)

# Instanz von TodoService erstellen
todo_service = TodoService()

@mcp.tool()
def create_todo(content: str) -> dict[str, Any]:
    """Neues Todo erstellen.

    Nur Benutzer mit 'create:todos'-Berechtigung dürfen Todos erstellen.
    """
    # Authentifizierungsinformationen abrufen
    auth_info = mcp_auth.auth_info

    # Benutzer-ID validieren
    try:
        user_id = assert_user_id(auth_info)
    except ValueError as e:
        return {"error": str(e)}

    # Prüfen, ob der Benutzer die erforderlichen Berechtigungen hat
    if not has_required_scopes(auth_info.scopes if auth_info else [], ['create:todos']):
        raise MCPAuthBearerAuthError('missing_required_scopes')

    # Neues Todo erstellen
    created_todo = todo_service.create_todo(content=content, owner_id=user_id)

    # Erstelltes Todo zurückgeben
    return created_todo.__dict__

# ...

Du findest unseren Beispielcode für alle weiteren Implementierungsdetails.

Checkpoint: Die todo-manager-Tools ausführen

Starte deinen MCP-Server neu und öffne den MCP Inspector im Browser. Wenn du auf die Schaltfläche "Connect" klickst, solltest du zur Anmeldeseite deines Autorisierungsservers weitergeleitet werden.

Nachdem du dich angemeldet hast und zum MCP Inspector zurückkehrst, wiederhole die Aktionen aus dem vorherigen Checkpoint, um die Todo-Manager-Tools auszuführen. Dieses Mal kannst du die Tools mit deiner authentifizierten Benutzeridentität nutzen. Das Verhalten der Tools hängt von den Rollen und Berechtigungen ab, die deinem Benutzer zugewiesen sind:

  • Wenn du als User (nur mit create:todos-Berechtigung) angemeldet bist:

    • Du kannst neue Todos mit dem Tool create-todo erstellen
    • Du kannst nur deine eigenen Todos ansehen und löschen
    • Du kannst keine Todos anderer Benutzer sehen oder löschen
  • Wenn du als Admin (mit allen Berechtigungen: create:todos, read:todos, delete:todos) angemeldet bist:

    • Du kannst neue Todos erstellen
    • Du kannst mit dem Tool get-todos alle Todos im System ansehen
    • Du kannst mit dem Tool delete-todo beliebige Todos löschen, unabhängig davon, wer sie erstellt hat

Du kannst diese verschiedenen Berechtigungsstufen testen, indem du:

  1. Die aktuelle Sitzung abmeldest (klicke auf "Disconnect" im MCP Inspector)
  2. Dich mit einem anderen Benutzerkonto anmeldest, das andere Rollen/Berechtigungen hat
  3. Die gleichen Tools erneut ausprobierst, um zu sehen, wie sich das Verhalten je nach Benutzerberechtigungen ändert

Das zeigt, wie rollenbasierte Zugangskontrolle (RBAC) in der Praxis funktioniert, wobei verschiedene Benutzer unterschiedliche Zugriffsebenen auf die Funktionen des Systems haben.

MCP Inspector Todo-Manager-Tool-Ergebnis

info

Sieh dir das MCP Auth Python SDK Repository für den vollständigen Code des MCP-Servers (OIDC-Version) an.

Abschließende Hinweise

🎊 Glückwunsch! Du hast das Tutorial erfolgreich abgeschlossen. Lass uns zusammenfassen, was wir gemacht haben:

  • Einen einfachen MCP-Server mit Todo-Management-Tools (create-todo, get-todos, delete-todo) eingerichtet
  • Rollenbasierte Zugangskontrolle (RBAC) mit unterschiedlichen Berechtigungsstufen für Benutzer und Admins implementiert
  • Den MCP-Server mit einem Autorisierungsserver über MCP Auth integriert
  • Den MCP Inspector so konfiguriert, dass Benutzer authentifiziert werden und Zugangstokens mit Berechtigungen zum Aufrufen von Tools verwendet werden

Sieh dir auch andere Tutorials und die Dokumentation an, um das Beste aus MCP Auth herauszuholen.