diff --git a/i18n/de/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx b/i18n/de/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
index 2402859..fa0ec65 100644
--- a/i18n/de/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
+++ b/i18n/de/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
@@ -13,23 +13,23 @@ import Tabs from '@theme/Tabs';
MCP Auth ist auch für Python verfügbar! Schau dir das [Python SDK Repository](https://github.com/mcp-auth/python) für Installation und Nutzung an.
:::
-In diesem Tutorial bauen wir einen Todo-Manager-MCP-Server mit Benutzer-Authentifizierung (Authentifizierung) und Autorisierung (Autorisierung). Nach der neuesten MCP-Spezifikation agiert unser MCP-Server als OAuth 2.0 **Ressourcenserver (Resource Server)**, der Zugangstokens validiert und berechtigungsbasierte Berechtigungen durchsetzt.
+In diesem Tutorial bauen wir einen Todo-Manager-MCP-Server mit Benutzer-Authentifizierung (Authentifizierung) und Autorisierung (Autorisierung). Nach der neuesten MCP-Spezifikation agiert unser MCP-Server als OAuth 2.0 **Ressourcenserver** (Resource Server), der Zugangstokens validiert und berechtigungsbasierte Berechtigungen durchsetzt.
Nach Abschluss dieses Tutorials hast du:
- ✅ Ein grundlegendes Verständnis, wie du rollenbasierte Zugangskontrolle (RBAC) in deinem MCP-Server einrichtest.
-- ✅ Einen MCP-Server, der als Ressourcenserver agiert und Zugangstokens akzeptiert, die von einem Autorisierungsserver ausgestellt wurden.
+- ✅ Einen MCP-Server, der als Ressourcenserver fungiert und Zugangstokens akzeptiert, die von einem Autorisierungsserver ausgestellt wurden.
- ✅ Eine funktionierende Implementierung der durch Berechtigungen gesteuerten Zugriffskontrolle für Todo-Operationen.
## Überblick \{#overview}
Das Tutorial umfasst folgende Komponenten:
-- **MCP-Client (VS Code)**: Ein Code-Editor mit eingebauter MCP-Unterstützung, der als OAuth 2.0/OIDC-Client agiert. Er initiiert den Autorisierungs-Flow mit dem Autorisierungsserver und erhält Zugangstokens, um Anfragen an den MCP-Server zu authentifizieren.
-- **Autorisierungsserver**: Ein OAuth 2.1- oder OpenID Connect-Anbieter, der Benutzeridentitäten verwaltet, Benutzer authentifiziert und Zugangstokens mit passenden Berechtigungen an autorisierte Clients ausstellt.
+- **MCP-Client (VS Code)**: Ein Code-Editor mit eingebauter MCP-Unterstützung, der als OAuth 2.0/OIDC-Client agiert. Er initiiert den Autorisierungsfluss mit dem Autorisierungsserver und erhält Zugangstokens, um Anfragen an den MCP-Server zu authentifizieren.
+- **Autorisierungsserver**: Ein OAuth 2.1 oder OpenID Connect Anbieter, der Benutzeridentitäten verwaltet, Benutzer authentifiziert und Zugangstokens mit entsprechenden Berechtigungen an autorisierte Clients ausstellt.
- **MCP-Server (Ressourcenserver)**: Nach der neuesten MCP-Spezifikation agiert der MCP-Server als Ressourcenserver im OAuth 2.0-Framework. Er validiert Zugangstokens, die vom Autorisierungsserver ausgestellt wurden, und erzwingt berechtigungsbasierte Berechtigungen für Todo-Operationen.
-Diese Architektur folgt dem Standard-OAuth 2.0-Flow, bei dem:
+Diese Architektur folgt dem Standard-OAuth 2.0-Fluss, bei dem:
- **VS Code** geschützte Ressourcen im Namen des Benutzers anfordert
- Der **Autorisierungsserver** den Benutzer authentifiziert und Zugangstokens ausstellt
@@ -46,7 +46,7 @@ sequenceDiagram
Client->>RS: MCP-Anfrage (kein Token)
RS-->>Client: 401 Nicht autorisiert (WWW-Authenticate)
- Note over Client: Extrahiere resource_metadata-URL
aus WWW-Authenticate-Header
+ Note over Client: Ressource_metadata-URL
aus WWW-Authenticate-Header extrahieren
Client->>RS: GET /.well-known/oauth-protected-resource (resource_metadata)
RS-->>Client: Geschützte Ressourcen-Metadaten
(enthält Autorisierungsserver-URL)
@@ -57,7 +57,7 @@ sequenceDiagram
AS-->>Client: Zugangstoken
Client->>RS: MCP-Anfrage (Authorization: Bearer )
- RS->>RS: Validiert Zugangstoken ist gültig und autorisiert
+ RS->>RS: Zugangstoken validieren (gültig und autorisiert)
RS-->>Client: MCP-Antwort
```
@@ -65,7 +65,7 @@ sequenceDiagram
### Zugangstokens mit Berechtigungen (Scopes) \{#access-tokens-with-scopes}
-Um [rollenbasierte Zugangskontrolle (RBAC)](https://auth.wiki/rbac) in deinem MCP-Server zu implementieren, muss dein Autorisierungsserver Zugangstokens mit Berechtigungen (Scopes) ausstellen können. Berechtigungen repräsentieren die Rechte, die einem Benutzer gewährt wurden.
+Um [rollenbasierte Zugangskontrolle (RBAC)](https://auth.wiki/rbac) in deinem MCP-Server zu implementieren, muss dein Autorisierungsserver die Ausgabe von Zugangstokens mit Berechtigungen unterstützen. Berechtigungen (Scopes) repräsentieren die Rechte, die einem Benutzer gewährt wurden.
@@ -104,26 +104,26 @@ Die Berechtigungen werden im `scope`-Anspruch des JWT-Zugangstokens als durch Le
OAuth 2.0 / OIDC-Anbieter unterstützen in der Regel berechtigungsbasierte Zugangskontrolle. Bei der Implementierung von RBAC:
1. Definiere die benötigten Berechtigungen in deinem Autorisierungsserver
-2. Konfiguriere deinen Client so, dass er diese Berechtigungen während des Autorisierungs-Flow anfordert
-3. Stelle sicher, dass dein Autorisierungsserver die gewährten Berechtigungen im Zugangstoken einträgt
-4. Die Berechtigungen sind üblicherweise im `scope`-Anspruch des JWT-Zugangstokens enthalten
+2. Konfiguriere deinen Client so, dass diese Berechtigungen während des Autorisierungsflusses angefordert werden
+3. Stelle sicher, dass dein Autorisierungsserver die gewährten Berechtigungen im Zugangstoken einfügt
+4. Die Berechtigungen sind normalerweise im `scope`-Anspruch des JWT-Zugangstokens enthalten
-Siehe die Dokumentation deines Anbieters für Details zu:
+Sieh in der Dokumentation deines Anbieters nach, wie:
-- Wie du Berechtigungen definierst und verwaltest
-- Wie Berechtigungen im Zugangstoken enthalten sind
-- Zusätzliche RBAC-Funktionen wie Rollenverwaltung
+- Berechtigungen definiert und verwaltet werden
+- Berechtigungen im Zugangstoken enthalten sind
+- Zusätzliche RBAC-Funktionen wie Rollenverwaltung unterstützt werden
### Tokens validieren und Berechtigungen prüfen \{#validating-tokens-and-checking-permissions}
-Nach der neuesten MCP-Spezifikation agiert der MCP-Server als **Ressourcenserver (Resource Server)** im OAuth 2.0-Framework. Als Ressourcenserver hat der MCP-Server folgende Aufgaben:
+Nach der neuesten MCP-Spezifikation agiert der MCP-Server als **Ressourcenserver** (Resource Server) im OAuth 2.0-Framework. Als Ressourcenserver hat der MCP-Server folgende Aufgaben:
-1. **Token-Validierung**: Überprüfe die Echtheit und Integrität der von MCP-Clients erhaltenen Zugangstokens
-2. **Berechtigungsdurchsetzung**: Extrahiere und prüfe die Berechtigungen aus dem Zugangstoken, um zu bestimmen, welche Operationen der Client ausführen darf
-3. **Ressourcenschutz**: Gebe geschützte Ressourcen (Tools ausführen) nur frei, wenn der Client gültige Tokens mit ausreichenden Berechtigungen vorlegt
+1. **Token-Validierung**: Überprüfe die Echtheit und Integrität der von MCP-Clients empfangenen Zugangstokens
+2. **Berechtigungsdurchsetzung**: Extrahiere und prüfe die Berechtigungen aus dem Zugangstoken, um festzustellen, welche Operationen der Client ausführen darf
+3. **Ressourcenschutz**: Geschützte Ressourcen (Tools ausführen) nur bereitstellen, wenn der Client gültige Tokens mit ausreichenden Berechtigungen vorlegt
Wenn dein MCP-Server eine Anfrage erhält, führt er folgenden Validierungsprozess durch:
@@ -132,7 +132,7 @@ Wenn dein MCP-Server eine Anfrage erhält, führt er folgenden Validierungsproze
3. Extrahiere die Berechtigungen und Benutzerinformationen aus dem validierten Token
4. Prüfe, ob das Token die erforderlichen Berechtigungen für die angeforderte Operation enthält
-Beispiel: Wenn ein Benutzer einen neuen Todo-Eintrag erstellen möchte, muss sein Zugangstoken die Berechtigung `create:todos` enthalten. So funktioniert der Validierungs-Flow des Ressourcenservers:
+Beispiel: Wenn ein Benutzer einen neuen Todo-Eintrag erstellen möchte, muss sein Zugangstoken die Berechtigung `create:todos` enthalten. So funktioniert der Validierungsablauf des Ressourcenservers:
```mermaid
sequenceDiagram
@@ -145,7 +145,7 @@ sequenceDiagram
alt JWT-Validierung (bevorzugt)
Server->>Auth: JWKS abrufen (falls nicht im Cache)
Auth-->>Server: JWKS zurückgeben
- Server->>Server: JWT-Signatur & Ansprüche lokal validieren
+ Server->>Server: JWT-Signatur & Claims lokal validieren
else Token-Introspektion (Fallback)
Server->>Auth: POST /introspect
(token=access_token)
Auth-->>Server: Token-Info zurückgeben
(active, scope, user_id, etc.)
@@ -157,7 +157,7 @@ sequenceDiagram
Server->>Server: Angeforderte Operation ausführen
Server->>Client: Operationsergebnis zurückgeben
else Fehlende Berechtigungen
- Server->>Client: 403 Verboten zurückgeben
(insufficient_scope error)
+ Server->>Client: 403 Verboten
(insufficient_scope error)
end
```
@@ -167,21 +167,21 @@ Dynamische Client-Registrierung ist für dieses Tutorial nicht erforderlich, kan
## Verstehe RBAC im Todo-Manager \{#understand-rbac-in-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.
+Zu Demonstrationszwecken implementieren wir ein einfaches rollenbasiertes Zugangskontrollsystem (RBAC) in unserem Todo-Manager-MCP-Server. Dies zeigt dir die Grundprinzipien von RBAC bei einer übersichtlichen Implementierung.
:::note
-Auch wenn dieses Tutorial RBAC-basierte Berechtigungsverwaltung demonstriert, ist es wichtig zu beachten, dass nicht alle Authentifizierungsanbieter die Berechtigungsverwaltung über Rollen implementieren. Manche Anbieter haben eigene Mechanismen zur Verwaltung von Zugangskontrolle und Berechtigungen.
+Obwohl dieses Tutorial RBAC-basierte Berechtigungsverwaltung demonstriert, ist es wichtig zu beachten, dass nicht alle Authentifizierungsanbieter die Berechtigungsverwaltung über Rollen implementieren. Manche Anbieter haben eigene Mechanismen zur Verwaltung von Zugangskontrolle und Berechtigungen.
:::
### Tools und Berechtigungen \{#tools-and-scopes}
Unser Todo-Manager-MCP-Server stellt drei Haupttools bereit:
-- `create-todo`: Erstelle einen neuen Todo-Eintrag
-- `get-todos`: Liste alle Todos auf
-- `delete-todo`: Lösche ein Todo anhand der ID
+- `create-todo`: Einen neuen Todo-Eintrag erstellen
+- `get-todos`: Alle Todos auflisten
+- `delete-todo`: Ein Todo per ID löschen
-Zur Zugriffskontrolle auf diese Tools definieren wir folgende Berechtigungen:
+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
@@ -201,24 +201,24 @@ Wir definieren zwei Rollen mit unterschiedlichen Zugriffsrechten:
### Ressourcenbesitz \{#resource-ownership}
-Obwohl die obige Berechtigungstabelle die expliziten Berechtigungen jeder Rolle zeigt, gibt es ein wichtiges Prinzip des Ressourcenbesitzes zu beachten:
+Obwohl die obige Berechtigungstabelle die expliziten Berechtigungen jeder Rolle zeigt, gibt es ein wichtiges Prinzip des Ressourcenbesitzes:
-- **Benutzer** haben nicht die Berechtigungen `read:todos` oder `delete:todos`, können aber trotzdem:
+- **Benutzer** haben nicht die Berechtigungen `read:todos` oder `delete:todos`, können aber dennoch:
- 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 daher:
+- **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.
+Dies zeigt 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.
:::tip Mehr erfahren
-Um tiefer in RBAC-Konzepte und Best Practices einzutauchen, siehe [Mastering RBAC: A Comprehensive Real-World Example](https://blog.logto.io/mastering-rbac).
+Um tiefer in RBAC-Konzepte und Best Practices einzutauchen, sieh dir [Mastering RBAC: A Comprehensive Real-World Example](https://blog.logto.io/mastering-rbac) an.
:::
-## Autorisierung in deinem Anbieter konfigurieren \{#configure-authorization-in-your-provider}
+## Autorisierung im Anbieter konfigurieren \{#configure-authorization-in-your-provider}
-Um das oben beschriebene Zugangskontrollsystem zu implementieren, musst du deinen Autorisierungsserver so konfigurieren, dass er die erforderlichen Berechtigungen unterstützt. So geht es mit verschiedenen Anbietern:
+Um das zuvor beschriebene Zugangskontrollsystem zu implementieren, musst du deinen Autorisierungsserver so konfigurieren, dass er die erforderlichen Berechtigungen unterstützt. So geht es mit verschiedenen Anbietern:
@@ -231,7 +231,7 @@ Um das oben beschriebene Zugangskontrollsystem zu implementieren, musst du deine
- Gehe zu "API-Ressourcen"
- Erstelle eine neue API-Ressource namens "Todo Manager" und verwende `http://localhost:3001/` als Ressourcenindikator.
- - **Wichtig**: Der Ressourcenindikator muss mit der URL deines MCP-Servers übereinstimmen. Für dieses Tutorial verwenden wir `http://localhost:3001/`, da unser MCP-Server auf Port 3001 läuft. In Produktion verwende deine tatsächliche MCP-Server-URL (z. B. `https://your-mcp-server.example.com/`).
+ - **Wichtig**: Der Ressourcenindikator muss mit der URL deines MCP-Servers übereinstimmen. Für dieses Tutorial verwenden wir `http://localhost:3001/`, da unser MCP-Server auf Port 3001 läuft. In der Produktion verwende deine tatsächliche MCP-Server-URL (z. B. `https://your-mcp-server.example.com/`).
- Erstelle folgende Berechtigungen:
- `create:todos`: "Neue Todo-Einträge erstellen"
- `read:todos`: "Alle Todo-Einträge lesen"
@@ -253,15 +253,15 @@ Um das oben beschriebene Zugangskontrollsystem zu implementieren, musst du deine
- Weise dem Benutzer Rollen im Tab "Rollen" zu
:::tip Programmatische Rollenverwaltung
-Du kannst auch die [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api) von Logto verwenden, um Benutzerrollen programmatisch zu verwalten. Das ist besonders nützlich für automatisiertes Benutzer-Management oder beim Bau von Admin-Panels.
+Du kannst auch die [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api) von Logto verwenden, um Benutzerrollen programmatisch zu verwalten. Das ist besonders nützlich für automatisierte Benutzerverwaltung oder beim Bau von Admin-Panels.
:::
-Beim Anfordern eines Zugangstokens wird Logto die Berechtigungen im `scope`-Anspruch des Tokens basierend auf den Rollenberechtigungen des Benutzers eintragen.
+Beim Anfordern eines Zugangstokens wird Logto die Berechtigungen im `scope`-Anspruch des Tokens basierend auf den Rollenberechtigungen des Benutzers einfügen.
-Für OAuth 2.0- oder OpenID Connect-Anbieter musst du die Berechtigungen konfigurieren, die verschiedene Rechte repräsentieren. Die genauen Schritte hängen von deinem Anbieter ab, aber im Allgemeinen:
+Für OAuth 2.0 oder OpenID Connect Anbieter musst du die Berechtigungen konfigurieren, die verschiedene Rechte repräsentieren. Die genauen Schritte hängen vom Anbieter ab, aber im Allgemeinen:
1. Berechtigungen definieren:
@@ -272,29 +272,29 @@ Für OAuth 2.0- oder OpenID Connect-Anbieter musst du die Berechtigungen konfigu
2. Client konfigurieren:
- - Registriere oder aktualisiere deinen Client, damit er diese Berechtigungen anfordert
+ - Registriere oder aktualisiere deinen Client, damit diese Berechtigungen angefordert werden
- Stelle sicher, dass die Berechtigungen im Zugangstoken enthalten sind
3. Berechtigungen zuweisen:
- - Verwende die Oberfläche deines Anbieters, um Benutzern die passenden Berechtigungen zuzuweisen
- - Manche Anbieter unterstützen rollenbasierte Verwaltung, andere direkte Berechtigungszuweisung
- - Siehe die Dokumentation deines Anbieters für den empfohlenen Ansatz
+ - Verwende die Oberfläche deines Anbieters, um Benutzern die entsprechenden Berechtigungen zu gewähren
+ - Manche Anbieter unterstützen rollenbasierte Verwaltung, andere verwenden direkte Berechtigungszuweisungen
+ - Sieh in der Dokumentation deines Anbieters nach, welcher Ansatz empfohlen wird
:::tip
-Die meisten Anbieter werden die gewährten Berechtigungen im `scope`-Anspruch des Zugangstokens eintragen. Das Format ist typischerweise eine durch Leerzeichen getrennte Zeichenkette von Berechtigungswerten.
+Die meisten Anbieter fügen die gewährten Berechtigungen im `scope`-Anspruch des Zugangstokens ein. Das Format ist typischerweise eine durch Leerzeichen getrennte Zeichenkette von Berechtigungswerten.
:::
:::note[Abschließender Schrägstrich im Ressourcenindikator]
-Füge immer einen abschließenden Schrägstrich (`/`) im Ressourcenindikator hinzu. Aufgrund eines aktuellen Bugs im offiziellen MCP-SDK fügen Clients, die das SDK verwenden, beim Starten von Auth-Anfragen automatisch einen Schrägstrich an Ressourcenkennungen an. Wenn dein Ressourcenindikator keinen Schrägstrich enthält, schlägt die Ressourcenvalidierung für diese Clients fehl. (VS Code ist von diesem Bug nicht betroffen.)
+Füge immer einen abschließenden Schrägstrich (`/`) im Ressourcenindikator ein. Aufgrund eines aktuellen Bugs im offiziellen MCP-SDK fügen Clients, die das SDK verwenden, beim Starten von Auth-Anfragen automatisch einen Schrägstrich an Ressourcenkennungen an. Wenn dein Ressourcenindikator keinen Schrägstrich enthält, schlägt die Ressourcenvalidierung für diese Clients fehl. (VS Code ist von diesem Bug nicht betroffen.)
:::
Nach der Konfiguration deines Autorisierungsservers erhalten Benutzer Zugangstokens mit ihren gewährten Berechtigungen. Der MCP-Server verwendet 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 ansehen darf
+- 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 \{#set-up-the-mcp-server}
@@ -315,7 +315,7 @@ npm pkg set scripts.start="node --experimental-strip-types todo-manager.ts"
```
:::note
-Wir verwenden TypeScript in unseren Beispielen, da Node.js v22.6.0+ TypeScript nativ mit dem Flag `--experimental-strip-types` ausführen kann. Wenn du JavaScript verwendest, ist der Code ähnlich – stelle nur sicher, dass du Node.js v22.6.0 oder neuer nutzt. Siehe Node.js-Dokumentation für Details.
+Wir verwenden TypeScript in unseren Beispielen, da Node.js v22.6.0+ TypeScript nativ mit dem Flag `--experimental-strip-types` ausführen kann. Wenn du JavaScript verwendest, ist der Code ähnlich – stelle nur sicher, dass du Node.js v22.6.0 oder neuer verwendest. Siehe Node.js-Dokumentation für Details.
:::
### MCP-SDK und Abhängigkeiten installieren \{#install-the-mcp-sdk-and-dependencies}
@@ -330,7 +330,102 @@ Oder ein anderes Paketmanagement-Tool deiner Wahl, wie `pnpm` oder `yarn`.
Erstelle eine Datei namens `todo-manager.ts` und füge folgenden Code hinzu:
-[Der Code bleibt unverändert, siehe oben.]
+```ts
+// todo-manager.ts
+
+import { z } from 'zod';
+import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
+import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
+import express, { type Request, type Response } from 'express';
+
+// Factory-Funktion zum Erstellen einer MCP-Server-Instanz
+// Im zustandslosen Modus benötigt jede Anfrage ihre eigene Serverinstanz
+const createMcpServer = () => {
+ const mcpServer = new McpServer({
+ name: 'Todo Manager',
+ version: '0.0.0',
+ });
+
+ mcpServer.registerTool(
+ 'create-todo',
+ {
+ description: 'Neues Todo erstellen',
+ inputSchema: { content: z.string() },
+ },
+ async ({ content }) => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Nicht implementiert' }) }],
+ };
+ }
+ );
+
+ mcpServer.registerTool(
+ 'get-todos',
+ {
+ description: 'Alle Todos auflisten',
+ inputSchema: {},
+ },
+ async () => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Nicht implementiert' }) }],
+ };
+ }
+ );
+
+ mcpServer.registerTool(
+ 'delete-todo',
+ {
+ description: 'Todo per ID löschen',
+ inputSchema: { id: z.string() },
+ },
+ async ({ id }) => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Nicht implementiert' }) }],
+ };
+ }
+ );
+
+ return mcpServer;
+};
+
+// Nachfolgend der Boilerplate-Code aus der MCP-SDK-Dokumentation
+const PORT = 3001;
+const app = express();
+
+app.post('/', async (request: Request, response: Response) => {
+ // Im zustandslosen Modus für jede Anfrage eine neue Transport- und Serverinstanz erstellen,
+ // um vollständige Isolation zu gewährleisten. Eine einzelne Instanz würde zu Request-ID-Kollisionen führen,
+ // wenn mehrere Clients gleichzeitig verbunden sind.
+ const mcpServer = createMcpServer();
+
+ try {
+ const transport = new StreamableHTTPServerTransport({
+ sessionIdGenerator: undefined,
+ });
+ await mcpServer.connect(transport);
+ await transport.handleRequest(request, response, request.body);
+ response.on('close', () => {
+ console.log('Anfrage geschlossen');
+ void transport.close();
+ void mcpServer.close();
+ });
+ } catch (error) {
+ console.error('Fehler bei der Verarbeitung der MCP-Anfrage:', error);
+ if (!response.headersSent) {
+ response.status(500).json({
+ jsonrpc: '2.0',
+ error: {
+ code: -32_603,
+ message: 'Interner Serverfehler',
+ },
+ id: null,
+ });
+ }
+ }
+});
+
+app.listen(PORT);
+```
Starte den Server mit:
@@ -361,18 +456,18 @@ Dies ist normalerweise die Basis-URL deines Autorisierungsservers, z. B. `https:
**Wie du den MCP-Client in deinem Autorisierungsserver registrierst**
- Wenn dein Autorisierungsserver [Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591) unterstützt, kannst du diesen Schritt überspringen, da sich der MCP-Client automatisch registriert.
-- Wenn dein Autorisierungsserver Dynamic Client Registration nicht unterstützt, musst du den MCP-Client manuell registrieren.
+- Wenn dein Autorisierungsserver keine Dynamic Client Registration unterstützt, musst du den MCP-Client manuell registrieren.
-**Verstehe Token-Request-Parameter**
+**Verstehe die Token-Anfrageparameter**
Beim Anfordern von Zugangstokens von verschiedenen Autorisierungsservern gibt es verschiedene Ansätze, um die Zielressource und Berechtigungen anzugeben. Hier die wichtigsten Muster:
- **Ressourcenindikator-basiert**:
- - Verwendet den `resource`-Parameter, um die Ziel-API anzugeben (siehe [RFC 8707: Resource Indicators for OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707))
+ - Verwendet den Parameter `resource`, um die Ziel-API anzugeben (siehe [RFC 8707: Resource Indicators for OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707))
- Häufig in modernen OAuth 2.0-Implementierungen
- Beispielanfrage:
```json
@@ -385,7 +480,7 @@ Beim Anfordern von Zugangstokens von verschiedenen Autorisierungsservern gibt es
- **Audience-basiert**:
- - Verwendet den `audience`-Parameter, um den beabsichtigten Token-Empfänger anzugeben
+ - Verwendet den Parameter `audience`, um den beabsichtigten Token-Empfänger anzugeben
- Ähnlich wie Ressourcenindikatoren, aber mit anderen Semantiken
- Beispielanfrage:
```json
@@ -395,7 +490,7 @@ Beim Anfordern von Zugangstokens von verschiedenen Autorisierungsservern gibt es
}
```
-- **Rein berechtigungsbasiert**:
+- **Nur Scope-basiert**:
- Verwendet ausschließlich Berechtigungen ohne resource/audience-Parameter
- Traditioneller OAuth 2.0-Ansatz
- Beispielanfrage:
@@ -417,16 +512,16 @@ Beim Anfordern von Zugangstokens von verschiedenen Autorisierungsservern gibt es
-Auch wenn jeder Anbieter eigene Anforderungen hat, führen dich die folgenden Schritte durch die Integration von VS Code und MCP-Server mit anbieter-spezifischen Konfigurationen.
+Während jeder Anbieter eigene Anforderungen haben kann, führen dich die folgenden Schritte durch die Integration von VS Code und dem MCP-Server mit anbieter-spezifischen Konfigurationen.
### MCP-Client als Drittanbieter-App registrieren \{#register-mcp-client-as-a-third-party-app}
-Die Integration des Todo-Managers mit [Logto](https://logto.io) ist unkompliziert, da es ein OpenID Connect-Anbieter ist, der Ressourcenindikatoren und Berechtigungen unterstützt. So kannst du deine Todo-API mit `http://localhost:3001/` als Ressourcenindikator absichern.
+Die Integration des Todo-Managers mit [Logto](https://logto.io) ist einfach, da es sich um einen OpenID Connect-Anbieter handelt, der Ressourcenindikatoren und Berechtigungen unterstützt. So kannst du deine Todo-API mit `http://localhost:3001/` als Ressourcenindikator absichern.
-Da Logto Dynamic Client Registration noch nicht unterstützt, musst du deinen MCP-Client (VS Code) manuell als Drittanbieter-App in deinem Logto-Tenant registrieren:
+Da Logto noch keine Dynamic Client Registration unterstützt, musst du deinen MCP-Client (VS Code) manuell als Drittanbieter-App in deinem Logto-Tenant registrieren:
1. Melde dich bei der [Logto Console](https://cloud.logto.io) (oder deiner selbst gehosteten Logto Console) an.
2. Navigiere zu **Anwendungen > Drittanbieter-Apps** und klicke auf "Anwendung erstellen".
@@ -458,14 +553,14 @@ Wenn dein Anbieter Dynamic Client Registration unterstützt, kannst du die manue
3. Falls dein Anbieter einen Client-Typ verlangt, wähle "Native App" oder "Public client".
-4. Nach dem Erstellen der Anwendung konfiguriere die Redirect-URIs. Für VS Code füge hinzu:
+4. Nach dem Erstellen der Anwendung konfiguriere die Redirect-URIs. Für VS Code füge Folgendes hinzu:
```
http://127.0.0.1
https://vscode.dev/redirect
```
-5. Konfiguriere die benötigten Berechtigungen für die Anwendung:
+5. Konfiguriere die erforderlichen Berechtigungen für die Anwendung:
```text
create:todos read:todos delete:todos
@@ -482,7 +577,7 @@ Installiere zuerst das MCP Auth SDK in deinem MCP-Server-Projekt.
-Jetzt müssen wir MCP Auth im MCP-Server initialisieren. Im geschützten Ressourcenmodus musst du deine Ressourcenmetadaten einschließlich der Autorisierungsserver konfigurieren.
+Nun müssen wir MCP Auth in deinem MCP-Server initialisieren. Im geschützten Ressourcenmodus musst du deine Ressourcenmetadaten einschließlich der Autorisierungsserver konfigurieren.
Es gibt zwei Möglichkeiten, Autorisierungsserver zu konfigurieren:
@@ -497,7 +592,7 @@ Zuerst benötigst du die Issuer-URL deines Autorisierungsservers:
-In Logto findest du die Issuer-URL auf der Anwendungsdetailseite in der Logto Console unter "Endpoints & Credentials / Issuer endpoint". Sie sollte etwa so aussehen: `https://my-project.logto.app/oidc`.
+In Logto findest du die Issuer-URL auf der Anwendungsdetailseite in der Logto Console unter "Endpoints & Credentials / Issuer endpoint". Sie sieht etwa so aus: `https://my-project.logto.app/oidc`.
@@ -505,9 +600,9 @@ In Logto findest du die Issuer-URL auf der Anwendungsdetailseite in der Logto Co
Für OAuth 2.0-Anbieter musst du:
-1. Die Dokumentation deines Anbieters nach der Autorisierungsserver-URL (oft Issuer-URL oder Basis-URL genannt) durchsuchen
+1. In der Dokumentation deines Anbieters nach der Autorisierungsserver-URL (oft Issuer-URL oder Basis-URL genannt) suchen
2. Manche Anbieter stellen dies unter `https://{your-domain}/.well-known/oauth-authorization-server` bereit
-3. Im Admin-Bereich deines Anbieters unter OAuth/API-Einstellungen nachsehen
+3. Im Admin-Panel deines Anbieters unter OAuth/API-Einstellungen nachsehen
@@ -515,34 +610,266 @@ Für OAuth 2.0-Anbieter musst du:
Jetzt konfiguriere die Protected Resource Metadata beim Erstellen der MCP Auth-Instanz:
-[Der Code bleibt unverändert, siehe oben.]
+```js
+// todo-manager.ts
+
+import { MCPAuth, fetchServerConfig } from 'mcp-auth';
+
+const issuerUrl = ''; // Ersetze durch die Issuer-URL deines Autorisierungsservers
+
+// Definiere den Ressourcenbezeichner für diesen MCP-Server
+const resourceId = 'http://localhost:3001/';
+
+// Autorisierungsserver-Konfiguration vorab abrufen (empfohlen)
+const authServerConfig = await fetchServerConfig(issuerUrl, { type: 'oidc' });
+
+// MCP Auth mit geschützten Ressourcenmetadaten konfigurieren
+const mcpAuth = new MCPAuth({
+ protectedResources: {
+ metadata: {
+ resource: resourceId,
+ authorizationServers: [authServerConfig],
+ // Berechtigungen, die dieser MCP-Server versteht
+ scopesSupported: ['create:todos', 'read:todos', 'delete:todos'],
+ },
+ },
+});
+```
### MCP-Server aktualisieren \{#update-mcp-server}
-Fast geschafft! Jetzt aktualisieren wir den MCP-Server, um die MCP Auth-Route und Middleware-Funktion anzuwenden und die berechtigungsbasierte Zugriffskontrolle für die Todo-Manager-Tools basierend auf den Benutzerberechtigungen zu implementieren.
+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.
Jetzt Protected Resource Metadata-Routen anwenden, damit MCP-Clients die erwarteten Ressourcenmetadaten vom MCP-Server abrufen können.
-[Der Code bleibt unverändert, siehe oben.]
+```ts
+// todo-manager.ts
+
+// Protected Resource Metadata-Routen einrichten
+// Stellt Metadaten über diesen Ressourcenserver für OAuth-Clients bereit
+app.use(mcpAuth.protectedResourceMetadataRouter());
+```
+
+Als nächstes wenden wir die MCP Auth-Middleware auf den MCP-Server an. Diese Middleware übernimmt Authentifizierung und Autorisierung für eingehende Anfragen und stellt sicher, dass nur autorisierte Benutzer Zugriff auf die Todo-Manager-Tools haben.
+
+```ts
+// todo-manager.ts
-Jetzt wenden wir die MCP Auth-Middleware auf den MCP-Server an. Diese Middleware übernimmt Authentifizierung und Autorisierung für eingehende Anfragen und stellt sicher, dass nur autorisierte Benutzer Zugriff auf die Todo-Manager-Tools haben.
+app.use(mcpAuth.protectedResourceMetadataRouter());
-[Der Code bleibt unverändert, siehe oben.]
+// MCP Auth-Middleware anwenden
+app.use(
+ mcpAuth.bearerAuth('jwt', {
+ resource: resourceId,
+ audience: resourceId,
+ })
+);
+```
+
+Jetzt können wir die Todo-Manager-Tools aktualisieren, um die MCP Auth-Middleware für Authentifizierung und Autorisierung zu nutzen.
+
+Aktualisieren wir die Implementierung der Tools.
+
+```js
+// todo-manager.ts
+
+// weitere Importe...
+import assert from 'node:assert';
+import { fetchServerConfig, MCPAuth, MCPAuthBearerAuthError } from 'mcp-auth';
+import { type AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
+
+// Wird im nächsten Abschnitt erwähnt
+import { TodoService } from './todo-service.js';
+
+const assertUserId = (authInfo?: AuthInfo) => {
+ const { subject } = authInfo ?? {};
+ assert(subject, 'Ungültige Auth-Info');
+ return subject;
+};
+
+const hasRequiredScopes = (userScopes: string[], requiredScopes: string[]): boolean => {
+ return requiredScopes.every((scope) => userScopes.includes(scope));
+};
+
+// TodoService ist ein Singleton, da wir den Zustand zwischen Anfragen teilen müssen
+const todoService = new TodoService();
+
+// Factory-Funktion zum Erstellen einer MCP-Server-Instanz
+// Im zustandslosen Modus benötigt jede Anfrage ihre eigene Serverinstanz
+const createMcpServer = () => {
+ const mcpServer = new McpServer({
+ name: 'Todo Manager',
+ version: '0.0.0',
+ });
+
+ mcpServer.registerTool(
+ 'create-todo',
+ {
+ description: 'Neues Todo erstellen',
+ inputSchema: { content: z.string() },
+ },
+ ({ content }, { authInfo }) => {
+ const userId = assertUserId(authInfo);
+
+ /**
+ * Nur Benutzer mit 'create:todos'-Berechtigung dürfen Todos erstellen
+ */
+ if (!hasRequiredScopes(authInfo?.scopes ?? [], ['create:todos'])) {
+ throw new MCPAuthBearerAuthError('missing_required_scopes');
+ }
+
+ const createdTodo = todoService.createTodo({ content, ownerId: userId });
+
+ return {
+ content: [{ type: 'text', text: JSON.stringify(createdTodo) }],
+ };
+ }
+ );
+
+ mcpServer.registerTool(
+ 'get-todos',
+ {
+ description: 'Alle Todos auflisten',
+ inputSchema: {},
+ },
+ (_params, { authInfo }) => {
+ const userId = assertUserId(authInfo);
+
+ /**
+ * Wenn der Benutzer die 'read:todos'-Berechtigung hat, kann er alle Todos sehen (todoOwnerId = undefined)
+ * Wenn nicht, kann er nur seine eigenen Todos sehen (todoOwnerId = userId)
+ */
+ const todoOwnerId = hasRequiredScopes(authInfo?.scopes ?? [], ['read:todos'])
+ ? undefined
+ : userId;
+
+ const todos = todoService.getAllTodos(todoOwnerId);
+
+ return {
+ content: [{ type: 'text', text: JSON.stringify(todos) }],
+ };
+ }
+ );
-Jetzt können wir die Implementierung der Tools aktualisieren.
+ mcpServer.registerTool(
+ 'delete-todo',
+ {
+ description: 'Todo per ID löschen',
+ inputSchema: { id: z.string() },
+ },
+ ({ id }, { authInfo }) => {
+ const userId = assertUserId(authInfo);
+
+ const todo = todoService.getTodoById(id);
+
+ if (!todo) {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Löschen des Todos fehlgeschlagen' }) }],
+ };
+ }
+
+ /**
+ * Benutzer dürfen nur ihre eigenen Todos löschen
+ * Benutzer mit 'delete:todos'-Berechtigung dürfen beliebige Todos löschen
+ */
+ if (todo.ownerId !== userId && !hasRequiredScopes(authInfo?.scopes ?? [], ['delete:todos'])) {
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({ error: 'Löschen des Todos fehlgeschlagen' }),
+ },
+ ],
+ };
+ }
+
+ const deletedTodo = todoService.deleteTodo(id);
+
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({
+ message: `Todo ${id} gelöscht`,
+ details: deletedTodo,
+ }),
+ },
+ ],
+ };
+ }
+ );
-[Der Code bleibt unverändert, siehe oben.]
+ return mcpServer;
+};
+```
Jetzt erstelle den "Todo-Service", der im obigen Code verwendet wird, um die zugehörige Funktionalität zu implementieren:
Erstelle die Datei `todo-service.ts` für den Todo-Service:
-[Der Code bleibt unverändert, siehe oben.]
+```ts
+// todo-service.ts
+
+type Todo = {
+ id: string;
+ content: string;
+ ownerId: string;
+ createdAt: string;
+};
+
+/**
+ * Ein einfacher Todo-Service zu Demonstrationszwecken.
+ * Verwendet ein In-Memory-Array zur Speicherung der Todos
+ */
+export class TodoService {
+ private readonly todos: Todo[] = [];
+
+ getAllTodos(ownerId?: string): Todo[] {
+ if (ownerId) {
+ return this.todos.filter((todo) => todo.ownerId === ownerId);
+ }
+ return this.todos;
+ }
+
+ getTodoById(id: string): Todo | undefined {
+ return this.todos.find((todo) => todo.id === id);
+ }
+
+ createTodo({ content, ownerId }: { content: string; ownerId: string }): Todo {
+ const todo: Todo = {
+ id: this.genId(),
+ content,
+ ownerId,
+ createdAt: new Date().toISOString(),
+ };
+
+ // eslint-disable-next-line @silverhand/fp/no-mutating-methods
+ this.todos.push(todo);
+ return todo;
+ }
+
+ deleteTodo(id: string): Todo | undefined {
+ const index = this.todos.findIndex((todo) => todo.id === id);
+
+ if (index === -1) {
+ return undefined;
+ }
+
+ // eslint-disable-next-line @silverhand/fp/no-mutating-methods
+ const [deleted] = this.todos.splice(index, 1);
+ return deleted;
+ }
+
+ private genId(): string {
+ return Math.random().toString(36).slice(2, 10);
+ }
+}
+```
Herzlichen Glückwunsch! Wir haben erfolgreich einen vollständigen MCP-Server mit Authentifizierung (Authentifizierung) und Autorisierung (Autorisierung) implementiert!
:::info
-Siehe das [MCP Auth Node.js SDK Repository](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src) für den vollständigen Code des MCP-Servers (OIDC-Version).
+Sieh dir das [MCP Auth Node.js SDK Repository](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src) für den vollständigen Code des MCP-Servers (OIDC-Version) an.
:::
## Checkpoint: Die `todo-manager`-Tools ausführen \{#checkpoint-run-the-todo-manager-tools}
@@ -553,11 +880,11 @@ Starte deinen MCP-Server neu und verbinde VS Code damit. So verbindest du dich m
2. Tippe `MCP: Add Server...` und wähle es aus.
3. Wähle `HTTP` als Servertyp.
4. Gib die MCP-Server-URL ein: `http://localhost:3001`
-5. Nach dem Start einer OAuth-Anfrage fordert dich VS Code auf, die **App ID** einzugeben. Gib die App ID ein, die du von deinem Autorisierungsserver kopiert hast.
+5. Nachdem eine OAuth-Anfrage gestartet wurde, fordert VS Code dich auf, die **App ID** einzugeben. Gib die App ID ein, die du von deinem Autorisierungsserver kopiert hast.
6. Da wir kein **App Secret** haben (es ist ein Public Client), drücke einfach Enter, um zu überspringen.
-7. Schließe den Anmeldeprozess im Browser ab.
+7. Schließe den Anmeldevorgang im Browser ab.
-Sobald du dich angemeldet hast und zu VS Code zurückkehrst, wiederhole die Aktionen aus dem vorherigen Checkpoint, um die Todo-Manager-Tools auszuführen. Diesmal kannst du die Tools mit deiner authentifizierten Benutzeridentität verwenden. Das Verhalten der Tools hängt von den Rollen und Berechtigungen ab, die deinem Benutzer zugewiesen sind:
+Sobald du dich angemeldet hast und zu VS Code zurückkehrst, wiederhole die Aktionen aus dem vorherigen Checkpoint, um die Todo-Manager-Tools auszuführen. Diesmal kannst du diese Tools mit deiner authentifizierten Benutzeridentität verwenden. 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:
@@ -576,10 +903,10 @@ Du kannst diese unterschiedlichen Berechtigungsstufen testen, indem du:
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 Zugriffsrechte auf die Funktionen des Systems haben.
+Dies zeigt, wie rollenbasierte Zugangskontrolle (RBAC) in der Praxis funktioniert, wobei verschiedene Benutzer unterschiedliche Zugriffsrechte auf die Funktionen des Systems haben.
:::info
-Siehe das [MCP Auth Node.js SDK Repository](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src) für den vollständigen Code des MCP-Servers (OIDC-Version).
+Sieh dir das [MCP Auth Node.js SDK Repository](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src) für den vollständigen Code des MCP-Servers (OIDC-Version) an.
:::
## Abschließende Hinweise \{#closing-notes}
diff --git a/i18n/es/docusaurus-plugin-content-docs/current/references/js/type-aliases/AuthServerConfigError.md b/i18n/es/docusaurus-plugin-content-docs/current/references/js/type-aliases/AuthServerConfigError.md
index 0110b48..eb9b91f 100644
--- a/i18n/es/docusaurus-plugin-content-docs/current/references/js/type-aliases/AuthServerConfigError.md
+++ b/i18n/es/docusaurus-plugin-content-docs/current/references/js/type-aliases/AuthServerConfigError.md
@@ -22,7 +22,7 @@ Representa un error que ocurre durante la validación de los metadatos del servi
optional cause: Error;
```
-Una causa opcional del error, normalmente una instancia de `Error` que proporciona más contexto.
+Una causa opcional del error, típicamente una instancia de `Error` que proporciona más contexto.
***
diff --git a/i18n/es/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx b/i18n/es/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
index c616da2..99870b1 100644
--- a/i18n/es/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
+++ b/i18n/es/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
@@ -1,13 +1,13 @@
---
sidebar_position: 2
-sidebar_label: 'Tutorial: Construye un gestor de tareas'
+sidebar_label: 'Tutorial: Crea un gestor de tareas'
---
import { NpmLikeInstallation } from '@site/src/components/NpmLikeInstallation';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
-# Tutorial: Construye un gestor de tareas
+# Tutorial: Crea un gestor de tareas
:::tip SDK de Python disponible
¡MCP Auth también está disponible para Python! Consulta el [repositorio del SDK de Python](https://github.com/mcp-auth/python) para instalación y uso.
@@ -21,7 +21,7 @@ Al completar este tutorial, tendrás:
- ✅ Un servidor MCP que actúa como Servidor de Recursos, consumiendo tokens de acceso emitidos por un Servidor de Autorización (Authorization Server).
- ✅ Una implementación funcional de la aplicación de permisos basados en Alcances (Scopes) para operaciones de tareas.
-## Visión general \{#overview}
+## Descripción general \{#overview}
El tutorial involucrará los siguientes componentes:
@@ -57,7 +57,7 @@ sequenceDiagram
AS-->>Client: Token de acceso
Client->>RS: Solicitud MCP (Authorization: Bearer )
- RS->>RS: Valida que el token de acceso sea válido y autorizado
+ RS->>RS: Valida que el token de acceso es válido y autorizado
RS-->>Client: Respuesta MCP
```
@@ -65,38 +65,38 @@ sequenceDiagram
### Tokens de acceso con Alcances (Scopes) \{#access-tokens-with-scopes}
-Para implementar el [control de acceso basado en roles (RBAC)](https://auth.wiki/rbac) en tu servidor MCP, tu servidor de autorización debe admitir la emisión de tokens de acceso con Alcances (Scopes). Los Alcances (Scopes) representan los Permisos (Permissions) que se han concedido a un usuario.
+Para implementar el [control de acceso basado en roles (RBAC)](https://auth.wiki/rbac) en tu servidor MCP, tu servidor de autorización debe admitir la emisión de tokens de acceso con Alcances (Scopes). Los Alcances (Scopes) representan los permisos que se han concedido a un usuario.
-[Logto](https://logto.io) proporciona soporte RBAC a través de sus Recursos de API (API resources) (conforme a [RFC 8707: Indicadores de recurso para OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707)) y funciones de Roles (Roles). Así es como se configura:
+[Logto](https://logto.io) proporciona soporte RBAC a través de sus recursos de API (conforme a [RFC 8707: Resource Indicators for OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707)) y funciones de roles. Así es como se configura:
-1. Inicia sesión en [Logto Console](https://cloud.logto.io) (o en tu instancia Logto autogestionada)
+1. Inicia sesión en [Logto Console](https://cloud.logto.io) (o tu instancia autoalojada de Logto Console)
-2. Crea un recurso de API y Alcances (Scopes):
+2. Crea recurso de API y Alcances (Scopes):
- - Ve a "Recursos de API (API Resources)"
- - Crea un nuevo recurso de API llamado "Gestor de tareas"
+ - Ve a "API Resources"
+ - Crea un nuevo recurso de API llamado "Todo Manager"
- Añade los siguientes Alcances (Scopes):
- `create:todos`: "Crear nuevas tareas"
- `read:todos`: "Leer todas las tareas"
- `delete:todos`: "Eliminar cualquier tarea"
-3. Crea Roles (Roles) (recomendado para una gestión más sencilla):
+3. Crea roles (recomendado para una gestión más sencilla):
- Ve a "Roles"
- Crea un rol "Admin" y asigna todos los Alcances (Scopes) (`create:todos`, `read:todos`, `delete:todos`)
- Crea un rol "User" y asigna solo el Alcance (Scope) `create:todos`
-4. Asigna Permisos (Permissions):
- - Ve a "Usuarios (Users)"
+4. Asigna permisos:
+ - Ve a "Users"
- Selecciona un usuario
- Puedes:
- - Asignar Roles (Roles) en la pestaña "Roles" (recomendado)
- - O asignar Alcances (Scopes) directamente en la pestaña "Permisos (Permissions)"
+ - Asignar roles en la pestaña "Roles" (recomendado)
+ - O asignar Alcances (Scopes) directamente en la pestaña "Permissions"
-Los Alcances (Scopes) se incluirán en el Reclamo (Claim) `scope` del token de acceso JWT como una cadena separada por espacios.
+Los Alcances (Scopes) se incluirán en el reclamo `scope` del token de acceso JWT como una cadena separada por espacios.
@@ -106,13 +106,13 @@ Los proveedores OAuth 2.0 / OIDC suelen admitir el control de acceso basado en A
1. Define los Alcances (Scopes) requeridos en tu servidor de autorización
2. Configura tu cliente para solicitar estos Alcances (Scopes) durante el flujo de autorización
3. Asegúrate de que tu servidor de autorización incluya los Alcances (Scopes) concedidos en el token de acceso
-4. Los Alcances (Scopes) suelen incluirse en el Reclamo (Claim) `scope` del token de acceso JWT
+4. Los Alcances (Scopes) suelen incluirse en el reclamo `scope` del token de acceso JWT
Consulta la documentación de tu proveedor para detalles específicos sobre:
- Cómo definir y gestionar Alcances (Scopes)
- Cómo se incluyen los Alcances (Scopes) en el token de acceso
-- Cualquier característica adicional de RBAC como la gestión de Roles (Roles)
+- Cualquier característica adicional de RBAC como la gestión de roles
@@ -122,7 +122,7 @@ Consulta la documentación de tu proveedor para detalles específicos sobre:
Según la última especificación MCP, el servidor MCP actúa como **Servidor de Recursos (Resource Server)** en el marco OAuth 2.0. Como Servidor de Recursos, el servidor MCP tiene las siguientes responsabilidades:
1. **Validación de tokens**: Verificar la autenticidad e integridad de los tokens de acceso recibidos de los clientes MCP
-2. **Aplicación de Alcances (Scope Enforcement)**: Extraer y validar los Alcances (Scopes) del token de acceso para determinar qué operaciones está autorizado a realizar el cliente
+2. **Aplicación de Alcances (Scopes)**: Extraer y validar los Alcances (Scopes) del token de acceso para determinar qué operaciones está autorizado a realizar el cliente
3. **Protección de recursos**: Solo servir recursos protegidos (ejecutar herramientas) cuando el cliente presente tokens válidos con permisos suficientes
Cuando tu servidor MCP recibe una solicitud, realiza el siguiente proceso de validación:
@@ -143,9 +143,9 @@ sequenceDiagram
Client->>Server: Solicitud con token de acceso
(Authorization: Bearer )
alt Validación JWT (Preferido)
- Server->>Auth: Obtener JWKS (si no está en caché)
+ Server->>Auth: Obtiene JWKS (si no está en caché)
Auth-->>Server: Devuelve JWKS
- Server->>Server: Valida localmente la firma y los reclamos del JWT
+ Server->>Server: Valida la firma y los reclamos del JWT localmente
else Introspección de token (Alternativa)
Server->>Auth: POST /introspect
(token=access_token)
Auth-->>Server: Devuelve información del token
(active, scope, user_id, etc.)
@@ -170,7 +170,7 @@ El registro dinámico de clientes no es necesario para este tutorial, pero puede
Para fines demostrativos, implementaremos un sistema simple de control de acceso basado en roles (RBAC) en nuestro servidor MCP gestor de tareas. Esto te mostrará los principios básicos de RBAC manteniendo la implementación sencilla.
:::note
-Aunque este tutorial demuestra la gestión de Alcances (Scopes) basada en RBAC, es importante señalar que no todos los proveedores de autenticación implementan la gestión de Alcances (Scopes) a través de Roles (Roles). Algunos proveedores pueden tener implementaciones y mecanismos propios para gestionar el control de acceso y los Permisos (Permissions).
+Aunque este tutorial demuestra la gestión de Alcances (Scopes) basada en RBAC, es importante señalar que no todos los proveedores de autenticación implementan la gestión de Alcances (Scopes) a través de roles. Algunos proveedores pueden tener sus propias implementaciones y mecanismos únicos para gestionar el control de acceso y los permisos.
:::
### Herramientas y Alcances (Scopes) \{#tools-and-scopes}
@@ -187,9 +187,9 @@ Para controlar el acceso a estas herramientas, definimos los siguientes Alcances
- `delete:todos`: Permite eliminar tareas existentes
- `read:todos`: Permite consultar y recuperar la lista de todas las tareas
-### Roles y Permisos (Permissions) \{#roles-and-permissions}
+### Roles y permisos \{#roles-and-permissions}
-Definiremos dos Roles (Roles) con diferentes niveles de acceso:
+Definiremos dos roles con diferentes niveles de acceso:
| Rol | create:todos | read:todos | delete:todos |
| ----- | ------------ | ---------- | ------------ |
@@ -201,19 +201,19 @@ Definiremos dos Roles (Roles) con diferentes niveles de acceso:
### Propiedad de recursos \{#resource-ownership}
-Aunque la tabla de permisos anterior muestra los Alcances (Scopes) explícitos asignados a cada Rol (Role), hay un principio importante de propiedad de recursos a considerar:
+Aunque la tabla de permisos anterior muestra los Alcances (Scopes) explícitos asignados a cada rol, hay un principio importante de propiedad de recursos a considerar:
-- **Usuarios (Users)** no tienen los Alcances (Scopes) `read:todos` o `delete:todos`, pero aún pueden:
+- **Los usuarios** no tienen los Alcances (Scopes) `read:todos` o `delete:todos`, pero aún pueden:
- Leer sus propias tareas
- Eliminar sus propias tareas
-- **Admins** tienen todos los permisos (`read:todos` y `delete:todos`), lo que les permite:
+- **Los administradores** tienen todos los permisos (`read:todos` y `delete:todos`), lo que les permite:
- Ver todas las tareas del sistema
- Eliminar cualquier tarea, sin importar la propiedad
Esto demuestra un patrón común en los sistemas RBAC donde la propiedad de recursos otorga permisos implícitos a los usuarios para sus propios recursos, mientras que los roles administrativos reciben permisos explícitos para todos los recursos.
:::tip Aprende más
-Para profundizar en los conceptos y mejores prácticas de RBAC, consulta [Dominando RBAC: Un ejemplo completo del mundo real](https://blog.logto.io/mastering-rbac).
+Para profundizar en los conceptos y mejores prácticas de RBAC, consulta [Mastering RBAC: A Comprehensive Real-World Example](https://blog.logto.io/mastering-rbac).
:::
## Configura la autorización en tu proveedor \{#configure-authorization-in-your-provider}
@@ -223,21 +223,21 @@ Para implementar el sistema de control de acceso que describimos antes, deberás
-[Logto](https://logto.io) proporciona soporte RBAC a través de sus Recursos de API (API resources) y funciones de Roles (Roles). Así es como se configura:
+[Logto](https://logto.io) proporciona soporte RBAC a través de sus recursos de API y funciones de roles. Así es como se configura:
-1. Inicia sesión en [Logto Console](https://cloud.logto.io) (o en tu instancia Logto autogestionada)
+1. Inicia sesión en [Logto Console](https://cloud.logto.io) (o tu instancia autoalojada de Logto Console)
-2. Crea un recurso de API y Alcances (Scopes):
+2. Crea recurso de API y Alcances (Scopes):
- - Ve a "Recursos de API (API Resources)"
- - Crea un nuevo recurso de API llamado "Gestor de tareas" y usa `http://localhost:3001/` como el indicador de recurso.
- - **Importante**: El indicador de recurso debe coincidir con la URL de tu servidor MCP. Para este tutorial, usamos `http://localhost:3001/` ya que nuestro servidor MCP se ejecuta en el puerto 3001. En producción, usa la URL real de tu servidor MCP (por ejemplo, `https://tu-servidor-mcp.ejemplo.com/`).
+ - Ve a "API Resources"
+ - Crea un nuevo recurso de API llamado "Todo Manager" y usa `http://localhost:3001/` como el indicador de recurso.
+ - **Importante**: El indicador de recurso debe coincidir con la URL de tu servidor MCP. Para este tutorial, usamos `http://localhost:3001/` ya que nuestro servidor MCP se ejecuta en el puerto 3001. En producción, usa la URL real de tu servidor MCP (por ejemplo, `https://your-mcp-server.example.com/`).
- Crea los siguientes Alcances (Scopes):
- `create:todos`: "Crear nuevas tareas"
- `read:todos`: "Leer todas las tareas"
- `delete:todos`: "Eliminar cualquier tarea"
-3. Crea Roles (Roles) (recomendado para una gestión más sencilla):
+3. Crea roles (recomendado para una gestión más sencilla):
- Ve a "Roles"
- Crea un rol "Admin" y asigna todos los Alcances (Scopes) (`create:todos`, `read:todos`, `delete:todos`)
@@ -246,22 +246,22 @@ Para implementar el sistema de control de acceso que describimos antes, deberás
4. Gestiona roles y permisos de usuario:
- Para nuevos usuarios:
- - Obtendrán automáticamente el rol "User" ya que lo establecimos como el rol predeterminado
+ - Obtendrán automáticamente el rol "User" ya que lo establecimos como rol predeterminado
- Para usuarios existentes:
- Ve a "Gestión de usuarios"
- Selecciona un usuario
- - Asigna roles al usuario en la pestaña "Roles"
+ - Asigna roles para el usuario en la pestaña "Roles"
-:::tip Gestión programática de roles
+:::tip Gestión de roles programática
También puedes usar la [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api) de Logto para gestionar roles de usuario de forma programática. Esto es especialmente útil para la gestión automatizada de usuarios o al construir paneles de administración.
:::
-Al solicitar un token de acceso, Logto incluirá los Alcances (Scopes) en el Reclamo (Claim) `scope` del token según los permisos de rol del usuario.
+Al solicitar un token de acceso, Logto incluirá los Alcances (Scopes) en el reclamo `scope` del token según los permisos de rol del usuario.
-Para proveedores OAuth 2.0 o OpenID Connect, deberás configurar los Alcances (Scopes) que representan diferentes Permisos (Permissions). Los pasos exactos dependerán de tu proveedor, pero generalmente:
+Para proveedores OAuth 2.0 o OpenID Connect, deberás configurar los Alcances (Scopes) que representan diferentes permisos. Los pasos exactos dependerán de tu proveedor, pero generalmente:
1. Define Alcances (Scopes):
@@ -275,13 +275,13 @@ Para proveedores OAuth 2.0 o OpenID Connect, deberás configurar los Alcances (S
- Registra o actualiza tu cliente para solicitar estos Alcances (Scopes)
- Asegúrate de que los Alcances (Scopes) estén incluidos en el token de acceso
-3. Asigna Permisos (Permissions):
+3. Asigna permisos:
- Usa la interfaz de tu proveedor para conceder los Alcances (Scopes) apropiados a los usuarios
- - Algunos proveedores pueden admitir la gestión basada en Roles (Roles), mientras que otros pueden usar asignaciones directas de Alcances (Scopes)
+ - Algunos proveedores pueden admitir la gestión basada en roles, mientras que otros pueden usar asignaciones directas de Alcances (Scopes)
- Consulta la documentación de tu proveedor para el enfoque recomendado
:::tip
-La mayoría de los proveedores incluirán los Alcances (Scopes) concedidos en el Reclamo (Claim) `scope` del token de acceso. El formato suele ser una cadena de valores de Alcance (Scope) separados por espacios.
+La mayoría de los proveedores incluirán los Alcances (Scopes) concedidos en el reclamo `scope` del token de acceso. El formato suele ser una cadena de valores de Alcances (Scopes) separados por espacios.
:::
@@ -291,7 +291,7 @@ La mayoría de los proveedores incluirán los Alcances (Scopes) concedidos en el
Incluye siempre una barra final (`/`) en el indicador de recurso. Debido a un error actual en el SDK oficial de MCP, los clientes que usan el SDK añadirán automáticamente una barra final a los identificadores de recurso al iniciar solicitudes de autenticación. Si tu indicador de recurso no incluye la barra final, la validación del recurso fallará para esos clientes. (VS Code no se ve afectado por este error.)
:::
-Después de configurar tu servidor de autorización, los usuarios recibirán tokens de acceso que contienen sus Alcances (Scopes) concedidos. El servidor MCP usará estos Alcances (Scopes) para determinar:
+Después de configurar tu servidor de autorización, los usuarios recibirán tokens de acceso que contienen los Alcances (Scopes) concedidos. El servidor MCP usará estos Alcances (Scopes) para determinar:
- Si un usuario puede crear nuevas tareas (`create:todos`)
- Si un usuario puede ver todas las tareas (`read:todos`) o solo las suyas
@@ -338,50 +338,55 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import express, { type Request, type Response } from 'express';
-// Crea un servidor MCP
-const server = new McpServer({
- name: 'Todo Manager',
- version: '0.0.0',
-});
+// Función de fábrica para crear una instancia del servidor MCP
+// En modo sin estado, cada solicitud necesita su propia instancia del servidor
+const createMcpServer = () => {
+ const mcpServer = new McpServer({
+ name: 'Todo Manager',
+ version: '0.0.0',
+ });
-server.registerTool(
- 'create-todo',
- {
- description: 'Crear una nueva tarea',
- inputSchema: { content: z.string() },
- },
- async ({ content }) => {
- return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'No implementado' }) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'create-todo',
+ {
+ description: 'Crear una nueva tarea',
+ inputSchema: { content: z.string() },
+ },
+ async ({ content }) => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'No implementado' }) }],
+ };
+ }
+ );
-server.registerTool(
- 'get-todos',
- {
- description: 'Listar todas las tareas',
- inputSchema: {},
- },
- async () => {
- return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'No implementado' }) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'get-todos',
+ {
+ description: 'Listar todas las tareas',
+ inputSchema: {},
+ },
+ async () => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'No implementado' }) }],
+ };
+ }
+ );
-server.registerTool(
- 'delete-todo',
- {
- description: 'Eliminar una tarea por id',
- inputSchema: { id: z.string() },
- },
- async ({ id }) => {
- return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'No implementado' }) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'delete-todo',
+ {
+ description: 'Eliminar una tarea por id',
+ inputSchema: { id: z.string() },
+ },
+ async ({ id }) => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'No implementado' }) }],
+ };
+ }
+ );
+
+ return mcpServer;
+};
// A continuación el código base de la documentación del SDK de MCP
const PORT = 3001;
@@ -391,18 +396,19 @@ app.post('/', async (request: Request, response: Response) => {
// En modo sin estado, crea una nueva instancia de transporte y servidor para cada solicitud
// para asegurar el aislamiento completo. Una sola instancia causaría colisiones de ID de solicitud
// cuando varios clientes se conectan simultáneamente.
+ const mcpServer = createMcpServer();
try {
- const transport: StreamableHTTPServerTransport = new StreamableHTTPServerTransport({
+ const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
- response.on('close', async () => {
+ await mcpServer.connect(transport);
+ await transport.handleRequest(request, response, request.body);
+ response.on('close', () => {
console.log('Solicitud cerrada');
- await transport.close();
- await server.close();
+ void transport.close();
+ void mcpServer.close();
});
- await server.connect(transport);
- await transport.handleRequest(request, response, request.body);
} catch (error) {
console.error('Error al manejar la solicitud MCP:', error);
if (!response.headersSent) {
@@ -418,36 +424,6 @@ app.post('/', async (request: Request, response: Response) => {
}
});
-// Notificaciones SSE no soportadas en modo sin estado
-app.get('/', async (request: Request, response: Response) => {
- console.log('Solicitud GET MCP recibida');
- response.writeHead(405).end(
- JSON.stringify({
- jsonrpc: '2.0',
- error: {
- code: -32_000,
- message: 'Método no permitido.',
- },
- id: null,
- })
- );
-});
-
-// Terminación de sesión no necesaria en modo sin estado
-app.delete('/', async (request: Request, response: Response) => {
- console.log('Solicitud DELETE MCP recibida');
- response.writeHead(405).end(
- JSON.stringify({
- jsonrpc: '2.0',
- error: {
- code: -32_000,
- message: 'Método no permitido.',
- },
- id: null,
- })
- );
-});
-
app.listen(PORT);
```
@@ -462,7 +438,7 @@ npm start
Para completar esta sección, hay varias consideraciones a tener en cuenta:
-**La URL del emisor (Issuer) de tu servidor de autorización**
+**La URL del emisor de tu servidor de autorización**
Normalmente es la URL base de tu servidor de autorización, como `https://auth.example.com`. Algunos proveedores pueden tener una ruta como `https://example.logto.app/oidc`, así que asegúrate de consultar la documentación de tu proveedor.
@@ -491,7 +467,7 @@ Al solicitar tokens de acceso de diferentes servidores de autorización, encontr
- **Basado en indicador de recurso**:
- - Usa el parámetro `resource` para especificar la API objetivo (ver [RFC 8707: Indicadores de recurso para OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707))
+ - Usa el parámetro `resource` para especificar la API objetivo (ver [RFC 8707: Resource Indicators for OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707))
- Común en implementaciones modernas de OAuth 2.0
- Ejemplo de solicitud:
```json
@@ -505,7 +481,7 @@ Al solicitar tokens de acceso de diferentes servidores de autorización, encontr
- **Basado en audiencia**:
- Usa el parámetro `audience` para especificar el destinatario previsto del token
- - Similar a los indicadores de recurso pero con diferentes semánticas
+ - Similar a los indicadores de recurso pero con diferente semántica
- Ejemplo de solicitud:
```json
{
@@ -523,12 +499,12 @@ Al solicitar tokens de acceso de diferentes servidores de autorización, encontr
"scope": "todo-api:create todo-api:read openid profile"
}
```
- - A menudo usa Alcances (Scopes) con prefijo para namespacing de permisos
+ - Suele usar Alcances (Scopes) con prefijo para namespacing de permisos
- Común en implementaciones más simples de OAuth 2.0
:::tip Mejores prácticas
-- Consulta la documentación de tu proveedor para los parámetros soportados
+- Consulta la documentación de tu proveedor para los parámetros admitidos
- Algunos proveedores admiten varios enfoques simultáneamente
- Los indicadores de recurso proporcionan mejor seguridad mediante restricción de audiencia
- Considera usar indicadores de recurso cuando estén disponibles para un mejor control de acceso
@@ -536,30 +512,30 @@ Al solicitar tokens de acceso de diferentes servidores de autorización, encontr
-Aunque cada proveedor puede tener requisitos específicos, los siguientes pasos te guiarán en el proceso de integración de VS Code y el servidor MCP con configuraciones específicas del proveedor.
+Aunque cada proveedor puede tener sus propios requisitos específicos, los siguientes pasos te guiarán en el proceso de integración de VS Code y el servidor MCP con configuraciones específicas del proveedor.
### Registra el cliente MCP como una app de terceros \{#register-mcp-client-as-a-third-party-app}
-Integrar el gestor de tareas con [Logto](https://logto.io) es sencillo ya que es un proveedor OpenID Connect que admite indicadores de recurso y Alcances (Scopes), permitiéndote asegurar tu API de tareas con `http://localhost:3001/` como indicador de recurso.
+Integrar el gestor de tareas con [Logto](https://logto.io) es sencillo ya que es un proveedor OpenID Connect que admite indicadores de recurso y Alcances (Scopes), permitiéndote proteger tu API de tareas con `http://localhost:3001/` como indicador de recurso.
Como Logto aún no admite Dynamic Client Registration, deberás registrar manualmente tu cliente MCP (VS Code) como una app de terceros en tu tenant de Logto:
-1. Inicia sesión en [Logto Console](https://cloud.logto.io) (o en tu instancia Logto autogestionada).
-2. Navega a **Aplicaciones > Apps de terceros** y haz clic en "Crear aplicación".
-3. Selecciona **App nativa** como tipo de aplicación.
+1. Inicia sesión en [Logto Console](https://cloud.logto.io) (o tu instancia autoalojada de Logto Console).
+2. Navega a **Applications > Third-party apps** y haz clic en "Create application".
+3. Selecciona **Native App** como tipo de aplicación.
4. Rellena los detalles de la aplicación:
- - **Nombre de la aplicación**: Ingresa un nombre, por ejemplo, "MCP Client".
- - **Descripción**: Ingresa una descripción, por ejemplo, "Cliente MCP para VS Code".
-5. Establece las siguientes **URIs de redirección** para VS Code:
+ - **Application name**: Introduce un nombre para tu aplicación, por ejemplo, "MCP Client".
+ - **Description**: Introduce una descripción, por ejemplo, "Cliente MCP para VS Code".
+5. Establece los siguientes **Redirect URIs** para VS Code:
```
http://127.0.0.1
https://vscode.dev/redirect
```
-6. Haz clic en "Guardar cambios".
-7. Ve a la pestaña **Permisos (Permissions)** de la app, en la sección **Usuario (User)**, añade los permisos `create:todos`, `read:todos` y `delete:todos` del recurso de API **Todo Manager** que creaste antes.
+6. Haz clic en "Save changes".
+7. Ve a la pestaña **Permissions** de la app, en la sección **User**, añade los permisos `create:todos`, `read:todos` y `delete:todos` del recurso de API **Todo Manager** que creaste antes.
8. En la tarjeta superior, verás el valor "App ID". Cópialo para usarlo más adelante.
@@ -573,31 +549,31 @@ Si tu proveedor admite Dynamic Client Registration, puedes omitir el registro ma
1. Inicia sesión en la consola de tu proveedor.
-2. Navega a la sección "Aplicaciones" o "Clientes", luego crea una nueva aplicación o cliente.
+2. Navega a la sección "Applications" o "Clients", luego crea una nueva aplicación o cliente.
-3. Si tu proveedor requiere un tipo de cliente, selecciona "App nativa" o "Cliente público".
+3. Si tu proveedor requiere un tipo de cliente, selecciona "Native App" o "Public client".
-4. Después de crear la aplicación, configura las URIs de redirección. Para VS Code, añade lo siguiente:
+4. Después de crear la aplicación, configura los Redirect URIs. Para VS Code, añade lo siguiente:
```
http://127.0.0.1
https://vscode.dev/redirect
```
-5. Configura los Alcances (Scopes)/Permisos (Permissions) requeridos para la aplicación:
+5. Configura los Alcances (Scopes)/permisos requeridos para la aplicación:
```text
create:todos read:todos delete:todos
```
-6. Busca el "Client ID" o "Application ID" de la aplicación recién creada y cópialo para usarlo más adelante.
+6. Busca el "Client ID" o "Application ID" de la nueva aplicación y cópialo para usarlo más adelante.
### Configura MCP Auth \{#set-up-mcp-auth}
-Primero, instala el SDK de MCP Auth en tu proyecto de servidor MCP.
+Primero, instala el SDK de MCP Auth en tu proyecto del servidor MCP.
@@ -606,11 +582,11 @@ Ahora necesitamos inicializar MCP Auth en tu servidor MCP. Con el modo de recurs
Hay dos formas de configurar los servidores de autorización:
- **Pre-obtenido (Recomendado)**: Usa `fetchServerConfig()` para obtener los metadatos antes de inicializar MCPAuth. Esto asegura que la configuración se valide al iniciar.
-- **Descubrimiento bajo demanda**: Solo proporciona `issuer` y `type` - los metadatos se obtendrán bajo demanda la primera vez que se necesiten. Esto es útil para entornos edge (como Cloudflare Workers) donde no se permite fetch asíncrono a nivel superior.
+- **Descubrimiento bajo demanda**: Solo proporciona `issuer` y `type` - los metadatos se obtendrán bajo demanda cuando se necesiten por primera vez. Esto es útil para entornos edge (como Cloudflare Workers) donde no se permite fetch asíncrono a nivel superior.
#### Configura los metadatos del recurso protegido \{#configure-protected-resource-metadata}
-Primero, obtén la URL del emisor (Issuer) de tu servidor de autorización:
+Primero, obtén la URL del emisor de tu servidor de autorización:
@@ -625,7 +601,7 @@ En Logto, puedes encontrar la URL del emisor en la página de detalles de tu apl
Para proveedores OAuth 2.0, deberás:
1. Consultar la documentación de tu proveedor para la URL del servidor de autorización (a menudo llamada issuer URL o base URL)
-2. Algunos proveedores la exponen en `https://{tu-dominio}/.well-known/oauth-authorization-server`
+2. Algunos proveedores pueden exponer esto en `https://{your-domain}/.well-known/oauth-authorization-server`
3. Busca en la consola de administración de tu proveedor bajo la configuración OAuth/API
@@ -639,7 +615,7 @@ Ahora, configura los metadatos del recurso protegido al construir la instancia d
import { MCPAuth, fetchServerConfig } from 'mcp-auth';
-const issuerUrl = ''; // Reemplaza con la URL del emisor de tu servidor de autorización
+const issuerUrl = ''; // Sustituye por la URL del emisor de tu servidor de autorización
// Define el identificador de recurso para este servidor MCP
const resourceId = 'http://localhost:3001/';
@@ -674,7 +650,7 @@ Ahora, aplica las rutas de metadatos de recurso protegido para que los clientes
app.use(mcpAuth.protectedResourceMetadataRouter());
```
-A continuación, aplicaremos el middleware de MCP Auth al servidor MCP. Este middleware manejará la Autenticación (Authentication) y Autorización (Authorization) para las solicitudes entrantes, asegurando que solo los usuarios autorizados puedan acceder a las herramientas del gestor de tareas.
+A continuación, aplicaremos el middleware de MCP Auth al servidor MCP. Este middleware gestionará la Autenticación (Authentication) y Autorización (Authorization) para las solicitudes entrantes, asegurando que solo los usuarios autorizados puedan acceder a las herramientas del gestor de tareas.
```ts
// todo-manager.ts
@@ -715,104 +691,116 @@ const hasRequiredScopes = (userScopes: string[], requiredScopes: string[]): bool
return requiredScopes.every((scope) => userScopes.includes(scope));
};
+// TodoService es un singleton ya que necesitamos compartir estado entre solicitudes
const todoService = new TodoService();
-server.registerTool(
- 'create-todo',
- {
- description: 'Crear una nueva tarea',
- inputSchema: { content: z.string() },
- },
- ({ content }, { authInfo }) => {
- const userId = assertUserId(authInfo);
-
- /**
- * Solo los usuarios con el Alcance (Scope) 'create:todos' pueden crear tareas
- */
- if (!hasRequiredScopes(authInfo?.scopes ?? [], ['create:todos'])) {
- throw new MCPAuthBearerAuthError('missing_required_scopes');
- }
+// Función de fábrica para crear una instancia del servidor MCP
+// En modo sin estado, cada solicitud necesita su propia instancia del servidor
+const createMcpServer = () => {
+ const mcpServer = new McpServer({
+ name: 'Todo Manager',
+ version: '0.0.0',
+ });
- const createdTodo = todoService.createTodo({ content, ownerId: userId });
-
- return {
- content: [{ type: 'text', text: JSON.stringify(createdTodo) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'create-todo',
+ {
+ description: 'Crear una nueva tarea',
+ inputSchema: { content: z.string() },
+ },
+ ({ content }, { authInfo }) => {
+ const userId = assertUserId(authInfo);
-server.registerTool(
- 'get-todos',
- {
- description: 'Listar todas las tareas',
- inputSchema: {},
- },
- (_params, { authInfo }) => {
- const userId = assertUserId(authInfo);
+ /**
+ * Solo los usuarios con el Alcance (Scope) 'create:todos' pueden crear tareas
+ */
+ if (!hasRequiredScopes(authInfo?.scopes ?? [], ['create:todos'])) {
+ throw new MCPAuthBearerAuthError('missing_required_scopes');
+ }
- /**
- * Si el usuario tiene el Alcance (Scope) 'read:todos', puede acceder a todas las tareas (todoOwnerId = undefined)
- * Si el usuario no tiene el Alcance (Scope) 'read:todos', solo puede acceder a sus propias tareas (todoOwnerId = userId)
- */
- const todoOwnerId = hasRequiredScopes(authInfo?.scopes ?? [], ['read:todos'])
- ? undefined
- : userId;
+ const createdTodo = todoService.createTodo({ content, ownerId: userId });
- const todos = todoService.getAllTodos(todoOwnerId);
+ return {
+ content: [{ type: 'text', text: JSON.stringify(createdTodo) }],
+ };
+ }
+ );
- return {
- content: [{ type: 'text', text: JSON.stringify(todos) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'get-todos',
+ {
+ description: 'Listar todas las tareas',
+ inputSchema: {},
+ },
+ (_params, { authInfo }) => {
+ const userId = assertUserId(authInfo);
-server.registerTool(
- 'delete-todo',
- {
- description: 'Eliminar una tarea por id',
- inputSchema: { id: z.string() },
- },
- ({ id }, { authInfo }) => {
- const userId = assertUserId(authInfo);
+ /**
+ * Si el usuario tiene el Alcance (Scope) 'read:todos', puede acceder a todas las tareas (todoOwnerId = undefined)
+ * Si el usuario no tiene el Alcance (Scope) 'read:todos', solo puede acceder a sus propias tareas (todoOwnerId = userId)
+ */
+ const todoOwnerId = hasRequiredScopes(authInfo?.scopes ?? [], ['read:todos'])
+ ? undefined
+ : userId;
- const todo = todoService.getTodoById(id);
+ const todos = todoService.getAllTodos(todoOwnerId);
- if (!todo) {
return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'No se pudo eliminar la tarea' }) }],
+ content: [{ type: 'text', text: JSON.stringify(todos) }],
};
}
+ );
+
+ mcpServer.registerTool(
+ 'delete-todo',
+ {
+ description: 'Eliminar una tarea por id',
+ inputSchema: { id: z.string() },
+ },
+ ({ id }, { authInfo }) => {
+ const userId = assertUserId(authInfo);
+
+ const todo = todoService.getTodoById(id);
+
+ if (!todo) {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'No se pudo eliminar la tarea' }) }],
+ };
+ }
+
+ /**
+ * Los usuarios solo pueden eliminar sus propias tareas
+ * Los usuarios con el Alcance (Scope) 'delete:todos' pueden eliminar cualquier tarea
+ */
+ if (todo.ownerId !== userId && !hasRequiredScopes(authInfo?.scopes ?? [], ['delete:todos'])) {
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({ error: 'No se pudo eliminar la tarea' }),
+ },
+ ],
+ };
+ }
+
+ const deletedTodo = todoService.deleteTodo(id);
- /**
- * Los usuarios solo pueden eliminar sus propias tareas
- * Los usuarios con el Alcance (Scope) 'delete:todos' pueden eliminar cualquier tarea
- */
- if (todo.ownerId !== userId && !hasRequiredScopes(authInfo?.scopes ?? [], ['delete:todos'])) {
return {
content: [
{
type: 'text',
- text: JSON.stringify({ error: 'No se pudo eliminar la tarea' }),
+ text: JSON.stringify({
+ message: `Tarea ${id} eliminada`,
+ details: deletedTodo,
+ }),
},
],
};
}
+ );
- const deletedTodo = todoService.deleteTodo(id);
-
- return {
- content: [
- {
- type: 'text',
- text: JSON.stringify({
- message: `Tarea ${id} eliminada`,
- details: deletedTodo,
- }),
- },
- ],
- };
- }
-);
+ return mcpServer;
+};
```
Ahora, crea el "Servicio de tareas" usado en el código anterior para implementar la funcionalidad relacionada:
@@ -831,7 +819,7 @@ type Todo = {
/**
* Un servicio de tareas simple para fines demostrativos.
- * Usa un array en memoria para almacenar tareas
+ * Usa un array en memoria para almacenar las tareas
*/
export class TodoService {
private readonly todos: Todo[] = [];
@@ -886,17 +874,17 @@ Consulta el [repositorio del SDK de MCP Auth para Node.js](https://github.com/mc
## Punto de control: Ejecuta las herramientas `todo-manager` \{#checkpoint-run-the-todo-manager-tools}
-Reinicia tu servidor MCP y conecta VS Code a él. Así es como puedes conectarte con autenticación:
+Reinicia tu servidor MCP y conecta VS Code a él. Así es como conectarse con autenticación:
1. En VS Code, presiona `Command + Shift + P` (macOS) o `Ctrl + Shift + P` (Windows/Linux) para abrir la paleta de comandos.
2. Escribe `MCP: Add Server...` y selecciónalo.
3. Elige `HTTP` como tipo de servidor.
-4. Ingresa la URL del servidor MCP: `http://localhost:3001`
-5. Después de que se inicie una solicitud OAuth, VS Code te pedirá que ingreses el **App ID**. Ingresa el App ID que copiaste de tu servidor de autorización.
+4. Introduce la URL del servidor MCP: `http://localhost:3001`
+5. Tras iniciarse una solicitud OAuth, VS Code te pedirá que introduzcas el **App ID**. Introduce el App ID que copiaste de tu servidor de autorización.
6. Como no tenemos un **App Secret** (es un cliente público), simplemente presiona Enter para omitir.
7. Completa el flujo de inicio de sesión en tu navegador.
-Una vez que inicies sesión y regreses a VS Code, repite las acciones que hicimos en el punto de control anterior para ejecutar las herramientas del gestor de tareas. Esta vez, puedes usar estas herramientas con tu identidad de usuario autenticada. El comportamiento de las herramientas dependerá de los Roles (Roles) y Permisos (Permissions) asignados a tu usuario:
+Una vez que inicies sesión y regreses a VS Code, repite las acciones que hicimos en el punto de control anterior para ejecutar las herramientas del gestor de tareas. Esta vez, puedes usar estas herramientas con tu identidad de usuario autenticada. El comportamiento de las herramientas dependerá de los roles y permisos asignados a tu usuario:
- Si has iniciado sesión como **User** (con solo el Alcance (Scope) `create:todos`):
@@ -911,8 +899,8 @@ Una vez que inicies sesión y regreses a VS Code, repite las acciones que hicimo
Puedes probar estos diferentes niveles de permisos:
-1. Desconectándote del servidor MCP (elimina la configuración del servidor en VS Code)
-2. Iniciando sesión con una cuenta de usuario diferente que tenga diferentes Roles (Roles)/Permisos (Permissions)
+1. Desconectando del servidor MCP (elimina la configuración del servidor en VS Code)
+2. Iniciando sesión con una cuenta de usuario diferente que tenga otros roles/permisos
3. Probando las mismas herramientas nuevamente para observar cómo cambia el comportamiento según los permisos del usuario
Esto demuestra cómo funciona el control de acceso basado en roles (RBAC) en la práctica, donde diferentes usuarios tienen diferentes niveles de acceso a la funcionalidad del sistema.
@@ -930,4 +918,4 @@ Consulta el [repositorio del SDK de MCP Auth para Node.js](https://github.com/mc
- Integración del servidor MCP con un servidor de autorización usando MCP Auth
- Configuración de VS Code para autenticar usuarios y usar tokens de acceso con Alcances (Scopes) para llamar a herramientas
-Asegúrate de consultar otros tutoriales y documentación para aprovechar al máximo MCP Auth.
\ No newline at end of file
+Asegúrate de consultar otros tutoriales y documentación para sacar el máximo provecho de MCP Auth.
\ No newline at end of file
diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx b/i18n/fr/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
index ce46eed..1ba5dc4 100644
--- a/i18n/fr/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
+++ b/i18n/fr/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
@@ -13,7 +13,7 @@ import Tabs from '@theme/Tabs';
MCP Auth est également disponible pour Python ! Consultez le [dépôt SDK Python](https://github.com/mcp-auth/python) pour l'installation et l'utilisation.
:::
-Dans ce tutoriel, nous allons construire un serveur MCP gestionnaire de tâches avec authentification et autorisation des utilisateurs. En suivant la dernière spécification MCP, notre serveur MCP agira en tant que **Serveur de ressources** OAuth 2.0 qui valide les jetons d’accès et applique les permissions basées sur la portée (scope).
+Dans ce tutoriel, nous allons créer un serveur MCP de gestionnaire de tâches avec authentification et autorisation des utilisateurs. En suivant la dernière spécification MCP, notre serveur MCP agira comme un **Serveur de ressources** OAuth 2.0 qui valide les jetons d’accès et applique les permissions basées sur la portée (scope).
Après avoir terminé ce tutoriel, vous aurez :
@@ -70,24 +70,24 @@ Pour mettre en œuvre le [contrôle d’accès basé sur les rôles (RBAC)](http
-[Logto](https://logto.io) propose la prise en charge du RBAC via ses ressources API (conformes à [RFC 8707 : Indicateurs de ressource pour OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707)) et ses fonctionnalités de rôles. Voici comment le configurer :
+[Logto](https://logto.io) fournit la prise en charge du RBAC via ses ressources API (conformes à [RFC 8707 : Indicateurs de ressource pour OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707)) et ses fonctionnalités de rôles. Voici comment le configurer :
1. Connectez-vous à [Logto Console](https://cloud.logto.io) (ou à votre propre instance Logto Console)
2. Créez une ressource API et des portées :
- Allez dans "Ressources API"
- - Créez une nouvelle ressource API nommée "Todo Manager"
+ - Créez une nouvelle ressource API nommée "Gestionnaire de tâches"
- Ajoutez les portées suivantes :
- - `create:todos` : "Créer de nouveaux éléments de tâches"
- - `read:todos` : "Lire tous les éléments de tâches"
- - `delete:todos` : "Supprimer n’importe quel élément de tâche"
+ - `create:todos` : "Créer de nouvelles tâches"
+ - `read:todos` : "Lire toutes les tâches"
+ - `delete:todos` : "Supprimer n’importe quelle tâche"
3. Créez des rôles (recommandé pour une gestion plus facile) :
- Allez dans "Rôles"
- Créez un rôle "Admin" et assignez toutes les portées (`create:todos`, `read:todos`, `delete:todos`)
- - Créez un rôle "User" et assignez uniquement la portée `create:todos`
+ - Créez un rôle "Utilisateur" et assignez uniquement la portée `create:todos`
4. Attribuez les permissions :
- Allez dans "Utilisateurs"
@@ -108,7 +108,7 @@ Les fournisseurs OAuth 2.0 / OIDC prennent généralement en charge le contrôle
3. Assurez-vous que votre serveur d’autorisation inclut les portées accordées dans le jeton d’accès
4. Les portées sont généralement incluses dans la revendication `scope` du jeton d’accès JWT
-Consultez la documentation de votre fournisseur pour plus de détails sur :
+Consultez la documentation de votre fournisseur pour les détails spécifiques sur :
- Comment définir et gérer les portées
- Comment les portées sont incluses dans le jeton d’accès
@@ -123,7 +123,7 @@ Selon la dernière spécification MCP, le serveur MCP agit comme un **Serveur de
1. **Validation du jeton** : Vérifier l’authenticité et l’intégrité des jetons d’accès reçus des clients MCP
2. **Application des portées** : Extraire et valider les portées du jeton d’accès pour déterminer quelles opérations le client est autorisé à effectuer
-3. **Protection des ressources** : Ne servir les ressources protégées (exécuter les outils) que lorsque le client présente des jetons valides avec des permissions suffisantes
+3. **Protection des ressources** : Servir uniquement les ressources protégées (exécuter des outils) lorsque le client présente des jetons valides avec des permissions suffisantes
Lorsque votre serveur MCP reçoit une requête, il effectue le processus de validation suivant :
@@ -142,16 +142,16 @@ sequenceDiagram
Client->>Server: Requête avec jeton d’accès
(Authorization: Bearer )
- alt Validation JWT (Préférée)
+ alt Validation JWT (Préféré)
Server->>Auth: Récupérer JWKS (si non en cache)
- Auth-->>Server: Retourne JWKS
+ Auth-->>Server: Retourner JWKS
Server->>Server: Valider la signature JWT & les revendications localement
else Introspection du jeton (Fallback)
Server->>Auth: POST /introspect
(token=access_token)
- Auth-->>Server: Retourne infos du jeton
(active, scope, user_id, etc.)
+ Auth-->>Server: Retourner les infos du jeton
(active, scope, user_id, etc.)
end
- Server->>Server: Extraire portées & contexte utilisateur
du jeton validé
+ Server->>Server: Extraire les portées & le contexte utilisateur
du jeton validé
alt Possède les portées requises
Server->>Server: Exécuter l’opération demandée
@@ -189,15 +189,15 @@ Pour contrôler l’accès à ces outils, nous définissons les portées suivant
### Rôles et permissions \{#roles-and-permissions}
-Nous allons définir deux rôles avec différents niveaux d’accès :
+Nous définirons deux rôles avec différents niveaux d’accès :
-| Rôle | create:todos | read:todos | delete:todos |
-| ----- | ------------ | ---------- | ------------ |
-| Admin | ✅ | ✅ | ✅ |
-| User | ✅ | | |
+| Rôle | create:todos | read:todos | delete:todos |
+| ------ | ------------ | ---------- | ------------ |
+| Admin | ✅ | ✅ | ✅ |
+| User | ✅ | | |
-- **User** : Un utilisateur régulier qui peut créer des tâches et voir ou supprimer uniquement ses propres tâches
-- **Admin** : Un administrateur qui peut créer, voir et supprimer toutes les tâches, quel que soit le propriétaire
+- **Utilisateur** : Un utilisateur classique qui peut créer des tâches et voir ou supprimer uniquement ses propres tâches
+- **Admin** : Un administrateur qui peut créer, voir et supprimer toutes les tâches, quelle que soit leur appartenance
### Propriété des ressources \{#resource-ownership}
@@ -208,7 +208,7 @@ Bien que le tableau des permissions ci-dessus montre les portées explicites att
- Supprimer leurs propres tâches
- **Les admins** ont toutes les permissions (`read:todos` et `delete:todos`), ce qui leur permet de :
- Voir toutes les tâches du système
- - Supprimer n’importe quelle tâche, quel que soit le propriétaire
+ - Supprimer n’importe quelle tâche, quelle que soit son appartenance
Cela illustre un schéma courant dans les systèmes RBAC où la propriété d’une ressource accorde des permissions implicites aux utilisateurs pour leurs propres ressources, tandis que les rôles administratifs reçoivent des permissions explicites pour toutes les ressources.
@@ -223,59 +223,59 @@ Pour mettre en œuvre le système de contrôle d’accès décrit précédemment
-[Logto](https://logto.io) propose la prise en charge du RBAC via ses ressources API et ses fonctionnalités de rôles. Voici comment le configurer :
+[Logto](https://logto.io) fournit la prise en charge du RBAC via ses ressources API et ses fonctionnalités de rôles. Voici comment le configurer :
1. Connectez-vous à [Logto Console](https://cloud.logto.io) (ou à votre propre instance Logto Console)
2. Créez une ressource API et des portées :
- Allez dans "Ressources API"
- - Créez une nouvelle ressource API nommée "Todo Manager" en utilisant `http://localhost:3001/` comme indicateur de ressource.
- - **Important** : L’indicateur de ressource doit correspondre à l’URL de votre serveur MCP. Pour ce tutoriel, nous utilisons `http://localhost:3001/` puisque notre serveur MCP tourne sur le port 3001. En production, utilisez l’URL réelle de votre serveur MCP (par exemple, `https://your-mcp-server.example.com/`).
+ - Créez une nouvelle ressource API nommée "Gestionnaire de tâches" et utilisez `http://localhost:3001/` comme indicateur de ressource.
+ - **Important** : L’indicateur de ressource doit correspondre à l’URL de votre serveur MCP. Pour ce tutoriel, nous utilisons `http://localhost:3001/` puisque notre serveur MCP tourne sur le port 3001. En production, utilisez l’URL réelle de votre serveur MCP (par exemple, `https://votre-mcp-server.example.com/`).
- Créez les portées suivantes :
- - `create:todos` : "Créer de nouveaux éléments de tâches"
- - `read:todos` : "Lire tous les éléments de tâches"
- - `delete:todos` : "Supprimer n’importe quel élément de tâche"
+ - `create:todos` : "Créer de nouvelles tâches"
+ - `read:todos` : "Lire toutes les tâches"
+ - `delete:todos` : "Supprimer n’importe quelle tâche"
3. Créez des rôles (recommandé pour une gestion plus facile) :
- Allez dans "Rôles"
- Créez un rôle "Admin" et assignez toutes les portées (`create:todos`, `read:todos`, `delete:todos`)
- - Créez un rôle "User" et assignez uniquement la portée `create:todos`
- - Dans la page de détails du rôle "User", passez à l’onglet "Général" et définissez le rôle "User" comme "Rôle par défaut".
+ - Créez un rôle "Utilisateur" et assignez uniquement la portée `create:todos`
+ - Dans la page de détails du rôle "Utilisateur", passez à l’onglet "Général" et définissez le rôle "Utilisateur" comme "Rôle par défaut".
-4. Gérer les rôles et permissions des utilisateurs :
+4. Gérez les rôles et permissions des utilisateurs :
- Pour les nouveaux utilisateurs :
- - Ils recevront automatiquement le rôle "User" puisque nous l’avons défini comme rôle par défaut
+ - Ils recevront automatiquement le rôle "Utilisateur" puisque nous l’avons défini comme rôle par défaut
- Pour les utilisateurs existants :
- Allez dans "Gestion des utilisateurs"
- Sélectionnez un utilisateur
- Attribuez des rôles à l’utilisateur dans l’onglet "Rôles"
-:::tip Gestion des rôles par API
+:::tip Gestion programmatique des rôles
Vous pouvez également utiliser la [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api) de Logto pour gérer les rôles des utilisateurs de manière programmatique. Ceci est particulièrement utile pour la gestion automatisée des utilisateurs ou lors de la création de panneaux d’administration.
:::
-Lors de la demande d’un jeton d’accès, Logto inclura les portées dans la revendication `scope` du jeton en fonction des permissions de rôle de l’utilisateur.
+Lors de la demande d’un jeton d’accès, Logto inclura les portées dans la revendication `scope` du jeton selon les permissions du rôle de l’utilisateur.
-Pour les fournisseurs OAuth 2.0 ou OpenID Connect, vous devrez configurer les portées qui représentent différentes permissions. Les étapes exactes dépendront de votre fournisseur, mais en général :
+Pour les fournisseurs OAuth 2.0 ou OpenID Connect, vous devrez configurer les portées qui représentent différentes permissions. Les étapes exactes dépendront de votre fournisseur, mais généralement :
-1. Définir les portées :
+1. Définissez les portées :
- Configurez votre serveur d’autorisation pour prendre en charge :
- `create:todos`
- `read:todos`
- `delete:todos`
-2. Configurer le client :
+2. Configurez le client :
- Enregistrez ou mettez à jour votre client pour demander ces portées
- Assurez-vous que les portées sont incluses dans le jeton d’accès
-3. Attribuer les permissions :
+3. Attribuez les permissions :
- Utilisez l’interface de votre fournisseur pour accorder les portées appropriées aux utilisateurs
- Certains fournisseurs peuvent prendre en charge la gestion basée sur les rôles, tandis que d’autres utilisent des attributions de portées directes
- Consultez la documentation de votre fournisseur pour la méthode recommandée
@@ -299,7 +299,7 @@ Après avoir configuré votre serveur d’autorisation, les utilisateurs recevro
## Mettre en place le serveur MCP \{#set-up-the-mcp-server}
-Nous allons utiliser les [SDK officiels MCP](https://github.com/modelcontextprotocol) pour créer notre serveur MCP gestionnaire de tâches.
+Nous allons utiliser les [SDKs officiels MCP](https://github.com/modelcontextprotocol) pour créer notre serveur MCP gestionnaire de tâches.
### Créer un nouveau projet \{#create-a-new-project}
@@ -338,71 +338,77 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import express, { type Request, type Response } from 'express';
-// Créer un serveur MCP
-const server = new McpServer({
- name: 'Todo Manager',
- version: '0.0.0',
-});
+// Fonction usine pour créer une instance de serveur MCP
+// En mode sans état, chaque requête nécessite sa propre instance de serveur
+const createMcpServer = () => {
+ const mcpServer = new McpServer({
+ name: 'Todo Manager',
+ version: '0.0.0',
+ });
-server.registerTool(
- 'create-todo',
- {
- description: 'Créer une nouvelle tâche',
- inputSchema: { content: z.string() },
- },
- async ({ content }) => {
- return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'Non implémenté' }) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'create-todo',
+ {
+ description: 'Créer une nouvelle tâche',
+ inputSchema: { content: z.string() },
+ },
+ async ({ content }) => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Non implémenté' }) }],
+ };
+ }
+ );
-server.registerTool(
- 'get-todos',
- {
- description: 'Lister toutes les tâches',
- inputSchema: {},
- },
- async () => {
- return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'Non implémenté' }) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'get-todos',
+ {
+ description: 'Lister toutes les tâches',
+ inputSchema: {},
+ },
+ async () => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Non implémenté' }) }],
+ };
+ }
+ );
-server.registerTool(
- 'delete-todo',
- {
- description: 'Supprimer une tâche par id',
- inputSchema: { id: z.string() },
- },
- async ({ id }) => {
- return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'Non implémenté' }) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'delete-todo',
+ {
+ description: 'Supprimer une tâche par id',
+ inputSchema: { id: z.string() },
+ },
+ async ({ id }) => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Non implémenté' }) }],
+ };
+ }
+ );
+
+ return mcpServer;
+};
// Ci-dessous le code standard issu de la documentation du SDK MCP
const PORT = 3001;
const app = express();
app.post('/', async (request: Request, response: Response) => {
- // En mode stateless, créez une nouvelle instance de transport et de serveur pour chaque requête
- // afin d’assurer une isolation complète. Une seule instance causerait des collisions d’ID de requête
+ // En mode sans état, créez une nouvelle instance de transport et de serveur pour chaque requête
+ // pour garantir une isolation complète. Une seule instance provoquerait des collisions d’ID de requête
// lorsque plusieurs clients se connectent simultanément.
+ const mcpServer = createMcpServer();
try {
- const transport: StreamableHTTPServerTransport = new StreamableHTTPServerTransport({
+ const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
- response.on('close', async () => {
+ await mcpServer.connect(transport);
+ await transport.handleRequest(request, response, request.body);
+ response.on('close', () => {
console.log('Requête fermée');
- await transport.close();
- await server.close();
+ void transport.close();
+ void mcpServer.close();
});
- await server.connect(transport);
- await transport.handleRequest(request, response, request.body);
} catch (error) {
console.error('Erreur lors du traitement de la requête MCP :', error);
if (!response.headersSent) {
@@ -418,36 +424,6 @@ app.post('/', async (request: Request, response: Response) => {
}
});
-// Les notifications SSE ne sont pas prises en charge en mode stateless
-app.get('/', async (request: Request, response: Response) => {
- console.log('Reçu une requête GET MCP');
- response.writeHead(405).end(
- JSON.stringify({
- jsonrpc: '2.0',
- error: {
- code: -32_000,
- message: 'Méthode non autorisée.',
- },
- id: null,
- })
- );
-});
-
-// La terminaison de session n’est pas nécessaire en mode stateless
-app.delete('/', async (request: Request, response: Response) => {
- console.log('Reçu une requête DELETE MCP');
- response.writeHead(405).end(
- JSON.stringify({
- jsonrpc: '2.0',
- error: {
- code: -32_000,
- message: 'Méthode non autorisée.',
- },
- id: null,
- })
- );
-});
-
app.listen(PORT);
```
@@ -485,7 +461,7 @@ Il s’agit généralement de l’URL de base de votre serveur d’autorisation,
-**Comprendre les paramètres de requête de jeton**
+**Comprendre les paramètres de la requête de jeton**
Lorsque vous demandez des jetons d’accès à différents serveurs d’autorisation, vous rencontrerez diverses approches pour spécifier la ressource cible et les permissions. Voici les principaux schémas :
@@ -505,7 +481,7 @@ Lorsque vous demandez des jetons d’accès à différents serveurs d’autorisa
- **Basé sur l’audience** :
- Utilise le paramètre `audience` pour spécifier le destinataire prévu du jeton
- - Semblable aux indicateurs de ressource mais avec une sémantique différente
+ - Semblable aux indicateurs de ressource mais avec des sémantiques différentes
- Exemple de requête :
```json
{
@@ -531,7 +507,7 @@ Lorsque vous demandez des jetons d’accès à différents serveurs d’autorisa
- Consultez la documentation de votre fournisseur pour les paramètres pris en charge
- Certains fournisseurs prennent en charge plusieurs approches simultanément
- Les indicateurs de ressource offrent une meilleure sécurité via la restriction d’audience
-- Envisagez d’utiliser les indicateurs de ressource lorsque c’est possible pour un meilleur contrôle d’accès
+- Privilégiez les indicateurs de ressource lorsque disponibles pour un meilleur contrôle d’accès
:::
@@ -551,7 +527,7 @@ Comme Logto ne prend pas encore en charge l’enregistrement dynamique du client
2. Naviguez vers **Applications > Applications tierces** et cliquez sur "Créer une application".
3. Sélectionnez **Application native** comme type d’application.
4. Renseignez les détails de l’application :
- - **Nom de l’application** : Entrez un nom, par exemple "MCP Client".
+ - **Nom de l’application** : Entrez un nom, par exemple "Client MCP".
- **Description** : Entrez une description, par exemple "Client MCP pour VS Code".
5. Définissez les **URI de redirection** suivants pour VS Code :
```
@@ -559,7 +535,7 @@ Comme Logto ne prend pas encore en charge l’enregistrement dynamique du client
https://vscode.dev/redirect
```
6. Cliquez sur "Enregistrer les modifications".
-7. Allez dans l’onglet **Permissions** de l’application, sous la section **Utilisateur**, ajoutez les permissions `create:todos`, `read:todos` et `delete:todos` de la ressource API **Todo Manager** que vous avez créée précédemment.
+7. Allez dans l’onglet **Permissions** de l’application, sous la section **Utilisateur**, ajoutez les permissions `create:todos`, `read:todos` et `delete:todos` de la ressource API **Gestionnaire de tâches** que vous avez créée précédemment.
8. Dans la carte supérieure, vous verrez la valeur "App ID". Copiez-la pour une utilisation ultérieure.
@@ -605,8 +581,8 @@ Nous devons maintenant initialiser MCP Auth dans votre serveur MCP. En mode ress
Il existe deux façons de configurer les serveurs d’autorisation :
-- **Pré-récupéré (Recommandé)** : Utilisez `fetchServerConfig()` pour récupérer les métadonnées avant d’initialiser MCPAuth. Cela garantit que la configuration est validée au démarrage.
-- **Découverte à la demande** : Fournissez uniquement `issuer` et `type` – les métadonnées seront récupérées à la demande lors du premier besoin. Ceci est utile pour les environnements edge (comme Cloudflare Workers) où l’appel asynchrone de haut niveau n’est pas autorisé.
+- **Pré-récupéré (recommandé)** : Utilisez `fetchServerConfig()` pour récupérer les métadonnées avant d’initialiser MCPAuth. Cela garantit que la configuration est validée au démarrage.
+- **Découverte à la demande** : Fournissez uniquement `issuer` et `type` – les métadonnées seront récupérées à la demande lors du premier besoin. Ceci est utile pour les environnements edge (comme Cloudflare Workers) où l’appel async top-level n’est pas autorisé.
#### Configurer les métadonnées de ressource protégée \{#configure-protected-resource-metadata}
@@ -624,9 +600,9 @@ Dans Logto, vous pouvez trouver l’URL de l’émetteur sur la page de détails
Pour les fournisseurs OAuth 2.0, vous devrez :
-1. Consulter la documentation de votre fournisseur pour l’URL du serveur d’autorisation (souvent appelée issuer URL ou base URL)
-2. Certains fournisseurs exposent cela à `https://{your-domain}/.well-known/oauth-authorization-server`
-3. Cherchez dans la console d’administration de votre fournisseur sous les paramètres OAuth / API
+1. Vérifier la documentation de votre fournisseur pour l’URL du serveur d’autorisation (souvent appelée issuer URL ou base URL)
+2. Certains fournisseurs l’exposent à `https://{votre-domaine}/.well-known/oauth-authorization-server`
+3. Chercher dans la console d’administration de votre fournisseur sous les paramètres OAuth / API
@@ -662,7 +638,7 @@ const mcpAuth = new MCPAuth({
### Mettre à jour le serveur MCP \{#update-mcp-server}
-Nous y sommes presque ! Il est temps de mettre à jour le serveur MCP pour appliquer la route et la fonction middleware MCP Auth, puis implémenter le contrôle d’accès basé sur les permissions pour les outils du gestionnaire de tâches selon les portées de l’utilisateur.
+Nous y sommes presque ! Il est temps de mettre à jour le serveur MCP pour appliquer la route et la fonction middleware MCP Auth, puis d’implémenter le contrôle d’accès basé sur les permissions pour les outils du gestionnaire de tâches selon les portées de l’utilisateur.
Appliquez maintenant les routes de métadonnées de ressource protégée afin que les clients MCP puissent récupérer les métadonnées attendues depuis le serveur MCP.
@@ -715,109 +691,121 @@ const hasRequiredScopes = (userScopes: string[], requiredScopes: string[]): bool
return requiredScopes.every((scope) => userScopes.includes(scope));
};
+// TodoService est un singleton car nous devons partager l’état entre les requêtes
const todoService = new TodoService();
-server.registerTool(
- 'create-todo',
- {
- description: 'Créer une nouvelle tâche',
- inputSchema: { content: z.string() },
- },
- ({ content }, { authInfo }) => {
- const userId = assertUserId(authInfo);
-
- /**
- * Seuls les utilisateurs avec la portée 'create:todos' peuvent créer des tâches
- */
- if (!hasRequiredScopes(authInfo?.scopes ?? [], ['create:todos'])) {
- throw new MCPAuthBearerAuthError('missing_required_scopes');
- }
+// Fonction usine pour créer une instance de serveur MCP
+// En mode sans état, chaque requête nécessite sa propre instance de serveur
+const createMcpServer = () => {
+ const mcpServer = new McpServer({
+ name: 'Todo Manager',
+ version: '0.0.0',
+ });
- const createdTodo = todoService.createTodo({ content, ownerId: userId });
-
- return {
- content: [{ type: 'text', text: JSON.stringify(createdTodo) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'create-todo',
+ {
+ description: 'Créer une nouvelle tâche',
+ inputSchema: { content: z.string() },
+ },
+ ({ content }, { authInfo }) => {
+ const userId = assertUserId(authInfo);
-server.registerTool(
- 'get-todos',
- {
- description: 'Lister toutes les tâches',
- inputSchema: {},
- },
- (_params, { authInfo }) => {
- const userId = assertUserId(authInfo);
+ /**
+ * Seuls les utilisateurs avec la portée 'create:todos' peuvent créer des tâches
+ */
+ if (!hasRequiredScopes(authInfo?.scopes ?? [], ['create:todos'])) {
+ throw new MCPAuthBearerAuthError('missing_required_scopes');
+ }
- /**
- * Si l’utilisateur a la portée 'read:todos', il peut accéder à toutes les tâches (todoOwnerId = undefined)
- * Sinon, il ne peut accéder qu’à ses propres tâches (todoOwnerId = userId)
- */
- const todoOwnerId = hasRequiredScopes(authInfo?.scopes ?? [], ['read:todos'])
- ? undefined
- : userId;
+ const createdTodo = todoService.createTodo({ content, ownerId: userId });
- const todos = todoService.getAllTodos(todoOwnerId);
+ return {
+ content: [{ type: 'text', text: JSON.stringify(createdTodo) }],
+ };
+ }
+ );
- return {
- content: [{ type: 'text', text: JSON.stringify(todos) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'get-todos',
+ {
+ description: 'Lister toutes les tâches',
+ inputSchema: {},
+ },
+ (_params, { authInfo }) => {
+ const userId = assertUserId(authInfo);
-server.registerTool(
- 'delete-todo',
- {
- description: 'Supprimer une tâche par id',
- inputSchema: { id: z.string() },
- },
- ({ id }, { authInfo }) => {
- const userId = assertUserId(authInfo);
+ /**
+ * Si l’utilisateur a la portée 'read:todos', il peut accéder à toutes les tâches (todoOwnerId = undefined)
+ * Sinon, il ne peut accéder qu’à ses propres tâches (todoOwnerId = userId)
+ */
+ const todoOwnerId = hasRequiredScopes(authInfo?.scopes ?? [], ['read:todos'])
+ ? undefined
+ : userId;
- const todo = todoService.getTodoById(id);
+ const todos = todoService.getAllTodos(todoOwnerId);
- if (!todo) {
return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'Échec de la suppression de la tâche' }) }],
+ content: [{ type: 'text', text: JSON.stringify(todos) }],
};
}
+ );
+
+ mcpServer.registerTool(
+ 'delete-todo',
+ {
+ description: 'Supprimer une tâche par id',
+ inputSchema: { id: z.string() },
+ },
+ ({ id }, { authInfo }) => {
+ const userId = assertUserId(authInfo);
+
+ const todo = todoService.getTodoById(id);
+
+ if (!todo) {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Échec de la suppression de la tâche' }) }],
+ };
+ }
+
+ /**
+ * Les utilisateurs ne peuvent supprimer que leurs propres tâches
+ * Les utilisateurs avec la portée 'delete:todos' peuvent supprimer n’importe quelle tâche
+ */
+ if (todo.ownerId !== userId && !hasRequiredScopes(authInfo?.scopes ?? [], ['delete:todos'])) {
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({ error: 'Échec de la suppression de la tâche' }),
+ },
+ ],
+ };
+ }
+
+ const deletedTodo = todoService.deleteTodo(id);
- /**
- * Les utilisateurs ne peuvent supprimer que leurs propres tâches
- * Les utilisateurs avec la portée 'delete:todos' peuvent supprimer n’importe quelle tâche
- */
- if (todo.ownerId !== userId && !hasRequiredScopes(authInfo?.scopes ?? [], ['delete:todos'])) {
return {
content: [
{
type: 'text',
- text: JSON.stringify({ error: 'Échec de la suppression de la tâche' }),
+ text: JSON.stringify({
+ message: `Tâche ${id} supprimée`,
+ details: deletedTodo,
+ }),
},
],
};
}
+ );
- const deletedTodo = todoService.deleteTodo(id);
-
- return {
- content: [
- {
- type: 'text',
- text: JSON.stringify({
- message: `Tâche ${id} supprimée`,
- details: deletedTodo,
- }),
- },
- ],
- };
- }
-);
+ return mcpServer;
+};
```
-Créez maintenant le "service Todo" utilisé dans le code ci-dessus pour implémenter la fonctionnalité associée :
+Créez maintenant le "service de tâches" utilisé dans le code ci-dessus pour implémenter la fonctionnalité associée :
-Créez le fichier `todo-service.ts` pour le service Todo :
+Créez le fichier `todo-service.ts` pour le service de tâches :
```ts
// todo-service.ts
@@ -893,12 +881,12 @@ Redémarrez votre serveur MCP et connectez VS Code à celui-ci. Voici comment se
3. Choisissez `HTTP` comme type de serveur.
4. Entrez l’URL du serveur MCP : `http://localhost:3001`
5. Après l’initiation d’une requête OAuth, VS Code vous demandera de saisir l’**App ID**. Entrez l’App ID que vous avez copié depuis votre serveur d’autorisation.
-6. Comme nous n’avons pas de **App Secret** (c’est un client public), appuyez simplement sur Entrée pour passer.
-7. Terminez le flux de connexion dans votre navigateur.
+6. Comme nous n’avons pas d’**App Secret** (c’est un client public), appuyez simplement sur Entrée pour passer.
+7. Complétez le flux de connexion dans votre navigateur.
Une fois connecté et de retour dans VS Code, répétez les actions du point de contrôle précédent pour exécuter les outils du gestionnaire de tâches. Cette fois, vous pouvez utiliser ces outils avec votre identité utilisateur authentifiée. Le comportement des outils dépendra des rôles et permissions attribués à votre utilisateur :
-- Si vous êtes connecté en tant que **User** (avec uniquement la portée `create:todos`) :
+- Si vous êtes connecté en tant qu’**Utilisateur** (avec uniquement la portée `create:todos`) :
- Vous pouvez créer de nouvelles tâches avec l’outil `create-todo`
- Vous ne pouvez voir et supprimer que vos propres tâches
@@ -907,11 +895,11 @@ Une fois connecté et de retour dans VS Code, répétez les actions du point de
- Si vous êtes connecté en tant qu’**Admin** (avec toutes les portées : `create:todos`, `read:todos`, `delete:todos`) :
- Vous pouvez créer de nouvelles tâches
- Vous pouvez voir toutes les tâches du système avec l’outil `get-todos`
- - Vous pouvez supprimer n’importe quelle tâche avec l’outil `delete-todo`, quel que soit le créateur
+ - Vous pouvez supprimer n’importe quelle tâche avec l’outil `delete-todo`, quel que soit son créateur
Vous pouvez tester ces différents niveaux de permission en :
-1. Vous déconnectant du serveur MCP (supprimez la configuration du serveur dans VS Code)
+1. Déconnectant du serveur MCP (supprimez la configuration du serveur dans VS Code)
2. Vous connectant avec un autre compte utilisateur ayant des rôles / permissions différents
3. Essayant à nouveau les mêmes outils pour observer comment le comportement change selon les permissions de l’utilisateur
@@ -926,7 +914,7 @@ Consultez le [dépôt SDK MCP Auth Node.js](https://github.com/mcp-auth/js/blob/
Félicitations ! Vous avez terminé avec succès le tutoriel. Récapitulons ce que nous avons fait :
- Mise en place d’un serveur MCP de base avec des outils de gestion de tâches (`create-todo`, `get-todos`, `delete-todo`)
-- Implémentation du contrôle d’accès basé sur les rôles (RBAC) avec différents niveaux de permissions pour les utilisateurs et les admins
+- Implémentation du contrôle d’accès basé sur les rôles (RBAC) avec différents niveaux de permission pour les utilisateurs et les admins
- Intégration du serveur MCP avec un serveur d’autorisation via MCP Auth
- Configuration de VS Code pour authentifier les utilisateurs et utiliser des jetons d’accès avec des portées pour appeler les outils
diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx b/i18n/ja/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
index 97d84e0..7488a46 100644
--- a/i18n/ja/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
+++ b/i18n/ja/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
@@ -13,25 +13,25 @@ import Tabs from '@theme/Tabs';
MCP Auth は Python でも利用可能です!インストール方法や使い方は [Python SDK リポジトリ](https://github.com/mcp-auth/python) をご覧ください。
:::
-このチュートリアルでは、ユーザー認証 (Authentication) と認可 (Authorization) を備えた todo マネージャー MCP サーバーを構築します。最新の MCP 仕様に従い、MCP サーバーは OAuth 2.0 **リソースサーバー (Resource Server)** として動作し、アクセス トークンの検証とスコープベースの権限管理を行います。
+このチュートリアルでは、ユーザー認証 (Authentication) と認可 (Authorization) を備えた todo マネージャー MCP サーバーを構築します。最新の MCP 仕様に従い、MCP サーバーは OAuth 2.0 **リソースサーバー (Resource Server)** として動作し、アクセス トークンを検証し、スコープベースの権限を強制します。
このチュートリアルを完了すると、次のことができるようになります:
- ✅ MCP サーバーでロールベースのアクセス制御 (RBAC) を設定する基本的な理解
- ✅ 認可サーバーが発行したアクセス トークンを利用するリソースサーバーとしての MCP サーバー
-- ✅ Todo 操作に対するスコープベースの権限管理の実装
+- ✅ Todo 操作に対するスコープベースの権限強制の実装
## 概要 \{#overview}
このチュートリアルでは、以下のコンポーネントを扱います:
- **MCP クライアント (VS Code)**:MCP サポートを内蔵したコードエディタで、OAuth 2.0/OIDC クライアントとして動作します。認可サーバーと認可フローを開始し、MCP サーバーへのリクエスト認証のためにアクセス トークンを取得します。
-- **認可サーバー (Authorization Server)**:OAuth 2.1 または OpenID Connect プロバイダーで、ユーザーのアイデンティティ管理、認証 (Authentication)、および認可されたクライアントへの適切なスコープ付きアクセス トークンの発行を行います。
-- **MCP サーバー (リソースサーバー)**:最新の MCP 仕様に基づき、OAuth 2.0 フレームワークのリソースサーバー (Resource Server) として動作します。認可サーバーが発行したアクセス トークンの検証と、todo 操作に対するスコープベースの権限管理を行います。
+- **認可サーバー (Authorization Server)**:OAuth 2.1 または OpenID Connect プロバイダーで、ユーザーアイデンティティの管理、ユーザー認証 (Authentication)、および認可されたクライアントへの適切なスコープ付きアクセス トークンの発行を行います。
+- **MCP サーバー (リソースサーバー)**:最新の MCP 仕様に従い、MCP サーバーは OAuth 2.0 フレームワークのリソースサーバー (Resource Server) として動作します。認可サーバーが発行したアクセス トークンを検証し、todo 操作に対してスコープベースの権限を強制します。
-このアーキテクチャは標準的な OAuth 2.0 フローに従います:
+このアーキテクチャは、標準的な OAuth 2.0 フローに従います:
-- **VS Code** がユーザーに代わって保護されたリソースをリクエスト
+- **VS Code** がユーザーの代理で保護されたリソースをリクエスト
- **認可サーバー (Authorization Server)** がユーザーを認証 (Authentication) し、アクセス トークンを発行
- **MCP サーバー** がトークンを検証し、付与された権限に基づいて保護されたリソースを提供
@@ -52,12 +52,12 @@ sequenceDiagram
RS-->>Client: 保護リソースのメタデータ
(認可サーバー URL を含む)
Client->>AS: GET /.well-known/oauth-authorization-server
- AS-->>Client: 認可サーバーのメタデータ
+ AS-->>Client: 認可サーバーメタデータ
Client->>AS: OAuth 認可 (ログイン & 同意)
AS-->>Client: アクセス トークン
Client->>RS: MCP リクエスト (Authorization: Bearer )
- RS->>RS: アクセス トークンの有効性と認可を検証
+ RS->>RS: アクセス トークンの検証と認可
RS-->>Client: MCP レスポンス
```
@@ -65,23 +65,23 @@ sequenceDiagram
### スコープ付きアクセス トークン \{#access-tokens-with-scopes}
-MCP サーバーで [ロールベースのアクセス制御 (RBAC)](https://auth.wiki/rbac) を実装するには、認可サーバーがスコープ付きのアクセス トークンを発行できる必要があります。スコープはユーザーに付与された権限を表します。
+MCP サーバーで [ロールベースのアクセス制御 (RBAC)](https://auth.wiki/rbac) を実装するには、認可サーバーがスコープ付きアクセス トークンの発行をサポートしている必要があります。スコープは、ユーザーに付与された権限を表します。
[Logto](https://logto.io) は、API リソース([RFC 8707: OAuth 2.0 のリソースインジケーター](https://datatracker.ietf.org/doc/html/rfc8707) に準拠)とロール機能を通じて RBAC をサポートしています。設定方法は以下の通りです:
-1. [Logto コンソール](https://cloud.logto.io)(またはセルフホスト Logto コンソール)にサインイン
+1. [Logto Console](https://cloud.logto.io)(またはセルフホストの Logto Console)にサインイン
2. API リソースとスコープを作成:
- 「API リソース」へ移動
- - 「Todo Manager」という新しい API リソースを作成
- - 以下のスコープを追加
- - `create:todos`: 「新しい todo アイテムの作成」
- - `read:todos`: 「すべての todo アイテムの閲覧」
- - `delete:todos`: 「任意の todo アイテムの削除」
+ - 「Todo Manager」という名前の新しい API リソースを作成
+ - 以下のスコープを追加:
+ - `create:todos`: "新しい todo アイテムの作成"
+ - `read:todos`: "すべての todo アイテムの閲覧"
+ - `delete:todos`: "任意の todo アイテムの削除"
3. ロールを作成(管理を簡単にするため推奨):
@@ -104,7 +104,7 @@ OAuth 2.0 / OIDC プロバイダーは通常、スコープベースのアクセ
1. 認可サーバーで必要なスコープを定義
2. クライアントが認可フロー中にこれらのスコープをリクエストするよう設定
-3. 認可サーバーが付与したスコープをアクセス トークンに含めることを確認
+3. 認可サーバーが付与されたスコープをアクセス トークンに含めることを確認
4. スコープは通常、JWT アクセス トークンの `scope` クレームに含まれます
スコープの定義・管理方法や、アクセス トークンへのスコープの含め方、ロール管理などの追加 RBAC 機能については、プロバイダーのドキュメントを参照してください。
@@ -114,13 +114,13 @@ OAuth 2.0 / OIDC プロバイダーは通常、スコープベースのアクセ
### トークンの検証と権限チェック \{#validating-tokens-and-checking-permissions}
-最新の MCP 仕様によると、MCP サーバーは OAuth 2.0 フレームワークの **リソースサーバー (Resource Server)** として動作します。リソースサーバーとしての MCP サーバーの責務は以下の通りです:
+最新の MCP 仕様によると、MCP サーバーは OAuth 2.0 フレームワークの **リソースサーバー (Resource Server)** として動作します。リソースサーバーとして、MCP サーバーには以下の責任があります:
1. **トークン検証**:MCP クライアントから受け取ったアクセス トークンの真正性と完全性を検証
-2. **スコープの強制**:アクセス トークンからスコープを抽出し、クライアントが実行できる操作を判定
-3. **リソース保護**:有効なトークンと十分な権限がある場合のみ保護リソース(ツールの実行)を提供
+2. **スコープ強制**:アクセス トークンからスコープを抽出し、クライアントが実行を許可されている操作を判定
+3. **リソース保護**:クライアントが有効なトークンと十分な権限を持っている場合のみ保護リソース(ツールの実行)を提供
-MCP サーバーがリクエストを受け取った際の検証プロセスは次の通りです:
+MCP サーバーがリクエストを受け取った際の検証プロセスは以下の通りです:
1. `Authorization` ヘッダーからアクセス トークンを抽出(Bearer トークン形式)
2. アクセス トークンの署名と有効期限を検証
@@ -141,7 +141,7 @@ sequenceDiagram
Server->>Auth: JWKS を取得(キャッシュされていない場合)
Auth-->>Server: JWKS を返す
Server->>Server: JWT 署名とクレームをローカルで検証
- else トークンイントロスペクション(フォールバック)
+ else トークンインスペクション(フォールバック)
Server->>Auth: POST /introspect
(token=access_token)
Auth-->>Server: トークン情報を返す
(active, scope, user_id など)
end
@@ -162,7 +162,7 @@ sequenceDiagram
## Todo マネージャーにおける RBAC を理解する \{#understand-rbac-in-todo-manager}
-デモ目的として、todo マネージャー MCP サーバーにシンプルなロールベースのアクセス制御 (RBAC) システムを実装します。これにより、RBAC の基本原則をシンプルな実装で体験できます。
+デモ目的で、todo マネージャー MCP サーバーにシンプルなロールベースのアクセス制御 (RBAC) システムを実装します。これにより、RBAC の基本原則をシンプルな実装で学べます。
:::note
このチュートリアルでは RBAC ベースのスコープ管理を紹介していますが、すべての認証 (Authentication) プロバイダーがロールによるスコープ管理を実装しているわけではありません。プロバイダーによっては独自のアクセス制御や権限管理の仕組みを持つ場合があります。
@@ -174,7 +174,7 @@ Todo マネージャー MCP サーバーは、主に次の 3 つのツールを
- `create-todo`: 新しい todo アイテムの作成
- `get-todos`: すべての todo の一覧取得
-- `delete-todo`: ID 指定で todo を削除
+- `delete-todo`: ID で todo を削除
これらのツールへのアクセスを制御するため、以下のスコープを定義します:
@@ -201,14 +201,14 @@ Todo マネージャー MCP サーバーは、主に次の 3 つのツールを
- **User** は `read:todos` や `delete:todos` スコープを持っていませんが、次のことが可能です:
- 自分の todo アイテムの閲覧
- 自分の todo アイテムの削除
-- **Admin** は `read:todos` および `delete:todos` を持つため:
+- **Admin** は完全な権限(`read:todos` および `delete:todos`)を持ち、次のことが可能です:
- システム内のすべての todo アイテムの閲覧
- 所有者に関係なく任意の todo アイテムの削除
-これは、RBAC システムでよく見られるパターンで、リソース所有者には自分のリソースに対する暗黙的な権限が与えられ、管理者ロールにはすべてのリソースに対する明示的な権限が付与されることを示しています。
+これは、RBAC システムでよく見られるパターンで、リソース所有者には自分のリソースに対する暗黙的な権限が付与され、管理者ロールにはすべてのリソースに対する明示的な権限が付与されることを示しています。
:::tip 詳しく学ぶ
-RBAC の概念やベストプラクティスをさらに深く学びたい場合は、[Mastering RBAC: A Comprehensive Real-World Example](https://blog.logto.io/mastering-rbac) をご覧ください。
+RBAC の概念やベストプラクティスについてさらに深く知りたい場合は、[Mastering RBAC: A Comprehensive Real-World Example](https://blog.logto.io/mastering-rbac) をご覧ください。
:::
## プロバイダーで認可を設定する \{#configure-authorization-in-your-provider}
@@ -218,40 +218,40 @@ RBAC の概念やベストプラクティスをさらに深く学びたい場合
-[Logto](https://logto.io) は API リソースとロール機能を通じて RBAC をサポートしています。設定方法は以下の通りです:
+[Logto](https://logto.io) は、API リソースとロール機能を通じて RBAC をサポートしています。設定方法は以下の通りです:
-1. [Logto コンソール](https://cloud.logto.io)(またはセルフホスト Logto コンソール)にサインイン
+1. [Logto Console](https://cloud.logto.io)(またはセルフホストの Logto Console)にサインイン
2. API リソースとスコープを作成:
- 「API リソース」へ移動
- - 「Todo Manager」という新しい API リソースを作成し、リソースインジケーターに `http://localhost:3001/` を使用
+ - 「Todo Manager」という名前の新しい API リソースを作成し、リソースインジケーターに `http://localhost:3001/` を使用
- **重要**:リソースインジケーターは MCP サーバーの URL と一致する必要があります。このチュートリアルでは MCP サーバーがポート 3001 で動作するため `http://localhost:3001/` を使用します。本番環境では実際の MCP サーバー URL(例:`https://your-mcp-server.example.com/`)を使用してください。
- - 以下のスコープを作成
- - `create:todos`: 「新しい todo アイテムの作成」
- - `read:todos`: 「すべての todo アイテムの閲覧」
- - `delete:todos`: 「任意の todo アイテムの削除」
+ - 以下のスコープを作成:
+ - `create:todos`: "新しい todo アイテムの作成"
+ - `read:todos`: "すべての todo アイテムの閲覧"
+ - `delete:todos`: "任意の todo アイテムの削除"
3. ロールを作成(管理を簡単にするため推奨):
- 「ロール」へ移動
- 「Admin」ロールを作成し、すべてのスコープ(`create:todos`, `read:todos`, `delete:todos`)を割り当て
- 「User」ロールを作成し、`create:todos` スコープのみ割り当て
- - 「User」ロールの詳細ページで「一般」タブに切り替え、「User」ロールを「デフォルトロール」に設定
+ - 「User」ロールの詳細ページで「一般」タブに切り替え、「User」ロールを「デフォルトロール」として設定
4. ユーザーのロールと権限を管理:
- 新規ユーザーの場合:
- - デフォルトロールを設定したため自動的に「User」ロールが付与されます
+ - デフォルトロールとして「User」ロールが自動的に割り当てられます
- 既存ユーザーの場合:
- 「ユーザー管理」へ移動
- ユーザーを選択
- - 「ロール」タブでロールを割り当て
+ - 「ロール」タブでユーザーにロールを割り当て
:::tip プログラムによるロール管理
-Logto の [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api) を利用して、ユーザーロールをプログラムで管理することも可能です。自動化や管理画面構築時に便利です。
+Logto の [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api) を使ってユーザーロールをプログラムで管理することも可能です。自動化や管理画面構築時に便利です。
:::
-アクセス トークンをリクエストすると、Logto はユーザーのロール権限に基づきスコープをトークンの `scope` クレームに含めます。
+アクセス トークンをリクエストする際、Logto はユーザーのロール権限に基づいてスコープをトークンの `scope` クレームに含めます。
@@ -260,7 +260,7 @@ OAuth 2.0 または OpenID Connect プロバイダーの場合、異なる権限
1. スコープの定義:
- - 認可サーバーで以下をサポートするよう設定
+ - 認可サーバーで以下をサポートするよう設定:
- `create:todos`
- `read:todos`
- `delete:todos`
@@ -272,29 +272,29 @@ OAuth 2.0 または OpenID Connect プロバイダーの場合、異なる権限
3. 権限の割り当て:
- プロバイダーの管理画面でユーザーに適切なスコープを付与
- - 一部プロバイダーはロールベース管理をサポートし、他は直接スコープ割り当てを採用
- - 推奨方法はプロバイダーのドキュメントを参照
+ - 一部のプロバイダーはロールベース管理をサポートし、他は直接スコープ割り当てを使用
+ - 推奨される方法はプロバイダーのドキュメントを参照
:::tip
-ほとんどのプロバイダーは付与したスコープをアクセス トークンの `scope` クレームに含めます。形式は通常スペース区切りのスコープ値です。
+ほとんどのプロバイダーは、付与されたスコープをアクセス トークンの `scope` クレームに含めます。形式は通常スペース区切りのスコープ値です。
:::
:::note[リソースインジケーターの末尾スラッシュ]
-リソースインジケーターには必ず末尾スラッシュ(`/`)を含めてください。現在の MCP 公式 SDK のバグにより、SDK を利用するクライアントは認証リクエスト時にリソース識別子へ自動的にスラッシュを付加します。リソースインジケーターにスラッシュが含まれていない場合、これらのクライアントでリソース検証が失敗します(VS Code はこのバグの影響を受けません)。
+リソースインジケーターには必ず末尾スラッシュ(`/`)を含めてください。現在の MCP 公式 SDK のバグにより、SDK を利用するクライアントは認証リクエスト時にリソース識別子へ自動的に末尾スラッシュを付加します。リソースインジケーターに末尾スラッシュがない場合、これらのクライアントでリソース検証が失敗します(VS Code にはこのバグの影響はありません)。
:::
-認可サーバーの設定後、ユーザーは付与されたスコープを含むアクセス トークンを受け取ります。MCP サーバーはこれらのスコープを利用して次の判定を行います:
+認可サーバーの設定後、ユーザーは付与されたスコープを含むアクセス トークンを受け取ります。MCP サーバーはこれらのスコープを使って次のことを判定します:
- 新しい todo の作成が可能か(`create:todos`)
- すべての todo の閲覧(`read:todos`)または自分の todo のみ閲覧可能か
- 任意の todo の削除(`delete:todos`)または自分の todo のみ削除可能か
-## MCP サーバーをセットアップする \{#set-up-the-mcp-server}
+## MCP サーバーのセットアップ \{#set-up-the-mcp-server}
-[公式 MCP SDK](https://github.com/modelcontextprotocol) を利用して todo マネージャー MCP サーバーを作成します。
+[公式 MCP SDK](https://github.com/modelcontextprotocol) を使って todo マネージャー MCP サーバーを作成します。
### 新しいプロジェクトを作成 \{#create-a-new-project}
@@ -303,49 +303,49 @@ OAuth 2.0 または OpenID Connect プロバイダーの場合、異なる権限
```bash
mkdir mcp-server
cd mcp-server
-npm init -y # または `pnpm init` を使用
+npm init -y # または `pnpm init`
npm pkg set type="module"
npm pkg set main="todo-manager.ts"
npm pkg set scripts.start="node --experimental-strip-types todo-manager.ts"
```
:::note
-サンプルでは TypeScript を使用しています。Node.js v22.6.0 以降では `--experimental-strip-types` フラグで TypeScript をネイティブ実行できます。JavaScript を使う場合もほぼ同様ですが、Node.js v22.6.0 以降を利用してください。詳細は Node.js ドキュメントを参照してください。
+サンプルでは TypeScript を使用しています。Node.js v22.6.0 以降では `--experimental-strip-types` フラグで TypeScript をネイティブ実行できます。JavaScript を使う場合もコードはほぼ同じです。詳細は Node.js ドキュメントを参照してください。
:::
-### MCP SDK と依存パッケージをインストール \{#install-the-mcp-sdk-and-dependencies}
+### MCP SDK と依存パッケージのインストール \{#install-the-mcp-sdk-and-dependencies}
```bash
npm install @modelcontextprotocol/sdk express zod
```
-または `pnpm` や `yarn` などお好みのパッケージマネージャーを利用できます。
+または `pnpm` や `yarn` などお好みのパッケージマネージャーを利用してください。
-### MCP サーバーを作成 \{#create-the-mcp-server}
+### MCP サーバーの作成 \{#create-the-mcp-server}
-`todo-manager.ts` というファイルを作成し、以下のコードを追加します:
+`todo-manager.ts` というファイルを作成し、次のコードを追加します:
-(※ ここはコードなので翻訳不要、省略)
+(※コード部分は翻訳不要のため省略)
-サーバーを起動するには:
+サーバーの起動:
```bash
npm start
```
-## 認可サーバーと連携する \{#integrate-with-your-authorization-server}
+## 認可サーバーとの連携 \{#integrate-with-your-authorization-server}
-このセクションを完了するには、いくつかのポイントを考慮する必要があります:
+このセクションを完了するには、いくつかの考慮事項があります:
**認可サーバーの発行者 (Issuer) URL**
-通常は `https://auth.example.com` のような認可サーバーのベース URL です。プロバイダーによっては `https://example.logto.app/oidc` のようなパスが付く場合もあるので、ドキュメントを確認してください。
+通常は認可サーバーのベース URL です(例:`https://auth.example.com`)。プロバイダーによっては `https://example.logto.app/oidc` のようなパスが付く場合もあるので、ドキュメントを確認してください。
-**認可サーバーのメタデータ取得方法**
+**認可サーバーメタデータの取得方法**
- 認可サーバーが [OAuth 2.0 Authorization Server Metadata](https://datatracker.ietf.org/doc/html/rfc8414) または [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) に準拠していれば、MCP Auth の組み込みユーティリティで自動取得できます。
- 準拠していない場合は、MCP サーバー設定でメタデータ URL やエンドポイントを手動指定する必要があります。詳細はプロバイダーのドキュメントを参照してください。
@@ -353,21 +353,21 @@ npm start
-**MCP クライアントの認可サーバーへの登録方法**
+**認可サーバーで MCP クライアントを登録する方法**
- 認可サーバーが [Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591) をサポートしていれば、この手順は不要です。MCP クライアントが自動登録されます。
-- サポートしていない場合は、MCP クライアントを手動で認可サーバーに登録する必要があります。
+- サポートしていない場合は、MCP クライアントを手動で登録する必要があります。
-**トークンリクエストパラメータの理解**
+**トークンリクエストパラメーターの理解**
-認可サーバーごとに、ターゲットリソースや権限指定の方法が異なります。主なパターンは次の通りです:
+認可サーバーごとに、ターゲットリソースや権限指定の方法が異なります。主なパターンは以下の通りです:
- **リソースインジケーター方式**:
- - `resource` パラメータでターゲット API を指定([RFC 8707: OAuth 2.0 のリソースインジケーター](https://datatracker.ietf.org/doc/html/rfc8707) 参照)
+ - `resource` パラメーターでターゲット API を指定([RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) 参照)
- モダンな OAuth 2.0 実装で一般的
- 例:
```json
@@ -376,11 +376,11 @@ npm start
"scope": "create:todos read:todos"
}
```
- - サーバーはリソースごとにバインドされたトークンを発行
+ - サーバーはリクエストされたリソース専用のトークンを発行
- **オーディエンス方式**:
- - `audience` パラメータでトークンの宛先を指定
+ - `audience` パラメーターでトークンの受信者を指定
- リソースインジケーターと似ているが意味が異なる
- 例:
```json
@@ -391,7 +391,7 @@ npm start
```
- **純粋なスコープ方式**:
- - resource/audience パラメータなしでスコープのみ利用
+ - resource/audience パラメーターなしでスコープのみを利用
- 従来の OAuth 2.0 アプローチ
- 例:
```json
@@ -404,29 +404,29 @@ npm start
:::tip ベストプラクティス
-- プロバイダーのドキュメントでサポートされているパラメータを確認
-- 複数方式を同時サポートするプロバイダーも存在
+- プロバイダーのドキュメントでサポートされているパラメーターを確認
+- 複数の方式を同時にサポートするプロバイダーも存在
- リソースインジケーターはオーディエンス制限によるセキュリティ向上に有効
- 利用可能な場合はリソースインジケーター方式を推奨
:::
-プロバイダーごとに細かな要件は異なりますが、以下の手順で VS Code と MCP サーバーをプロバイダー固有の設定で連携できます。
+プロバイダーごとに要件は異なりますが、以下の手順で VS Code と MCP サーバーをプロバイダー固有の設定で連携できます。
### MCP クライアントをサードパーティアプリとして登録 \{#register-mcp-client-as-a-third-party-app}
-[Logto](https://logto.io) との連携は簡単です。OpenID Connect プロバイダーであり、リソースインジケーターとスコープをサポートしているため、`http://localhost:3001/` をリソースインジケーターとして todo API を保護できます。
+[Logto](https://logto.io) との連携は簡単です。OpenID Connect プロバイダーであり、リソースインジケーターとスコープをサポートしているため、`http://localhost:3001/` をリソースインジケーターとして todo API を安全に保護できます。
-Logto は現時点で Dynamic Client Registration をサポートしていないため、MCP クライアント(VS Code)を Logto テナントのサードパーティアプリとして手動登録する必要があります:
+Logto は Dynamic Client Registration をまだサポートしていないため、MCP クライアント(VS Code)を Logto テナントのサードパーティアプリとして手動登録する必要があります:
-1. [Logto コンソール](https://cloud.logto.io)(またはセルフホスト Logto コンソール)にサインイン
+1. [Logto Console](https://cloud.logto.io)(またはセルフホストの Logto Console)にサインイン
2. **アプリケーション > サードパーティアプリ** へ移動し、「アプリケーションを作成」をクリック
-3. **ネイティブアプリ** をアプリケーションタイプとして選択
-4. アプリケーション情報を入力:
+3. アプリケーションタイプとして **ネイティブアプリ** を選択
+4. アプリケーション詳細を入力:
- **アプリケーション名**:例「MCP Client」
- **説明**:例「VS Code 用 MCP クライアント」
5. VS Code 用の **リダイレクト URI** を設定:
@@ -434,22 +434,22 @@ Logto は現時点で Dynamic Client Registration をサポートしていない
http://127.0.0.1
https://vscode.dev/redirect
```
-6. 「変更を保存」をクリック
-7. アプリの **権限** タブで、**User** セクションにて、先ほど作成した **Todo Manager** API リソースから `create:todos`, `read:todos`, `delete:todos` 権限を追加
-8. 上部カードに「App ID」が表示されるので、後で使用するためコピー
+6. 「変更を保存」
+7. アプリの **権限** タブで、**ユーザー** セクションにて、先ほど作成した **Todo Manager** API リソースから `create:todos`, `read:todos`, `delete:todos` 権限を追加
+8. 上部カードに「App ID」が表示されるので、後で使うためコピー
:::note
-これは一般的な OAuth 2.0 / OpenID Connect プロバイダー連携ガイドです。OIDC は OAuth 2.0 上に構築されているため、手順はほぼ同じです。詳細はプロバイダーのドキュメントを参照してください。
+これは汎用的な OAuth 2.0 / OpenID Connect プロバイダー連携ガイドです。OIDC は OAuth 2.0 上に構築されているため、手順はほぼ同じです。詳細はプロバイダーのドキュメントを参照してください。
:::
-Dynamic Client Registration をサポートしていれば手動登録は不要ですが、サポートしていない場合は MCP クライアントを手動登録してください:
+Dynamic Client Registration をサポートしていれば手動登録は不要ですが、そうでない場合は MCP クライアントを手動登録します:
1. プロバイダーのコンソールにサインイン
-2. 「アプリケーション」または「クライアント」セクションで新規アプリケーションまたはクライアントを作成
+2. 「アプリケーション」または「クライアント」セクションで新しいアプリまたはクライアントを作成
3. クライアントタイプが必要な場合は「ネイティブアプリ」または「パブリッククライアント」を選択
@@ -460,18 +460,18 @@ Dynamic Client Registration をサポートしていれば手動登録は不要
https://vscode.dev/redirect
```
-5. 必要なスコープ/権限をアプリケーションに設定:
+5. 必要なスコープ/権限を設定:
```text
create:todos read:todos delete:todos
```
-6. 新規アプリケーションの「Client ID」または「Application ID」を控えておく
+6. 新規作成したアプリの「Client ID」または「Application ID」を控えておく
-### MCP Auth をセットアップ \{#set-up-mcp-auth}
+### MCP Auth のセットアップ \{#set-up-mcp-auth}
まず、MCP サーバープロジェクトに MCP Auth SDK をインストールします。
@@ -481,18 +481,18 @@ Dynamic Client Registration をサポートしていれば手動登録は不要
認可サーバーの設定方法は 2 通りあります:
-- **事前取得(推奨)**:`fetchServerConfig()` でメタデータを事前取得し、MCPAuth 初期化時に設定。起動時に設定が検証されます。
+- **事前取得(推奨)**:`fetchServerConfig()` でメタデータを取得してから MCPAuth を初期化。起動時に設定が検証されます。
- **オンデマンドディスカバリー**:`issuer` と `type` のみ指定し、初回利用時にメタデータを取得。Cloudflare Workers などトップレベル async fetch が許可されない環境で便利です。
#### 保護リソースメタデータの設定 \{#configure-protected-resource-metadata}
-まず、認可サーバーの発行者 (issuer) URL を取得します:
+まず、認可サーバーの issuer URL を取得します:
-Logto では、Logto コンソールのアプリケーション詳細ページ「エンドポイント & 資格情報 / Issuer endpoint」セクションで issuer URL を確認できます。例:`https://my-project.logto.app/oidc`
+Logto では、Logto Console のアプリ詳細ページ「エンドポイント & 資格情報 / Issuer endpoint」セクションで issuer URL を確認できます。例:`https://my-project.logto.app/oidc`
@@ -502,55 +502,59 @@ OAuth 2.0 プロバイダーの場合:
1. 認可サーバー URL(issuer URL または base URL と呼ばれる)をドキュメントで確認
2. 多くの場合 `https://{your-domain}/.well-known/oauth-authorization-server` で公開
-3. 管理コンソールの OAuth/API 設定を確認
+3. 管理画面の OAuth/API 設定を確認
-次に、MCP Auth インスタンス構築時に Protected Resource Metadata を設定します:
+次に、MCP Auth インスタンス作成時に Protected Resource Metadata を設定します:
-(※ ここはコードなので翻訳不要、省略)
+(※コード部分は翻訳不要のため省略)
-### MCP サーバーを更新 \{#update-mcp-server}
+### MCP サーバーの更新 \{#update-mcp-server}
-あと少しです!MCP Auth ルートとミドルウェア関数を適用し、ユーザーのスコープに基づく権限管理を実装します。
+いよいよ MCP サーバーに MCP Auth ルートとミドルウェア関数を適用し、ユーザーのスコープに基づく権限制御を実装します。
まず、MCP クライアントが MCP サーバーからリソースメタデータを取得できるよう、保護リソースメタデータルートを適用します。
-(※ ここはコードなので翻訳不要、省略)
+(※コード部分は翻訳不要のため省略)
-次に、MCP サーバーに MCP Auth ミドルウェアを適用します。このミドルウェアはリクエストの認証 (Authentication) と認可 (Authorization) を処理し、認可されたユーザーのみが todo マネージャーツールにアクセスできるようにします。
+次に、MCP Auth ミドルウェアを MCP サーバーに適用します。このミドルウェアはリクエストの認証 (Authentication) と認可 (Authorization) を処理し、認可されたユーザーのみが todo マネージャーツールにアクセスできるようにします。
-(※ ここはコードなので翻訳不要、省略)
+(※コード部分は翻訳不要のため省略)
-ここまでで、todo マネージャーツールの実装を MCP Auth ミドルウェアを利用した認証 (Authentication)・認可 (Authorization) 対応に更新できます。
+ここまでで、MCP Auth ミドルウェアを利用した認証 (Authentication)・認可 (Authorization) の仕組みをツール実装に反映できます。
-(※ ここはコードなので翻訳不要、省略)
+ツールの実装を更新しましょう。
+
+(※コード部分は翻訳不要のため省略)
次に、上記コードで利用している「Todo サービス」を作成します:
-(※ ここはコードなので翻訳不要、省略)
+`todo-service.ts` ファイルを作成し、Todo サービスの機能を実装します:
+
+(※コード部分は翻訳不要のため省略)
-おめでとうございます!これで認証 (Authentication) と認可 (Authorization) を備えた MCP サーバーが完成しました。
+おめでとうございます!これで認証 (Authentication) と認可 (Authorization) を備えた MCP サーバーが完成しました!
:::info
-[MCP Auth Node.js SDK リポジトリ](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src) で MCP サーバー(OIDC 版)の完全なコードを確認できます。
+MCP サーバー(OIDC バージョン)の完全なコードは [MCP Auth Node.js SDK リポジトリ](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src) をご覧ください。
:::
-## チェックポイント: `todo-manager` ツールを実行する \{#checkpoint-run-the-todo-manager-tools}
+## チェックポイント: `todo-manager` ツールを実行 \{#checkpoint-run-the-todo-manager-tools}
MCP サーバーを再起動し、VS Code から接続します。認証付きで接続する手順は以下の通りです:
1. VS Code で `Command + Shift + P`(macOS)または `Ctrl + Shift + P`(Windows/Linux)を押してコマンドパレットを開く
-2. `MCP: Add Server...` と入力し選択
+2. `MCP: Add Server...` と入力して選択
3. サーバータイプに `HTTP` を選択
4. MCP サーバーの URL を入力:`http://localhost:3001`
-5. OAuth リクエストが開始されると、VS Code から **App ID** の入力を求められます。認可サーバーからコピーした App ID を入力
+5. OAuth リクエストが開始されると、VS Code から **App ID** の入力を求められます。認可サーバーで控えた App ID を入力
6. **App Secret** は不要(パブリッククライアントのため)なので Enter でスキップ
7. ブラウザでサインインフローを完了
-サインイン後 VS Code に戻り、前回のチェックポイントと同様に todo マネージャーツールを実行できます。今回は認証済みユーザーとしてツールを利用でき、ユーザーに割り当てられたロールと権限によって動作が変わります:
+サインイン後 VS Code に戻り、前回のチェックポイントと同じ操作で todo マネージャーツールを実行します。今回は認証済みユーザーとしてツールを利用できます。ツールの挙動はユーザーに割り当てられたロールと権限によって異なります:
- **User**(`create:todos` スコープのみ)の場合:
@@ -561,27 +565,27 @@ MCP サーバーを再起動し、VS Code から接続します。認証付き
- **Admin**(すべてのスコープ:`create:todos`, `read:todos`, `delete:todos`)の場合:
- 新しい todo の作成が可能
- `get-todos` ツールでシステム内のすべての todo を閲覧可能
- - `delete-todo` ツールで所有者に関係なく任意の todo を削除可能
+ - `delete-todo` ツールで誰が作成したかに関係なく任意の todo を削除可能
異なる権限レベルをテストするには:
1. MCP サーバーから切断(VS Code のサーバー設定を削除)
2. 別のロール/権限を持つユーザーアカウントでサインイン
-3. 同じツールを再度試し、ユーザーの権限による動作の違いを確認
+3. 同じツールを再度試して、ユーザーの権限による挙動の違いを確認
-これにより、ロールベースのアクセス制御 (RBAC) が実際にどのように機能するかを体験できます。
+これにより、ロールベースのアクセス制御 (RBAC) が実際にどのように機能するかを体験できます。異なるユーザーがシステムの機能に対して異なるアクセスレベルを持つことが分かります。
:::info
-[MCP Auth Node.js SDK リポジトリ](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src) で MCP サーバー(OIDC 版)の完全なコードを確認できます。
+MCP サーバー(OIDC バージョン)の完全なコードは [MCP Auth Node.js SDK リポジトリ](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src) をご覧ください。
:::
## 締めくくり \{#closing-notes}
-おめでとうございます!チュートリアルを無事完了しました。ここまでで実施した内容を振り返ります:
+おめでとうございます!チュートリアルを無事完了しました。ここまでの内容を振り返りましょう:
-- Todo 管理ツール(`create-todo`, `get-todos`, `delete-todo`)付きの基本的な MCP サーバーのセットアップ
+- Todo 管理ツール(`create-todo`, `get-todos`, `delete-todo`)を備えた基本的な MCP サーバーのセットアップ
- ユーザーと管理者向けに異なる権限レベルを持つロールベースのアクセス制御 (RBAC) の実装
-- MCP サーバーと認可サーバーの連携(MCP Auth 利用)
-- VS Code でユーザー認証 (Authentication)・スコープ付きアクセス トークンによるツール利用の設定
+- MCP Auth を使った MCP サーバーと認可サーバーの連携
+- VS Code でユーザー認証 (Authentication)・スコープ付きアクセス トークンを利用したツール呼び出しの設定
-他のチュートリアルやドキュメントもぜひご覧いただき、MCP Auth を最大限活用してください。
\ No newline at end of file
+他のチュートリアルやドキュメントもぜひご覧いただき、MCP Auth を最大限に活用してください。
\ No newline at end of file
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/references/js/type-aliases/AuthServerConfigError.md b/i18n/ko/docusaurus-plugin-content-docs/current/references/js/type-aliases/AuthServerConfigError.md
index 86e0955..a281c35 100644
--- a/i18n/ko/docusaurus-plugin-content-docs/current/references/js/type-aliases/AuthServerConfigError.md
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/references/js/type-aliases/AuthServerConfigError.md
@@ -22,7 +22,7 @@ type AuthServerConfigError = {
optional cause: Error;
```
-오류의 선택적 원인으로, 일반적으로 더 많은 맥락을 제공하는 `Error` 인스턴스입니다.
+오류의 선택적 원인입니다. 일반적으로 더 많은 맥락을 제공하는 `Error` 인스턴스입니다.
***
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx b/i18n/ko/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
index ea28a14..997468c 100644
--- a/i18n/ko/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
@@ -1,39 +1,39 @@
---
sidebar_position: 2
-sidebar_label: '튜토리얼: Todo 매니저 만들기'
+sidebar_label: '튜토리얼: 할 일 관리 앱 만들기'
---
import { NpmLikeInstallation } from '@site/src/components/NpmLikeInstallation';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
-# 튜토리얼: Todo 매니저 만들기 (Tutorial: Build a todo manager)
+# 튜토리얼: 할 일 관리 앱 만들기 (Tutorial: Build a todo manager)
:::tip Python SDK 사용 가능
MCP Auth는 Python에서도 사용할 수 있습니다! 설치 및 사용법은 [Python SDK 저장소](https://github.com/mcp-auth/python)를 확인하세요.
:::
-이 튜토리얼에서는 사용자 인증 (Authentication) 및 인가 (Authorization)가 적용된 todo 매니저 MCP 서버를 구축합니다. 최신 MCP 명세를 따라, 우리의 MCP 서버는 액세스 토큰 (Access token)을 검증하고 스코프 (Scope) 기반 권한을 적용하는 OAuth 2.0 **리소스 서버 (Resource Server)** 역할을 하게 됩니다.
+이 튜토리얼에서는 사용자 인증 (Authentication)과 인가 (Authorization)가 적용된 할 일 관리 MCP 서버를 만들어봅니다. 최신 MCP 명세를 따라, 우리의 MCP 서버는 액세스 토큰 (Access token)을 검증하고 스코프 기반 권한 (Permission)을 적용하는 OAuth 2.0 **리소스 서버 (Resource Server)** 역할을 하게 됩니다.
이 튜토리얼을 완료하면 다음을 얻게 됩니다:
-- ✅ MCP 서버에서 역할 기반 접근 제어 (RBAC)를 설정하는 방법에 대한 기본 이해
-- ✅ 인가 서버 (Authorization Server)가 발급한 액세스 토큰을 사용하는 리소스 서버 역할의 MCP 서버
-- ✅ todo 작업에 대한 스코프 (Scope) 기반 권한 적용의 실제 구현
+- ✅ MCP 서버에서 역할 기반 접근 제어 (RBAC)에 대한 기본 이해
+- ✅ 인가 서버가 발급한 액세스 토큰을 사용하는 리소스 서버 역할의 MCP 서버
+- ✅ 할 일 작업에 대한 스코프 기반 권한 적용의 실제 구현
## 개요 (Overview) \{#overview}
이 튜토리얼에는 다음과 같은 구성 요소가 포함됩니다:
-- **MCP 클라이언트 (VS Code)**: 내장 MCP 지원이 있는 코드 에디터로, OAuth 2.0/OIDC 클라이언트 역할을 합니다. 인가 서버와 인가 플로우를 시작하고, MCP 서버에 인증된 요청을 보내기 위해 액세스 토큰을 획득합니다.
-- **인가 서버 (Authorization Server)**: 사용자 아이덴티티를 관리하고, 사용자를 인증 (Authentication)하며, 인가된 클라이언트에 적절한 스코프 (Scope)가 포함된 액세스 토큰을 발급하는 OAuth 2.1 또는 OpenID Connect 제공자입니다.
-- **MCP 서버 (Resource Server)**: 최신 MCP 명세에 따라, MCP 서버는 OAuth 2.0 프레임워크에서 리소스 서버 역할을 합니다. 인가 서버가 발급한 액세스 토큰을 검증하고, todo 작업에 대해 스코프 (Scope) 기반 권한을 적용합니다.
+- **MCP 클라이언트 (VS Code)**: MCP 지원이 내장된 코드 에디터로, OAuth 2.0/OIDC 클라이언트 역할을 합니다. 인가 서버와 인가 플로우를 시작하고, MCP 서버에 인증된 요청을 보내기 위해 액세스 토큰을 획득합니다.
+- **인가 서버 (Authorization Server)**: 사용자 아이덴티티를 관리하고, 사용자를 인증 (Authentication)하며, 인가된 클라이언트에 적절한 스코프가 포함된 액세스 토큰을 발급하는 OAuth 2.1 또는 OpenID Connect 제공자입니다.
+- **MCP 서버 (리소스 서버)**: 최신 MCP 명세에 따라, MCP 서버는 OAuth 2.0 프레임워크에서 리소스 서버 역할을 합니다. 인가 서버가 발급한 액세스 토큰을 검증하고, 할 일 작업에 대해 스코프 기반 권한을 적용합니다.
이 아키텍처는 표준 OAuth 2.0 플로우를 따릅니다:
-- **VS Code**가 사용자를 대신하여 보호된 리소스를 요청합니다
-- **인가 서버 (Authorization Server)**가 사용자를 인증하고 액세스 토큰을 발급합니다
-- **MCP 서버**가 토큰을 검증하고, 부여된 권한에 따라 보호된 리소스를 제공합니다
+- **VS Code**가 사용자를 대신해 보호된 리소스에 요청
+- **인가 서버**가 사용자를 인증하고 액세스 토큰 발급
+- **MCP 서버**가 토큰을 검증하고, 부여된 권한에 따라 보호된 리소스 제공
아래는 이 구성 요소들 간의 상호작용을 나타낸 고수준 다이어그램입니다:
@@ -65,12 +65,12 @@ sequenceDiagram
### 스코프가 포함된 액세스 토큰 (Access tokens with scopes) \{#access-tokens-with-scopes}
-[MCP 서버에서 역할 기반 접근 제어 (RBAC)](https://auth.wiki/rbac)를 구현하려면, 인가 서버가 스코프 (Scope)가 포함된 액세스 토큰을 발급할 수 있어야 합니다. 스코프는 사용자가 부여받은 권한 (Permission)을 나타냅니다.
+[MCP 서버에서 역할 기반 접근 제어 (RBAC)](https://auth.wiki/rbac)를 구현하려면, 인가 서버가 스코프가 포함된 액세스 토큰을 발급할 수 있어야 합니다. 스코프는 사용자가 부여받은 권한 (Permission)을 나타냅니다.
-[Logto](https://logto.io)는 API 리소스 (API resource) ([RFC 8707: OAuth 2.0을 위한 리소스 지표](https://datatracker.ietf.org/doc/html/rfc8707)) 및 역할 (Role) 기능을 통해 RBAC를 지원합니다. 설정 방법은 다음과 같습니다:
+[Logto](https://logto.io)는 API 리소스 ([RFC 8707: OAuth 2.0을 위한 리소스 지표](https://datatracker.ietf.org/doc/html/rfc8707)) 및 역할 (Role) 기능을 통해 RBAC를 지원합니다. 설정 방법은 다음과 같습니다:
1. [Logto Console](https://cloud.logto.io) (또는 자체 호스팅 Logto Console)에 로그인하세요.
@@ -79,21 +79,21 @@ sequenceDiagram
- "API 리소스"로 이동
- "Todo Manager"라는 새 API 리소스 생성
- 다음 스코프 추가:
- - `create:todos`: "새 todo 항목 생성"
- - `read:todos`: "모든 todo 항목 읽기"
- - `delete:todos`: "모든 todo 항목 삭제"
+ - `create:todos`: "새 할 일 항목 생성"
+ - `read:todos`: "모든 할 일 항목 읽기"
+ - `delete:todos`: "모든 할 일 항목 삭제"
-3. 역할 생성 (관리가 쉬우므로 권장):
+3. 역할 생성 (관리를 쉽게 하기 위해 권장):
- "역할"로 이동
- - "Admin" 역할을 생성하고 모든 스코프 (`create:todos`, `read:todos`, `delete:todos`) 할당
+ - "Admin" 역할을 생성하고 모든 스코프(`create:todos`, `read:todos`, `delete:todos`) 할당
- "User" 역할을 생성하고 `create:todos` 스코프만 할당
4. 권한 할당:
- "사용자"로 이동
- 사용자를 선택
- - "Roles" 탭에서 역할을 할당하거나 (권장)
- - 또는 "Permissions" 탭에서 직접 스코프를 할당할 수 있습니다
+ - "Roles" 탭에서 역할 할당(권장)
+ - 또는 "Permissions" 탭에서 직접 스코프 할당
스코프는 JWT 액세스 토큰의 `scope` 클레임에 공백으로 구분된 문자열로 포함됩니다.
@@ -102,10 +102,10 @@ sequenceDiagram
OAuth 2.0 / OIDC 제공자는 일반적으로 스코프 기반 접근 제어를 지원합니다. RBAC을 구현할 때:
-1. 인가 서버에서 필요한 스코프를 정의하세요
-2. 클라이언트가 인가 플로우 중에 이 스코프를 요청하도록 구성하세요
-3. 인가 서버가 부여된 스코프를 액세스 토큰에 포함하는지 확인하세요
-4. 스코프는 보통 JWT 액세스 토큰의 `scope` 클레임에 포함됩니다
+1. 인가 서버에서 필요한 스코프 정의
+2. 클라이언트가 인가 플로우 중에 이 스코프를 요청하도록 구성
+3. 인가 서버가 부여된 스코프를 액세스 토큰에 포함하는지 확인
+4. 스코프는 보통 JWT 액세스 토큰의 `scope` 클레임에 포함됨
스코프 정의 및 관리 방법, 액세스 토큰에 스코프가 포함되는 방식, 역할 관리 등 추가 RBAC 기능은 제공자 문서를 참고하세요.
@@ -114,11 +114,11 @@ OAuth 2.0 / OIDC 제공자는 일반적으로 스코프 기반 접근 제어를
### 토큰 검증 및 권한 확인 (Validating tokens and checking permissions) \{#validating-tokens-and-checking-permissions}
-최신 MCP 명세에 따르면, MCP 서버는 OAuth 2.0 프레임워크에서 **리소스 서버 (Resource Server)** 역할을 합니다. 리소스 서버로서 MCP 서버의 책임은 다음과 같습니다:
+최신 MCP 명세에 따르면, MCP 서버는 OAuth 2.0 프레임워크에서 **리소스 서버 (Resource Server)** 역할을 합니다. 리소스 서버로서 MCP 서버의 주요 책임은 다음과 같습니다:
1. **토큰 검증**: MCP 클라이언트로부터 받은 액세스 토큰의 진위 및 무결성 확인
2. **스코프 적용**: 액세스 토큰에서 스코프를 추출 및 검증하여 클라이언트가 수행할 수 있는 작업 결정
-3. **리소스 보호**: 클라이언트가 유효한 토큰과 충분한 권한을 제시할 때만 보호된 리소스(도구 실행) 제공
+3. **리소스 보호**: 유효한 토큰과 충분한 권한이 있는 경우에만 보호된 리소스(도구 실행) 제공
MCP 서버가 요청을 받으면 다음과 같은 검증 과정을 거칩니다:
@@ -127,7 +127,7 @@ MCP 서버가 요청을 받으면 다음과 같은 검증 과정을 거칩니다
3. 검증된 토큰에서 스코프 및 사용자 정보 추출
4. 요청된 작업에 필요한 스코프가 토큰에 포함되어 있는지 확인
-예를 들어, 사용자가 새 todo 항목을 생성하려면 액세스 토큰에 `create:todos` 스코프가 포함되어야 합니다. 리소스 서버 검증 플로우는 다음과 같습니다:
+예를 들어, 사용자가 새 할 일 항목을 생성하려면 액세스 토큰에 `create:todos` 스코프가 포함되어 있어야 합니다. 리소스 서버의 검증 플로우는 다음과 같습니다:
```mermaid
sequenceDiagram
@@ -148,62 +148,62 @@ sequenceDiagram
Server->>Server: 검증된 토큰에서 스코프 및 사용자 컨텍스트 추출
- alt 필요한 스코프 보유
+ alt 필요한 스코프 있음
Server->>Server: 요청된 작업 실행
Server->>Client: 작업 결과 반환
else 필요한 스코프 없음
- Server->>Client: 403 Forbidden
(insufficient_scope 오류)
+ Server->>Client: 403 Forbidden 반환
(insufficient_scope 오류)
end
```
### 동적 클라이언트 등록 (Dynamic Client Registration) \{#dynamic-client-registration}
-이 튜토리얼에서는 필수는 아니지만, 인가 서버에 MCP 클라이언트 등록을 자동화하고 싶다면 유용할 수 있습니다. 자세한 내용은 [동적 클라이언트 등록이 필요한가요?](/provider-list#is-dcr-required)를 참고하세요.
+이 튜토리얼에서는 필수는 아니지만, MCP 클라이언트 등록을 인가 서버와 자동화하고 싶다면 유용할 수 있습니다. 자세한 내용은 [동적 클라이언트 등록이 필요한가요?](/provider-list#is-dcr-required)를 참고하세요.
-## Todo 매니저에서 RBAC 이해하기 (Understand RBAC in todo manager) \{#understand-rbac-in-todo-manager}
+## 할 일 관리 앱에서 RBAC 이해하기 (Understand RBAC in todo manager) \{#understand-rbac-in-todo-manager}
-데모 목적으로, todo 매니저 MCP 서버에 간단한 역할 기반 접근 제어 (RBAC) 시스템을 구현합니다. 이를 통해 RBAC의 기본 원리를 쉽게 이해할 수 있습니다.
+데모 목적상, 할 일 관리 MCP 서버에 간단한 역할 기반 접근 제어 (RBAC) 시스템을 구현합니다. 이를 통해 RBAC의 기본 원리를 쉽게 이해할 수 있습니다.
:::note
-이 튜토리얼은 RBAC 기반 스코프 관리를 시연하지만, 모든 인증 (Authentication) 제공자가 역할을 통한 스코프 관리를 구현하는 것은 아닙니다. 일부 제공자는 자체적인 접근 제어 및 권한 (Permission) 관리 메커니즘을 가질 수 있습니다.
+이 튜토리얼은 RBAC 기반 스코프 관리를 시연하지만, 모든 인증 (Authentication) 제공자가 역할을 통해 스코프 관리를 구현하는 것은 아닙니다. 일부 제공자는 자체적인 접근 제어 및 권한 (Permission) 관리 방식을 가질 수 있습니다.
:::
### 도구와 스코프 (Tools and scopes) \{#tools-and-scopes}
-우리 todo 매니저 MCP 서버는 세 가지 주요 도구를 제공합니다:
+우리의 할 일 관리 MCP 서버는 세 가지 주요 도구를 제공합니다:
-- `create-todo`: 새 todo 항목 생성
-- `get-todos`: 모든 todo 목록 조회
-- `delete-todo`: ID로 todo 삭제
+- `create-todo`: 새 할 일 항목 생성
+- `get-todos`: 모든 할 일 목록 조회
+- `delete-todo`: ID로 할 일 삭제
이 도구들에 대한 접근을 제어하기 위해 다음과 같은 스코프를 정의합니다:
-- `create:todos`: 새 todo 항목 생성 허용
-- `delete:todos`: 기존 todo 항목 삭제 허용
-- `read:todos`: 모든 todo 항목 조회 및 검색 허용
+- `create:todos`: 새 할 일 항목 생성 허용
+- `delete:todos`: 기존 할 일 항목 삭제 허용
+- `read:todos`: 모든 할 일 항목 목록 조회 및 검색 허용
### 역할과 권한 (Roles and permissions) \{#roles-and-permissions}
다음과 같이 서로 다른 접근 수준을 가진 두 가지 역할을 정의합니다:
-| 역할 (Role) | create:todos | read:todos | delete:todos |
-| ----------- | ------------ | ---------- | ------------ |
-| Admin | ✅ | ✅ | ✅ |
-| User | ✅ | | |
+| 역할 | create:todos | read:todos | delete:todos |
+| ----- | ------------ | ---------- | ------------ |
+| Admin | ✅ | ✅ | ✅ |
+| User | ✅ | | |
-- **User**: 자신의 todo만 생성, 조회, 삭제할 수 있는 일반 사용자
-- **Admin**: 소유자와 상관없이 모든 todo를 생성, 조회, 삭제할 수 있는 관리자
+- **User**: 자신의 할 일만 생성, 조회, 삭제할 수 있는 일반 사용자
+- **Admin**: 소유자와 관계없이 모든 할 일을 생성, 조회, 삭제할 수 있는 관리자
### 리소스 소유권 (Resource ownership) \{#resource-ownership}
-위 권한 테이블은 각 역할에 명시적으로 할당된 스코프를 보여주지만, 리소스 소유권의 중요한 원칙이 있습니다:
+위 권한 테이블은 각 역할에 명시적으로 할당된 스코프를 보여주지만, 리소스 소유권이라는 중요한 원칙이 있습니다:
-- **User**는 `read:todos` 또는 `delete:todos` 스코프가 없지만, 여전히:
- - 자신의 todo 항목을 조회할 수 있습니다
- - 자신의 todo 항목을 삭제할 수 있습니다
+- **User**는 `read:todos` 또는 `delete:todos` 스코프가 없어도:
+ - 자신의 할 일 항목을 조회할 수 있고
+ - 자신의 할 일 항목을 삭제할 수 있습니다
- **Admin**은 전체 권한 (`read:todos`, `delete:todos`)을 가지므로:
- - 시스템의 모든 todo 항목을 볼 수 있습니다
- - 소유자와 상관없이 모든 todo 항목을 삭제할 수 있습니다
+ - 시스템의 모든 할 일 항목을 조회할 수 있고
+ - 소유자와 관계없이 모든 할 일 항목을 삭제할 수 있습니다
이는 RBAC 시스템에서 리소스 소유권이 사용자의 자신의 리소스에 대한 암묵적 권한을 부여하고, 관리 역할은 모든 리소스에 대한 명시적 권한을 받는 일반적인 패턴을 보여줍니다.
@@ -218,37 +218,37 @@ RBAC 개념과 모범 사례를 더 깊이 이해하려면 [Mastering RBAC: A Co
-[Logto](https://logto.io)는 API 리소스 및 역할 기능을 통해 RBAC를 지원합니다. 설정 방법은 다음과 같습니다:
+[Logto](https://logto.io)는 API 리소스와 역할 기능을 통해 RBAC를 지원합니다. 설정 방법은 다음과 같습니다:
1. [Logto Console](https://cloud.logto.io) (또는 자체 호스팅 Logto Console)에 로그인하세요.
2. API 리소스 및 스코프 생성:
- "API 리소스"로 이동
- - "Todo Manager"라는 새 API 리소스를 생성하고, 리소스 지표 (Resource indicator)로 `http://localhost:3001/`을 사용하세요.
- - **중요**: 리소스 지표는 MCP 서버의 URL과 일치해야 합니다. 이 튜토리얼에서는 MCP 서버가 3001 포트에서 실행되므로 `http://localhost:3001/`을 사용합니다. 운영 환경에서는 실제 MCP 서버 URL (예: `https://your-mcp-server.example.com/`)을 사용하세요.
+ - "Todo Manager"라는 새 API 리소스를 생성하고, 리소스 지표 (Resource indicator)로 `http://localhost:3001/` 사용
+ - **중요**: 리소스 지표는 MCP 서버의 URL과 일치해야 합니다. 이 튜토리얼에서는 MCP 서버가 3001 포트에서 실행되므로 `http://localhost:3001/`을 사용합니다. 운영 환경에서는 실제 MCP 서버 URL(예: `https://your-mcp-server.example.com/`)을 사용하세요.
- 다음 스코프 생성:
- - `create:todos`: "새 todo 항목 생성"
- - `read:todos`: "모든 todo 항목 읽기"
- - `delete:todos`: "모든 todo 항목 삭제"
+ - `create:todos`: "새 할 일 항목 생성"
+ - `read:todos`: "모든 할 일 항목 읽기"
+ - `delete:todos`: "모든 할 일 항목 삭제"
-3. 역할 생성 (관리가 쉬우므로 권장):
+3. 역할 생성 (관리를 쉽게 하기 위해 권장):
- "Roles"로 이동
- - "Admin" 역할을 생성하고 모든 스코프 (`create:todos`, `read:todos`, `delete:todos`) 할당
+ - "Admin" 역할을 생성하고 모든 스코프(`create:todos`, `read:todos`, `delete:todos`) 할당
- "User" 역할을 생성하고 `create:todos` 스코프만 할당
- "User" 역할 상세 페이지에서 "General" 탭으로 이동하여 "User" 역할을 "기본 역할 (Default role)"로 설정
4. 사용자 역할 및 권한 관리:
- 신규 사용자:
- - 기본 역할로 "User" 역할이 자동 할당됩니다
+ - 기본 역할로 "User" 역할이 자동 할당됨
- 기존 사용자:
- "사용자 관리"로 이동
- 사용자를 선택
- "Roles" 탭에서 역할 할당
-:::tip 프로그래밍 방식의 역할 관리
-Logto의 [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api)를 사용하여 프로그래밍 방식으로 사용자 역할을 관리할 수도 있습니다. 자동화된 사용자 관리나 관리자 패널 구축 시 유용합니다.
+:::tip 프로그래밍 방식 역할 관리
+Logto의 [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api)를 사용하여 프로그래밍 방식으로 사용자 역할을 관리할 수 있습니다. 자동화된 사용자 관리나 관리자 패널 구축 시 유용합니다.
:::
액세스 토큰을 요청할 때, Logto는 사용자 역할 권한에 따라 토큰의 `scope` 클레임에 스코프를 포함합니다.
@@ -256,7 +256,7 @@ Logto의 [Management API](https://docs.logto.io/integrate-logto/interact-with-ma
-OAuth 2.0 또는 OpenID Connect 제공자의 경우, 서로 다른 권한을 나타내는 스코프를 구성해야 합니다. 구체적인 단계는 제공자마다 다르지만, 일반적으로:
+OAuth 2.0 또는 OpenID Connect 제공자의 경우, 서로 다른 권한을 나타내는 스코프를 구성해야 합니다. 구체적인 단계는 제공자마다 다르지만 일반적으로:
1. 스코프 정의:
@@ -271,8 +271,8 @@ OAuth 2.0 또는 OpenID Connect 제공자의 경우, 서로 다른 권한을 나
- 액세스 토큰에 스코프가 포함되는지 확인
3. 권한 할당:
- - 제공자 인터페이스를 사용하여 사용자에게 적절한 스코프를 부여
- - 일부 제공자는 역할 기반 관리, 일부는 직접 스코프 할당을 지원
+ - 제공자 인터페이스를 통해 사용자에게 적절한 스코프 부여
+ - 일부 제공자는 역할 기반 관리, 일부는 직접 스코프 할당 방식 지원
- 권장 방식은 제공자 문서를 참고
:::tip
@@ -288,13 +288,13 @@ OAuth 2.0 또는 OpenID Connect 제공자의 경우, 서로 다른 권한을 나
인가 서버를 구성한 후, 사용자는 부여된 스코프가 포함된 액세스 토큰을 받게 됩니다. MCP 서버는 이 스코프를 사용하여 다음을 결정합니다:
-- 사용자가 새 todo를 생성할 수 있는지 (`create:todos`)
-- 사용자가 모든 todo를 볼 수 있는지 (`read:todos`) 또는 자신의 todo만 볼 수 있는지
-- 사용자가 모든 todo를 삭제할 수 있는지 (`delete:todos`) 또는 자신의 todo만 삭제할 수 있는지
+- 사용자가 새 할 일을 생성할 수 있는지 (`create:todos`)
+- 사용자가 모든 할 일을 볼 수 있는지 (`read:todos`) 또는 자신의 할 일만 볼 수 있는지
+- 사용자가 모든 할 일을 삭제할 수 있는지 (`delete:todos`) 또는 자신의 할 일만 삭제할 수 있는지
## MCP 서버 설정하기 (Set up the MCP server) \{#set-up-the-mcp-server}
-[MCP 공식 SDK](https://github.com/modelcontextprotocol)를 사용하여 todo 매니저 MCP 서버를 만듭니다.
+[MCP 공식 SDK](https://github.com/modelcontextprotocol)를 사용하여 할 일 관리 MCP 서버를 만듭니다.
### 새 프로젝트 생성 (Create a new project) \{#create-a-new-project}
@@ -310,7 +310,7 @@ npm pkg set scripts.start="node --experimental-strip-types todo-manager.ts"
```
:::note
-예제에서는 Node.js v22.6.0+에서 `--experimental-strip-types` 플래그로 TypeScript를 네이티브로 실행합니다. JavaScript를 사용하는 경우 코드가 거의 동일하며, Node.js v22.6.0 이상을 사용해야 합니다. 자세한 내용은 Node.js 문서를 참고하세요.
+예제에서는 Node.js v22.6.0+에서 `--experimental-strip-types` 플래그로 TypeScript를 네이티브로 실행할 수 있으므로 TypeScript를 사용합니다. JavaScript를 사용할 경우 코드가 유사하니, Node.js v22.6.0 이상을 사용하세요. 자세한 내용은 Node.js 문서를 참고하세요.
:::
### MCP SDK 및 의존성 설치 (Install the MCP SDK and dependencies) \{#install-the-mcp-sdk-and-dependencies}
@@ -319,15 +319,109 @@ npm pkg set scripts.start="node --experimental-strip-types todo-manager.ts"
npm install @modelcontextprotocol/sdk express zod
```
-또는 `pnpm`, `yarn` 등 원하는 패키지 매니저를 사용할 수 있습니다.
+또는 `pnpm`, `yarn` 등 원하는 패키지 매니저를 사용하세요.
-### MCP 서버 생성 (Create the MCP server) \{#create-the-mcp-server}
+### MCP 서버 만들기 (Create the MCP server) \{#create-the-mcp-server}
`todo-manager.ts` 파일을 만들고 다음 코드를 추가하세요:
-[코드 블록은 번역하지 않습니다.]
+```ts
+// todo-manager.ts
-서버 실행:
+import { z } from 'zod';
+import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
+import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
+import express, { type Request, type Response } from 'express';
+
+// MCP 서버 인스턴스 생성 팩토리 함수
+// 무상태 모드에서는 각 요청마다 별도의 서버 인스턴스가 필요
+const createMcpServer = () => {
+ const mcpServer = new McpServer({
+ name: 'Todo Manager',
+ version: '0.0.0',
+ });
+
+ mcpServer.registerTool(
+ 'create-todo',
+ {
+ description: '새 할 일 생성',
+ inputSchema: { content: z.string() },
+ },
+ async ({ content }) => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Not implemented' }) }],
+ };
+ }
+ );
+
+ mcpServer.registerTool(
+ 'get-todos',
+ {
+ description: '모든 할 일 목록 조회',
+ inputSchema: {},
+ },
+ async () => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Not implemented' }) }],
+ };
+ }
+ );
+
+ mcpServer.registerTool(
+ 'delete-todo',
+ {
+ description: 'ID로 할 일 삭제',
+ inputSchema: { id: z.string() },
+ },
+ async ({ id }) => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Not implemented' }) }],
+ };
+ }
+ );
+
+ return mcpServer;
+};
+
+// 아래는 MCP SDK 문서의 보일러플레이트 코드입니다
+const PORT = 3001;
+const app = express();
+
+app.post('/', async (request: Request, response: Response) => {
+ // 무상태 모드에서는 각 요청마다 별도의 transport 및 서버 인스턴스를 생성해야 함
+ // 단일 인스턴스 사용 시 여러 클라이언트가 동시에 연결될 때 요청 ID 충돌 발생
+ const mcpServer = createMcpServer();
+
+ try {
+ const transport = new StreamableHTTPServerTransport({
+ sessionIdGenerator: undefined,
+ });
+ await mcpServer.connect(transport);
+ await transport.handleRequest(request, response, request.body);
+ response.on('close', () => {
+ console.log('Request closed');
+ void transport.close();
+ void mcpServer.close();
+ });
+ } catch (error) {
+ console.error('Error handling MCP request:', error);
+ if (!response.headersSent) {
+ response.status(500).json({
+ jsonrpc: '2.0',
+ error: {
+ code: -32_603,
+ message: 'Internal server error',
+ },
+ id: null,
+ });
+ }
+ }
+});
+
+app.listen(PORT);
+```
+
+서버를 실행하세요:
```bash
npm start
@@ -340,22 +434,22 @@ npm start
**인가 서버의 발급자 (Issuer) URL**
-일반적으로 인가 서버의 기본 URL입니다. 예: `https://auth.example.com`. 일부 제공자는 `https://example.logto.app/oidc`와 같은 경로를 가질 수 있으니, 제공자 문서를 확인하세요.
+일반적으로 인가 서버의 기본 URL(예: `https://auth.example.com`)입니다. 일부 제공자는 `https://example.logto.app/oidc`와 같은 경로를 사용할 수 있으니, 제공자 문서를 확인하세요.
-**인가 서버 메타데이터 조회 방법**
+**인가 서버 메타데이터 가져오기 방법**
-- 인가 서버가 [OAuth 2.0 Authorization Server Metadata](https://datatracker.ietf.org/doc/html/rfc8414) 또는 [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html)를 준수한다면, MCP Auth 내장 유틸리티로 메타데이터를 자동으로 가져올 수 있습니다.
-- 준수하지 않는 경우, MCP 서버 설정에서 메타데이터 URL 또는 엔드포인트를 수동으로 지정해야 합니다. 제공자 문서에서 엔드포인트를 확인하세요.
+- 인가 서버가 [OAuth 2.0 인가 서버 메타데이터](https://datatracker.ietf.org/doc/html/rfc8414) 또는 [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html)를 준수한다면, MCP Auth 내장 유틸리티로 메타데이터를 자동으로 가져올 수 있습니다.
+- 준수하지 않는 경우, MCP 서버 설정에서 메타데이터 URL 또는 엔드포인트를 수동으로 지정해야 합니다. 제공자 문서를 참고하세요.
**인가 서버에 MCP 클라이언트 등록 방법**
-- 인가 서버가 [동적 클라이언트 등록 (Dynamic Client Registration)](https://datatracker.ietf.org/doc/html/rfc7591)을 지원한다면, MCP 클라이언트가 자동으로 등록됩니다.
+- 인가 서버가 [동적 클라이언트 등록](https://datatracker.ietf.org/doc/html/rfc7591)을 지원한다면, MCP 클라이언트가 자동으로 등록됩니다.
- 지원하지 않는 경우, MCP 클라이언트를 인가 서버에 수동으로 등록해야 합니다.
@@ -363,7 +457,7 @@ npm start
**토큰 요청 파라미터 이해하기**
-인가 서버에서 액세스 토큰을 요청할 때, 대상 리소스 및 권한을 지정하는 다양한 방식이 있습니다. 주요 패턴은 다음과 같습니다:
+인가 서버에서 액세스 토큰을 요청할 때, 대상 리소스와 권한을 지정하는 다양한 방식이 있습니다. 주요 패턴은 다음과 같습니다:
- **리소스 지표 기반**:
@@ -376,7 +470,7 @@ npm start
"scope": "create:todos read:todos"
}
```
- - 서버는 요청된 리소스에 바인딩된 토큰을 발급
+ - 서버는 요청된 리소스에만 바인딩된 토큰 발급
- **대상 (Audience) 기반**:
@@ -400,26 +494,26 @@ npm start
}
```
- 권한 네임스페이스를 위해 접두사 스코프 사용
- - 간단한 OAuth 2.0 구현에서 일반적
+ - 단순한 OAuth 2.0 구현에서 일반적
:::tip 모범 사례
-- 제공자 문서에서 지원되는 파라미터 확인
+- 제공자 문서에서 지원 파라미터 확인
- 일부 제공자는 여러 방식을 동시에 지원
-- 리소스 지표는 대상 제한을 통해 더 나은 보안을 제공
-- 가능하다면 리소스 지표 사용을 고려하여 더 나은 접근 제어 구현
+- 리소스 지표는 대상 제한을 통해 더 나은 보안 제공
+- 가능하다면 리소스 지표 사용을 권장
:::
-각 제공자마다 구체적인 요구 사항이 다를 수 있지만, 아래 단계는 VS Code와 MCP 서버를 제공자별 설정과 통합하는 과정을 안내합니다.
+제공자마다 구체적인 요구사항이 다를 수 있지만, 아래 단계는 VS Code와 MCP 서버를 제공자별 설정과 함께 통합하는 과정을 안내합니다.
### MCP 클라이언트를 서드파티 앱으로 등록하기 (Register MCP client as a third-party app) \{#register-mcp-client-as-a-third-party-app}
-[Logto](https://logto.io)는 OpenID Connect 제공자로, 리소스 지표와 스코프를 지원하므로 `http://localhost:3001/`을 리소스 지표로 사용하여 todo API를 안전하게 보호할 수 있습니다.
+[Logto](https://logto.io)는 OpenID Connect 제공자로, 리소스 지표와 스코프를 지원하므로 `http://localhost:3001/`을 리소스 지표로 사용해 할 일 API를 안전하게 보호할 수 있습니다.
Logto는 아직 동적 클라이언트 등록을 지원하지 않으므로, MCP 클라이언트(VS Code)를 Logto 테넌트의 서드파티 앱으로 수동 등록해야 합니다:
@@ -427,16 +521,16 @@ Logto는 아직 동적 클라이언트 등록을 지원하지 않으므로, MCP
2. **Applications > Third-party apps**로 이동 후 "Create application" 클릭
3. **Native App**을 애플리케이션 유형으로 선택
4. 애플리케이션 정보 입력:
- - **Application name**: 예) "MCP Client"
- - **Description**: 예) "MCP client for VS Code"
+ - **Application name**: 예시로 "MCP Client"
+ - **Description**: 예시로 "MCP client for VS Code"
5. VS Code용 **Redirect URI** 설정:
```
http://127.0.0.1
https://vscode.dev/redirect
```
6. "Save changes" 클릭
-7. 앱의 **Permissions** 탭에서 **User** 섹션 아래, 앞서 생성한 **Todo Manager** API 리소스의 `create:todos`, `read:todos`, `delete:todos` 권한 추가
-8. 상단 카드에서 "App ID" 값을 확인하고 복사해둡니다
+7. 앱의 **Permissions** 탭에서 **User** 섹션에, 앞서 만든 **Todo Manager** API 리소스의 `create:todos`, `read:todos`, `delete:todos` 권한 추가
+8. 상단 카드에서 "App ID" 값을 확인하고 복사해둡니다.
@@ -451,7 +545,7 @@ Logto는 아직 동적 클라이언트 등록을 지원하지 않으므로, MCP
2. "Applications" 또는 "Clients" 섹션에서 새 애플리케이션/클라이언트 생성
-3. 클라이언트 유형을 요구한다면 "Native App" 또는 "Public client" 선택
+3. 클라이언트 유형이 필요하다면 "Native App" 또는 "Public client" 선택
4. 애플리케이션 생성 후, 리디렉션 URI를 설정합니다. VS Code의 경우 다음을 추가:
@@ -466,12 +560,12 @@ Logto는 아직 동적 클라이언트 등록을 지원하지 않으므로, MCP
create:todos read:todos delete:todos
```
-6. 새로 생성된 애플리케이션의 "Client ID" 또는 "Application ID"를 찾아 복사해둡니다
+6. 새로 생성된 애플리케이션의 "Client ID" 또는 "Application ID"를 복사해둡니다.
-### MCP Auth 설정 (Set up MCP Auth) \{#set-up-mcp-auth}
+### MCP Auth 설정하기 (Set up MCP Auth) \{#set-up-mcp-auth}
먼저 MCP 서버 프로젝트에 MCP Auth SDK를 설치하세요.
@@ -479,20 +573,20 @@ Logto는 아직 동적 클라이언트 등록을 지원하지 않으므로, MCP
이제 MCP 서버에서 MCP Auth를 초기화해야 합니다. 보호된 리소스 모드에서는 인가 서버를 포함한 리소스 메타데이터를 구성해야 합니다.
-인가 서버를 구성하는 방법은 두 가지가 있습니다:
+인가 서버를 구성하는 방법은 두 가지입니다:
-- **사전 패치(권장)**: `fetchServerConfig()`로 메타데이터를 미리 가져와 MCPAuth를 초기화합니다. 시작 시 구성이 검증됩니다.
-- **온디맨드 디스커버리**: `issuer`와 `type`만 제공하면, 최초 필요 시 메타데이터를 가져옵니다. (Cloudflare Workers 등 top-level async fetch가 불가한 환경에 유용)
+- **사전 페치(권장)**: `fetchServerConfig()`로 메타데이터를 미리 가져와 MCPAuth 초기화 전에 검증합니다.
+- **온디맨드 디스커버리**: `issuer`와 `type`만 제공하면, 최초 필요 시 메타데이터를 가져옵니다. (Cloudflare Workers 등 엣지 런타임에서 유용)
#### 보호된 리소스 메타데이터 구성 (Configure protected resource metadata) \{#configure-protected-resource-metadata}
-먼저 인가 서버의 발급자(issuer) URL을 확인하세요:
+먼저 인가 서버의 발급자 (Issuer) URL을 확인하세요:
-Logto에서는 Logto Console의 애플리케이션 상세 페이지 "Endpoints & Credentials / Issuer endpoint" 섹션에서 issuer URL을 확인할 수 있습니다. 예: `https://my-project.logto.app/oidc`
+Logto에서는 Logto Console의 애플리케이션 상세 페이지 "Endpoints & Credentials / Issuer endpoint" 섹션에서 발급자 URL을 확인할 수 있습니다. 예시: `https://my-project.logto.app/oidc`
@@ -500,7 +594,7 @@ Logto에서는 Logto Console의 애플리케이션 상세 페이지 "Endpoints &
OAuth 2.0 제공자의 경우:
-1. 제공자 문서에서 인가 서버 URL(issuer URL 또는 base URL)을 확인
+1. 인가 서버 URL(발급자 URL 또는 base URL)을 제공자 문서에서 확인
2. 일부 제공자는 `https://{your-domain}/.well-known/oauth-authorization-server`에서 노출
3. 제공자 관리 콘솔의 OAuth/API 설정에서 확인
@@ -510,41 +604,273 @@ OAuth 2.0 제공자의 경우:
이제 MCP Auth 인스턴스를 만들 때 보호된 리소스 메타데이터를 구성하세요:
-[코드 블록은 번역하지 않습니다.]
+```js
+// todo-manager.ts
+
+import { MCPAuth, fetchServerConfig } from 'mcp-auth';
+
+const issuerUrl = ''; // 인가 서버의 발급자 URL로 교체
+
+// 이 MCP 서버의 리소스 식별자 정의
+const resourceId = 'http://localhost:3001/';
+
+// 인가 서버 구성 사전 페치(권장)
+const authServerConfig = await fetchServerConfig(issuerUrl, { type: 'oidc' });
+
+// 보호된 리소스 메타데이터로 MCP Auth 구성
+const mcpAuth = new MCPAuth({
+ protectedResources: {
+ metadata: {
+ resource: resourceId,
+ authorizationServers: [authServerConfig],
+ // MCP 서버가 이해하는 스코프
+ scopesSupported: ['create:todos', 'read:todos', 'delete:todos'],
+ },
+ },
+});
+```
### MCP 서버 업데이트 (Update MCP server) \{#update-mcp-server}
-거의 다 왔습니다! 이제 MCP Auth 라우트와 미들웨어를 적용하고, 사용자의 스코프에 따라 todo 매니저 도구에 권한 기반 접근 제어를 구현합니다.
+거의 다 왔습니다! 이제 MCP Auth 라우트와 미들웨어 함수를 적용하고, 사용자의 스코프에 따라 할 일 관리 도구에 권한 기반 접근 제어를 구현합니다.
먼저, 보호된 리소스 메타데이터 라우트를 적용하여 MCP 클라이언트가 MCP 서버에서 예상 리소스 메타데이터를 가져올 수 있도록 합니다.
-[코드 블록은 번역하지 않습니다.]
+```ts
+// todo-manager.ts
-다음으로, MCP Auth 미들웨어를 MCP 서버에 적용합니다. 이 미들웨어는 인증 (Authentication) 및 인가 (Authorization)를 처리하여, 인가된 사용자만 todo 매니저 도구에 접근할 수 있도록 합니다.
+// 보호된 리소스 메타데이터 라우트 설정
+// OAuth 클라이언트를 위한 리소스 서버 메타데이터 노출
+app.use(mcpAuth.protectedResourceMetadataRouter());
+```
+
+다음으로, MCP Auth 미들웨어를 MCP 서버에 적용합니다. 이 미들웨어는 인증 (Authentication) 및 인가 (Authorization)를 처리하여, 인가된 사용자만 할 일 관리 도구에 접근할 수 있도록 합니다.
+
+```ts
+// todo-manager.ts
+
+app.use(mcpAuth.protectedResourceMetadataRouter());
+
+// MCP Auth 미들웨어 적용
+app.use(
+ mcpAuth.bearerAuth('jwt', {
+ resource: resourceId,
+ audience: resourceId,
+ })
+);
+```
-[코드 블록은 번역하지 않습니다.]
+이제 할 일 관리 도구의 구현을 업데이트하여 MCP Auth 미들웨어를 통한 인증 (Authentication) 및 인가 (Authorization)를 활용할 수 있습니다.
-이제 todo 매니저 도구의 구현을 업데이트하여 MCP Auth 미들웨어를 통한 인증 및 인가를 활용할 수 있습니다.
+도구 구현을 업데이트해봅시다.
-[코드 블록은 번역하지 않습니다.]
+```js
+// todo-manager.ts
-위 코드에서 사용된 "Todo 서비스"를 구현하세요:
+// 기타 import...
+import assert from 'node:assert';
+import { fetchServerConfig, MCPAuth, MCPAuthBearerAuthError } from 'mcp-auth';
+import { type AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
-`todo-service.ts` 파일을 생성하여 Todo 서비스를 구현합니다:
+// 다음 섹션에서 언급할 예정
+import { TodoService } from './todo-service.js';
-[코드 블록은 번역하지 않습니다.]
+const assertUserId = (authInfo?: AuthInfo) => {
+ const { subject } = authInfo ?? {};
+ assert(subject, 'Invalid auth info');
+ return subject;
+};
+
+const hasRequiredScopes = (userScopes: string[], requiredScopes: string[]): boolean => {
+ return requiredScopes.every((scope) => userScopes.includes(scope));
+};
+
+// TodoService는 상태 공유를 위해 싱글톤으로 사용
+const todoService = new TodoService();
+
+// MCP 서버 인스턴스 생성 팩토리 함수
+// 무상태 모드에서는 각 요청마다 별도의 서버 인스턴스 필요
+const createMcpServer = () => {
+ const mcpServer = new McpServer({
+ name: 'Todo Manager',
+ version: '0.0.0',
+ });
+
+ mcpServer.registerTool(
+ 'create-todo',
+ {
+ description: '새 할 일 생성',
+ inputSchema: { content: z.string() },
+ },
+ ({ content }, { authInfo }) => {
+ const userId = assertUserId(authInfo);
+
+ /**
+ * 'create:todos' 스코프가 있는 사용자만 할 일 생성 가능
+ */
+ if (!hasRequiredScopes(authInfo?.scopes ?? [], ['create:todos'])) {
+ throw new MCPAuthBearerAuthError('missing_required_scopes');
+ }
+
+ const createdTodo = todoService.createTodo({ content, ownerId: userId });
+
+ return {
+ content: [{ type: 'text', text: JSON.stringify(createdTodo) }],
+ };
+ }
+ );
+
+ mcpServer.registerTool(
+ 'get-todos',
+ {
+ description: '모든 할 일 목록 조회',
+ inputSchema: {},
+ },
+ (_params, { authInfo }) => {
+ const userId = assertUserId(authInfo);
+
+ /**
+ * 'read:todos' 스코프가 있으면 모든 할 일 접근 가능 (todoOwnerId = undefined)
+ * 없으면 자신의 할 일만 접근 가능 (todoOwnerId = userId)
+ */
+ const todoOwnerId = hasRequiredScopes(authInfo?.scopes ?? [], ['read:todos'])
+ ? undefined
+ : userId;
+
+ const todos = todoService.getAllTodos(todoOwnerId);
+
+ return {
+ content: [{ type: 'text', text: JSON.stringify(todos) }],
+ };
+ }
+ );
+
+ mcpServer.registerTool(
+ 'delete-todo',
+ {
+ description: 'ID로 할 일 삭제',
+ inputSchema: { id: z.string() },
+ },
+ ({ id }, { authInfo }) => {
+ const userId = assertUserId(authInfo);
+
+ const todo = todoService.getTodoById(id);
+
+ if (!todo) {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Failed to delete todo' }) }],
+ };
+ }
+
+ /**
+ * 사용자는 자신의 할 일만 삭제 가능
+ * 'delete:todos' 스코프가 있으면 모든 할 일 삭제 가능
+ */
+ if (todo.ownerId !== userId && !hasRequiredScopes(authInfo?.scopes ?? [], ['delete:todos'])) {
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({ error: 'Failed to delete todo' }),
+ },
+ ],
+ };
+ }
+
+ const deletedTodo = todoService.deleteTodo(id);
+
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({
+ message: `Todo ${id} deleted`,
+ details: deletedTodo,
+ }),
+ },
+ ],
+ };
+ }
+ );
+
+ return mcpServer;
+};
+```
+
+이제 위 코드에서 사용한 "Todo 서비스"를 구현해봅시다:
+
+`todo-service.ts` 파일을 생성하세요:
+
+```ts
+// todo-service.ts
+
+type Todo = {
+ id: string;
+ content: string;
+ ownerId: string;
+ createdAt: string;
+};
+
+/**
+ * 데모용 간단한 Todo 서비스.
+ * 메모리 배열에 할 일 저장
+ */
+export class TodoService {
+ private readonly todos: Todo[] = [];
+
+ getAllTodos(ownerId?: string): Todo[] {
+ if (ownerId) {
+ return this.todos.filter((todo) => todo.ownerId === ownerId);
+ }
+ return this.todos;
+ }
+
+ getTodoById(id: string): Todo | undefined {
+ return this.todos.find((todo) => todo.id === id);
+ }
+
+ createTodo({ content, ownerId }: { content: string; ownerId: string }): Todo {
+ const todo: Todo = {
+ id: this.genId(),
+ content,
+ ownerId,
+ createdAt: new Date().toISOString(),
+ };
+
+ // eslint-disable-next-line @silverhand/fp/no-mutating-methods
+ this.todos.push(todo);
+ return todo;
+ }
+
+ deleteTodo(id: string): Todo | undefined {
+ const index = this.todos.findIndex((todo) => todo.id === id);
+
+ if (index === -1) {
+ return undefined;
+ }
+
+ // eslint-disable-next-line @silverhand/fp/no-mutating-methods
+ const [deleted] = this.todos.splice(index, 1);
+ return deleted;
+ }
+
+ private genId(): string {
+ return Math.random().toString(36).slice(2, 10);
+ }
+}
+```
-축하합니다! 인증 (Authentication) 및 인가 (Authorization)가 적용된 완전한 MCP 서버를 성공적으로 구현했습니다!
+축하합니다! 인증 (Authentication)과 인가 (Authorization)가 적용된 완전한 MCP 서버를 성공적으로 구현했습니다!
:::info
-MCP 서버(OIDC 버전)의 전체 코드는 [MCP Auth Node.js SDK 저장소](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src)에서 확인할 수 있습니다.
+[MCP Auth Node.js SDK 저장소](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src)에서 MCP 서버(OIDC 버전)의 전체 코드를 확인할 수 있습니다.
:::
## 체크포인트: `todo-manager` 도구 실행 (Checkpoint: Run the `todo-manager` tools) \{#checkpoint-run-the-todo-manager-tools}
-MCP 서버를 재시작하고 VS Code에서 연결하세요. 인증과 함께 연결하는 방법은 다음과 같습니다:
+MCP 서버를 재시작하고 VS Code에서 연결하세요. 인증 (Authentication)과 함께 연결하는 방법은 다음과 같습니다:
-1. VS Code에서 `Command + Shift + P`(macOS) 또는 `Ctrl + Shift + P`(Windows/Linux)를 눌러 커맨드 팔레트 열기
+1. VS Code에서 `Command + Shift + P`(macOS) 또는 `Ctrl + Shift + P`(Windows/Linux)를 눌러 명령 팔레트 열기
2. `MCP: Add Server...` 입력 후 선택
3. 서버 유형으로 `HTTP` 선택
4. MCP 서버 URL 입력: `http://localhost:3001`
@@ -552,17 +878,17 @@ MCP 서버를 재시작하고 VS Code에서 연결하세요. 인증과 함께
6. **App Secret**은 없으므로(공개 클라이언트), Enter를 눌러 건너뜁니다.
7. 브라우저에서 로그인 플로우를 완료하세요.
-로그인 후 VS Code로 돌아와, 이전 체크포인트에서 했던 것처럼 todo 매니저 도구를 실행하세요. 이번에는 인증된 사용자 아이덴티티로 도구를 사용할 수 있습니다. 도구의 동작은 사용자에게 할당된 역할과 권한에 따라 달라집니다:
+로그인 후 VS Code로 돌아오면, 이전 체크포인트에서 했던 것처럼 할 일 관리 도구를 실행하세요. 이번에는 인증된 사용자 아이덴티티로 도구를 사용할 수 있습니다. 도구의 동작은 사용자에게 할당된 역할과 권한에 따라 달라집니다:
-- **User**(오직 `create:todos` 스코프만 보유)로 로그인한 경우:
- - `create-todo` 도구로 새 todo 생성 가능
- - 자신의 todo만 조회 및 삭제 가능
- - 다른 사용자의 todo는 볼 수 없고 삭제도 불가
+- **User**(오직 `create:todos` 스코프만 가진 사용자)로 로그인한 경우:
+ - `create-todo` 도구로 새 할 일 생성 가능
+ - 자신의 할 일만 조회 및 삭제 가능
+ - 다른 사용자의 할 일은 볼 수 없고 삭제도 불가
-- **Admin**(모든 스코프: `create:todos`, `read:todos`, `delete:todos`)로 로그인한 경우:
- - 새 todo 생성 가능
- - `get-todos` 도구로 시스템의 모든 todo 조회 가능
- - `delete-todo` 도구로 소유자와 상관없이 모든 todo 삭제 가능
+- **Admin**(모든 스코프: `create:todos`, `read:todos`, `delete:todos` 보유)로 로그인한 경우:
+ - 새 할 일 생성 가능
+ - `get-todos` 도구로 시스템의 모든 할 일 조회 가능
+ - 누가 만들었든 모든 할 일 삭제 가능
다른 권한 수준을 테스트하려면:
@@ -570,19 +896,19 @@ MCP 서버를 재시작하고 VS Code에서 연결하세요. 인증과 함께
2. 다른 역할/권한을 가진 사용자 계정으로 로그인
3. 동일한 도구를 다시 실행하여 권한에 따라 동작이 어떻게 달라지는지 확인
-이렇게 하면 역할 기반 접근 제어 (RBAC)가 실제로 어떻게 동작하는지, 서로 다른 사용자가 시스템 기능에 대해 서로 다른 접근 권한을 가지는지 확인할 수 있습니다.
+이렇게 하면 역할 기반 접근 제어 (RBAC)가 실제로 어떻게 동작하는지, 서로 다른 사용자가 시스템 기능에 대해 서로 다른 접근 권한을 갖는지 확인할 수 있습니다.
:::info
-MCP 서버(OIDC 버전)의 전체 코드는 [MCP Auth Node.js SDK 저장소](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src)에서 확인할 수 있습니다.
+[MCP Auth Node.js SDK 저장소](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src)에서 MCP 서버(OIDC 버전)의 전체 코드를 확인할 수 있습니다.
:::
## 마무리 (Closing notes) \{#closing-notes}
-축하합니다! 튜토리얼을 성공적으로 완료했습니다. 지금까지 한 내용을 정리해봅시다:
+축하합니다! 튜토리얼을 성공적으로 완료했습니다. 지금까지 한 일을 요약해봅시다:
-- todo 관리 도구(`create-todo`, `get-todos`, `delete-todo`)가 포함된 기본 MCP 서버 설정
+- 할 일 관리 도구(`create-todo`, `get-todos`, `delete-todo`)가 포함된 기본 MCP 서버 설정
- 사용자와 관리자를 위한 서로 다른 권한 수준의 역할 기반 접근 제어 (RBAC) 구현
-- MCP Auth를 사용하여 MCP 서버를 인가 서버와 통합
+- MCP Auth를 사용해 MCP 서버를 인가 서버와 통합
- VS Code에서 사용자 인증 및 스코프가 포함된 액세스 토큰으로 도구 호출 구성
-MCP Auth를 최대한 활용하려면 다른 튜토리얼과 문서도 꼭 확인해보세요.
\ No newline at end of file
+MCP Auth를 최대한 활용하려면 다른 튜토리얼과 문서도 꼭 확인해보세요.
diff --git a/i18n/pt-BR/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx b/i18n/pt-BR/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
index 658b6c5..8145c7a 100644
--- a/i18n/pt-BR/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
+++ b/i18n/pt-BR/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
@@ -1,38 +1,38 @@
---
sidebar_position: 2
-sidebar_label: 'Tutorial: Construa um gerenciador de tarefas'
+sidebar_label: 'Tutorial: Crie um gerenciador de tarefas'
---
import { NpmLikeInstallation } from '@site/src/components/NpmLikeInstallation';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
-# Tutorial: Construa um gerenciador de tarefas
+# Tutorial: Crie um gerenciador de tarefas
:::tip SDK Python disponível
MCP Auth também está disponível para Python! Confira o [repositório do SDK Python](https://github.com/mcp-auth/python) para instalação e uso.
:::
-Neste tutorial, vamos construir um servidor MCP de gerenciador de tarefas com autenticação e autorização de usuários. Seguindo a especificação MCP mais recente, nosso servidor MCP atuará como um **Resource Server** OAuth 2.0 que valida tokens de acesso e aplica permissões baseadas em escopo.
+Neste tutorial, vamos construir um servidor MCP de gerenciador de tarefas com Autenticação (Authentication) e Autorização (Authorization) de usuários. Seguindo a especificação mais recente do MCP, nosso servidor MCP atuará como um **Servidor de Recursos (Resource Server)** OAuth 2.0 que valida tokens de acesso e aplica permissões baseadas em escopo.
Após concluir este tutorial, você terá:
-- ✅ Uma compreensão básica de como configurar controle de acesso baseado em papel (RBAC) em seu servidor MCP.
-- ✅ Um servidor MCP que atua como Resource Server, consumindo tokens de acesso emitidos por um Authorization Server.
+- ✅ Uma compreensão básica de como configurar o controle de acesso baseado em papel (RBAC) em seu servidor MCP.
+- ✅ Um servidor MCP que atua como um Servidor de Recursos, consumindo tokens de acesso emitidos por um Servidor de Autorização.
- ✅ Uma implementação funcional de aplicação de permissões baseadas em escopo para operações de tarefas.
## Visão geral \{#overview}
O tutorial envolverá os seguintes componentes:
-- **Cliente MCP (VS Code)**: Um editor de código com suporte MCP integrado que atua como cliente OAuth 2.0/OIDC. Ele inicia o fluxo de autorização com o authorization server e obtém tokens de acesso para autenticar requisições ao servidor MCP.
-- **Authorization Server**: Um provedor OAuth 2.1 ou OpenID Connect que gerencia identidades de usuários, autentica usuários e emite tokens de acesso com escopos apropriados para clientes autorizados.
-- **Servidor MCP (Resource Server)**: De acordo com a especificação MCP mais recente, o servidor MCP atua como Resource Server no framework OAuth 2.0. Ele valida tokens de acesso emitidos pelo authorization server e aplica permissões baseadas em escopo para operações de tarefas.
+- **Cliente MCP (VS Code)**: Um editor de código com suporte MCP integrado que atua como um cliente OAuth 2.0/OIDC. Ele inicia o fluxo de autorização com o servidor de autorização e obtém tokens de acesso para autenticar solicitações ao servidor MCP.
+- **Servidor de Autorização**: Um provedor OAuth 2.1 ou OpenID Connect que gerencia identidades de usuários, autentica usuários e emite tokens de acesso com escopos apropriados para clientes autorizados.
+- **Servidor MCP (Servidor de Recursos)**: De acordo com a especificação mais recente do MCP, o servidor MCP atua como um Servidor de Recursos no framework OAuth 2.0. Ele valida tokens de acesso emitidos pelo servidor de autorização e aplica permissões baseadas em escopo para operações de tarefas.
Esta arquitetura segue o fluxo padrão do OAuth 2.0 onde:
- O **VS Code** solicita recursos protegidos em nome do usuário
-- O **Authorization Server** autentica o usuário e emite tokens de acesso
+- O **Servidor de Autorização** autentica o usuário e emite tokens de acesso
- O **Servidor MCP** valida tokens e serve recursos protegidos com base nas permissões concedidas
Aqui está um diagrama de alto nível da interação entre esses componentes:
@@ -40,44 +40,44 @@ Aqui está um diagrama de alto nível da interação entre esses componentes:
```mermaid
sequenceDiagram
autonumber
- participant Client as VS Code
(OAuth Client)
- participant RS as Servidor MCP
(Resource Server)
- participant AS as Authorization Server
+ participant Client as VS Code
(Cliente OAuth)
+ participant RS as Servidor MCP
(Servidor de Recursos)
+ participant AS as Servidor de Autorização
- Client->>RS: Requisição MCP (sem token)
+ Client->>RS: Solicitação MCP (sem token)
RS-->>Client: 401 Não autorizado (WWW-Authenticate)
Note over Client: Extrair URL resource_metadata
do cabeçalho WWW-Authenticate
Client->>RS: GET /.well-known/oauth-protected-resource (resource_metadata)
- RS-->>Client: Metadados do recurso protegido
(inclui URL do authorization server)
+ RS-->>Client: Metadados do recurso protegido
(inclui URL do servidor de autorização)
Client->>AS: GET /.well-known/oauth-authorization-server
- AS-->>Client: Metadados do authorization server
+ AS-->>Client: Metadados do servidor de autorização
Client->>AS: Autorização OAuth (login & consentimento)
AS-->>Client: Token de acesso
- Client->>RS: Requisição MCP (Authorization: Bearer )
+ Client->>RS: Solicitação MCP (Authorization: Bearer )
RS->>RS: Validar se o token de acesso é válido e autorizado
RS-->>Client: Resposta MCP
```
-## Entenda seu authorization server \{#understand-your-authorization-server}
+## Entenda seu servidor de autorização \{#understand-your-authorization-server}
### Tokens de acesso com escopos \{#access-tokens-with-scopes}
-Para implementar [controle de acesso baseado em papel (RBAC)](https://auth.wiki/rbac) em seu servidor MCP, seu authorization server precisa suportar a emissão de tokens de acesso com escopos. Escopos representam as permissões que um usuário recebeu.
+Para implementar [controle de acesso baseado em papel (RBAC)](https://auth.wiki/rbac) em seu servidor MCP, seu servidor de autorização precisa suportar a emissão de tokens de acesso com escopos. Escopos representam as permissões que um usuário recebeu.
[Logto](https://logto.io) oferece suporte a RBAC por meio de seus recursos de API (conforme [RFC 8707: Resource Indicators for OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707)) e funcionalidades de papéis. Veja como configurar:
-1. Faça login no [Logto Console](https://cloud.logto.io) (ou em seu Logto Console auto-hospedado)
+1. Faça login no [Logto Console](https://cloud.logto.io) (ou no seu Logto Console auto-hospedado)
2. Crie recurso de API e escopos:
- - Vá em "API Resources"
- - Crie um novo recurso de API chamado "Todo Manager"
+ - Vá em "Recursos de API"
+ - Crie um novo recurso de API chamado "Gerenciador de Tarefas"
- Adicione os seguintes escopos:
- `create:todos`: "Criar novas tarefas"
- `read:todos`: "Ler todas as tarefas"
@@ -85,16 +85,16 @@ Para implementar [controle de acesso baseado em papel (RBAC)](https://auth.wiki/
3. Crie papéis (recomendado para facilitar o gerenciamento):
- - Vá em "Roles"
+ - Vá em "Papéis"
- Crie um papel "Admin" e atribua todos os escopos (`create:todos`, `read:todos`, `delete:todos`)
- Crie um papel "User" e atribua apenas o escopo `create:todos`
4. Atribua permissões:
- - Vá em "Users"
+ - Vá em "Usuários"
- Selecione um usuário
- Você pode:
- - Atribuir papéis na aba "Roles" (recomendado)
- - Ou atribuir escopos diretamente na aba "Permissions"
+ - Atribuir papéis na aba "Papéis" (recomendado)
+ - Ou atribuir escopos diretamente na aba "Permissões"
Os escopos serão incluídos na reivindicação `scope` do token de acesso JWT como uma string separada por espaços.
@@ -103,50 +103,50 @@ Os escopos serão incluídos na reivindicação `scope` do token de acesso JWT c
Provedores OAuth 2.0 / OIDC normalmente suportam controle de acesso baseado em escopo. Ao implementar RBAC:
-1. Defina os escopos necessários em seu authorization server
+1. Defina os escopos necessários em seu servidor de autorização
2. Configure seu cliente para solicitar esses escopos durante o fluxo de autorização
-3. Certifique-se de que seu authorization server inclua os escopos concedidos no token de acesso
+3. Certifique-se de que seu servidor de autorização inclua os escopos concedidos no token de acesso
4. Os escopos geralmente são incluídos na reivindicação `scope` do token de acesso JWT
Consulte a documentação do seu provedor para detalhes específicos sobre:
- Como definir e gerenciar escopos
- Como os escopos são incluídos no token de acesso
-- Quaisquer recursos adicionais de RBAC como gerenciamento de papéis
+- Quaisquer recursos adicionais de RBAC, como gerenciamento de papéis
### Validando tokens e verificando permissões \{#validating-tokens-and-checking-permissions}
-De acordo com a especificação MCP mais recente, o servidor MCP atua como **Resource Server** no framework OAuth 2.0. Como Resource Server, o servidor MCP tem as seguintes responsabilidades:
+De acordo com a especificação mais recente do MCP, o servidor MCP atua como um **Servidor de Recursos (Resource Server)** no framework OAuth 2.0. Como Servidor de Recursos, o servidor MCP tem as seguintes responsabilidades:
-1. **Validação de token**: Verificar a autenticidade e integridade dos tokens de acesso recebidos dos clientes MCP
-2. **Aplicação de escopos**: Extrair e validar os escopos do token de acesso para determinar quais operações o cliente está autorizado a executar
-3. **Proteção de recursos**: Servir apenas recursos protegidos (executar ferramentas) quando o cliente apresentar tokens válidos com permissões suficientes
+1. **Validação de Token**: Verificar a autenticidade e integridade dos tokens de acesso recebidos dos clientes MCP
+2. **Aplicação de Escopo**: Extrair e validar os escopos do token de acesso para determinar quais operações o cliente está autorizado a executar
+3. **Proteção de Recursos**: Servir apenas recursos protegidos (executar ferramentas) quando o cliente apresentar tokens válidos com permissões suficientes
-Quando seu servidor MCP recebe uma requisição, ele executa o seguinte processo de validação:
+Quando seu servidor MCP recebe uma solicitação, ele executa o seguinte processo de validação:
1. Extrai o token de acesso do cabeçalho `Authorization` (formato Bearer token)
2. Valida a assinatura e expiração do token de acesso
3. Extrai os escopos e informações do usuário do token validado
4. Verifica se o token possui os escopos necessários para a operação solicitada
-Por exemplo, se um usuário quiser criar uma nova tarefa, seu token de acesso deve incluir o escopo `create:todos`. Veja como funciona o fluxo de validação do Resource Server:
+Por exemplo, se um usuário deseja criar uma nova tarefa, seu token de acesso deve incluir o escopo `create:todos`. Veja como funciona o fluxo de validação do Servidor de Recursos:
```mermaid
sequenceDiagram
participant Client as Cliente MCP
- participant Server as Servidor MCP
(Resource Server)
- participant Auth as Authorization Server
+ participant Server as Servidor MCP
(Servidor de Recursos)
+ participant Auth as Servidor de Autorização
- Client->>Server: Requisição com token de acesso
(Authorization: Bearer )
+ Client->>Server: Solicitação com token de acesso
(Authorization: Bearer )
alt Validação JWT (Preferencial)
Server->>Auth: Buscar JWKS (se não estiver em cache)
Auth-->>Server: Retornar JWKS
- Server->>Server: Validar assinatura e claims do JWT localmente
- else Introspecção de token (Alternativa)
+ Server->>Server: Validar assinatura e reivindicações do JWT localmente
+ else Introspecção de Token (Alternativa)
Server->>Auth: POST /introspect
(token=access_token)
Auth-->>Server: Retornar informações do token
(active, scope, user_id, etc.)
end
@@ -161,25 +161,25 @@ sequenceDiagram
end
```
-### Registro dinâmico de cliente \{#dynamic-client-registration}
+### Registro Dinâmico de Cliente \{#dynamic-client-registration}
-O Registro Dinâmico de Cliente não é necessário para este tutorial, mas pode ser útil se você quiser automatizar o processo de registro do cliente MCP com seu authorization server. Veja [Is Dynamic Client Registration required?](/provider-list#is-dcr-required) para mais detalhes.
+O Registro Dinâmico de Cliente não é necessário para este tutorial, mas pode ser útil se você quiser automatizar o processo de registro do cliente MCP com seu servidor de autorização. Veja [O Registro Dinâmico de Cliente é necessário?](/provider-list#is-dcr-required) para mais detalhes.
-## Entenda RBAC no gerenciador de tarefas \{#understand-rbac-in-todo-manager}
+## Entenda o RBAC no gerenciador de tarefas \{#understand-rbac-in-todo-manager}
-Para fins de demonstração, implementaremos um sistema simples de controle de acesso baseado em papel (RBAC) em nosso servidor MCP de gerenciador de tarefas. Isso mostrará os princípios básicos do RBAC mantendo a implementação simples.
+Para fins de demonstração, implementaremos um sistema simples de controle de acesso baseado em papel (RBAC) em nosso servidor MCP gerenciador de tarefas. Isso mostrará os princípios básicos do RBAC mantendo a implementação simples.
:::note
-Embora este tutorial demonstre gerenciamento de escopos baseado em RBAC, é importante notar que nem todos os provedores de autenticação implementam gerenciamento de escopos por meio de papéis. Alguns provedores podem ter suas próprias implementações e mecanismos exclusivos para gerenciar controle de acesso e permissões.
+Embora este tutorial demonstre o gerenciamento de escopos baseado em RBAC, é importante observar que nem todos os provedores de autenticação implementam o gerenciamento de escopos por meio de papéis. Alguns provedores podem ter suas próprias implementações e mecanismos exclusivos para gerenciar controle de acesso e permissões.
:::
### Ferramentas e escopos \{#tools-and-scopes}
-Nosso servidor MCP de gerenciador de tarefas fornece três ferramentas principais:
+Nosso servidor MCP gerenciador de tarefas fornece três ferramentas principais:
-- `create-todo`: Criar uma nova tarefa
-- `get-todos`: Listar todas as tarefas
-- `delete-todo`: Excluir uma tarefa pelo ID
+- `create-todo`: Cria uma nova tarefa
+- `get-todos`: Lista todas as tarefas
+- `delete-todo`: Exclui uma tarefa pelo ID
Para controlar o acesso a essas ferramentas, definimos os seguintes escopos:
@@ -201,37 +201,37 @@ Definiremos dois papéis com diferentes níveis de acesso:
### Propriedade do recurso \{#resource-ownership}
-Embora a tabela de permissões acima mostre os escopos explícitos atribuídos a cada papel, há um princípio importante de propriedade do recurso a considerar:
+Embora a tabela de permissões acima mostre os escopos explícitos atribuídos a cada papel, há um princípio importante de propriedade de recurso a considerar:
- **Usuários** não possuem os escopos `read:todos` ou `delete:todos`, mas ainda podem:
- Ler suas próprias tarefas
- Excluir suas próprias tarefas
-- **Admins** possuem permissões completas (`read:todos` e `delete:todos`), permitindo:
- - Visualizar todas as tarefas do sistema
- - Excluir qualquer tarefa, independentemente da propriedade
+- **Admins** possuem permissões totais (`read:todos` e `delete:todos`), permitindo que:
+ - Visualizem todas as tarefas do sistema
+ - Excluam qualquer tarefa, independentemente da propriedade
Isso demonstra um padrão comum em sistemas RBAC onde a propriedade do recurso concede permissões implícitas aos usuários para seus próprios recursos, enquanto papéis administrativos recebem permissões explícitas para todos os recursos.
:::tip Saiba mais
-Para se aprofundar em conceitos e boas práticas de RBAC, confira [Dominando RBAC: Um exemplo abrangente do mundo real](https://blog.logto.io/mastering-rbac).
+Para se aprofundar nos conceitos e melhores práticas de RBAC, confira [Dominando RBAC: Um Exemplo Abrangente do Mundo Real](https://blog.logto.io/mastering-rbac).
:::
## Configure a autorização em seu provedor \{#configure-authorization-in-your-provider}
-Para implementar o sistema de controle de acesso que descrevemos anteriormente, você precisará configurar seu authorization server para suportar os escopos necessários. Veja como fazer isso em diferentes provedores:
+Para implementar o sistema de controle de acesso que descrevemos anteriormente, você precisará configurar seu servidor de autorização para suportar os escopos necessários. Veja como fazer isso com diferentes provedores:
[Logto](https://logto.io) oferece suporte a RBAC por meio de recursos de API e funcionalidades de papéis. Veja como configurar:
-1. Faça login no [Logto Console](https://cloud.logto.io) (ou em seu Logto Console auto-hospedado)
+1. Faça login no [Logto Console](https://cloud.logto.io) (ou no seu Logto Console auto-hospedado)
2. Crie recurso de API e escopos:
- - Vá em "API Resources"
- - Crie um novo recurso de API chamado "Todo Manager" usando `http://localhost:3001/` como indicador de recurso.
- - **Importante**: O indicador de recurso deve corresponder à URL do seu servidor MCP. Para este tutorial, usamos `http://localhost:3001/` pois nosso servidor MCP roda na porta 3001. Em produção, use a URL real do seu servidor MCP (ex: `https://seu-mcp-server.exemplo.com/`).
+ - Vá em "Recursos de API"
+ - Crie um novo recurso de API chamado "Gerenciador de Tarefas" usando `http://localhost:3001/` como indicador de recurso.
+ - **Importante**: O indicador de recurso deve corresponder à URL do seu servidor MCP. Para este tutorial, usamos `http://localhost:3001/` já que nosso servidor MCP roda na porta 3001. Em produção, use a URL real do seu servidor MCP (ex: `https://seu-servidor-mcp.exemplo.com/`).
- Crie os seguintes escopos:
- `create:todos`: "Criar novas tarefas"
- `read:todos`: "Ler todas as tarefas"
@@ -239,20 +239,20 @@ Para implementar o sistema de controle de acesso que descrevemos anteriormente,
3. Crie papéis (recomendado para facilitar o gerenciamento):
- - Vá em "Roles"
+ - Vá em "Papéis"
- Crie um papel "Admin" e atribua todos os escopos (`create:todos`, `read:todos`, `delete:todos`)
- Crie um papel "User" e atribua apenas o escopo `create:todos`
- - Na página de detalhes do papel "User", vá para a aba "General" e defina o papel "User" como o "Default role".
+ - Na página de detalhes do papel "User", vá para a aba "Geral" e defina o papel "User" como o "Papel padrão".
4. Gerencie papéis e permissões dos usuários:
- Para novos usuários:
- - Eles receberão automaticamente o papel "User" pois o definimos como padrão
+ - Eles receberão automaticamente o papel "User" já que o definimos como padrão
- Para usuários existentes:
- - Vá em "User management"
+ - Vá em "Gerenciamento de usuários"
- Selecione um usuário
- - Atribua papéis ao usuário na aba "Roles"
+ - Atribua papéis ao usuário na aba "Papéis"
-:::tip Gerenciamento de papéis programático
+:::tip Gerenciamento de Papéis Programático
Você também pode usar a [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api) do Logto para gerenciar papéis de usuários programaticamente. Isso é especialmente útil para automação ou ao construir painéis administrativos.
:::
@@ -261,11 +261,11 @@ Ao solicitar um token de acesso, o Logto incluirá os escopos na reivindicação
-Para provedores OAuth 2.0 ou OpenID Connect, você precisará configurar os escopos que representam diferentes permissões. Os passos exatos dependem do seu provedor, mas geralmente:
+Para provedores OAuth 2.0 ou OpenID Connect, você precisará configurar os escopos que representam diferentes permissões. Os passos exatos dependerão do seu provedor, mas geralmente:
1. Defina escopos:
- - Configure seu authorization server para suportar:
+ - Configure seu servidor de autorização para suportar:
- `create:todos`
- `read:todos`
- `delete:todos`
@@ -288,18 +288,18 @@ A maioria dos provedores incluirá os escopos concedidos na reivindicação `sco
:::note[Barra no final do indicador de recurso]
-Sempre inclua uma barra (`/`) no final do indicador de recurso. Devido a um bug atual no SDK oficial MCP, clientes usando o SDK adicionarão automaticamente uma barra ao final dos identificadores de recurso ao iniciar requisições de autenticação. Se seu indicador de recurso não incluir a barra, a validação do recurso falhará para esses clientes. (O VS Code não é afetado por esse bug.)
+Sempre inclua uma barra (`/`) no final do indicador de recurso. Devido a um bug atual no SDK oficial do MCP, clientes que usam o SDK adicionarão automaticamente uma barra ao final dos identificadores de recurso ao iniciar solicitações de autenticação. Se seu indicador de recurso não incluir a barra, a validação do recurso falhará para esses clientes. (O VS Code não é afetado por esse bug.)
:::
-Após configurar seu authorization server, os usuários receberão tokens de acesso contendo seus escopos concedidos. O servidor MCP usará esses escopos para determinar:
+Após configurar seu servidor de autorização, os usuários receberão tokens de acesso contendo seus escopos concedidos. O servidor MCP usará esses escopos para determinar:
- Se um usuário pode criar novas tarefas (`create:todos`)
-- Se um usuário pode visualizar todas as tarefas (`read:todos`) ou apenas as suas
-- Se um usuário pode excluir qualquer tarefa (`delete:todos`) ou apenas as suas
+- Se um usuário pode visualizar todas as tarefas (`read:todos`) ou apenas as suas próprias
+- Se um usuário pode excluir qualquer tarefa (`delete:todos`) ou apenas as suas próprias
## Configure o servidor MCP \{#set-up-the-mcp-server}
-Usaremos os [SDKs oficiais MCP](https://github.com/modelcontextprotocol) para criar nosso servidor MCP de gerenciador de tarefas.
+Usaremos os [SDKs oficiais do MCP](https://github.com/modelcontextprotocol) para criar nosso servidor MCP gerenciador de tarefas.
### Crie um novo projeto \{#create-a-new-project}
@@ -315,10 +315,10 @@ npm pkg set scripts.start="node --experimental-strip-types todo-manager.ts"
```
:::note
-Estamos usando TypeScript em nossos exemplos pois o Node.js v22.6.0+ suporta rodar TypeScript nativamente usando a flag `--experimental-strip-types`. Se você estiver usando JavaScript, o código será semelhante - apenas certifique-se de usar Node.js v22.6.0 ou superior. Veja a documentação do Node.js para detalhes.
+Estamos usando TypeScript em nossos exemplos, pois o Node.js v22.6.0+ suporta execução nativa de TypeScript usando a flag `--experimental-strip-types`. Se você estiver usando JavaScript, o código será semelhante - apenas certifique-se de usar Node.js v22.6.0 ou superior. Veja a documentação do Node.js para detalhes.
:::
-### Instale o MCP SDK e dependências \{#install-the-mcp-sdk-and-dependencies}
+### Instale o SDK MCP e dependências \{#install-the-mcp-sdk-and-dependencies}
```bash
npm install @modelcontextprotocol/sdk express zod
@@ -338,79 +338,85 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import express, { type Request, type Response } from 'express';
-// Crie um servidor MCP
-const server = new McpServer({
- name: 'Todo Manager',
- version: '0.0.0',
-});
+// Função de fábrica para criar uma instância do servidor MCP
+// No modo stateless, cada requisição precisa de sua própria instância do servidor
+const createMcpServer = () => {
+ const mcpServer = new McpServer({
+ name: 'Gerenciador de Tarefas',
+ version: '0.0.0',
+ });
-server.registerTool(
- 'create-todo',
- {
- description: 'Criar uma nova tarefa',
- inputSchema: { content: z.string() },
- },
- async ({ content }) => {
- return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'Not implemented' }) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'create-todo',
+ {
+ description: 'Criar uma nova tarefa',
+ inputSchema: { content: z.string() },
+ },
+ async ({ content }) => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Não implementado' }) }],
+ };
+ }
+ );
-server.registerTool(
- 'get-todos',
- {
- description: 'Listar todas as tarefas',
- inputSchema: {},
- },
- async () => {
- return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'Not implemented' }) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'get-todos',
+ {
+ description: 'Listar todas as tarefas',
+ inputSchema: {},
+ },
+ async () => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Não implementado' }) }],
+ };
+ }
+ );
-server.registerTool(
- 'delete-todo',
- {
- description: 'Excluir uma tarefa pelo id',
- inputSchema: { id: z.string() },
- },
- async ({ id }) => {
- return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'Not implemented' }) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'delete-todo',
+ {
+ description: 'Excluir uma tarefa pelo id',
+ inputSchema: { id: z.string() },
+ },
+ async ({ id }) => {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Não implementado' }) }],
+ };
+ }
+ );
-// Abaixo está o código boilerplate da documentação do MCP SDK
+ return mcpServer;
+};
+
+// Abaixo está o código boilerplate da documentação do SDK MCP
const PORT = 3001;
const app = express();
app.post('/', async (request: Request, response: Response) => {
- // No modo stateless, crie uma nova instância de transport e server para cada requisição
+ // No modo stateless, crie uma nova instância de transporte e servidor para cada requisição
// para garantir isolamento completo. Uma única instância causaria colisão de IDs de requisição
// quando múltiplos clientes conectam simultaneamente.
+ const mcpServer = createMcpServer();
try {
- const transport: StreamableHTTPServerTransport = new StreamableHTTPServerTransport({
+ const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
- response.on('close', async () => {
- console.log('Request closed');
- await transport.close();
- await server.close();
- });
- await server.connect(transport);
+ await mcpServer.connect(transport);
await transport.handleRequest(request, response, request.body);
+ response.on('close', () => {
+ console.log('Requisição encerrada');
+ void transport.close();
+ void mcpServer.close();
+ });
} catch (error) {
- console.error('Erro ao lidar com requisição MCP:', error);
+ console.error('Erro ao lidar com a requisição MCP:', error);
if (!response.headersSent) {
response.status(500).json({
jsonrpc: '2.0',
error: {
code: -32_603,
- message: 'Internal server error',
+ message: 'Erro interno do servidor',
},
id: null,
});
@@ -418,36 +424,6 @@ app.post('/', async (request: Request, response: Response) => {
}
});
-// Notificações SSE não suportadas no modo stateless
-app.get('/', async (request: Request, response: Response) => {
- console.log('Recebida requisição GET MCP');
- response.writeHead(405).end(
- JSON.stringify({
- jsonrpc: '2.0',
- error: {
- code: -32_000,
- message: 'Method not allowed.',
- },
- id: null,
- })
- );
-});
-
-// Encerramento de sessão não é necessário no modo stateless
-app.delete('/', async (request: Request, response: Response) => {
- console.log('Recebida requisição DELETE MCP');
- response.writeHead(405).end(
- JSON.stringify({
- jsonrpc: '2.0',
- error: {
- code: -32_000,
- message: 'Method not allowed.',
- },
- id: null,
- })
- );
-});
-
app.listen(PORT);
```
@@ -457,43 +433,43 @@ Execute o servidor com:
npm start
```
-## Integre com seu authorization server \{#integrate-with-your-authorization-server}
+## Integre com seu servidor de autorização \{#integrate-with-your-authorization-server}
-Para completar esta seção, há várias considerações a serem feitas:
+Para concluir esta seção, há várias considerações a serem feitas:
-**A URL do issuer do seu authorization server**
+**A URL do emissor do seu servidor de autorização**
-Normalmente é a URL base do seu authorization server, como `https://auth.example.com`. Alguns provedores podem ter um caminho como `https://example.logto.app/oidc`, então verifique a documentação do seu provedor.
+Normalmente é a URL base do seu servidor de autorização, como `https://auth.exemplo.com`. Alguns provedores podem ter um caminho como `https://exemplo.logto.app/oidc`, então verifique a documentação do seu provedor.
-**Como obter os metadados do authorization server**
+**Como obter os metadados do servidor de autorização**
-- Se seu authorization server estiver em conformidade com [OAuth 2.0 Authorization Server Metadata](https://datatracker.ietf.org/doc/html/rfc8414) ou [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html), você pode usar as utilidades integradas do MCP Auth para buscar os metadados automaticamente.
-- Se seu authorization server não for compatível com esses padrões, você precisará especificar manualmente a URL dos metadados ou endpoints na configuração do servidor MCP. Consulte a documentação do seu provedor para os endpoints específicos.
+- Se seu servidor de autorização está em conformidade com [OAuth 2.0 Authorization Server Metadata](https://datatracker.ietf.org/doc/html/rfc8414) ou [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html), você pode usar as utilidades integradas do MCP Auth para buscar os metadados automaticamente.
+- Se seu servidor de autorização não está em conformidade com esses padrões, você precisará especificar manualmente a URL dos metadados ou endpoints na configuração do servidor MCP. Consulte a documentação do seu provedor para os endpoints específicos.
-**Como registrar o cliente MCP em seu authorization server**
+**Como registrar o cliente MCP em seu servidor de autorização**
-- Se seu authorization server suporta [Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591), você pode pular esta etapa pois o cliente MCP se registrará automaticamente.
-- Se seu authorization server não suporta Dynamic Client Registration, você precisará registrar manualmente o cliente MCP em seu authorization server.
+- Se seu servidor de autorização suporta [Registro Dinâmico de Cliente](https://datatracker.ietf.org/doc/html/rfc7591), você pode pular esta etapa, pois o cliente MCP se registrará automaticamente.
+- Se seu servidor de autorização não suporta Registro Dinâmico de Cliente, você precisará registrar manualmente o cliente MCP em seu servidor de autorização.
-**Entenda os parâmetros de requisição de token**
+**Entenda os parâmetros de solicitação de token**
-Ao solicitar tokens de acesso de diferentes authorization servers, você encontrará várias abordagens para especificar o recurso alvo e permissões. Aqui estão os principais padrões:
+Ao solicitar tokens de acesso de diferentes servidores de autorização, você encontrará várias abordagens para especificar o recurso alvo e permissões. Aqui estão os principais padrões:
- **Baseado em indicador de recurso**:
- Usa o parâmetro `resource` para especificar a API alvo (veja [RFC 8707: Resource Indicators for OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707))
- Comum em implementações modernas de OAuth 2.0
- - Exemplo de requisição:
+ - Exemplo de solicitação:
```json
{
"resource": "http://localhost:3001/",
@@ -502,11 +478,11 @@ Ao solicitar tokens de acesso de diferentes authorization servers, você encontr
```
- O servidor emite tokens vinculados especificamente ao recurso solicitado
-- **Baseado em audience**:
+- **Baseado em audiência**:
- Usa o parâmetro `audience` para especificar o destinatário pretendido do token
- Semelhante a indicadores de recurso, mas com semânticas diferentes
- - Exemplo de requisição:
+ - Exemplo de solicitação:
```json
{
"audience": "todo-api",
@@ -515,9 +491,9 @@ Ao solicitar tokens de acesso de diferentes authorization servers, você encontr
```
- **Baseado apenas em escopo**:
- - Depende apenas de escopos sem parâmetros de recurso/audience
+ - Depende apenas de escopos sem parâmetros de recurso/audiência
- Abordagem tradicional do OAuth 2.0
- - Exemplo de requisição:
+ - Exemplo de solicitação:
```json
{
"scope": "todo-api:create todo-api:read openid profile"
@@ -526,11 +502,11 @@ Ao solicitar tokens de acesso de diferentes authorization servers, você encontr
- Frequentemente usa escopos prefixados para namespacing de permissões
- Comum em implementações OAuth 2.0 mais simples
-:::tip Boas práticas
+:::tip Melhores Práticas
- Verifique a documentação do seu provedor para os parâmetros suportados
- Alguns provedores suportam múltiplas abordagens simultaneamente
-- Indicadores de recurso fornecem melhor segurança por restrição de audience
+- Indicadores de recurso fornecem melhor segurança por restrição de audiência
- Considere usar indicadores de recurso quando disponíveis para melhor controle de acesso
:::
@@ -545,52 +521,52 @@ Embora cada provedor possa ter requisitos específicos, os passos a seguir irão
Integrar o gerenciador de tarefas com o [Logto](https://logto.io) é simples, pois é um provedor OpenID Connect que suporta indicadores de recurso e escopos, permitindo proteger sua API de tarefas com `http://localhost:3001/` como indicador de recurso.
-Como o Logto ainda não suporta Dynamic Client Registration, você precisará registrar manualmente seu cliente MCP (VS Code) como um app de terceiros em seu tenant Logto:
+Como o Logto ainda não suporta Registro Dinâmico de Cliente, você precisará registrar manualmente seu cliente MCP (VS Code) como um app de terceiros em seu tenant Logto:
-1. Faça login no [Logto Console](https://cloud.logto.io) (ou em seu Logto Console auto-hospedado).
-2. Navegue até **Applications > Third-party apps** e clique em "Create application".
-3. Selecione **Native App** como tipo de aplicação.
-4. Preencha os detalhes da aplicação:
- - **Application name**: Insira um nome para sua aplicação, ex: "MCP Client".
- - **Description**: Insira uma descrição, ex: "MCP client for VS Code".
-5. Defina os seguintes **Redirect URIs** para o VS Code:
+1. Faça login no [Logto Console](https://cloud.logto.io) (ou no seu Logto Console auto-hospedado).
+2. Navegue até **Aplicativos > Apps de terceiros** e clique em "Criar aplicativo".
+3. Selecione **Aplicativo Nativo** como tipo de aplicativo.
+4. Preencha os detalhes do aplicativo:
+ - **Nome do aplicativo**: Insira um nome, ex: "Cliente MCP".
+ - **Descrição**: Insira uma descrição, ex: "Cliente MCP para VS Code".
+5. Defina os seguintes **URIs de redirecionamento** para o VS Code:
```
http://127.0.0.1
https://vscode.dev/redirect
```
-6. Clique em "Save changes".
-7. Vá até a aba **Permissions** do app, na seção **User**, adicione as permissões `create:todos`, `read:todos` e `delete:todos` do recurso de API **Todo Manager** que você criou anteriormente.
-8. No cartão superior, você verá o valor "App ID". Copie-o para uso posterior.
+6. Clique em "Salvar alterações".
+7. Vá até a aba **Permissões** do app, na seção **Usuário**, adicione as permissões `create:todos`, `read:todos` e `delete:todos` do recurso de API **Gerenciador de Tarefas** que você criou anteriormente.
+8. No cartão superior, você verá o valor "App ID". Copie para uso posterior.
:::note
-Este é um guia genérico de integração com provedores OAuth 2.0 / OpenID Connect. Ambos seguem passos semelhantes, pois OIDC é construído sobre OAuth 2.0. Consulte a documentação do seu provedor para detalhes específicos.
+Este é um guia genérico de integração com provedores OAuth 2.0 / OpenID Connect. Ambos seguem etapas semelhantes, pois OIDC é construído sobre OAuth 2.0. Consulte a documentação do seu provedor para detalhes específicos.
:::
-Se seu provedor suporta Dynamic Client Registration, você pode pular o registro manual; caso contrário, será necessário registrar manualmente o cliente MCP:
+Se seu provedor suporta Registro Dinâmico de Cliente, você pode pular o registro manual; caso contrário, será necessário registrar manualmente o cliente MCP:
1. Faça login no console do seu provedor.
-2. Navegue até a seção "Applications" ou "Clients" e crie uma nova aplicação ou cliente.
+2. Navegue até a seção "Aplicativos" ou "Clientes" e crie um novo aplicativo ou cliente.
-3. Se seu provedor exigir um tipo de cliente, selecione "Native App" ou "Public client".
+3. Se seu provedor exigir um tipo de cliente, selecione "Aplicativo Nativo" ou "Cliente Público".
-4. Após criar a aplicação, configure os redirect URIs. Para o VS Code, adicione:
+4. Após criar o aplicativo, configure os URIs de redirecionamento. Para o VS Code, adicione:
```
http://127.0.0.1
https://vscode.dev/redirect
```
-5. Configure os escopos/permissões necessários para a aplicação:
+5. Configure os escopos/permissões necessários para o aplicativo:
```text
create:todos read:todos delete:todos
```
-6. Encontre o "Client ID" ou "Application ID" da aplicação recém-criada e copie para uso posterior.
+6. Encontre o "Client ID" ou "Application ID" do novo aplicativo e copie para uso posterior.
@@ -601,22 +577,22 @@ Primeiro, instale o SDK MCP Auth em seu projeto do servidor MCP.
-Agora precisamos inicializar o MCP Auth em seu servidor MCP. No modo de recurso protegido, você precisa configurar seus metadados de recurso incluindo os authorization servers.
+Agora precisamos inicializar o MCP Auth em seu servidor MCP. No modo de recurso protegido, você precisa configurar seus metadados de recurso incluindo os servidores de autorização.
-Existem duas formas de configurar authorization servers:
+Existem duas formas de configurar servidores de autorização:
- **Pré-busca (Recomendado)**: Use `fetchServerConfig()` para buscar os metadados antes de inicializar o MCPAuth. Isso garante que a configuração seja validada na inicialização.
-- **Descoberta sob demanda**: Forneça apenas `issuer` e `type` - os metadados serão buscados sob demanda quando necessário. Isso é útil para runtimes edge (como Cloudflare Workers) onde não é permitido fetch assíncrono no topo do código.
+- **Descoberta sob demanda**: Forneça apenas `issuer` e `type` - os metadados serão buscados sob demanda quando necessário. Útil para runtimes edge (como Cloudflare Workers) onde fetch assíncrono no topo do arquivo não é permitido.
#### Configure os metadados do recurso protegido \{#configure-protected-resource-metadata}
-Primeiro, obtenha a URL do issuer do seu authorization server:
+Primeiro, obtenha a URL do emissor do seu servidor de autorização:
-No Logto, você pode encontrar a URL do issuer na página de detalhes da sua aplicação dentro do Logto Console, na seção "Endpoints & Credentials / Issuer endpoint". Deve ser algo como `https://meu-projeto.logto.app/oidc`.
+No Logto, você pode encontrar a URL do emissor na página de detalhes do seu aplicativo dentro do Logto Console, na seção "Endpoints & Credentials / Issuer endpoint". Deve ser algo como `https://meu-projeto.logto.app/oidc`.
@@ -624,9 +600,9 @@ No Logto, você pode encontrar a URL do issuer na página de detalhes da sua apl
Para provedores OAuth 2.0, você precisará:
-1. Verificar a documentação do seu provedor para a URL do authorization server (geralmente chamada de issuer URL ou base URL)
+1. Verificar a documentação do seu provedor para a URL do servidor de autorização (geralmente chamada de issuer URL ou base URL)
2. Alguns provedores expõem isso em `https://{seu-dominio}/.well-known/oauth-authorization-server`
-3. Procure no console administrativo do seu provedor em configurações OAuth/API
+3. Procurar no console administrativo do seu provedor em configurações OAuth/API
@@ -639,12 +615,12 @@ Agora, configure os Metadados do Recurso Protegido ao construir a instância do
import { MCPAuth, fetchServerConfig } from 'mcp-auth';
-const issuerUrl = ''; // Substitua pela URL do issuer do seu authorization server
+const issuerUrl = ''; // Substitua pela URL do emissor do seu servidor de autorização
// Defina o identificador do recurso para este servidor MCP
const resourceId = 'http://localhost:3001/';
-// Pré-busque a configuração do authorization server (recomendado)
+// Pré-busca da configuração do servidor de autorização (recomendado)
const authServerConfig = await fetchServerConfig(issuerUrl, { type: 'oidc' });
// Configure o MCP Auth com os metadados do recurso protegido
@@ -662,7 +638,7 @@ const mcpAuth = new MCPAuth({
### Atualize o servidor MCP \{#update-mcp-server}
-Estamos quase lá! É hora de atualizar o servidor MCP para aplicar a rota e o middleware do MCP Auth, e então implementar o controle de acesso baseado em permissões para as ferramentas do gerenciador de tarefas com base nos escopos do usuário.
+Estamos quase lá! É hora de atualizar o servidor MCP para aplicar a rota e middleware do MCP Auth, e então implementar o controle de acesso baseado em permissões para as ferramentas do gerenciador de tarefas com base nos escopos do usuário.
Agora, aplique as rotas de metadados de recurso protegido para que clientes MCP possam recuperar os metadados esperados do recurso a partir do servidor MCP.
@@ -670,11 +646,11 @@ Agora, aplique as rotas de metadados de recurso protegido para que clientes MCP
// todo-manager.ts
// Configure as rotas de Metadados do Recurso Protegido
-// Isso expõe metadados sobre este resource server para clientes OAuth
+// Isso expõe metadados sobre este servidor de recursos para clientes OAuth
app.use(mcpAuth.protectedResourceMetadataRouter());
```
-Em seguida, aplicaremos o middleware MCP Auth ao servidor MCP. Esse middleware irá lidar com autenticação e autorização das requisições recebidas, garantindo que apenas usuários autorizados possam acessar as ferramentas do gerenciador de tarefas.
+Em seguida, aplicaremos o middleware MCP Auth ao servidor MCP. Este middleware irá lidar com a autenticação e autorização das requisições recebidas, garantindo que apenas usuários autorizados acessem as ferramentas do gerenciador de tarefas.
```ts
// todo-manager.ts
@@ -707,7 +683,7 @@ import { TodoService } from './todo-service.js';
const assertUserId = (authInfo?: AuthInfo) => {
const { subject } = authInfo ?? {};
- assert(subject, 'Invalid auth info');
+ assert(subject, 'Informação de autenticação inválida');
return subject;
};
@@ -715,104 +691,116 @@ const hasRequiredScopes = (userScopes: string[], requiredScopes: string[]): bool
return requiredScopes.every((scope) => userScopes.includes(scope));
};
+// TodoService é singleton pois precisamos compartilhar estado entre requisições
const todoService = new TodoService();
-server.registerTool(
- 'create-todo',
- {
- description: 'Criar uma nova tarefa',
- inputSchema: { content: z.string() },
- },
- ({ content }, { authInfo }) => {
- const userId = assertUserId(authInfo);
-
- /**
- * Apenas usuários com o escopo 'create:todos' podem criar tarefas
- */
- if (!hasRequiredScopes(authInfo?.scopes ?? [], ['create:todos'])) {
- throw new MCPAuthBearerAuthError('missing_required_scopes');
- }
+// Função de fábrica para criar uma instância do servidor MCP
+// No modo stateless, cada requisição precisa de sua própria instância do servidor
+const createMcpServer = () => {
+ const mcpServer = new McpServer({
+ name: 'Gerenciador de Tarefas',
+ version: '0.0.0',
+ });
- const createdTodo = todoService.createTodo({ content, ownerId: userId });
-
- return {
- content: [{ type: 'text', text: JSON.stringify(createdTodo) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'create-todo',
+ {
+ description: 'Criar uma nova tarefa',
+ inputSchema: { content: z.string() },
+ },
+ ({ content }, { authInfo }) => {
+ const userId = assertUserId(authInfo);
-server.registerTool(
- 'get-todos',
- {
- description: 'Listar todas as tarefas',
- inputSchema: {},
- },
- (_params, { authInfo }) => {
- const userId = assertUserId(authInfo);
+ /**
+ * Apenas usuários com o escopo 'create:todos' podem criar tarefas
+ */
+ if (!hasRequiredScopes(authInfo?.scopes ?? [], ['create:todos'])) {
+ throw new MCPAuthBearerAuthError('missing_required_scopes');
+ }
- /**
- * Se o usuário tem o escopo 'read:todos', pode acessar todas as tarefas (todoOwnerId = undefined)
- * Se não tem, pode acessar apenas suas próprias tarefas (todoOwnerId = userId)
- */
- const todoOwnerId = hasRequiredScopes(authInfo?.scopes ?? [], ['read:todos'])
- ? undefined
- : userId;
+ const createdTodo = todoService.createTodo({ content, ownerId: userId });
- const todos = todoService.getAllTodos(todoOwnerId);
+ return {
+ content: [{ type: 'text', text: JSON.stringify(createdTodo) }],
+ };
+ }
+ );
- return {
- content: [{ type: 'text', text: JSON.stringify(todos) }],
- };
- }
-);
+ mcpServer.registerTool(
+ 'get-todos',
+ {
+ description: 'Listar todas as tarefas',
+ inputSchema: {},
+ },
+ (_params, { authInfo }) => {
+ const userId = assertUserId(authInfo);
-server.registerTool(
- 'delete-todo',
- {
- description: 'Excluir uma tarefa pelo id',
- inputSchema: { id: z.string() },
- },
- ({ id }, { authInfo }) => {
- const userId = assertUserId(authInfo);
+ /**
+ * Se o usuário possui o escopo 'read:todos', pode acessar todas as tarefas (todoOwnerId = undefined)
+ * Se não possui, pode acessar apenas suas próprias tarefas (todoOwnerId = userId)
+ */
+ const todoOwnerId = hasRequiredScopes(authInfo?.scopes ?? [], ['read:todos'])
+ ? undefined
+ : userId;
- const todo = todoService.getTodoById(id);
+ const todos = todoService.getAllTodos(todoOwnerId);
- if (!todo) {
return {
- content: [{ type: 'text', text: JSON.stringify({ error: 'Failed to delete todo' }) }],
+ content: [{ type: 'text', text: JSON.stringify(todos) }],
};
}
+ );
+
+ mcpServer.registerTool(
+ 'delete-todo',
+ {
+ description: 'Excluir uma tarefa pelo id',
+ inputSchema: { id: z.string() },
+ },
+ ({ id }, { authInfo }) => {
+ const userId = assertUserId(authInfo);
+
+ const todo = todoService.getTodoById(id);
+
+ if (!todo) {
+ return {
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Falha ao excluir tarefa' }) }],
+ };
+ }
+
+ /**
+ * Usuários só podem excluir suas próprias tarefas
+ * Usuários com o escopo 'delete:todos' podem excluir qualquer tarefa
+ */
+ if (todo.ownerId !== userId && !hasRequiredScopes(authInfo?.scopes ?? [], ['delete:todos'])) {
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({ error: 'Falha ao excluir tarefa' }),
+ },
+ ],
+ };
+ }
+
+ const deletedTodo = todoService.deleteTodo(id);
- /**
- * Usuários só podem excluir suas próprias tarefas
- * Usuários com o escopo 'delete:todos' podem excluir qualquer tarefa
- */
- if (todo.ownerId !== userId && !hasRequiredScopes(authInfo?.scopes ?? [], ['delete:todos'])) {
return {
content: [
{
type: 'text',
- text: JSON.stringify({ error: 'Failed to delete todo' }),
+ text: JSON.stringify({
+ message: `Tarefa ${id} excluída`,
+ details: deletedTodo,
+ }),
},
],
};
}
+ );
- const deletedTodo = todoService.deleteTodo(id);
-
- return {
- content: [
- {
- type: 'text',
- text: JSON.stringify({
- message: `Todo ${id} deleted`,
- details: deletedTodo,
- }),
- },
- ],
- };
- }
-);
+ return mcpServer;
+};
```
Agora, crie o "serviço de tarefas" usado no código acima para implementar a funcionalidade relacionada:
@@ -878,7 +866,7 @@ export class TodoService {
}
```
-Parabéns! Implementamos com sucesso um servidor MCP completo com autenticação e autorização!
+Parabéns! Implementamos com sucesso um servidor MCP completo com Autenticação (Authentication) e Autorização (Authorization)!
:::info
Confira o [repositório do SDK MCP Auth Node.js](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src) para o código completo do servidor MCP (versão OIDC).
@@ -888,15 +876,15 @@ Confira o [repositório do SDK MCP Auth Node.js](https://github.com/mcp-auth/js/
Reinicie seu servidor MCP e conecte o VS Code a ele. Veja como conectar com autenticação:
-1. No VS Code, pressione `Command + Shift + P` (macOS) ou `Ctrl + Shift + P` (Windows/Linux) para abrir a Command Palette.
+1. No VS Code, pressione `Command + Shift + P` (macOS) ou `Ctrl + Shift + P` (Windows/Linux) para abrir a Paleta de Comandos.
2. Digite `MCP: Add Server...` e selecione.
3. Escolha `HTTP` como tipo de servidor.
4. Insira a URL do servidor MCP: `http://localhost:3001`
-5. Após uma requisição OAuth ser iniciada, o VS Code solicitará que você insira o **App ID**. Insira o App ID copiado do seu authorization server.
+5. Após uma solicitação OAuth ser iniciada, o VS Code solicitará que você insira o **App ID**. Insira o App ID que você copiou do seu servidor de autorização.
6. Como não temos um **App Secret** (é um cliente público), apenas pressione Enter para pular.
7. Complete o fluxo de login no seu navegador.
-Depois de fazer login e retornar ao VS Code, repita as ações do checkpoint anterior para executar as ferramentas do gerenciador de tarefas. Desta vez, você pode usar essas ferramentas com sua identidade de usuário autenticada. O comportamento das ferramentas dependerá dos papéis e permissões atribuídos ao seu usuário:
+Depois de fazer login e retornar ao VS Code, repita as ações do checkpoint anterior para executar as ferramentas do gerenciador de tarefas. Desta vez, você poderá usar essas ferramentas com sua identidade de usuário autenticada. O comportamento das ferramentas dependerá dos papéis e permissões atribuídos ao seu usuário:
- Se você estiver logado como **User** (com apenas o escopo `create:todos`):
@@ -913,7 +901,7 @@ Você pode testar esses diferentes níveis de permissão:
1. Desconectando do servidor MCP (remova a configuração do servidor no VS Code)
2. Fazendo login com outra conta de usuário que tenha papéis/permissões diferentes
-3. Testando as mesmas ferramentas novamente para observar como o comportamento muda de acordo com as permissões do usuário
+3. Tentando as mesmas ferramentas novamente para observar como o comportamento muda de acordo com as permissões do usuário
Isso demonstra como o controle de acesso baseado em papel (RBAC) funciona na prática, onde diferentes usuários têm diferentes níveis de acesso à funcionalidade do sistema.
@@ -925,9 +913,9 @@ Confira o [repositório do SDK MCP Auth Node.js](https://github.com/mcp-auth/js/
Parabéns! Você concluiu com sucesso o tutorial. Vamos recapitular o que fizemos:
-- Configuramos um servidor MCP básico com ferramentas de gerenciamento de tarefas (`create-todo`, `get-todos`, `delete-todo`)
-- Implementamos controle de acesso baseado em papel (RBAC) com diferentes níveis de permissão para usuários e admins
-- Integramos o servidor MCP com um authorization server usando MCP Auth
-- Configuramos o VS Code para autenticar usuários e usar tokens de acesso com escopos para chamar ferramentas
+- Configuração de um servidor MCP básico com ferramentas de gerenciamento de tarefas (`create-todo`, `get-todos`, `delete-todo`)
+- Implementação de controle de acesso baseado em papel (RBAC) com diferentes níveis de permissão para usuários e administradores
+- Integração do servidor MCP com um servidor de autorização usando MCP Auth
+- Configuração do VS Code para autenticar usuários e usar tokens de acesso com escopos para chamar ferramentas
Não deixe de conferir outros tutoriais e a documentação para aproveitar ao máximo o MCP Auth.
\ No newline at end of file
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
index c6a1d96..54b6f08 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
@@ -10,10 +10,10 @@ import Tabs from '@theme/Tabs';
# 教程:构建一个待办事项管理器
:::tip Python SDK 可用
-MCP Auth 也支持 Python!请查看 [Python SDK 仓库](https://github.com/mcp-auth/python) 了解安装和用法。
+MCP Auth 也支持 Python!请查看 [Python SDK 仓库](https://github.com/mcp-auth/python) 获取安装和使用方法。
:::
-在本教程中,我们将构建一个带有用户认证 (Authentication) 和授权 (Authorization) 的待办事项管理器 MCP 服务器。按照最新的 MCP 规范,我们的 MCP 服务器将作为 OAuth 2.0 **资源服务器 (Resource Server)**,用于验证访问令牌 (Access token) 并强制执行基于权限 (Scope) 的权限控制。
+在本教程中,我们将构建一个带有用户认证 (Authentication) 和授权 (Authorization) 的待办事项管理器 MCP 服务器。遵循最新的 MCP 规范,我们的 MCP 服务器将作为 OAuth 2.0 **资源服务器 (Resource Server)**,用于验证访问令牌 (Access token) 并强制执行基于权限 (Scope) 的权限控制。
完成本教程后,你将获得:
@@ -23,17 +23,17 @@ MCP Auth 也支持 Python!请查看 [Python SDK 仓库](https://github.com/mcp
## 概览 \{#overview}
-本教程涉及以下组件:
+本教程将涉及以下组件:
-- **MCP 客户端(VS Code)**:一个内置 MCP 支持的代码编辑器,作为 OAuth 2.0/OIDC 客户端。它发起与授权服务器的授权流程,并获取访问令牌 (Access token) 以认证 (Authentication) 对 MCP 服务器的请求。
+- **MCP 客户端(VS Code)**:一个内置 MCP 支持的代码编辑器,作为 OAuth 2.0/OIDC 客户端。它发起与授权服务器 (Authorization Server) 的授权流程,并获取访问令牌 (Access token) 以认证 (Authentication) 对 MCP 服务器的请求。
- **授权服务器 (Authorization Server)**:一个 OAuth 2.1 或 OpenID Connect 提供商,负责管理用户身份、认证 (Authentication) 用户,并向授权客户端签发带有相应权限 (Scope) 的访问令牌 (Access token)。
-- **MCP 服务器(资源服务器 Resource Server)**:根据最新的 MCP 规范,MCP 服务器在 OAuth 2.0 框架中作为资源服务器 (Resource Server)。它验证授权服务器签发的访问令牌 (Access token),并对待办事项操作强制执行基于权限 (Scope) 的权限控制。
+- **MCP 服务器(资源服务器 Resource Server)**:根据最新 MCP 规范,MCP 服务器在 OAuth 2.0 框架中作为资源服务器 (Resource Server)。它验证由授权服务器 (Authorization Server) 签发的访问令牌 (Access token),并对待办事项操作强制执行基于权限 (Scope) 的权限控制。
该架构遵循标准的 OAuth 2.0 流程:
- **VS Code** 代表用户请求受保护资源
- **授权服务器 (Authorization Server)** 认证 (Authentication) 用户并签发访问令牌 (Access token)
-- **MCP 服务器** 验证令牌并根据授予的权限 (Scope) 提供受保护资源
+- **MCP 服务器** 验证令牌并根据授予的权限 (Permission) 提供受保护资源
以下是这些组件之间交互的高级流程图:
@@ -61,16 +61,16 @@ sequenceDiagram
RS-->>Client: MCP 响应
```
-## 了解你的授权服务器 \{#understand-your-authorization-server}
+## 了解你的授权服务器 (Authorization Server) \{#understand-your-authorization-server}
-### 带权限 (Scope) 的访问令牌 (Access token) \{#access-tokens-with-scopes}
+### 带有权限 (Scope) 的访问令牌 (Access tokens) \{#access-tokens-with-scopes}
-要在 MCP 服务器中实现[基于角色的访问控制 (RBAC)](https://auth.wiki/rbac),你的授权服务器需要支持签发带有权限 (Scope) 的访问令牌 (Access token)。权限 (Scope) 代表用户被授予的权限。
+要在 MCP 服务器中实现[基于角色的访问控制 (RBAC)](https://auth.wiki/rbac),你的授权服务器 (Authorization Server) 需要支持签发带有权限 (Scope) 的访问令牌 (Access token)。权限 (Scope) 代表用户被授予的权限 (Permission)。
-[Logto](https://logto.io) 通过其 API 资源(符合 [RFC 8707: OAuth 2.0 的资源指示器 Resource Indicators](https://datatracker.ietf.org/doc/html/rfc8707))和角色 (Role) 功能提供 RBAC 支持。设置方法如下:
+[Logto](https://logto.io) 通过其 API 资源(符合 [RFC 8707: OAuth 2.0 资源指示器](https://datatracker.ietf.org/doc/html/rfc8707))和角色 (Role) 功能提供 RBAC 支持。设置方法如下:
1. 登录 [Logto 控制台](https://cloud.logto.io)(或你的自托管 Logto 控制台)
@@ -86,29 +86,29 @@ sequenceDiagram
3. 创建角色 (Role)(推荐,便于管理):
- 进入“角色 (Roles)”
- - 创建一个“Admin”角色,并分配所有权限 (`create:todos`, `read:todos`, `delete:todos`)
- - 创建一个“User”角色,仅分配 `create:todos` 权限
+ - 创建一个“Admin”角色,并分配所有权限 (Scope)(`create:todos`、`read:todos`、`delete:todos`)
+ - 创建一个“User”角色,仅分配 `create:todos` 权限 (Scope)
-4. 分配权限:
+4. 分配权限 (Permission):
- 进入“用户”
- 选择一个用户
- 你可以:
- - 在“角色 (Roles)”标签页分配角色(推荐)
- - 或在“权限 (Permissions)”标签页直接分配权限 (Scope)
+ - 在“角色 (Roles)”标签页分配角色 (Role)(推荐)
+ - 或直接在“权限 (Permissions)”标签页分配权限 (Scope)
-这些权限 (Scope) 会以空格分隔字符串的形式包含在 JWT 访问令牌 (Access token) 的 `scope` 声明 (Claim) 中。
+这些权限 (Scope) 会作为空格分隔的字符串包含在 JWT 访问令牌 (Access token) 的 `scope` 声明 (Claim) 中。
OAuth 2.0 / OIDC 提供商通常支持基于权限 (Scope) 的访问控制。实现 RBAC 时:
-1. 在授权服务器中定义所需的权限 (Scope)
+1. 在授权服务器 (Authorization Server) 中定义所需的权限 (Scope)
2. 配置客户端在授权流程中请求这些权限 (Scope)
-3. 确保授权服务器在访问令牌 (Access token) 中包含授予的权限 (Scope)
+3. 确保授权服务器 (Authorization Server) 在访问令牌 (Access token) 中包含授予的权限 (Scope)
4. 权限 (Scope) 通常包含在 JWT 访问令牌 (Access token) 的 `scope` 声明 (Claim) 中
-请查阅你的提供商文档,了解以下内容:
+请查阅你的提供商文档,了解:
- 如何定义和管理权限 (Scope)
- 权限 (Scope) 如何包含在访问令牌 (Access token) 中
@@ -117,22 +117,22 @@ OAuth 2.0 / OIDC 提供商通常支持基于权限 (Scope) 的访问控制。实
-### 验证令牌并检查权限 \{#validating-tokens-and-checking-permissions}
+### 验证令牌并检查权限 (Permission) \{#validating-tokens-and-checking-permissions}
-根据最新的 MCP 规范,MCP 服务器在 OAuth 2.0 框架中作为**资源服务器 (Resource Server)**。作为资源服务器 (Resource Server),MCP 服务器有以下职责:
+根据最新 MCP 规范,MCP 服务器在 OAuth 2.0 框架中作为**资源服务器 (Resource Server)**。作为资源服务器 (Resource Server),MCP 服务器有以下职责:
1. **令牌验证**:验证从 MCP 客户端收到的访问令牌 (Access token) 的真实性和完整性
-2. **权限 (Scope) 强制执行**:从访问令牌 (Access token) 中提取并验证权限 (Scope),以确定客户端被授权执行哪些操作
-3. **资源保护**:仅在客户端提供有效且权限 (Scope) 足够的令牌时,才提供受保护资源(执行工具)
+2. **权限 (Scope) 强制**:从访问令牌 (Access token) 中提取并验证权限 (Scope),以确定客户端被授权执行哪些操作
+3. **资源保护**:仅在客户端提供有效且权限 (Permission) 充足的令牌时,才提供受保护资源(执行工具)
-当你的 MCP 服务器收到请求时,会执行如下验证流程:
+当你的 MCP 服务器收到请求时,会执行以下验证流程:
1. 从 `Authorization` 头中提取访问令牌 (Access token)(Bearer token 格式)
2. 验证访问令牌 (Access token) 的签名和过期时间
3. 从已验证的令牌中提取权限 (Scope) 和用户信息
-4. 检查令牌是否包含请求操作所需的权限 (Scope)
+4. 检查令牌是否包含所请求操作所需的权限 (Scope)
-例如,如果用户想创建新的待办事项,其访问令牌 (Access token) 必须包含 `create:todos` 权限 (Scope)。以下是资源服务器 (Resource Server) 验证流程:
+例如,如果用户想要创建新的待办事项,其访问令牌 (Access token) 必须包含 `create:todos` 权限 (Scope)。以下是资源服务器 (Resource Server) 验证流程:
```mermaid
sequenceDiagram
@@ -154,23 +154,23 @@ sequenceDiagram
Server->>Server: 从已验证令牌中提取权限 (Scope) 和用户上下文
alt 拥有所需权限 (Scope)
- Server->>Server: 执行请求的操作
+ Server->>Server: 执行请求操作
Server->>Client: 返回操作结果
else 缺少所需权限 (Scope)
Server->>Client: 返回 403 Forbidden
(insufficient_scope 错误)
end
```
-### 动态客户端注册 \{#dynamic-client-registration}
+### 动态客户端注册(Dynamic Client Registration)\{#dynamic-client-registration}
-本教程不要求动态客户端注册,但如果你希望自动化 MCP 客户端与授权服务器的注册流程,可以参考 [是否需要动态客户端注册?](/provider-list#is-dcr-required) 了解详情。
+本教程不要求动态客户端注册,但如果你希望自动化 MCP 客户端与授权服务器 (Authorization Server) 的注册流程,可以参考 [是否需要动态客户端注册?](/provider-list#is-dcr-required) 获取更多信息。
## 了解待办事项管理器中的 RBAC \{#understand-rbac-in-todo-manager}
为了演示,我们将在待办事项管理器 MCP 服务器中实现一个简单的基于角色的访问控制 (RBAC) 系统。这将向你展示 RBAC 的基本原理,同时保持实现简洁。
:::note
-虽然本教程演示了基于 RBAC 的权限 (Scope) 管理,但需要注意,并非所有认证 (Authentication) 提供商都通过角色 (Role) 实现权限 (Scope) 管理。有些提供商可能有自己独特的访问控制和权限管理机制。
+虽然本教程演示了基于 RBAC 的权限 (Scope) 管理,但需要注意,并非所有认证 (Authentication) 提供商都通过角色 (Role) 实现权限 (Scope) 管理。有些提供商可能有自己独特的访问控制和权限 (Permission) 管理机制。
:::
### 工具与权限 (Scope) \{#tools-and-scopes}
@@ -179,7 +179,7 @@ sequenceDiagram
- `create-todo`:创建新的待办事项
- `get-todos`:列出所有待办事项
-- `delete-todo`:按 ID 删除待办事项
+- `delete-todo`:根据 ID 删除待办事项
为了控制对这些工具的访问,我们定义了以下权限 (Scope):
@@ -196,29 +196,29 @@ sequenceDiagram
| Admin | ✅ | ✅ | ✅ |
| User | ✅ | | |
-- **User**:普通用户,可以创建待办事项,并仅查看或删除自己的待办事项
-- **Admin**:管理员,可以创建、查看和删除所有待办事项,无论归属谁
+- **User**:普通用户,可以创建待办事项,仅能查看或删除自己的待办事项
+- **Admin**:管理员,可以创建、查看和删除所有待办事项,无论归属
-### 资源归属 \{#resource-ownership}
+### 资源归属 (Resource ownership) \{#resource-ownership}
虽然上表显示了每个角色 (Role) 明确分配的权限 (Scope),但还有一个重要的资源归属原则:
-- **User** 没有 `read:todos` 或 `delete:todos` 权限 (Scope),但他们仍然可以:
+- **User** 没有 `read:todos` 或 `delete:todos` 权限 (Scope),但仍然可以:
- 查看自己的待办事项
- 删除自己的待办事项
- **Admin** 拥有全部权限 (`read:todos` 和 `delete:todos`),可以:
- 查看系统中所有待办事项
- - 删除任意待办事项,无论归属谁
+ - 删除任意待办事项,无论归属
-这体现了 RBAC 系统中的常见模式:资源归属为用户自己的资源隐式授予权限,而管理员角色 (Role) 则对所有资源拥有显式权限。
+这展示了 RBAC 系统中的常见模式:资源归属为用户自己的资源隐式授予权限 (Permission),而管理员角色 (Role) 获得所有资源的显式权限 (Permission)。
:::tip 了解更多
-想深入了解 RBAC 概念和最佳实践,请查看 [精通 RBAC:一个全面的真实案例](https://blog.logto.io/mastering-rbac)。
+想深入了解 RBAC 概念和最佳实践,请查看 [精通 RBAC:全面的真实案例](https://blog.logto.io/mastering-rbac)。
:::
## 在你的提供商中配置授权 (Authorization) \{#configure-authorization-in-your-provider}
-要实现我们前述的访问控制系统,你需要在授权服务器中配置所需的权限 (Scope)。不同提供商的配置方法如下:
+要实现我们前面描述的访问控制系统,你需要在授权服务器 (Authorization Server) 中配置所需的权限 (Scope)。不同提供商的配置方法如下:
@@ -231,7 +231,7 @@ sequenceDiagram
- 进入“API 资源”
- 创建一个名为“Todo Manager”的新 API 资源,并使用 `http://localhost:3001/` 作为资源指示器 (Resource indicator)。
- - **重要**:资源指示器 (Resource indicator) 必须与你的 MCP 服务器 URL 完全一致。本教程使用 `http://localhost:3001/`,因为 MCP 服务器运行在 3001 端口。生产环境请使用实际 MCP 服务器 URL(如 `https://your-mcp-server.example.com/`)。
+ - **重要**:资源指示器 (Resource indicator) 必须与你的 MCP 服务器 URL 匹配。本教程使用 `http://localhost:3001/`,因为 MCP 服务器运行在 3001 端口。生产环境请使用实际 MCP 服务器 URL(如 `https://your-mcp-server.example.com/`)。
- 创建以下权限 (Scope):
- `create:todos`:“创建新的待办事项”
- `read:todos`:“读取所有待办事项”
@@ -240,32 +240,32 @@ sequenceDiagram
3. 创建角色 (Role)(推荐,便于管理):
- 进入“角色 (Roles)”
- - 创建一个“Admin”角色,并分配所有权限 (`create:todos`, `read:todos`, `delete:todos`)
- - 创建一个“User”角色,仅分配 `create:todos` 权限
+ - 创建一个“Admin”角色,并分配所有权限 (Scope)(`create:todos`、`read:todos`、`delete:todos`)
+ - 创建一个“User”角色,仅分配 `create:todos` 权限 (Scope)
- 在“User”角色详情页,切换到“常规”标签,并将“User”角色设置为“默认角色 (Default role)”。
4. 管理用户角色 (Role) 和权限 (Permission):
- 新用户:
- - 因为设置了默认角色,注册后会自动获得“User”角色
+ - 因为我们设置了默认角色 (Role),新用户会自动获得“User”角色
- 已有用户:
- 进入“用户管理”
- 选择一个用户
- - 在“角色 (Roles)”标签页为用户分配角色
+ - 在“角色 (Roles)”标签页为用户分配角色 (Role)
:::tip 编程方式管理角色 (Role)
-你也可以使用 Logto 的 [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api) 以编程方式管理用户角色 (Role)。这对于自动化用户管理或构建管理后台特别有用。
+你也可以使用 Logto 的 [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api) 以编程方式管理用户角色 (Role)。这对于自动化用户管理或构建管理后台非常有用。
:::
-请求访问令牌 (Access token) 时,Logto 会根据用户角色 (Role) 权限将权限 (Scope) 包含在令牌的 `scope` 声明 (Claim) 中。
+请求访问令牌 (Access token) 时,Logto 会根据用户角色 (Role) 权限 (Permission) 在令牌的 `scope` 声明 (Claim) 中包含相应权限 (Scope)。
-对于 OAuth 2.0 或 OpenID Connect 提供商,你需要配置代表不同权限的权限 (Scope)。具体步骤视你的提供商而定,但通常包括:
+对于 OAuth 2.0 或 OpenID Connect 提供商,你需要配置代表不同权限 (Permission) 的权限 (Scope)。具体步骤取决于你的提供商,但一般流程如下:
1. 定义权限 (Scope):
- - 配置授权服务器支持:
+ - 配置授权服务器 (Authorization Server) 支持:
- `create:todos`
- `read:todos`
- `delete:todos`
@@ -277,21 +277,21 @@ sequenceDiagram
3. 分配权限 (Permission):
- 使用你的提供商界面为用户授予相应权限 (Scope)
- - 有些提供商支持基于角色 (Role) 的管理,有些则直接分配权限 (Scope)
+ - 有些提供商支持基于角色 (Role) 的管理,另一些可能直接分配权限 (Scope)
- 查阅你的提供商文档,了解推荐做法
:::tip
-大多数提供商会将授予的权限 (Scope) 以空格分隔字符串的形式包含在访问令牌 (Access token) 的 `scope` 声明 (Claim) 中。
+大多数提供商会在访问令牌 (Access token) 的 `scope` 声明 (Claim) 中包含授予的权限 (Scope)。格式通常为空格分隔的权限 (Scope) 字符串。
:::
:::note[资源指示器 (Resource indicator) 末尾斜杠]
-资源指示器 (Resource indicator) 一定要带上末尾斜杠(`/`)。由于 MCP 官方 SDK 当前存在一个 bug,使用该 SDK 的客户端在发起认证 (Authentication) 请求时会自动在资源标识符后追加斜杠。如果你的资源指示器没有斜杠,这些客户端的资源验证会失败。(VS Code 不受此 bug 影响。)
+资源指示器 (Resource indicator) 一定要包含末尾斜杠(`/`)。由于 MCP 官方 SDK 当前存在一个 bug,使用该 SDK 的客户端在发起认证 (Authentication) 请求时会自动为资源标识符添加斜杠。如果你的资源指示器 (Resource indicator) 没有包含斜杠,这些客户端的资源验证会失败。(VS Code 不受此 bug 影响。)
:::
-配置好授权服务器后,用户将获得包含其权限 (Scope) 的访问令牌 (Access token)。MCP 服务器将使用这些权限 (Scope) 判断:
+配置好授权服务器 (Authorization Server) 后,用户将获得包含其权限 (Scope) 的访问令牌 (Access token)。MCP 服务器将使用这些权限 (Scope) 判断:
- 用户是否可以创建新的待办事项(`create:todos`)
- 用户是否可以查看所有待办事项(`read:todos`)或仅能查看自己的
@@ -315,7 +315,7 @@ npm pkg set scripts.start="node --experimental-strip-types todo-manager.ts"
```
:::note
-我们的示例使用 TypeScript,因为 Node.js v22.6.0+ 原生支持通过 `--experimental-strip-types` 运行 TypeScript。如果你使用 JavaScript,代码类似——只需确保 Node.js 版本为 v22.6.0 或更高。详见 Node.js 官方文档。
+我们的示例使用 TypeScript,因为 Node.js v22.6.0+ 原生支持通过 `--experimental-strip-types` 运行 TypeScript。如果你使用 JavaScript,代码也类似——只需确保 Node.js 版本为 v22.6.0 或更高。详情见 Node.js 官方文档。
:::
### 安装 MCP SDK 及依赖 \{#install-the-mcp-sdk-and-dependencies}
@@ -330,7 +330,7 @@ npm install @modelcontextprotocol/sdk express zod
创建名为 `todo-manager.ts` 的文件,并添加如下代码:
-(代码部分保持原样,不翻译)
+(此处代码与原文一致,保持不变)
运行服务器:
@@ -338,41 +338,41 @@ npm install @modelcontextprotocol/sdk express zod
npm start
```
-## 与授权服务器集成 \{#integrate-with-your-authorization-server}
+## 与授权服务器 (Authorization Server) 集成 \{#integrate-with-your-authorization-server}
-完成本节前,你需要考虑以下事项:
+完成本节需要考虑以下几点:
-**你的授权服务器的发行者 (Issuer) URL**
+**你的授权服务器 (Authorization Server) 的发行者 (Issuer) URL**
-通常是你的授权服务器的基础 URL,如 `https://auth.example.com`。有些提供商可能是 `https://example.logto.app/oidc`,请查阅你的提供商文档。
+通常是你的授权服务器 (Authorization Server) 的基础 URL,如 `https://auth.example.com`。有些提供商可能是 `https://example.logto.app/oidc`,请查阅你的提供商文档。
-**如何获取授权服务器元数据**
+**如何获取授权服务器 (Authorization Server) 元数据**
-- 如果你的授权服务器符合 [OAuth 2.0 授权服务器元数据](https://datatracker.ietf.org/doc/html/rfc8414) 或 [OpenID Connect 发现](https://openid.net/specs/openid-connect-discovery-1_0.html),你可以使用 MCP Auth 内置工具自动获取元数据。
+- 如果你的授权服务器 (Authorization Server) 遵循 [OAuth 2.0 授权服务器元数据](https://datatracker.ietf.org/doc/html/rfc8414) 或 [OpenID Connect 发现](https://openid.net/specs/openid-connect-discovery-1_0.html),你可以使用 MCP Auth 内置工具自动获取元数据。
- 如果不符合这些标准,你需要在 MCP 服务器配置中手动指定元数据 URL 或端点。请查阅你的提供商文档。
-**如何在授权服务器注册 MCP 客户端**
+**如何在授权服务器 (Authorization Server) 注册 MCP 客户端**
-- 如果你的授权服务器支持 [动态客户端注册](https://datatracker.ietf.org/doc/html/rfc7591),可以跳过此步骤,MCP 客户端会自动注册。
-- 如果不支持动态客户端注册,你需要手动在授权服务器注册 MCP 客户端。
+- 如果你的授权服务器 (Authorization Server) 支持 [动态客户端注册 (Dynamic Client Registration)](https://datatracker.ietf.org/doc/html/rfc7591),可以跳过此步骤,MCP 客户端会自动注册。
+- 如果不支持动态客户端注册,则需要手动在授权服务器 (Authorization Server) 注册 MCP 客户端。
**了解令牌请求参数**
-向不同授权服务器请求访问令牌 (Access token) 时,指定目标资源和权限 (Scope) 的方式各有不同。主要模式如下:
+向不同授权服务器 (Authorization Server) 请求访问令牌 (Access token) 时,指定目标资源和权限 (Permission) 的方式各有不同。主要模式如下:
- **基于资源指示器 (Resource indicator)**:
- - 使用 `resource` 参数指定目标 API(见 [RFC 8707: OAuth 2.0 的资源指示器](https://datatracker.ietf.org/doc/html/rfc8707))
+ - 使用 `resource` 参数指定目标 API(见 [RFC 8707: OAuth 2.0 资源指示器](https://datatracker.ietf.org/doc/html/rfc8707))
- 现代 OAuth 2.0 实现常见
- 示例请求:
```json
@@ -385,8 +385,8 @@ npm start
- **基于受众 (Audience)**:
- - 使用 `audience` 参数指定令牌接收方
- - 与资源指示器类似,但语义不同
+ - 使用 `audience` 参数指定令牌的目标接收者
+ - 与资源指示器 (Resource indicator) 类似,但语义不同
- 示例请求:
```json
{
@@ -397,66 +397,66 @@ npm start
- **纯权限 (Scope) 模式**:
- 仅依赖权限 (Scope),无资源/受众参数
- - 传统 OAuth 2.0 做法
+ - 传统 OAuth 2.0 方式
- 示例请求:
```json
{
"scope": "todo-api:create todo-api:read openid profile"
}
```
- - 通常用前缀权限 (Scope) 进行命名空间隔离
- - 简单 OAuth 2.0 实现常见
+ - 通常使用前缀权限 (Scope) 进行命名空间
+ - 适用于简单 OAuth 2.0 实现
:::tip 最佳实践
- 查阅你的提供商文档,了解支持哪些参数
- 有些提供商同时支持多种方式
-- 资源指示器 (Resource indicator) 通过受众限制提升安全性
-- 如可用,优先使用资源指示器 (Resource indicator) 以获得更好的访问控制
+- 资源指示器 (Resource indicator) 通过受众限制提供更好的安全性
+- 有条件时优先使用资源指示器 (Resource indicator) 以获得更好的访问控制
:::
-每个提供商可能有自己的具体要求,以下步骤将指导你如何结合 VS Code 和 MCP 服务器进行集成,并进行针对性配置。
+虽然每个提供商可能有自己的具体要求,以下步骤将指导你如何结合 VS Code 和 MCP 服务器进行针对不同提供商的配置。
### 注册 MCP 客户端为第三方应用 \{#register-mcp-client-as-a-third-party-app}
-将待办事项管理器与 [Logto](https://logto.io) 集成非常简单,因为它是支持资源指示器 (Resource indicator) 和权限 (Scope) 的 OpenID Connect 提供商,可以用 `http://localhost:3001/` 作为资源指示器保护你的 todo API。
+将待办事项管理器与 [Logto](https://logto.io) 集成非常简单,因为它是支持资源指示器 (Resource indicator) 和权限 (Scope) 的 OpenID Connect 提供商,可以用 `http://localhost:3001/` 作为资源指示器 (Resource indicator) 保护你的 todo API。
-由于 Logto 目前尚不支持动态客户端注册,你需要手动将 MCP 客户端(VS Code)注册为 Logto 租户的第三方应用:
+由于 Logto 目前尚不支持动态客户端注册 (Dynamic Client Registration),你需要手动将 MCP 客户端(VS Code)作为第三方应用注册到你的 Logto 租户:
1. 登录 [Logto 控制台](https://cloud.logto.io)(或你的自托管 Logto 控制台)。
-2. 进入 **应用程序 > 第三方应用**,点击“创建应用”。
-3. 选择 **原生应用 (Native App)** 作为应用类型。
+2. 导航到 **应用 > 第三方应用**,点击“创建应用”。
+3. 选择 **原生应用** 作为应用类型。
4. 填写应用信息:
- - **应用名称**:如“MCP Client”
- - **描述**:如“VS Code 的 MCP 客户端”
+ - **应用名称**:如 "MCP Client"
+ - **描述**:如 "MCP client for VS Code"
5. 为 VS Code 设置以下 **重定向 URI**:
```
http://127.0.0.1
https://vscode.dev/redirect
```
6. 点击“保存更改”。
-7. 进入应用的 **权限 (Permissions)** 标签页,在 **用户** 部分,添加你之前创建的 **Todo Manager** API 资源下的 `create:todos`、`read:todos` 和 `delete:todos` 权限。
-8. 在顶部卡片中,你会看到“App ID”值。复制备用。
+7. 进入应用的 **权限 (Permissions)** 标签页,在 **用户** 部分,添加你之前创建的 **Todo Manager** API 资源中的 `create:todos`、`read:todos` 和 `delete:todos` 权限 (Permission)。
+8. 在顶部卡片中,你会看到 "App ID" 值。复制备用。
:::note
-这是通用的 OAuth 2.0 / OpenID Connect 提供商集成指南。OAuth 2.0 和 OIDC 步骤类似,因为 OIDC 构建在 OAuth 2.0 之上。具体细节请查阅你的提供商文档。
+这是通用的 OAuth 2.0 / OpenID Connect 提供商集成指南。OIDC 基于 OAuth 2.0,步骤类似。具体细节请查阅你的提供商文档。
:::
-如果你的提供商支持动态客户端注册,可以跳过手动注册;否则需要手动注册 MCP 客户端:
+如果你的提供商支持动态客户端注册 (Dynamic Client Registration),可以跳过手动注册;否则需要手动注册 MCP 客户端:
1. 登录你的提供商控制台。
-2. 进入“应用程序”或“客户端”部分,创建新应用或客户端。
+2. 导航到“应用”或“客户端”部分,创建新应用或客户端。
-3. 如需选择客户端类型,选择“原生应用 (Native App)”或“公共客户端 (Public client)”。
+3. 如果需要选择客户端类型,选择“原生应用”或“公有客户端”。
4. 创建应用后,配置重定向 URI。对于 VS Code,添加如下:
@@ -465,39 +465,39 @@ npm start
https://vscode.dev/redirect
```
-5. 为应用配置所需权限 (Scope):
+5. 配置应用所需的权限 (Scope)/权限 (Permission):
```text
create:todos read:todos delete:todos
```
-6. 找到新建应用的“Client ID”或“Application ID”,复制备用。
+6. 找到新建应用的 "Client ID" 或 "Application ID",复制备用。
### 设置 MCP Auth \{#set-up-mcp-auth}
-首先,在 MCP 服务器项目中安装 MCP Auth SDK。
+首先,在你的 MCP 服务器项目中安装 MCP Auth SDK。
-现在需要在 MCP 服务器中初始化 MCP Auth。在受保护资源模式下,你需要配置资源元数据,包括授权服务器信息。
+现在我们需要在 MCP 服务器中初始化 MCP Auth。在受保护资源模式下,你需要配置资源元数据,包括授权服务器 (Authorization Server)。
-配置授权服务器有两种方式:
+有两种方式配置授权服务器 (Authorization Server):
-- **预获取(推荐)**:使用 `fetchServerConfig()` 在初始化 MCPAuth 前获取元数据,确保启动时配置已验证。
-- **按需发现**:只提供 `issuer` 和 `type`,首次需要时再获取元数据。适用于如 Cloudflare Workers 等不允许顶层异步 fetch 的边缘运行时。
+- **预获取(推荐)**:使用 `fetchServerConfig()` 在初始化 MCPAuth 前获取元数据。这样可以在启动时验证配置。
+- **按需发现**:只提供 `issuer` 和 `type`,首次需要时再获取元数据。适用于如 Cloudflare Workers 这类不允许顶层异步 fetch 的边缘运行时。
#### 配置受保护资源元数据 \{#configure-protected-resource-metadata}
-首先,获取你的授权服务器发行者 (Issuer) URL:
+首先,获取你的授权服务器 (Authorization Server) 的发行者 (Issuer) URL:
-在 Logto 中,你可以在 Logto 控制台的应用详情页“端点与凭据 / 发行者端点 (Issuer endpoint)”部分找到发行者 (Issuer) URL,格式类似 `https://my-project.logto.app/oidc`。
+在 Logto 中,你可以在 Logto 控制台的应用详情页 "Endpoints & Credentials / Issuer endpoint" 部分找到发行者 (Issuer) URL,格式如 `https://my-project.logto.app/oidc`。
@@ -505,9 +505,9 @@ npm start
对于 OAuth 2.0 提供商,你需要:
-1. 查阅你的提供商文档,获取授权服务器 URL(通常称为发行者 (Issuer) URL 或基础 URL)
+1. 查阅你的提供商文档,获取授权服务器 (Authorization Server) URL(通常称为发行者 (Issuer) URL 或基础 URL)
2. 有些提供商会在 `https://{your-domain}/.well-known/oauth-authorization-server` 暴露此信息
-3. 在提供商管理后台的 OAuth/API 设置中查找
+3. 在你的提供商管理后台的 OAuth/API 设置中查找
@@ -515,51 +515,51 @@ npm start
现在,在构建 MCP Auth 实例时配置受保护资源元数据:
-(代码部分保持原样,不翻译)
+(此处代码与原文一致,保持不变)
### 更新 MCP 服务器 \{#update-mcp-server}
-我们快完成了!现在需要更新 MCP 服务器,应用 MCP Auth 路由和中间件,并基于用户权限 (Scope) 实现待办事项工具的权限控制。
+我们快完成了!现在需要更新 MCP 服务器,应用 MCP Auth 路由和中间件函数,并基于用户权限 (Scope) 实现待办事项工具的权限控制。
-首先,应用受保护资源元数据路由,让 MCP 客户端可以从 MCP 服务器获取资源元数据。
+首先,应用受保护资源元数据路由,让 MCP 客户端可以从 MCP 服务器获取期望的资源元数据。
-(代码部分保持原样,不翻译)
+(此处代码与原文一致,保持不变)
-接下来,应用 MCP Auth 中间件到 MCP 服务器。该中间件会处理所有请求的认证 (Authentication) 和授权 (Authorization),确保只有被授权的用户才能访问待办事项工具。
+接下来,我们将把 MCP Auth 中间件应用到 MCP 服务器。该中间件将处理所有请求的认证 (Authentication) 和授权 (Authorization),确保只有被授权的用户才能访问待办事项工具。
-(代码部分保持原样,不翻译)
+(此处代码与原文一致,保持不变)
-现在,我们可以更新待办事项工具的实现,利用 MCP Auth 中间件进行认证 (Authentication) 和授权 (Authorization)。
+此时,我们可以更新待办事项工具的实现,利用 MCP Auth 中间件进行认证 (Authentication) 和授权 (Authorization)。
-(代码部分保持原样,不翻译)
+(此处代码与原文一致,保持不变)
-接下来,创建上面代码中用到的“Todo service”:
+现在,创建上述代码中用到的 "Todo service" 实现相关功能:
-创建 `todo-service.ts` 文件,实现相关功能:
+创建 `todo-service.ts` 文件:
-(代码部分保持原样,不翻译)
+(此处代码与原文一致,保持不变)
恭喜!我们已经成功实现了一个带有认证 (Authentication) 和授权 (Authorization) 的完整 MCP 服务器!
:::info
-查看 [MCP Auth Node.js SDK 仓库](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src) 获取 MCP 服务器(OIDC 版本)的完整代码。
+完整 MCP 服务器(OIDC 版本)代码请参考 [MCP Auth Node.js SDK 仓库](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src)。
:::
## 检查点:运行 `todo-manager` 工具 \{#checkpoint-run-the-todo-manager-tools}
-重启你的 MCP 服务器,并用 VS Code 连接它。以下是带认证 (Authentication) 的连接方法:
+重启你的 MCP 服务器,并用 VS Code 连接它。认证 (Authentication) 连接方法如下:
-1. 在 VS Code 中,按下 `Command + Shift + P`(macOS)或 `Ctrl + Shift + P`(Windows/Linux)打开命令面板。
-2. 输入 `MCP: Add Server...` 并选择它。
-3. 选择 `HTTP` 作为服务器类型。
+1. 在 VS Code 中按下 `Command + Shift + P`(macOS)或 `Ctrl + Shift + P`(Windows/Linux)打开命令面板
+2. 输入 `MCP: Add Server...` 并选择
+3. 选择 `HTTP` 作为服务器类型
4. 输入 MCP 服务器 URL:`http://localhost:3001`
-5. OAuth 请求发起后,VS Code 会提示你输入 **App ID**。输入你从授权服务器复制的 App ID。
-6. 因为我们没有 **App Secret**(这是公共客户端),直接回车跳过。
-7. 在浏览器中完成登录流程。
+5. OAuth 请求发起后,VS Code 会提示你输入 **App ID**。输入你从授权服务器 (Authorization Server) 复制的 App ID
+6. 因为我们没有 **App Secret**(这是公有客户端),直接回车跳过
+7. 在浏览器中完成登录流程
-登录并返回 VS Code 后,重复上一个检查点的操作,运行待办事项管理器工具。这一次,你可以用已认证 (Authentication) 的用户身份使用这些工具。工具的行为将取决于你用户的角色 (Role) 和权限 (Permission):
+登录后回到 VS Code,重复上一个检查点的操作来运行待办事项工具。这一次,你可以用认证 (Authentication) 用户身份使用这些工具。工具的行为将取决于分配给你的角色 (Role) 和权限 (Permission):
-- 如果你以 **User**(仅有 `create:todos` 权限)身份登录:
+- 如果你以 **User**(仅有 `create:todos` 权限 (Scope))身份登录:
- 可以用 `create-todo` 工具创建新待办事项
- 只能查看和删除自己的待办事项
@@ -568,27 +568,27 @@ npm start
- 如果你以 **Admin**(拥有全部权限:`create:todos`、`read:todos`、`delete:todos`)身份登录:
- 可以创建新待办事项
- 可以用 `get-todos` 工具查看系统中所有待办事项
- - 可以用 `delete-todo` 工具删除任意待办事项,无论归属谁
+ - 可以用 `delete-todo` 工具删除任意待办事项,无论归属
你可以通过以下方式测试不同权限级别:
1. 断开 MCP 服务器连接(在 VS Code 中移除服务器配置)
-2. 用拥有不同角色 (Role)/权限 (Permission) 的其他用户账号登录
-3. 再次尝试相同工具,观察因用户权限不同而产生的行为变化
+2. 用具有不同角色 (Role)/权限 (Permission) 的其他用户账号登录
+3. 再次尝试相同工具,观察因用户权限 (Permission) 不同而产生的行为变化
这展示了基于角色的访问控制 (RBAC) 在实际中的工作方式,不同用户对系统功能有不同访问级别。
:::info
-查看 [MCP Auth Node.js SDK 仓库](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src) 获取 MCP 服务器(OIDC 版本)的完整代码。
+完整 MCP 服务器(OIDC 版本)代码请参考 [MCP Auth Node.js SDK 仓库](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src)。
:::
## 结语 \{#closing-notes}
恭喜!你已成功完成本教程。让我们回顾一下所做的内容:
-- 搭建了一个基础的 MCP 服务器,包含待办事项管理工具(`create-todo`、`get-todos`、`delete-todo`)
+- 搭建了一个带有待办事项管理工具(`create-todo`、`get-todos`、`delete-todo`)的基础 MCP 服务器
- 实现了基于角色的访问控制 (RBAC),为用户和管理员设置了不同权限级别
-- 使用 MCP Auth 将 MCP 服务器与授权服务器集成
-- 配置 VS Code 认证 (Authentication) 用户,并用带权限 (Scope) 的访问令牌 (Access token) 调用工具
+- 使用 MCP Auth 将 MCP 服务器与授权服务器 (Authorization Server) 集成
+- 配置 VS Code 认证 (Authentication) 用户,并用带有权限 (Scope) 的访问令牌 (Access token) 调用工具
欢迎查阅其他教程和文档,充分发挥 MCP Auth 的强大能力。
\ No newline at end of file
diff --git a/i18n/zh-TW/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx b/i18n/zh-TW/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
index 2fdb3c1..cb1fe11 100644
--- a/i18n/zh-TW/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
+++ b/i18n/zh-TW/docusaurus-plugin-content-docs/current/tutorials/todo-manager/README.mdx
@@ -1,48 +1,48 @@
---
sidebar_position: 2
-sidebar_label: '教學:打造待辦事項管理器 (Tutorial: Build a todo manager)'
+sidebar_label: '教學:打造一個待辦事項管理器'
---
import { NpmLikeInstallation } from '@site/src/components/NpmLikeInstallation';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
-# 教學:打造待辦事項管理器 (Tutorial: Build a todo manager)
+# 教學:打造一個待辦事項管理器 (Tutorial: Build a todo manager)
:::tip Python SDK available
MCP Auth 也支援 Python!請參考 [Python SDK repository](https://github.com/mcp-auth/python) 以取得安裝與使用方式。
:::
-在本教學中,我們將建立一個具備使用者驗證 (Authentication) 與授權 (Authorization) 的待辦事項管理器 MCP 伺服器。根據最新 MCP 規範,我們的 MCP 伺服器將作為 OAuth 2.0 **資源伺服器 (Resource Server)**,負責驗證存取權杖 (Access token) 並執行基於權限範圍 (Scope) 的權限控管。
+在本教學中,我們將建立一個具備使用者驗證 (Authentication) 與授權 (Authorization) 的待辦事項 MCP 伺服器。根據最新 MCP 規範,我們的 MCP 伺服器將作為 OAuth 2.0 **資源伺服器 (Resource Server)**,負責驗證存取權杖 (Access tokens) 並執行基於權限範圍 (Scope) 的權限控管。
完成本教學後,你將會:
-- ✅ 基本瞭解如何在 MCP 伺服器中設置角色型存取控制 (RBAC, Role-based access control)
-- ✅ 擁有一個作為資源伺服器 (Resource Server) 的 MCP 伺服器,能消耗由授權伺服器 (Authorization Server) 發出的存取權杖 (Access token)
+- ✅ 基本瞭解如何在 MCP 伺服器中設定角色型存取控制 (RBAC, Role-based access control)
+- ✅ 擁有一個作為資源伺服器 (Resource Server) 的 MCP 伺服器,能消耗由授權伺服器 (Authorization Server) 發出的存取權杖 (Access tokens)
- ✅ 實作基於權限範圍 (Scope) 的待辦事項操作權限控管
## 概覽 (Overview) \{#overview}
本教學將包含以下元件:
-- **MCP 用戶端 (VS Code)**:一個內建 MCP 支援的程式碼編輯器,作為 OAuth 2.0 / OIDC 用戶端。它會與授權伺服器啟動授權流程並取得存取權杖 (Access token) 以驗證對 MCP 伺服器的請求。
-- **授權伺服器 (Authorization Server)**:一個 OAuth 2.1 或 OpenID Connect 提供者,負責管理使用者身分、驗證使用者並向授權用戶端發放帶有適當權限範圍 (Scope) 的存取權杖 (Access token)。
-- **MCP 伺服器 (資源伺服器, Resource Server)**:根據最新 MCP 規範,MCP 伺服器在 OAuth 2.0 架構中作為資源伺服器 (Resource Server)。它驗證授權伺服器發出的存取權杖 (Access token),並針對待辦事項操作執行基於權限範圍 (Scope) 的權限控管。
+- **MCP 用戶端 (VS Code)**:一個內建 MCP 支援的程式碼編輯器,作為 OAuth 2.0 / OIDC 用戶端。它會啟動授權流程,向授權伺服器取得存取權杖 (Access tokens) 以驗證對 MCP 伺服器的請求。
+- **授權伺服器 (Authorization Server)**:一個 OAuth 2.1 或 OpenID Connect 提供者,負責管理使用者身分、驗證使用者並向授權的用戶端發放帶有適當權限範圍 (Scopes) 的存取權杖 (Access tokens)。
+- **MCP 伺服器 (資源伺服器 Resource Server)**:根據最新 MCP 規範,MCP 伺服器在 OAuth 2.0 架構中作為資源伺服器 (Resource Server)。它會驗證授權伺服器發出的存取權杖,並根據權限範圍 (Scopes) 控管待辦事項操作。
此架構遵循標準 OAuth 2.0 流程:
- **VS Code** 代表使用者請求受保護資源
-- **授權伺服器 (Authorization Server)** 驗證使用者並發放存取權杖 (Access token)
+- **授權伺服器 (Authorization Server)** 驗證使用者並發出存取權杖
- **MCP 伺服器 (Resource Server)** 驗證權杖並根據授權權限提供受保護資源
-以下是這些元件互動的高階圖示:
+以下是這些元件互動的高階流程圖:
```mermaid
sequenceDiagram
autonumber
participant Client as VS Code
(OAuth 用戶端)
participant RS as MCP 伺服器
(資源伺服器)
- participant AS as 授權伺服器 (Authorization Server)
+ participant AS as 授權伺服器
Client->>RS: MCP 請求(無權杖)
RS-->>Client: 401 未授權 (WWW-Authenticate)
@@ -63,27 +63,27 @@ sequenceDiagram
## 瞭解你的授權伺服器 (Understand your authorization server) \{#understand-your-authorization-server}
-### 具備權限範圍 (Scope) 的存取權杖 (Access tokens) \{#access-tokens-with-scopes}
+### 具備權限範圍 (Scopes) 的存取權杖 (Access tokens) \{#access-tokens-with-scopes}
-若要在 MCP 伺服器中實作 [角色型存取控制 (RBAC)](https://auth.wiki/rbac),你的授權伺服器需支援發放帶有權限範圍 (Scope) 的存取權杖 (Access token)。權限範圍 (Scope) 代表使用者被授予的權限。
+若要在 MCP 伺服器中實作 [角色型存取控制 (RBAC)](https://auth.wiki/rbac),你的授權伺服器需支援發放帶有權限範圍 (Scopes) 的存取權杖。權限範圍代表使用者被授予的權限。
-[Logto](https://logto.io) 透過 API 資源(符合 [RFC 8707: Resource Indicators for OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707))與角色 (Roles) 功能支援 RBAC。設定方式如下:
+[Logto](https://logto.io) 透過其 API 資源 (API resources)(符合 [RFC 8707: Resource Indicators for OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc8707))與角色 (Roles) 功能支援 RBAC。設定方式如下:
1. 登入 [Logto Console](https://cloud.logto.io)(或你的自架 Logto Console)
2. 建立 API 資源與權限範圍 (Scopes):
- 前往「API 資源」
- - 建立名為「Todo Manager」的新 API 資源
- - 新增以下權限範圍 (Scopes):
- - `create:todos`:「建立新待辦事項」
+ - 建立一個名為「Todo Manager」的新 API 資源
+ - 新增以下權限範圍:
+ - `create:todos`:「建立新的待辦事項」
- `read:todos`:「讀取所有待辦事項」
- - `delete:todos`:「刪除任一待辦事項」
+ - `delete:todos`:「刪除任意待辦事項」
-3. 建立角色(建議,方便管理):
+3. 建立角色(建議以便管理):
- 前往「角色」
- 建立「Admin」角色並指派所有權限範圍(`create:todos`、`read:todos`、`delete:todos`)
@@ -96,49 +96,49 @@ sequenceDiagram
- 在「角色」分頁指派角色(建議)
- 或直接在「權限」分頁指派權限範圍
-這些權限範圍 (Scopes) 會以空格分隔字串的形式包含在 JWT 存取權杖 (Access token) 的 `scope` 宣告 (Claim) 中。
+這些權限範圍會以空格分隔字串的形式包含在 JWT 存取權杖的 `scope` 宣告 (Claim) 中。
OAuth 2.0 / OIDC 提供者通常支援基於權限範圍 (Scope) 的存取控制。實作 RBAC 時:
-1. 在授權伺服器中定義所需的權限範圍 (Scopes)
-2. 設定用戶端在授權流程中請求這些權限範圍
-3. 確保授權伺服器將授予的權限範圍包含在存取權杖 (Access token) 中
+1. 在授權伺服器中定義所需權限範圍
+2. 設定用戶端於授權流程中請求這些權限範圍
+3. 確保授權伺服器將授予的權限範圍包含在存取權杖中
4. 權限範圍通常會包含在 JWT 存取權杖的 `scope` 宣告 (Claim) 中
-請參閱你的提供者文件以瞭解:
+請查閱你的提供者文件以瞭解:
-- 如何定義與管理權限範圍 (Scopes)
+- 如何定義與管理權限範圍
- 權限範圍如何包含在存取權杖中
-- 是否有額外的 RBAC 功能如角色管理
+- 其他如角色管理等 RBAC 功能
### 權杖驗證與權限檢查 (Validating tokens and checking permissions) \{#validating-tokens-and-checking-permissions}
-根據最新 MCP 規範,MCP 伺服器在 OAuth 2.0 架構中作為 **資源伺服器 (Resource Server)**。作為資源伺服器,MCP 伺服器有以下職責:
+根據最新 MCP 規範,MCP 伺服器在 OAuth 2.0 架構中作為 **資源伺服器 (Resource Server)**。作為資源伺服器,MCP 伺服器需負責:
-1. **權杖驗證**:驗證從 MCP 用戶端收到的存取權杖 (Access token) 的真實性與完整性
-2. **權限範圍執行**:從存取權杖中擷取並驗證權限範圍 (Scope),以判斷用戶端被授權執行哪些操作
-3. **資源保護**:僅在用戶端提供有效且具備足夠權限的權杖時,才提供受保護資源(執行工具)
+1. **權杖驗證**:驗證從 MCP 用戶端收到的存取權杖的真實性與完整性
+2. **權限範圍檢查**:從存取權杖中擷取並驗證權限範圍,以判斷用戶端可執行哪些操作
+3. **資源保護**:僅在用戶端提供有效且具足夠權限的權杖時,才提供受保護資源(執行工具)
當 MCP 伺服器收到請求時,會執行以下驗證流程:
1. 從 `Authorization` 標頭擷取存取權杖(Bearer 權杖格式)
2. 驗證存取權杖的簽章與有效期限
3. 從已驗證的權杖中擷取權限範圍與使用者資訊
-4. 檢查權杖是否具備執行請求操作所需的權限範圍
+4. 檢查權杖是否具備執行該操作所需的權限範圍
-例如,若使用者要建立新待辦事項,其存取權杖必須包含 `create:todos` 權限範圍。以下為資源伺服器驗證流程圖:
+例如,若使用者要建立新的待辦事項,其存取權杖必須包含 `create:todos` 權限範圍。以下為資源伺服器驗證流程:
```mermaid
sequenceDiagram
participant Client as MCP 用戶端
participant Server as MCP 伺服器
(資源伺服器)
- participant Auth as 授權伺服器 (Authorization Server)
+ participant Auth as 授權伺服器
Client->>Server: 夾帶存取權杖的請求
(Authorization: Bearer )
@@ -157,35 +157,35 @@ sequenceDiagram
Server->>Server: 執行請求操作
Server->>Client: 回傳操作結果
else 欠缺所需權限範圍
- Server->>Client: 回傳 403 禁止存取
(insufficient_scope error)
+ Server->>Client: 回傳 403 Forbidden
(insufficient_scope error)
end
```
### 動態用戶端註冊 (Dynamic Client Registration) \{#dynamic-client-registration}
-本教學不需動態用戶端註冊,但若你想自動化 MCP 用戶端在授權伺服器的註冊流程,可參考 [動態用戶端註冊是否必要?](/provider-list#is-dcr-required) 以取得更多資訊。
+本教學不強制需要動態用戶端註冊,但若你想自動化 MCP 用戶端在授權伺服器的註冊流程,可參考 [是否需要動態用戶端註冊?](/provider-list#is-dcr-required) 以取得更多資訊。
## 瞭解待辦事項管理器中的 RBAC (Understand RBAC in todo manager) \{#understand-rbac-in-todo-manager}
-為了示範,我們會在待辦事項管理器 MCP 伺服器中實作一個簡單的角色型存取控制 (RBAC) 系統。這將讓你瞭解 RBAC 的基本原理,同時保持實作簡單明瞭。
+為了示範,我們會在待辦事項 MCP 伺服器中實作一個簡單的角色型存取控制 (RBAC) 系統。這將讓你瞭解 RBAC 的基本原理,同時保持實作簡潔。
:::note
-雖然本教學以 RBAC 為例進行權限範圍管理,但並非所有驗證 (Authentication) 提供者都透過角色 (Role) 來管理權限範圍 (Scope)。有些提供者可能有自己獨特的存取控制與權限管理機制。
+雖然本教學以 RBAC 為基礎進行權限範圍管理,但需注意並非所有驗證 (Authentication) 提供者都透過角色來管理權限範圍。部分提供者可能有自己獨特的存取控制與權限管理機制。
:::
### 工具與權限範圍 (Tools and scopes) \{#tools-and-scopes}
-我們的待辦事項管理器 MCP 伺服器提供三個主要工具:
+我們的待辦事項 MCP 伺服器提供三個主要工具:
-- `create-todo`:建立新待辦事項
+- `create-todo`:建立新的待辦事項
- `get-todos`:列出所有待辦事項
- `delete-todo`:依 ID 刪除待辦事項
-為控管這些工具的存取,我們定義以下權限範圍 (Scopes):
+為控管這些工具的存取,我們定義以下權限範圍:
-- `create:todos`:允許建立新待辦事項
+- `create:todos`:允許建立新的待辦事項
- `delete:todos`:允許刪除現有待辦事項
-- `read:todos`:允許查詢並取得所有待辦事項列表
+- `read:todos`:允許查詢並取得所有待辦事項清單
### 角色與權限 (Roles and permissions) \{#roles-and-permissions}
@@ -201,16 +201,16 @@ sequenceDiagram
### 資源擁有權 (Resource ownership) \{#resource-ownership}
-雖然上表明確列出每個角色被指派的權限範圍 (Scopes),但還有一個重要的資源擁有權原則:
+雖然上表明確列出每個角色被指派的權限範圍,但還有一個重要的資源擁有權原則:
- **User** 沒有 `read:todos` 或 `delete:todos` 權限範圍,但仍可:
- 讀取自己的待辦事項
- 刪除自己的待辦事項
- **Admin** 具備完整權限(`read:todos` 與 `delete:todos`),可:
- 檢視系統中所有待辦事項
- - 刪除任何待辦事項,不論擁有者
+ - 刪除任何待辦事項,不論擁有者為誰
-這展現了 RBAC 系統中常見的模式:資源擁有權會隱含授予使用者對自己資源的操作權限,而管理員角色則獲得對所有資源的明確權限。
+這展現了 RBAC 系統中常見的模式:資源擁有權會隱含授予使用者對自己資源的權限,而管理角色則獲得對所有資源的明確權限。
:::tip 深入學習
想更深入瞭解 RBAC 概念與最佳實踐,請參閱 [Mastering RBAC: A Comprehensive Real-World Example](https://blog.logto.io/mastering-rbac)。
@@ -218,52 +218,52 @@ sequenceDiagram
## 在你的提供者中設定授權 (Configure authorization in your provider) \{#configure-authorization-in-your-provider}
-要實作上述存取控制系統,你需要在授權伺服器中設定所需的權限範圍 (Scopes)。以下為不同提供者的設定方式:
+要實作上述存取控制系統,你需要在授權伺服器中設定所需的權限範圍。不同提供者的設定方式如下:
-[Logto](https://logto.io) 透過 API 資源與角色 (Roles) 功能支援 RBAC。設定方式如下:
+[Logto](https://logto.io) 透過 API 資源與角色功能支援 RBAC。設定方式如下:
1. 登入 [Logto Console](https://cloud.logto.io)(或你的自架 Logto Console)
-2. 建立 API 資源與權限範圍 (Scopes):
+2. 建立 API 資源與權限範圍:
- 前往「API 資源」
- 建立名為「Todo Manager」的新 API 資源,並將 `http://localhost:3001/` 設為資源標示符 (Resource indicator)。
- **重要**:資源標示符必須與你的 MCP 伺服器 URL 相符。本教學使用 `http://localhost:3001/`,因 MCP 伺服器運行於 3001 埠。正式環境請使用實際 MCP 伺服器 URL(如 `https://your-mcp-server.example.com/`)。
- - 建立以下權限範圍 (Scopes):
- - `create:todos`:「建立新待辦事項」
+ - 建立以下權限範圍:
+ - `create:todos`:「建立新的待辦事項」
- `read:todos`:「讀取所有待辦事項」
- - `delete:todos`:「刪除任一待辦事項」
+ - `delete:todos`:「刪除任意待辦事項」
-3. 建立角色(建議,方便管理):
+3. 建立角色(建議以便管理):
- 前往「角色」
- 建立「Admin」角色並指派所有權限範圍(`create:todos`、`read:todos`、`delete:todos`)
- 建立「User」角色並僅指派 `create:todos` 權限範圍
- - 在「User」角色詳細頁切換到「一般」分頁,將「User」設為「預設角色 (Default role)」
+ - 在「User」角色詳細頁切換到「一般」分頁,將「User」設為「預設角色」
4. 管理使用者角色與權限:
- 新使用者:
- - 會自動取得「User」角色(因已設為預設角色)
+ - 會自動獲得「User」角色(因已設為預設角色)
- 現有使用者:
- 前往「使用者管理」
- 選擇一位使用者
- 在「角色」分頁指派角色
:::tip 程式化角色管理
-你也可以使用 Logto 的 [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api) 以程式方式管理使用者角色。這對自動化使用者管理或建立管理後台特別有用。
+你也可以透過 Logto 的 [Management API](https://docs.logto.io/integrate-logto/interact-with-management-api) 程式化管理使用者角色。這對自動化使用者管理或建立管理後台特別有用。
:::
-請求存取權杖時,Logto 會根據使用者角色權限將權限範圍 (Scopes) 包含於權杖的 `scope` 宣告中。
+請求存取權杖時,Logto 會根據使用者角色權限將權限範圍包含於權杖的 `scope` 宣告中。
-對於 OAuth 2.0 或 OpenID Connect 提供者,你需設定代表不同權限的權限範圍 (Scopes)。具體步驟依提供者而異,但一般流程如下:
+對於 OAuth 2.0 或 OpenID Connect 提供者,你需要設定代表不同權限的權限範圍。具體步驟依提供者而異,但一般流程如下:
-1. 定義權限範圍 (Scopes):
+1. 定義權限範圍:
- 設定授權伺服器支援:
- `create:todos`
@@ -273,37 +273,37 @@ sequenceDiagram
2. 設定用戶端:
- 註冊或更新用戶端以請求這些權限範圍
- - 確保權限範圍包含於存取權杖中
+ - 確保權限範圍會包含於存取權杖中
3. 指派權限:
- - 透過提供者介面將適當權限範圍指派給使用者
+ - 使用提供者介面將適當權限範圍授予使用者
- 有些提供者支援基於角色的管理,有些則直接指派權限範圍
- - 請參閱提供者文件以取得建議做法
+ - 請查閱提供者文件以取得建議做法
:::tip
-大多數提供者會將授予的權限範圍包含於存取權杖的 `scope` 宣告中,格式通常為空格分隔的字串。
+大多數提供者會將授予的權限範圍包含於存取權杖的 `scope` 宣告中,格式通常為空格分隔的權限範圍字串。
:::
:::note[資源標示符結尾斜線]
-資源標示符 (Resource indicator) 請務必加上結尾斜線(`/`)。由於 MCP 官方 SDK 目前有個 bug,使用該 SDK 的用戶端在發起驗證請求時會自動於資源標示符後加上斜線。若你的資源標示符未包含斜線,這些用戶端的資源驗證將失敗。(VS Code 不受此 bug 影響。)
+資源標示符請務必加上結尾斜線(`/`)。由於 MCP 官方 SDK 目前有一個 bug,使用該 SDK 的用戶端在發起驗證請求時會自動於資源標示符後加上斜線。若你的資源標示符未包含斜線,這些用戶端的資源驗證將會失敗。(VS Code 不受此 bug 影響。)
:::
-設定好授權伺服器後,使用者將取得包含其權限範圍的存取權杖。MCP 伺服器會根據這些權限範圍判斷:
+設定好授權伺服器後,使用者將會收到包含其授權權限範圍的存取權杖。MCP 伺服器會根據這些權限範圍判斷:
- 使用者是否能建立新待辦事項(`create:todos`)
-- 使用者能否檢視所有待辦事項(`read:todos`)或僅能檢視自己的
-- 使用者能否刪除任一待辦事項(`delete:todos`)或僅能刪除自己的
+- 使用者是否能檢視所有待辦事項(`read:todos`)或僅能檢視自己的
+- 使用者是否能刪除任意待辦事項(`delete:todos`)或僅能刪除自己的
## 建立 MCP 伺服器 (Set up the MCP server) \{#set-up-the-mcp-server}
-我們將使用 [MCP 官方 SDK](https://github.com/modelcontextprotocol) 來建立待辦事項管理器 MCP 伺服器。
+我們將使用 [MCP 官方 SDK](https://github.com/modelcontextprotocol) 來建立待辦事項 MCP 伺服器。
### 建立新專案 (Create a new project) \{#create-a-new-project}
-建立新的 Node.js 專案:
+建立一個新的 Node.js 專案:
```bash
mkdir mcp-server
@@ -315,7 +315,7 @@ npm pkg set scripts.start="node --experimental-strip-types todo-manager.ts"
```
:::note
-我們範例中使用 TypeScript,因 Node.js v22.6.0+ 原生支援 `--experimental-strip-types` 執行 TypeScript。若你使用 JavaScript,程式碼大致相同,只需確保 Node.js 版本為 v22.6.0 或以上。詳情請參閱 Node.js 文件。
+我們範例中使用 TypeScript,因 Node.js v22.6.0+ 原生支援 `--experimental-strip-types` 執行 TypeScript。若你使用 JavaScript,程式碼大致相同,只需確保 Node.js 版本為 v22.6.0 或以上。詳情請參閱 Node.js 官方文件。
:::
### 安裝 MCP SDK 與相依套件 (Install the MCP SDK and dependencies) \{#install-the-mcp-sdk-and-dependencies}
@@ -330,7 +330,7 @@ npm install @modelcontextprotocol/sdk express zod
建立名為 `todo-manager.ts` 的檔案並加入以下程式碼:
-(原始程式碼略,請參考原文)
+(原始程式碼同上,請依指示複製)
啟動伺服器:
@@ -345,15 +345,15 @@ npm start
**你的授權伺服器的簽發者 (Issuer) URL**
-通常是授權伺服器的基礎 URL,例如 `https://auth.example.com`。有些提供者可能為 `https://example.logto.app/oidc`,請參閱提供者文件確認。
+通常是你的授權伺服器基礎 URL,例如 `https://auth.example.com`。部分提供者可能為 `https://example.logto.app/oidc`,請查閱提供者文件確認。
**如何取得授權伺服器中繼資料**
-- 若授權伺服器符合 [OAuth 2.0 授權伺服器中繼資料](https://datatracker.ietf.org/doc/html/rfc8414) 或 [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html),可用 MCP Auth 內建工具自動取得中繼資料。
-- 若不符合上述標準,需手動於 MCP 伺服器設定中指定中繼資料 URL 或端點。請參閱提供者文件。
+- 若你的授權伺服器符合 [OAuth 2.0 授權伺服器中繼資料](https://datatracker.ietf.org/doc/html/rfc8414) 或 [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html),可用 MCP Auth 內建工具自動取得中繼資料。
+- 若不符合,需手動於 MCP 伺服器設定中指定中繼資料 URL 或端點。請查閱提供者文件。
@@ -405,31 +405,31 @@ npm start
}
```
- 常見於簡單 OAuth 2.0 實作,會用前綴命名空間
- - ...
+ - 權限控管較粗略
:::tip 最佳實踐
-- 請參閱提供者文件以確認支援哪些參數
+- 查閱提供者文件以確認支援哪些參數
- 有些提供者同時支援多種方式
- 資源標示符可提升安全性(限制受眾)
-- 若可用,建議優先使用資源標示符以加強存取控管
+- 建議有支援時優先使用資源標示符
:::
-每個提供者可能有不同需求,以下步驟將指引你如何依提供者設定 VS Code 與 MCP 伺服器。
+每個提供者可能有不同細節,以下步驟將引導你整合 VS Code 與 MCP 伺服器,並進行提供者專屬設定。
### 註冊 MCP 用戶端為第三方應用 (Register MCP client as a third-party app) \{#register-mcp-client-as-a-third-party-app}
-將待辦事項管理器整合至 [Logto](https://logto.io) 非常簡單,因其為支援資源標示符與權限範圍的 OpenID Connect 提供者,可用 `http://localhost:3001/` 作為資源標示符保護你的 todo API。
+將待辦事項管理器整合至 [Logto](https://logto.io) 很簡單,因其為支援資源標示符與權限範圍的 OpenID Connect 提供者,可用 `http://localhost:3001/` 作為資源標示符保護你的 todo API。
-由於 Logto 尚未支援動態用戶端註冊,你需手動將 MCP 用戶端(VS Code)註冊為 Logto 租戶的第三方應用:
+由於 Logto 尚未支援動態用戶端註冊,你需手動將 MCP 用戶端(VS Code)註冊為 Logto 租戶中的第三方應用:
1. 登入 [Logto Console](https://cloud.logto.io)(或你的自架 Logto Console)。
-2. 前往 **應用程式 > 第三方應用** 並點擊「建立應用程式」。
+2. 前往 **應用程式 > 第三方應用**,點擊「建立應用程式」。
3. 選擇 **原生應用 (Native App)** 作為應用程式類型。
4. 填寫應用程式資訊:
- **應用程式名稱**:如 "MCP Client"
@@ -441,24 +441,24 @@ npm start
```
6. 點擊「儲存變更」。
7. 前往應用程式的 **權限** 分頁,在 **User** 區段,新增你先前建立的 **Todo Manager** API 資源中的 `create:todos`、`read:todos`、`delete:todos` 權限。
-8. 在頂部卡片可看到「App ID」,請複製以備後用。
+8. 在頂部卡片可看到「App ID」值,複製以備後用。
:::note
-這是通用的 OAuth 2.0 / OpenID Connect 提供者整合指引。兩者步驟類似,因 OIDC 建立於 OAuth 2.0 之上。請參閱你的提供者文件以取得細節。
+這是通用 OAuth 2.0 / OpenID Connect 提供者整合指引。OIDC 建立於 OAuth 2.0 之上,兩者步驟類似。請查閱你的提供者文件以取得細節。
:::
若你的提供者支援動態用戶端註冊,可略過手動註冊;否則需手動註冊 MCP 用戶端:
-1. 登入提供者管理後台。
+1. 登入你的提供者管理後台。
2. 前往「應用程式」或「用戶端」區,建立新應用程式或用戶端。
-3. 若需選擇用戶端類型,請選「原生應用 (Native App)」或「公開用戶端 (Public client)」。
+3. 若需選擇用戶端類型,請選擇「原生應用 (Native App)」或「公開用戶端 (Public client)」。
-4. 建立應用程式後,設定 Redirect URI。對 VS Code,請新增:
+4. 建立應用程式後,設定 Redirect URI。對於 VS Code,請加入:
```
http://127.0.0.1
@@ -471,7 +471,7 @@ npm start
create:todos read:todos delete:todos
```
-6. 找到新應用程式的「Client ID」或「Application ID」並複製備用。
+6. 找到新應用程式的「Client ID」或「Application ID」,複製以備後用。
@@ -482,16 +482,16 @@ npm start
-接著初始化 MCP Auth。以受保護資源模式,你需設定資源中繼資料 (Resource metadata),包含授權伺服器資訊。
+接著初始化 MCP Auth。以受保護資源模式,你需設定資源中繼資料,包括授權伺服器。
有兩種設定授權伺服器的方式:
-- **預先取得(建議)**:用 `fetchServerConfig()` 於初始化前取得中繼資料,確保啟動時即驗證設定。
-- **隨需探索**:僅提供 `issuer` 與 `type`,首次需要時才取得中繼資料。適用於無法在頂層 async fetch 的環境(如 Cloudflare Workers)。
+- **預先擷取(建議)**:使用 `fetchServerConfig()` 於初始化 MCPAuth 前先取得中繼資料,確保啟動時即驗證設定。
+- **隨需探索**:僅提供 `issuer` 與 `type`,首次需要時才擷取中繼資料。適合無法在頂層 async fetch 的 edge runtime(如 Cloudflare Workers)。
#### 設定受保護資源中繼資料 (Configure protected resource metadata) \{#configure-protected-resource-metadata}
-首先,取得授權伺服器的簽發者 (Issuer) URL:
+首先,取得你的授權伺服器簽發者 (Issuer) URL:
@@ -505,7 +505,7 @@ npm start
對於 OAuth 2.0 提供者:
-1. 請參閱提供者文件取得授權伺服器 URL(常稱 issuer URL 或 base URL)
+1. 查閱提供者文件取得授權伺服器 URL(通常稱為 issuer URL 或 base URL)
2. 有些提供者會在 `https://{your-domain}/.well-known/oauth-authorization-server` 提供
3. 也可於管理後台 OAuth / API 設定中查找
@@ -515,27 +515,29 @@ npm start
現在,於建立 MCP Auth 實例時設定受保護資源中繼資料:
-(原始程式碼略,請參考原文)
+(原始程式碼同上,請依指示複製)
### 更新 MCP 伺服器 (Update MCP server) \{#update-mcp-server}
快完成了!現在要將 MCP Auth 路由與中介軟體 (middleware) 套用到 MCP 伺服器,並根據使用者權限範圍實作待辦事項工具的權限控管。
-首先,套用受保護資源中繼資料路由,讓 MCP 用戶端能從 MCP 伺服器取得資源中繼資料。
+首先,套用受保護資源中繼資料路由,讓 MCP 用戶端能從 MCP 伺服器取得預期的資源中繼資料。
-(原始程式碼略,請參考原文)
+(原始程式碼同上,請依指示複製)
-接著,套用 MCP Auth 中介軟體,處理進入請求的驗證 (Authentication) 與授權 (Authorization),確保只有授權使用者能存取待辦事項工具。
+接著,將 MCP Auth 中介軟體套用到 MCP 伺服器。此中介軟體會處理所有進來請求的驗證 (Authentication) 與授權 (Authorization),確保只有授權使用者能存取待辦事項工具。
-(原始程式碼略,請參考原文)
+(原始程式碼同上,請依指示複製)
現在可以更新待辦事項工具的實作,讓其利用 MCP Auth 中介軟體進行驗證與授權。
-(原始程式碼略,請參考原文)
+(原始程式碼同上,請依指示複製)
+
+接著,建立上述程式碼中用到的「Todo service」:
-最後,建立上述程式碼中用到的「Todo service」:
+建立 `todo-service.ts` 檔案:
-(原始程式碼略,請參考原文)
+(原始程式碼同上,請依指示複製)
恭喜!你已成功實作一個具備驗證 (Authentication) 與授權 (Authorization) 的完整 MCP 伺服器!
@@ -547,34 +549,34 @@ npm start
重啟 MCP 伺服器並用 VS Code 連線。連線並驗證的步驟如下:
-1. 在 VS Code 按下 `Command + Shift + P`(macOS)或 `Ctrl + Shift + P`(Windows / Linux)開啟命令面板
+1. 在 VS Code 按下 `Command + Shift + P`(macOS)或 `Ctrl + Shift + P`(Windows/Linux)開啟指令面板
2. 輸入 `MCP: Add Server...` 並選擇
3. 選擇 `HTTP` 作為伺服器類型
4. 輸入 MCP 伺服器 URL:`http://localhost:3001`
-5. 啟動 OAuth 請求後,VS Code 會提示你輸入 **App ID**,請輸入你從授權伺服器複製的 App ID
-6. 因為沒有 **App Secret**(屬於公開用戶端),直接按 Enter 跳過
+5. 當 OAuth 請求啟動時,VS Code 會提示你輸入 **App ID**,請輸入你從授權伺服器複製的 App ID
+6. 因為我們沒有 **App Secret**(屬於公開用戶端),直接按 Enter 跳過
7. 在瀏覽器完成登入流程
-登入並返回 VS Code 後,重複前一檢查點的操作以執行待辦事項工具。這次你將以已驗證的使用者身分使用這些工具,工具行為將依你被指派的角色與權限而異:
+登入並返回 VS Code 後,重複前一檢查點的操作以執行待辦事項工具。這次你將以已驗證的使用者身分使用這些工具,工具行為會依你被指派的角色與權限而異:
-- 若以 **User**(僅有 `create:todos` 權限範圍)登入:
+- 若你以 **User**(僅有 `create:todos` 權限範圍)登入:
- 可用 `create-todo` 工具建立新待辦事項
- 只能檢視與刪除自己的待辦事項
- 無法看到或刪除其他使用者的待辦事項
-- 若以 **Admin**(具備所有權限範圍:`create:todos`、`read:todos`、`delete:todos`)登入:
+- 若你以 **Admin**(擁有所有權限範圍:`create:todos`、`read:todos`、`delete:todos`)登入:
- 可建立新待辦事項
- 可用 `get-todos` 工具檢視系統所有待辦事項
- 可用 `delete-todo` 工具刪除任何待辦事項,不論擁有者
-你可以這樣測試不同權限層級:
+你可以透過以下方式測試不同權限層級:
1. 斷開 MCP 伺服器連線(於 VS Code 移除伺服器設定)
-2. 以不同角色 / 權限的帳號重新登入
+2. 以不同角色/權限的帳號登入
3. 再次嘗試相同工具,觀察行為如何隨使用者權限變化
-這展現了角色型存取控制 (RBAC) 的實際運作,不同使用者對系統功能有不同存取層級。
+這實際展示了角色型存取控制 (RBAC) 的運作,不同使用者對系統功能有不同存取層級。
:::info
完整 MCP 伺服器(OIDC 版本)程式碼請參考 [MCP Auth Node.js SDK repository](https://github.com/mcp-auth/js/blob/master/packages/sample-servers/src)。