wikijs-mcp-google-auth
wikijs-mcp-google-auth
Ein MCP-Layer auf Basis einer bestehenden Wiki.js 2.5.x: Ein Unternehmensbenutzer meldet sich mit Google Workspace an und arbeitet über ein LLM (claude.ai, Claude Desktop, beliebiger MCP-Client) mit dem Wiki — streng innerhalb seiner eigenen Wiki.js-Berechtigungen.
Kernprinzip: Wiki.js ist die einzige Quelle der Wahrheit für die Autorisierung. Der MCP-Server hat keine eigenen Benutzer/Gruppen/Berechtigungen und keinen globalen API-Schlüssel. Jede Operation läuft unter dem nativen Wiki.js-JWT des jeweiligen Benutzers, und Wiki.js selbst entscheidet über Erlauben/Verweigern (Gruppen / Berechtigungen / Seitenregeln).
Google Workspace ──OAuth/OIDC──▶ MCP Server ──signed assertion──▶ Wiki.js
│ auth module "mcpdelegation"
│ → refreshToken() → native JWT
│
MCP client (claude.ai / Desktop) ◀──┴── tools: search / get / list /
create / update / delete / whoami
(all via GraphQL with the user's JWT)Komponenten
Verzeichnis | Beschreibung |
| Eigenes Authentifizierungsmodul für Wiki.js 2.5.x — prüft RS256-Assertions, die vom MCP-Server signiert wurden, und gibt ein natives Wiki.js-JWT zurück (Details) |
| Entfernter MCP-Server (Streamable HTTP): ein OAuth-2.1-Autorisierungsserver für MCP-Clients auf Basis von Google OIDC + Token-Broker + Tools |
| Nur für Tests: Browser-UI-E2E (Playwright) und ein eigenständiger Fake-Google-IdP-Emulator |
| Isolierter Teststand (Wiki.js 2.5.303 + Postgres + ACL-Seed) — nur für Entwicklung/CI |
| Vollständiger UI-E2E-Stack (Fake-IdP + Wiki.js + MCP + Playwright) — nur für Tests |
| Produktions-Deployment: nur der MCP-Server, der auf Ihre bestehende Wiki.js zeigt |
| Einstiegspunkt zum Befüllen des Teststands ( |
Related MCP server: wikijs-mcp
So funktioniert es
Der MCP-Client verbindet sich mit
https://mcp.company.com/mcpund führt OAuth-Lauf 2.1 durch (Dynamic Client Registration + PKCE). Google unterstützt kein DCR, daher ist der MCP-Server selbst der Autorisierungsserver für die Clients, und Google wird nur zur Authentifizierung des Menschen verwendet. Google-Tokens verlassen den Server nie; die Clients erhalten die eigenen opaken Tokens des MCP-Servers. Nach dem Google-Login sieht der Benutzer einen Zustimmungsbildschirm, der die Anwendung und ihre Redirect-URI nennt — eine Verteidigungsmaßnahme gegen das Confused-Deputy-Problem (damit ein registrierter Drittanbieter-Client den Token des Benutzers nicht ohne dessen Wissen erhalten kann); die Zustimmung wird pro Benutzer und pro Client gespeichert.Das
id_tokenvon Google wird verifiziert (Signatur,iss,aud,email_verified,hd= Ihre Workspace-Domain).Der Token-Broker des MCP-Servers tauscht die Google-Identität gegen ein Wiki-JWT: Er signiert eine kurzlebige RS256-Assertion (TTL 60 s, eindeutiges
jti) und ruft mit der Standardmutation GraphQLauthentication.logindie Strategiemcpdelegationauf. Das Wiki.js-Modul prüft die Assertion, ermittelt den Benutzer anhand der E-Mail und gibt über den Standard-FlowrefreshToken()ein JWT zurück. Das JWT wird gecacht und vor seinem Ablauf erneuert.Jeder Tool-Aufruf erfolgt mit
Authorization: Bearer <user's JWT>an die Wiki.js-GraphQL-API. Eine nicht erlaubte Seite kann weder gelesen noch verändert werden und erscheint nicht in der Suche oder in Listen — durch E2E-Tests verifiziert (Erlaubt/Verweigert-Matrix für zwei Benutzer in verschiedenen Gruppen).
Tools
Tool | Beschreibung |
| Die Identität des Benutzers + dessen Wiki.js-Gruppen und -Berechtigungen (Zugriffsdiagnose) |
| Volltextsuche; Ergebnisse werden anhand der Benutzerrechte gefiltert |
| Eine Seite per ID oder geben Sie den Pfad (Metadaten + vollständiges Markdown) |
| Für den Benutzer sichtbare Seiten (Filterung nach Pfad-Präfix) |
| Seite erstellen (Markdown) |
| Aktualisieren: Lesen-Zusammenführen-Schreiben; nicht angegebene Felder bleiben erhalten |
| Löschen (destruktiv; Wiki.js erzwingt |
Integration in Ihre eigene Wiki.js: Schritt für Schritt
Sie benötigen: Wiki.js 2.5.x (getestet mit 2.5.303) mit Zugriff auf das Dateisystem bzw. die Docker-Konfiguration; einen Host für den MCP-Server mit einem öffentlichen HTTPS-Endpunkt; Administratorzugriff auf die Google Cloud Console Ihres Workspace.
Schritt 1: Auth-Modul in Wiki.js installieren
Docker: Fügen Sie dem Wiki-Dienst ein Volume hinzu und starten Sie den Container neu:
services:
wiki:
image: ghcr.io/requarks/wiki:2.5.303
volumes:
- /opt/wikijs-mcp/wikijs-auth-module:/wiki/server/modules/authentication/mcpdelegation:ro(Der Inhalt von packages/wikijs-auth-module/ aus diesem Repository wird nach /opt/wikijs-mcp/wikijs-auth-module gelegt; der Zielordnername muss exakt mcpdelegation lauten.)
Bare Metal: Kopieren Sie packages/wikijs-auth-module/ nach <wiki>/server/modules/authentication/mcpdelegation/ und starten Sie Wiki.js neu.
Nach der Konfiguration (Schritt 3) erscheint im Wiki.js-Log: Authentication Strategy MCP Delegation: [ OK ].
Schritt 2: Assert-Schlüssel generieren
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out mcp-assertion-key.pem
openssl pkey -in mcp-assertion-key.pem -pubout -out mcp-assertion-key.pub.pemDer private Schlüssel (mcp-assertion-key.pem) bleibt nur auf dem MCP-Server-Host. Der öffentliche Schlüssel wird im nächsten Schritt in Wiki.js eingetragen.
Schritt 3: Strategie in der Wiki.js-Administration konfigurieren
Administration → Auth → Strategie hinzufügen → MCP-Delegation:
Assertion Public Key (PEM) — den Inhalt von
mcp-assertion-key.pub.pem;Expected Audience / Issuer — die Standardwerte beibehalten (
urn:wikijs:mcp-delegation/urn:wikijs-mcp-google-auth);User Lookup Provider Priority — die Reihenfolge der Provider, über die der Benutzer anhand seiner E-Mail gefunden wird. Wenn Ihre Leute über Google/OIDC im Wiki anmelden, diesen Provider an die erste Stelle setzen (Modul-Keys sind ebenfalls zulässig:
google,oidc,local);(optional) Self-Registration + Domain-Whitelist + Auto-Enrollment-Gruppen — damit neue Workspace-Nutzer bei ihrer ersten MCP-Anfrage automatisch angelegt werden;
Speichern.
Der Strategie-Instanzschlüssel wird in der Liste angezeigt (dies ist für den MCP-Server der WIKIJS_STRATEGY_KEY; wenn Sie die Strategie manuell über die Oberfläche erstellt haben, erzeugt Wiki.js eine UUID — kopieren Sie diese).
Konten mit aktiviertem TFA können nicht über Delegation verwendet werden — der MCP-Server liefert eine klare Fehlermeldung.
Schritt 4: Google-OAuth-Client erstellen
Google Cloud Console → APIs und Dienste → Anmeldedaten → Anmeldedaten erstellen → OAuth-Client-ID.
Anwendungstyp: Webanwendung;
Autorisierte Weiterleitungs-URI:
https://mcp.company.com/oauth/google/callback(IhrePUBLIC_URL+/oauth/google/callback);OAuth-Zustimmungsbildschirm: Typ Intern (nur Ihr Workspace).
Speichern Sie die Client-ID und das Client-Secret.
Schritt 5: MCP-Server bereitstellen
cd deploy
cp .env.example .env # fill in the values
mkdir -p keys && cp /path/to/mcp-assertion-key.pem keys/
chmod 644 keys/mcp-assertion-key.pem # the container runs as non-root node (uid 1000)
docker compose -f docker-compose.prod.yml up -dDer Container läuft als Nicht-Root-Benutzer
node— die eingehängte Schlüsseldatei muss für ihn lesbar sein (chmod 644); der private Schlüssel selbst bleibt durch die Berechtigungen des Host-Verzeichnisseskeys/geschützt.
.env-Variablen:
Variable | Wert |
| Getagtes Image (der Workflow |
| Die öffentliche HTTPS-URL des MCP-Servers |
| Die URL Ihrer Wiki.js (intern bevorzugt) |
| Der Strategie-Instanzschlüssel aus Schritt 3 ( |
| Aus Schritt 4 |
| Ihre Workspace-Domain, z. B. |
Stellen Sie einen TLS-Reverse-Proxy vor Port 8000. Minimal nginx:
server {
listen 443 ssl http2;
server_name mcp.company.com;
# ssl_certificate ...; ssl_certificate_key ...;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $host;
proxy_buffering off; # streamable HTTP
}
}Prüfen: curl https://mcp.company.com/healthz → {"ok":true}; curl https://mcp.company.com/.well-known/oauth-authorization-server → OAuth-Metadaten.
Schritt 6: Clients verbinden
claude.ai (Team/Enterprise): Einstellungen → Connectors → Benutzerdefinierten Connector hinzufügen → URL: https://mcp.company.com/mcp. Beim ersten Einsatz macht der Client folgende Aktionen: Client-Registrierung → Google-Login --> fertig.
Claude Desktop: Einstellungen → Connectors → Benutzerdefinierten Connector hinzufügen (mit derselben URL) (oder über mcp-remote für ältere Versionen).
MCP Inspector (Diagnose): npx @modelcontextprotocol/inspector → Transport: Streamable HTTP → URL https://mcp.company.com/mcp → Open Auth → Flow durchspielen.
Schritt 7: Prüfen
Im LLM-Chat:
„Who am I in Wiki?“ →
whoamisollte Ihre E-Mail, Gruppen und Berechtigungen aus Wiki-js zeigen.Bitten Sie danach, eine Seite zu finden/zu öffnen, auf die Sie Zugriff haben → OK.
Bitten Sie eine Seite an, für die Sie keine Rechte haben → klare Ablehnung („Wiki.js hat diesen Vorgang abgelehnt …“), und diese Seite fehlt auch nicht in Suche und Anzeige.
Lokale Entwicklung
npm ci
npm run stand:up # Wiki.js 2.5.303 + Postgres (docker)
npm run stand:seed # finalize + groups/users/pages + strategy + dev keys
npm test # unit tests (auth module + OAuth provider)
npm run build && npm run e2e # in-process e2e: delegation, OAuth, tools — against a live stand
npm run stand:downTeststand: admin@example.com/admin1234!, john@example.com (Engineering, kein Zugriff auf /admin), weil kate@example.com (Management). Jeder PR läuft durch die schnellen Checkpins (CI: Lint + Unit + Build); das schwere Docker-E2E (e2e) und das Browser-ui-e2e laufen nur bei Pushes auf dev/main (also vor dem Merge), damit PR-Iterationen nicht verlangsamt werden.
Browser-UI-E2E (Playwright) mit Rollen
Ein separater Docker-Stack deploy/docker-compose.e2e.yml bringt einen Fake-Google-IdP-Emulator (packages/e2e-ui/idp/ — eine Anmeldeseite mit Rollenauswahl statt echtem Google), Wiki.js, den MCP-Server und einen Playwright-Runner hoch, der den gesamten Browser-OAuth-/Consent-Flow unter verschiedenen Rollen durchläuft (John/Kate/outside-Domain). Emulator und Playwright kommen nur in diesem E2E-Stack vor — sie landen nie in den Produktions-/Dev-Images.
C=deploy/docker-compose.e2e.yml
docker compose -f $C build mcp
docker compose -f $C up -d db wiki idp # no --wait on wiki: the seed script is the readiness gate
docker compose -f $C run --rm seed
docker compose -f $C up -d --wait mcp
docker compose -f $C run --rm playwright # exit code = test result
docker compose -f $C down -vEs prüft: Anmeldung als Rolle → der Zustimmungsbildschirm nennt den Client → Genehmigen →
whoami und die auf die Rolle eingeschränkten Seiten (John kann management/* nicht sehen, Kate schon);
Ablehnen → access_denied; ein Konto außerhalb der Domäne wird vor der Zustimmung abgewiesen. Ein
separater CI-Workflow (ui-e2e) erledigt das bei Pushes auf dev/main.
Den MCP-Server manuell gegen den Teststand ausführen:
PUBLIC_URL=http://localhost:8000 \
WIKIJS_URL=http://127.0.0.1:3000 \
MCP_ASSERTION_PRIVATE_KEY_FILE=deploy/keys/mcp-assertion-key.pem \
GOOGLE_CLIENT_ID=... GOOGLE_CLIENT_SECRET=... GOOGLE_ALLOWED_DOMAIN=example.com \
npm run dev -w @wikijs-mcp/serverReleases
Releases erfolgen automatisch. Erhöhe die version in der Root-package.json auf dev,
öffne einen dev → main-PR und merge ihn. Der Workflow Release on main baut und pusht
bei dem beiden Push auf main das Image
ghcr.io/<owner>/wikijs-mcp-server:vX.Y.Z (+ :latest) und erstellt den Git-Tag
vX.Y.Z sowie ein GitHub-Release – alles in einem einzigen Workflow-Lauf, und zwar nur
mit dem eingebauten GITHUB_TOKEN (kein PAT/Secret zu konfigurieren). Wenn die Version
unverändert ist, ist der Lauf ein No-op, sodass gewöhnliche Merges auf main keine
Releases erzeugen.
Einmalige Repository-Einstellungen dafür: Settings → Actions → General → Workflow permissions = Read and write permissions; und falls du Tags mit einem Ruleset schützst, erlaube GitHub Actions,
v*-Tags zu erstellen.
Sicherheitshinweise
Assertion: RS256, TTL 60 s, eindeutige
jti, Replay-Schutz; der private Schlüssel liegt ausschließlich auf dem MCP-Server. Ein kompromittierter Schlüssel bedeutet, dass man sich als beliebiger Wiki-Benutzer anmelden kann – behandle ihn also wie ein Root-Geheimnis und rotiere ihn (neues Schlüsselpaar erzeugen und den öffentlichen Schlüssel in der der Strategie aktualisieren).Google-Identität: Der kanonische Identifikator ist
iss+sub; die E-Mail dient zur Nachschlagen. Diehd-Domäne wird aus dem signiertenid_tokenverifiziert, nicht aus Parametern.Confused-Deputy-Schutz: Bevor ein Autorisierungscode ausgegeben wird, muss der Benutzer einen eine, auf den jeweiligen Client zugeschnittenen Zustimmungsbildschirm durchlaufen (kann nur für ein vertrauenswürdiges First-Party-Szenario über
requireConsentdeaktiviert werden). Das verhindert, dass ein Angreifer, der über DCR eine eigenen eigenen OAuth-Client registriert hat, unbemerkt an das Token des Opfers gelangt.Wiki.js-Ratenlimit:
authentication.loginist pro IP auf 5 Aufrufe/min begrenzt, und alle Delegations-Logins kommen von der IP des MCP-Servers. Der Broker, cachen JWTs (standardmäßig 30 min) und wiederholt bei Erreichen des Limits, sodass das im normalen Betrieb unsichtbar ist; verzögertungen von bis zu einer Minute sind möglich.Widerruf: Standard-OAuth
/revoke(pro Token); eine Deaktivierung eines Benutzers in Wiki.js unterbricht die Delegation beim nächste JWT-Refresh (≤30 min); das Löschen der DateiSESSION_STORE_FILE+ Neustart des MCP-Servers beendet alle Sessions auf der einmal.Audit: Jeder Tool-Aufruf wird strukturiert protokolliert (wer, welches Tool, ok/denied) – ohne Seiteninhalt.
MCP-Endpunkt: bearer-only, 120 requests/min pro Token, Security-Header; die OAuth-Endpunkte werden durch die eingebaute Ratenbegrenzung des SDK geschützt.
Einschränkungen und Pläne
RAG/semantische Suche ist ein separater zukünftiger Dienst. Der Anschlusspunkt ist bereit:
search_wikifunktioniert über dieSearchBackend-Schnittstelle (src/search/– v1 = native Wiki.js-Suche; der RAG-Dienst erhält das Wiki.js-JWT des Benutzers und bewahrt dadurch das ACL-Modell). Siehedocs/rag-integration.md.Nur eine MCP-Serverinstanz (FileStore + In-Memory-Replay-Cache). HA erfordert einen gemeinsamen Store (Redis) – die
KVStore-Schnittstelle ist bereits extrahiert.Wiki.js 3.x verwendet unterschiedlichen Authentifizierungsmechanismus – das Modul zählt auf 2.5.x.
Lizenz
Apache-2.0
This server cannot be deployed
Maintenance
Related MCP Connectors
- hiveWikiOAuthai.hivewiki
Shared project wiki for AI agents: read and write pages, next actions, and activity logs over MCP.
Hosted MCP for Google Workspace, Atlassian and Notion: one OAuth, per-user accounts, write access.
- FlowdexOAuthdk.flowdex
Read and write your team's shared, AI-readable wiki from any MCP client.
Read-only MCP for the Eco game wiki: search, Markdown pages, and wiki_* lookups. No keys, no writes.
Related MCP Servers
- AlicenseAqualityFmaintenanceEnables reading, creating, updating, and appending content to Yandex Wiki pages via MCP. Supports both read-write and read-only modes.728 PyPI9MIT
- AlicenseAqualityAmaintenanceEnables MCP clients to search, read, and edit Wiki.js pages, and manage assets, comments, users, groups, and maintenance jobs through the Wiki.js GraphQL API.6287 npm3MIT
- FlicenseNot gradedqualityBmaintenanceEnables MCP clients to interact with a Wiki.js 2.x instance via its GraphQL API, allowing page listing, reading, full-text search, creation, updating, and deletion, with a read-only mode and robust path handling.-
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to maintain a persistent Markdown knowledge base by ingesting sources, searching and reading notes, and creating or updating wiki pages with optimistic locking.12AGPL 3.0