OAuth für eigene MCP-Clients
Wenn du deinen eigenen MCP-Client baust (CLI, SDK, IDE-Plugin), beschreibt diese Seite unsere OAuth-Implementierung: welche Standards wir unterstützen, die Endpoints, redirect_uri-Regeln und wie du typische Fehler behebst. Nutzer von Claude.ai und ChatGPT brauchen diese Seite nicht — nimm stattdessen den Quickstart.
Standards, die wir implementieren
mcp-telegram.com ist vollständig konform mit den OAuth-Spezifikationen, auf die das MCP-Ökosystem baut — keine proprietären Erweiterungen, keine in Clients eingebackenen Shared Secrets.
- RFC 6749 — OAuth 2.0 Authorization Framework — Basis-Authorization-Code-Grant mit Refresh-Tokens
- RFC 7591 — Dynamic Client Registration — jeder Client kann sich ohne vorherige Abstimmung selbst unter /oauth/register registrieren
- RFC 7636 — PKCE (Proof Key for Code Exchange) — S256-Challenge ist Pflicht für Public Clients
- RFC 8252 — OAuth 2.0 for Native Apps — Loopback-IP-Redirect-URIs mit Flexibilität für ephemere Ports
- RFC 8414 — OAuth 2.0 Authorization Server Metadata — Discovery-Dokument unter /.well-known/oauth-authorization-server
- RFC 9728 — OAuth 2.0 Protected Resource Metadata — Discovery der MCP-Ressourcengrenze
Endpoints
Authorization Code Flow mit PKCE
Standard-Flow nach RFC 6749 §4.1 + RFC 7636. Keine Überraschungen — wenn deine OAuth-Bibliothek „Authorization Code + PKCE" beherrscht, funktioniert es.
Registriere deinen Client
POST /oauth/register mit { redirect_uris: ["http://127.0.0.1:<port>/callback"], client_name: "dein-client-name" }. Der Server liefert client_id + client_secret zurück (das Secret ist für Public PKCE Clients optional, aber zu erhalten schadet nicht).
Generiere das PKCE-Paar
Erzeuge einen zufälligen code_verifier mit 43-128 Zeichen und berechne dann code_challenge = BASE64URL(SHA256(code_verifier)). Speichere den Verifier lokal für Schritt 4.
Öffne /oauth/authorize im Browser
Leite den Nutzer auf /oauth/authorize?response_type=code&client_id=...&redirect_uri=...&state=...&code_challenge=...&code_challenge_method=S256 um. Der Server zeigt einen QR-Code; der Nutzer scannt ihn in der Telegram-App, um sich zu authentifizieren.
Empfange den Authorization Code
Nach dem QR-Scan leitet der Server auf deinen redirect_uri mit ?code=...&state=... um. Prüfe, dass der state-Parameter dem entspricht, was du gesendet hast.
Tausche den Code gegen einen Token
POST /oauth/token mit grant_type=authorization_code, code, redirect_uri, code_verifier, client_id. Du erhältst einen access_token (10 Jahre TTL — siehe Token Lifetime unten) und einen refresh_token. Nutze den access_token als Authorization: Bearer ... bei /mcp-Requests.
redirect_uri-Matching-Regeln
Wir halten uns strikt an RFC 8252 §7.3 und §8.4. Der Matching-Algorithmus hängt davon ab, ob der registrierte URI ein Loopback-IP-Literal ist.
Loopback (http://127.0.0.1 oder http://[::1])
Wenn du einen Loopback-URI registriert hast, muss der redirect_uri zur Authorize-Zeit in Scheme, Host, Path und Query exakt übereinstimmen — der Port darf aber abweichen. Das fordert RFC 8252 §7.3, weil native Clients an einen vom Betriebssystem zugewiesenen ephemeren Port binden, der sich zwischen Läufen ändern kann.
- Registriert http://127.0.0.1:36201/callback matcht zur Authorize-Zeit http://127.0.0.1:50000/callback ✅
- Registriert http://127.0.0.1:36201/callback matcht NICHT http://127.0.0.1:50000/different-path — der Path muss exakt sein
- Registriert http://[::1]:36201/cb matcht NICHT http://127.0.0.1:36201/cb — IPv4- und IPv6-Loopback sind getrennte Identifikatoren
HTTPS (https://your-domain.example/...)
Exakte byteweise Übereinstimmung erforderlich, einschließlich Path, Query und Port (RFC 6749 §3.1.2). Keine Flexibilität.
localhost (NICHT empfohlen)
Wir behandeln http://localhost wie einen normalen Hostnamen — exakte Übereinstimmung erforderlich, keine Port-Flexibilität. RFC 8252 §8.3 empfiehlt, IP-Literale (127.0.0.1 / [::1]) statt localhost zu verwenden, weil die DNS-Auflösung implementierungsabhängig ist.
PKCE ist Pflicht
code_challenge_method=S256 ist bei jedem Authorize-Request erforderlich. Die plain-Methode wird abgelehnt. Wenn du code_challenge ganz weglässt, schlägt der /token-Tausch bei der code_verifier-Validierung fehl.
Token-Lebensdauer
Die access_token-TTL ist absichtlich lang (10 Jahre), weil manche MCP-Clients den refresh_token nicht zuverlässig persistieren. Ein refresh_token wird trotzdem ausgegeben und rotiert bei jedem Refresh (RFC 6819 §5.2.2.3). Der Nutzer kann jederzeit unter /my/sessions oder durch Abmelden aus Telegram alle Tokens widerrufen. Alternativ kann der Nutzer auch explizit POST an /oauth/revoke (RFC 7009) senden, um eine Session zu beenden.
Häufige Fehler
HTTP 400 „Invalid redirect_uri" bei /oauth/authorize
Der redirect_uri-Query-Parameter passt zu keinem für diese client_id registrierten URI. Für Loopback-Clients: prüfe, dass Scheme + Host + Path + Query exakt übereinstimmen (nur der Port ist flexibel). Für HTTPS-Clients: vollständige Byte-Gleichheit erforderlich — achte auf abschließende Slashes und Unterschiede beim URL-Encoding.
HTTP 400 „Unknown client"
Die client_id existiert nicht in unserer Datenbank. Entweder hast du den /oauth/register-Schritt übersprungen, die Registrierungsantwort ging verloren, bevor du die client_id gespeichert hast, oder der Client wurde vom Nutzer über /my/clients widerrufen.
Client meldet wiederholt „Needs Auth"
Wenn dein Client den access_token persistiert, aber nicht den refresh_token, siehst du das, sobald der access_token abläuft. Unsere Access-Tokens haben gerade deswegen eine TTL von 10 Jahren, aber wenn dein Client Tokens clientseitig nach einem kürzeren Fenster ablaufen lässt, musst du entweder den refresh_token persistieren oder bei Bedarf /oauth/revoke + Re-Auth aufrufen.
Getestete Clients
Interoperabilität mit unserem Server bestätigt. Wenn du etwas Neues baust und es funktioniert, schick uns einen PR, damit wir es hier ergänzen können.
- Claude.ai Web — über den eingebauten MCP-Connector
- ChatGPT Apps — über den eingebauten MCP-Connector
- Hermes Agent — Open-Source-CLI-MCP-Client (RFC 8252 Loopback-Flow)
- Cursor MCP — IDE-Plugin (RFC 8252 Loopback-Flow)
- Jeder Client, der RFC 6749 + RFC 7591 + RFC 7636 + RFC 8252 erfüllt, sollte ohne Codeänderungen auf unserer Seite funktionieren.
Mehrere Telegram-Konten an einer OAuth-Verbindung
Seit v2.32.0 kann eine einzige OAuth-Verbindung mehrere Telegram-Identitäten halten und mit einem einzigen Tool-Aufruf zwischen ihnen umschalten — kein Disconnect/Connect-Zyklus, keine neue Client-Registrierung.
Anzeigen, was verbunden ist
Rufen Sie telegram-accounts-list auf. Sie sehen Ihr primary-Konto (OAuth-gebunden) mit ⭐ markiert, sofern es aktiv ist, sowie alle hinzugefügten Sekundärkonten.
Weiteres Konto anbinden
Rufen Sie telegram-accounts-add mit einem optionalen Label auf (z. B. "testing"). Das Tool liefert eine Einmal-URL zurück (TTL 10 minutes) — öffnen Sie sie auf einem beliebigen Gerät und scannen Sie den QR mit dem Telegram-Konto, das Sie hinzufügen möchten.
Aktives Konto wechseln
Rufen Sie telegram-accounts-switch mit identifier=label, @username, account_id oder 'primary' auf. Der nächste telegram-*-Tool-Aufruf verwendet dieses Konto sofort. Kein Reconnect.
Sekundärkonto trennen
Rufen Sie telegram-accounts-remove identifier=… auf einem Sekundärkonto auf. Das Telegram-Konto selbst wird NICHT abgemeldet — nur die Bindung hier wird entfernt. Das primary-Konto kann auf diesem Weg nicht entfernt werden; nutzen Sie den Disconnect-Flow Ihres Clients, um sich vollständig abzumelden.
Jede OAuth-Verbindung ist isoliert: Konten, die Sie über Hermes anbinden, sind für Claude.ai oder ChatGPT unsichtbar — selbst wenn es dieselbe Telegram-Identität ist. Um unterschiedliche Konten an unterschiedliche MCP-Clients anzubinden, registrieren Sie jeden Client separat und nutzen Sie telegram-accounts-add innerhalb seiner eigenen Sitzung.