OAuth für delegierte Agenten, scoped Tokens für B2B, anonym für Read-only. Rate-Limiting, Logging und der Auth-Entscheidungsbaum für MCP-Server.
DE

MCP-Authentifizierungsmuster: OAuth, Tokens und wann was

4.60 /5 - (8 Stimmen )
Zuletzt überprüft: 1. Mai 2026
8Min. Lesezeit
Leitfaden
500+ WP-Projekte
KI-Integration

#MCP-Authentifizierungsmuster: OAuth, Tokens und wann was

Die Model-Context-Protocol-Spezifikation (modelcontextprotocol.io) definiert Transporte und Primitive. Sie definiert Authentifizierung nicht. Das ist richtig, denn Authentifizierung ist eine Transport- und Deployment-Sorge, keine Protokoll-Sorge. Es ist auch die Quelle des häufigsten Produktionsfehlers, den ich sehe: ein MCP-Server geht ohne Auth ans Netz und exponiert Tools, die Zustand verändern. In DACH-Projekten kommt dazu, dass DSGVO Art. 32 ohnehin angemessene technische Maßnahmen verlangt, sobald personenbezogene Daten im Spiel sind.

Dieser Artikel verankert sich am Pillar MCP-Server-Entwicklungsservice.

#TL;DR

  • Read-only auf öffentlichen Daten mit Rate-Limit ist der einzige legitime Anonym-Fall.
  • Scoped API-Tokens mit gehashter Speicherung und kurzer TTL decken B2B und Headless-Flows ab.
  • OAuth 2.1 mit PKCE deckt Konsumenten-Assistenten ab, die für eingeloggte Nutzer handeln.
  • Rate-Limiting hängt am Principal; mutierende Tools bekommen ein engeres Bucket.
  • Jedes Auth-Ereignis wird geloggt: ausgegeben, verwendet, widerrufen, gescheitert.

#Der Entscheidungsbaum

Ich gehe vor jeder Auth-Wahl dieselben fünf Fragen durch:

  1. Verändert irgendein Tool Zustand? Wenn ja, anonym ist vom Tisch.
  2. Handelt der Agent im Namen eines konkreten menschlichen Endnutzers? Wenn ja, OAuth.
  3. Handelt der Agent als B2B-Integration ohne menschlichen Endnutzer? Wenn ja, scoped API-Token.
  4. Ist die Datenoberfläche im öffentlichen Internet erreichbar? Wenn ja, Rate-Limiting ist Pflicht.
  5. Mischen sich mutierende und Read-only-Tools im selben Server? Wenn ja, Auth pro Tool, nicht pro Server.

Der Entscheidungsbaum mappt auf drei Muster:

MusterWann nutzenUmsetzung
Anonym + IP-Rate-LimitÖffentlicher Katalog, Read-only, begrenzte LastWorker prüft nur das IP-Bucket
Scoped API-TokenB2B-Integration, Headless-Agenten-Runtime, kein menschlicher EndnutzerJWT mit Claims, gehashte Speicherung, Rotation
OAuth 2.1 + PKCEKonsumenten-Agent für eingeloggten NutzerStandard-Authorization-Code-Flow

Die Muster schließen sich nicht aus. Ein realer Produktionsserver fährt oft alle drei, mit jedem Tool getaggt mit dem nötigen Scope.

#Muster eins: anonymer Read-only mit Rate-Limit

Ein Katalog-Browse-Tool, das /wp-json/wc/v3/products?stock_status=instock kapselt, exponiert dieselben Daten, die die öffentliche Website ohnehin ausliefert. Auth davorzusetzen verbessert die Sicherheitslage nicht; es senkt nur Erreichbarkeit. Die legitime Bedrohung ist Last: eine Agenten-Schleife oder ein Wettbewerber-Scrape kann den WooCommerce-Origin hämmern.

Die Umsetzung:

