mcp-server-manager


MCP Server Manager


Das MCP-Server-Manager-Modul verwaltet Nutzerzugriffe auf die selbstgehosteten MCP-Server unter mcp-server.weinify.de: Es nimmt den Server-Katalog vom Gateway entgegen, gibt eingeloggten Nutzern API-Tokens für KI-Clients wie Claude aus und prüft diese Tokens für den Gateway – inklusive vollem OAuth-2.1-Connector-Support.

Allgemein

Katalog & Freischaltung


Der Gateway meldet regelmäßig seinen aktuellen Server-Katalog (ID, Name, Beschreibung, optionaler Web-Pfad) an dieses Modul, das ihn lokal spiegelt. Für jeden Server im Katalog entsteht zur Laufzeit eine eigene Berechtigung; Administratoren schalten Nutzer im WordPress-Profil oder über eine Freigabe-Tabelle auf der Modul-Admin-Seite pro Server frei.

API-Tokens für KI-Clients


Freigeschaltete Nutzer erzeugen über ein Dashboard eigene, langlebige API-Tokens (gültig 5 Jahre) mit eigener Bezeichnung und optional eingeschränktem Server-Scope, um sie in die Konfiguration von KI-Clients wie Claude Desktop einzutragen. Jeder Token lässt sich jederzeit einzeln widerrufen.

OAuth-2.1-Connector-Support


Für Anbindungen, die einen klassischen OAuth-Login-Flow statt eines manuell eingetragenen Tokens erwarten (Connector), spielt WordPress selbst den Authorization Server: Dynamic Client Registration, Login samt Einwilligungsseite und Token-Ausstellung laufen alle über dieses Modul und münden am Ende im selben Token-Format wie die manuell erzeugten Tokens.

Eingebettete Web-Oberflächen


Für Server mit eigener Web-Oberfläche lässt sich diese direkt in eine weinify.de-Seite einbetten – das Modul prägt dafür automatisch einen kurzlebigen, auf genau diesen Server begrenzten Token, ohne dass Nutzer manuell etwas eintragen müssen.

Shortcodes

ShortcodeBeschreibung
weinhold_mcp_server_manager_dashboardDashboard für eingeloggte Nutzer: eigene MCP-Server-Zugriffe einsehen, API-Tokens erzeugen und widerrufen. Keine Parameter
weinhold_mcp_server_manager_embedBettet die Web-Oberfläche eines MCP-Servers per iframe ein, mit drei Zuständen (bitte einloggen / kein Zugriff / normale Anzeige). Parameter server: Server-ID aus dem Katalog, z. B. „memory“ (muss einen Web-Pfad hinterlegt haben)

Dateien

modules/mcp_server_manager.php – einzige Datei des Moduls: Katalog-Spiegel, Capability-Verwaltung, JWT-Signierung/-Prüfung, Token-Speicher, OAuth-2.1/DCR-Endpunkte, Shortcodes, Admin-Oberflächen, Cleanup.

Für Entwickler

Dynamische Capabilities statt eigener ACL-Tabelle


Statt einer eigenen Datenbanktabelle für Zugriffsrechte nutzt das Modul WordPress-Capabilities: Pro Server im Katalog entsteht zur Laufzeit eine Capability mcp_access_{id}. weinhold_mcp_server_manager_get_user_server_ids() ist die einzige Quelle der Wahrheit dafür, welcher Nutzer welchen Server sehen darf – sowohl fürs eigene Dashboard als auch für die Token-Prüfung des Gateways. Eine separate Verwaltungs-Capability (manage_mcp_server_users) regelt, wer die Server-Zuordnung anderer Nutzer bearbeiten darf; nur Administratoren erhalten sie automatisch.

Selbst signierte JWTs, Widerruf per jti


Tokens sind HS256-signierte JWTs (Secret aus der Konstante MCP_JWT_SECRET in der wp-config.php), enthalten aber zusätzlich eine eindeutige jti. Diese wird beim Erzeugen als Metadatensatz im User-Meta abgelegt; weinhold_mcp_server_manager_verify_token() prüft Signatur, Ablaufzeit UND ob die jti noch in dieser Liste steht – ein Token ist also trotz gültiger Signatur sofort ungültig, sobald er im Dashboard widerrufen wurde. Die effektiven Server-IDs eines Tokens sind die Schnittmenge aus dem beim Erzeugen gewählten Scope und den AKTUELLEN Nutzer-Berechtigungen: Ein Token kann also nie mehr, als der Nutzer JETZT darf, selbst wenn der Scope bei der Erzeugung weiter war.

Server-zu-Server ohne Login


Katalog-Sync und Token-Prüfung kommen vom Gateway selbst, ohne WordPress-Session. Beide Endpunkte laufen über nopriv-Ajax-Hooks und werden stattdessen über ein Shared Secret (Header X-MCP-Gateway-Secret, Konstante MCP_WP_API_SECRET) mit hash_equals() abgesichert – ein eigenes Secret, getrennt vom JWT-Signing-Secret.

OAuth-2.1-Endpunkte


.well-known/oauth-authorization-server wird über den parse_request-Hook bedient, weil RFC 8414 einen festen Pfad ohne admin-ajax.php-Präfix verlangt. Dynamic Client Registration (RFC 7591) nimmt praktisch jede Registrierung mit gültigen Redirect-URIs (https oder localhost) an und vergibt nur eine Client-ID ohne Secret – Public-Client-Modell, abgesichert über PKCE statt Client-Secret-Verwaltung. Registrierung, Authorize-Endpunkt und Token-Endpunkt antworten bewusst NICHT im WordPress-Ajax-Hüllformat ({„success“:true,“data“:…}), sondern mit unverpackten JSON-Antworten nach OAuth-Spezifikation, da ein echter OAuth-Client die WP-Hülle nicht verstehen würde. Connector-Tokens laufen mit 180 Tagen Gültigkeit deutlich kürzer als die 5 Jahre manuell erzeugter Tokens.

Besonderheiten

Der Modul-Header trägt Scope: site, das Modul selbst orientiert sich aber am Muster des PPNP-Spiel-Auth-Moduls (signierte Tokens, Shared-Secret für Server-zu-Server-Calls, Capability-basierte statt tabellenbasierte Rechte) – mit zwei bewussten Abweichungen: Die Server-Liste ist dynamisch statt drei fest einprogrammierter Capabilities, und Tokens sind langlebig und darum per jti widerrufbar statt rein zustandslos wie PPNPs 120-Sekunden-Bootstrap-Token.

Der eingebettete Web-Oberflächen-Token liest der jeweilige MCP-Server direkt aus dem URL-Fragment nach dem Raute-Zeichen aus – Fragmente werden nie an den Server mitgesendet, sondern bleiben rein clientseitig im Browser, was den Token vor Server-Logs schützt.

Trotz voller OAuth-2.1-Unterstützung gibt es keinen Refresh-Grant: Connector-Tokens laufen nach 180 Tagen schlicht ab und müssen neu autorisiert werden, sind aber jederzeit vorher über das Dashboard „Deine Tokens“ widerrufbar.

Versionshistorie

VersionDatumÄnderung
1.0.022.09.2026Einführung der Versionierung.