async function checkAnonymousRateLimit(request: Request, env: Env): Promise<boolean> {
  const ip = request.headers.get("CF-Connecting-IP") ?? "unknown";
  const key = `rl:anon:${ip}`;
  const count = Number((await env.RATE_LIMIT.get(key)) ?? "0");
  if (count >= 60) return false;
  await env.RATE_LIMIT.put(key, String(count + 1), { expirationTtl: 60 });
  return true;
}

60 Requests pro Minute pro IP ist mein Default. Der KV-basierte Zähler ist approximativ (eventually consistent bei KV-Writes); für engere Limits sind Durable Objects oder Cloudflares natives Rate-Limiting-Binding das richtige Werkzeug.

Was dieses Muster nicht abdeckt: jedes Tool, das nutzerspezifische Daten zurückgibt, jedes Tool, das Zustand verändert, jedes Tool, das Bestand für nicht öffentliche Produkte preisgibt. Diese brauchen einen echten Principal.

#Muster zwei: scoped API-Tokens für B2B

Der B2B-Fall: eine Partner-Integration liefert einen Agenten aus, der deinen MCP-Server im Namen der Partner-Organisation aufruft, nicht im Namen eines konkreten menschlichen Endnutzers. Beispiele sind ein Inventar-Sync-Agent bei einem Großhändler, eine Marktplatz-Integration bei einem Aggregator, ein Analytik-Agent, der Bestelltrends an ein BI-Tool meldet.

Der Ablauf:

  1. Eine Admin-Person im WordPress-Backend legt ein Token an, mit Name, Scope-Set (catalogue:read, inventory:read, orders:write) und Ablauf (Default 90 Tage).
  2. Das Token wird der Admin-Person einmal angezeigt, dann als SHA-256-Hash plus Scope-Set plus Ablauf gespeichert.
  3. Der Partner trägt das Token in seinem MCP-Client als Authorization: Bearer <token>-Header ein.
  4. Der Worker hasht das eingehende Token und schlägt den Hash in KV nach. Stimmt der Hash, liegt der Ablauf in der Zukunft und ist der für das Tool nötige Scope im Scope-Set, läuft der Aufruf weiter.
async function verifyApiToken(authHeader: string | null, env: Env): Promise<TokenContext | null> {
  if (!authHeader?.startsWith("Bearer ")) return null;
  const token = authHeader.slice(7);
  const hash = await sha256(token);
  const record = await env.TOKENS.get(`tok:${hash}`, "json") as TokenRecord | null;
  if (!record) return null;
  if (record.expiresAt < Date.now()) return null;
  return { tokenId: record.id, scopes: record.scopes, principal: record.principal };
}

function requireScope(ctx: TokenContext, scope: string): void {
  if (!ctx.scopes.includes(scope)) {
    throw new McpError("forbidden", `Tool requires scope ${scope}`);
  }
}

Zwei operative Gewohnheiten halten dieses Muster sauber:

Rotation, keine Ewigkeit. Ein Token, das nie abläuft, ist ein Token, das in sechs Monaten in einem öffentlichen GitHub-Repo landet. 90 Tage Default mit Renewal-Flow, der altes und neues Token sieben Tage überlappt, ist das Muster, das echte Partner überlebt.

Gehashte Speicherung, kein Klartext. Wird dein KV exfiltriert, sind die Hashes ohne Originaltoken nutzlos. Hattest du Klartext-Tokens, braucht jede Partner-Integration sofortige Rotation. Der Kostenunterschied bei der Ausgabe ist ein einziger sha256-Aufruf.

#Muster drei: OAuth 2.1 mit PKCE für delegierte Agenten

Der Konsumentenfall: ein Nutzer öffnet Claude Desktop, verbindet sein Konto auf deinem Shop per OAuth und bittet den Agenten, “zeige meine letzte Bestellung”. Der Agent muss deinen MCP-Server jetzt mit Credentials anrufen, die “ich handle für Nutzer 4231” sagen.

OAuth 2.1 (draft-ietf-oauth-v2-1) ist das konsolidierte Profil. PKCE (RFC 7636) ist Pflicht für öffentliche Clients (das schließt Desktop-Assistenten ohne vertraulichen serverseitigen Anteil ein).

Der Flow in fünf Etappen:

  1. Der MCP-Host öffnet einen Browser auf deinen Authorization-Endpoint mit response_type=code, code_challenge=<S256-Hash des Verifier> und den geforderten Scopes.
  2. Der Nutzer loggt sich auf deiner WordPress-Site (oder bei deinem Auth-Provider) ein und genehmigt die Scopes.
  3. Dein Authorization-Endpoint redirected zurück an den Host mit einem einmaligen Authorization-Code.
  4. Der Host tauscht den Code plus den ursprünglichen code_verifier an deinem Token-Endpoint gegen ein Access-Token (kurze TTL, 1 Stunde) und ein Refresh-Token (längere TTL, 30 Tage).
  5. Der Host ruft den MCP-Server mit Authorization: Bearer <access_token> auf. Der Worker prüft Signatur, Ablauf und Scope-Set des Tokens gegen das aufgerufene Tool.

Das Access-Token ist ein signiertes JWT. Der Worker prüft es mit der Web-Crypto-API (Cloudflare-Workers-Referenz) ohne externe Bibliothek:

async function verifyJwt(token: string, env: Env): Promise<JwtClaims | null> {
  const [headerB64, payloadB64, sigB64] = token.split(".");
  const data = new TextEncoder().encode(`${headerB64}.${payloadB64}`);
  const sig = base64UrlDecode(sigB64);
  const valid = await crypto.subtle.verify("RS256", env.PUBLIC_KEY, sig, data);
  if (!valid) return null;
  const payload = JSON.parse(new TextDecoder().decode(base64UrlDecode(payloadB64)));
  if (payload.exp * 1000 < Date.now()) return null;
  return payload as JwtClaims;
}

Die Scopes im JWT spiegeln die Scopes aus dem Scoped-Token-Muster: catalogue:read, orders:read, orders:write. Die WordPress-Nutzer-ID reitet im sub-Claim, sodass ein orders:read-Aufruf nur die Bestellungen dieses Nutzers liefert.

#Muster im selben Server mischen

Ein realer WooCommerce-MCP-Server exponiert in der Regel:

  • catalogue.list und product.detail: anonym + IP-Rate-Limit.
  • inventory.check (für Partner): scoped Token mit inventory:read.
  • order.status (für eingeloggten Nutzer): OAuth mit orders:read.
  • order.intent (für eingeloggten Nutzer): OAuth mit orders:write, plus engerem Rate-Limit.

Die Pre-Dispatch-Logik im Worker geht die Muster durch:

async function authenticate(request: Request, toolName: string, env: Env): Promise<Principal> {
  const requirement = TOOL_AUTH_REQUIREMENTS[toolName];
  if (requirement === "anonymous") {
    if (!await checkAnonymousRateLimit(request, env)) throw new McpError("rate_limit");
    return { kind: "anonymous" };
  }
  const auth = request.headers.get("Authorization");
  if (requirement === "api_token") {
    const ctx = await verifyApiToken(auth, env);
    if (!ctx) throw new McpError("unauthorized");
    return { kind: "api_token", ctx };
  }
  if (requirement === "oauth") {
    const claims = auth?.startsWith("Bearer ") ? await verifyJwt(auth.slice(7), env) : null;
    if (!claims) throw new McpError("unauthorized");
    return { kind: "oauth", claims };
  }
  throw new Error(`Unknown auth requirement for ${toolName}`);
}

Die TOOL_AUTH_REQUIREMENTS-Map ist die einzige Wahrheit darüber, welches Tool welchen Auth-Modus braucht. Kein Tool wird ohne expliziten Eintrag hinzugefügt.

#Rate-Limit pro Principal

Anonymer Verkehr bekommt ein Bucket pro IP. Token-authentifizierter Verkehr bekommt ein Bucket pro Token. OAuth-Verkehr bekommt ein Bucket pro Nutzer. Mutierende Tools bekommen unabhängig vom Principal eine engere Decke als Lese-Tools.

Für die WooCommerce-Form sind meine Default-Buckets:

Tool-KategorieAnonymTokenOAuth
catalogue.* (Lesen)60 / Minute / IP600 / Minute / Token120 / Minute / Nutzer
inventory.* (Lesen)nicht erlaubt300 / Minute / Tokennicht erlaubt
order.status (Lesen)nicht erlaubt60 / Minute / Token60 / Minute / Nutzer
order.intent (Schreiben)nicht erlaubt30 / Minute / Token10 / Minute / Nutzer

Die Zahlen sind Startwerte; die richtigen Werte liefert Beobachtung von echtem Verkehr über zwei Wochen plus Tuning. Die Struktur zählt.

#Auth-Ereignisse loggen

Jedes auth-relevante Ereignis landet im Log:

  • Token ausgegeben. Admin-Nutzer, Ziel-Principal, Scopes, Ablauf.
  • Token verwendet. Token-ID, Tool-Name, Principal, Latenz, Erfolg/Fehler.
  • Token widerrufen. Token-ID, wer hat widerrufen, warum.
  • Token gescheitert. Grund (abgelaufen, Scope fehlt, Hash-Mismatch), IP, User-Agent.
  • OAuth-Code getauscht. Nutzer-ID, gewährte Scopes, ausgegebenes Refresh-Token.
  • OAuth-Refresh. Nutzer-ID, neues Access-Token ausgegeben, altes Token verdrängt.

Die Logs gehen via Cloudflare Logpush in einen Langzeit-Store. Eine Dashboard-Abfrage, die “Tokens, die in den letzten 24 Stunden genutzt wurden, aber in den 90 Tagen davor nicht”, überwacht, fängt wahrscheinlichen Token-Diebstahl ab. Eine Abfrage auf “fehlgeschlagene Token-Verifikationen pro IP” fängt Credential-Stuffing-Versuche ab.

#Wo das im Cluster sitzt

Dieser Artikel deckt die Auth-Oberfläche ab. Für den Implementierungs-Durchstich siehe MCP-Server für WooCommerce aufbauen. Für typisierte Tool-Definitionen siehe typisierte Katalog-Tools mit Zod für MCP. Für die Protokoll-Entscheidung siehe MCP vs REST. Für den Migrationspfad aus einer bestehenden API siehe bestehende WordPress-API auf MCP migrieren. Der Pillar ist MCP-Server-Entwicklung.

Preisgestaltung individuell, weil der Auth-Umfang davon abhängt, welche Muster deine Umgebung verlangt; ein Anonym-only-Read-Server ist ein anderer Auftrag als eine vollständige OAuth-Ausgabe-Oberfläche.

Nächster Schritt

Machen Sie aus dem Artikel eine echte Umsetzung

Dieser Block stärkt die interne Verlinkung und führt Nutzer gezielt zum nächsten sinnvollen Schritt im Service- und Content-System.

Soll das Thema auf Ihrer Website umgesetzt werden?

Ich kann daraus ein konkretes Audit, Hardening-Maßnahmen und einen priorisierten Fix-Plan ableiten.

Relevanter Cluster

Weitere WordPress-Dienste und Wissensbasis entdecken

Stärken Sie Ihr Unternehmen mit professionellem technischen Support in den Kernbereichen des WordPress-Ökosystems.

Artikel-FAQ

Häufig gestellte Fragen

Praktische Antworten zur Umsetzung des Themas.

SEO-ready GEO-ready AEO-ready 5 Q&A
Verlangt die MCP-Spezifikation Authentifizierung?
Nein. Die Model-Context-Protocol-Spezifikation lässt Authentifizierung der Transportschicht. Stdio-Transporte sind in der Regel allein dadurch vertrauenswürdig, dass sie lokal laufen. HTTP-Transporte ins Internet brauchen eine Authentifizierungsschicht, die das SDK nicht out of the box mitbringt.
Wann ist ein anonymer MCP-Server akzeptabel?
Wenn jedes exponierte Tool Read-only auf öffentlichen Daten ist und die Lastauswirkung durch IP-basiertes Rate-Limiting begrenzt wird. Ein Katalog-Browse-Tool, das /wp-json/wc/v3/products?stock_status=instock kapselt, ist akzeptabel. Ein Order-Lookup-Tool nicht.
Warum gerade OAuth 2.1?
OAuth 2.1 konsolidiert die moderne Leitlinie aus OAuth 2.0 plus PKCE, wirft die deprekierten Implicit- und Resource-Owner-Password-Flows raus und passt zu dem, was Claude Desktop und andere MCP-Hosts nativ für delegierten Agenten-Zugriff unterstützen.
Wo leben scoped Tokens?
Tokens werden auf der WordPress-Seite über eine Admin-Oberfläche ausgegeben, mit gehashtem Wert plus Scopes plus Ablauf abgelegt und bei jedem MCP-Request verifiziert. Plaintext speichern ist derselbe Fehler wie Passwörter im Klartext zu speichern.
Wie greift Rate-Limiting in Auth ein?
Rate-Limits hängen am Principal: ein authentifiziertes Token hat sein eigenes Bucket, anonymer Verkehr teilt sich ein Bucket pro IP. Mutierende Tools bekommen ein engeres Bucket unabhängig vom Principal, damit ein kompromittiertes Token nicht in einer Schleife auf order.intent loopen kann.

Sie brauchen ein FAQ für Branche und Zielmarkt? Wir erstellen eine Version passend zu Ihren Business-Zielen.

Kontakt aufnehmen

Ähnliche Artikel

Praktischer Durchstich zum Aufbau eines Model-Context-Protocol-Servers vor WooCommerce. Tool-Definitionen, Katalog- und Bestell-Endpunkte, schema.org-Abgleich, Zod-Validierung und ein Cloudflare-Workers-Deployment, mit dem ein KI-Agent reden kann.
wordpress

MCP-Server für WooCommerce aufbauen: ein Praktiker-Leitfaden

Praktischer Durchstich zum Aufbau eines Model-Context-Protocol-Servers vor WooCommerce. Tool-Definitionen, Katalog- und Bestell-Endpunkte, schema.org-Abgleich, Zod-Validierung und ein Cloudflare-Workers-Deployment, mit dem ein KI-Agent reden kann.

Entscheidungsleitfaden für die Wahl zwischen Model Context Protocol und REST API, wenn der Konsument ein KI-Agent ist. Typisierte Oberfläche vs JSON-Form-Inferenz, mutierende Aktionen, Authentifizierung und das Hybrid-Muster, das oft beide schlägt.
wordpress

MCP vs REST: wann was gewinnt für KI-Agenten-Integration

Entscheidungsleitfaden für die Wahl zwischen Model Context Protocol und REST API, wenn der Konsument ein KI-Agent ist. Typisierte Oberfläche vs JSON-Form-Inferenz, mutierende Aktionen, Authentifizierung und das Hybrid-Muster, das oft beide schlägt.

Wie man Zod-Schemata für MCP-Tool-Inputs und -Outputs entwirft, inklusive Idempotenz-Schlüsseln, Fehler-Envelopes und typisierten Agenten-Verträgen, die stille Drift zwischen MCP-Server und WooCommerce-Origin verhindern.
wordpress

Typisierte Katalog-Tools mit Zod für MCP

Wie man Zod-Schemata für MCP-Tool-Inputs und -Outputs entwirft, inklusive Idempotenz-Schlüsseln, Fehler-Envelopes und typisierten Agenten-Verträgen, die stille Drift zwischen MCP-Server und WooCommerce-Origin verhindern.