Skip to main content
Glama
MaxPopov
by MaxPopov

wikijs-mcp-google-auth

Una capa MCP sobre un Wiki.js 2.5.x existente: un usuario corporativo inicia sesión con Google Workspace and trabaja con la wiki a través of un LLM (claude.ai, Claude Desktop, cualquier cliente MCP) — estrictamente dentro de sus propios permisos de Wiki.js.

Principio central: Wiki.js es la única fuente de la verdad para la autorización. El servidor MCP no tiene usuarios/grupos/permisos propios ni una clave API global. Cada operación se ejecuta con el JWT nativo de Wiki.js del usuario individual, y Wiki.js itself decides allow/deny (Grupos / Permisos / Reglas de página).

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)

Componentes

Dirección

Qué es

packages/wikijs-auth-module/

Módulo de autenticación a a medida para Wiki.js 2.5.x — verica aserciones RS256 firmadas por el servidor MCP y devuelve un JWT nativo de Wiki.js (details)

packages/mcp-server/

Servidor MCP remoto (Streamable HTTP): un servidor de autorización OAuth 2.1 para clientes MCP sobre Google OIDC + token broker + herramientas

packages/e2e-ui/

Solo para pruebas: e2e de interfaz en navegador (Playwright) y un emulador independente de Google IdP falso

deploy/docker-compose.dev.yml

Banco de pruebas aislado (Wiki.js 2.5.303 + Postgres + seed de ACL) — solo para desarrollo/CI

deploy/docker-compose.e2e.yml

Stack de e2e de interfaz completo (IdP falso + Wiki.js + MCP + Playwright) — solo para pruebas

deploy/docker-compose.prod.yml

Despliegue de producción: solo el servidor MCP, que apunta a tu Wiki.js existente

deploy/seed/run.mjs

Punto de entrada para inicializar el banco de pruebas (seed.mjs es la librería)

Related MCP server: Yandex Wiki MCP

Cómo funciona

  1. El cliente MCP se conecta a https://mcp.company.com/mcp y ejecuta OAuth 2.1 (Registro dinámico de clientes + PKCE). Google no admite DCR, por lo que el servidor MCP es en sí mismo el servidor de autorización para los clientes y Google se utiliza solo para autenticar al humano. Los tokens de Google nunca salen del servidor; los clientes reciben los tokens opacos del propio servidor MCP. Tras el inicio de sesión de Google, el usuario ve una pantalla de consentimiento con el nombre de la aplicación y su URI de redirección — una defensa del tipo confused deputy (para que un cliente registrado por un tercero no pueda obtener el token del usuario sin su conocimiento); la aprobación se recuerda por usuario y por cliente.

  2. La id_token de Google se verifica (firma, iss, aud, email_verified, hd = tu dominio de Workspace).

  3. El token broker del servidor MCP intercambia la identidad de Google por un JWT nativo de Wiki.js: firma una aserción RS256 de corta duración (TTL 60 s, jti único) y llama a la mutación GraphQL estándar authentication.login con la estrategia mcpdelegation. El módulo de Wiki.js verifica la aserción, resolves el usuario por correo electrónico y devuelve un JWT mediante el flujo estándar refrshToken(). El JWT se cachea y se renova antes de que expire.

  4. Cada llamada de herramienta va a la GraphQL de Wiki.js con Authorization: Bearer <JWT del usuario>. Una página prohibida no puede leerse ni modificarse y no aparece en las búsquedas ni en los listados — something verificado pro e2e tests (matriz de permitos/prohibidos para usuarios de diferentes grupos).

Herramientas

Herramienta

Descripción

whoami

La identidad del usuario + sus grupos y permisos de Wiki.js (diagnóstico de accesso)

search_wiki

Búsqueda de texto completo; los resultos se filtrán según users' permisos

get_page

Una página por id o ruta (metadatos + markdown completo)

list_pages

Páginas visibles para el usuario (filter por prefijo de ruta)

create_blp

Crear una página (markdown)

update_page

Actualización: leer-fusionar-escribe; los campos no especificados se con preservan

delete_page

Eliminar (destructivo; Wiki.js aplica delete:pages)


Integración with tu Wiki.js: paso a paso

Necesitas: Wiki.js 2.5.x (probado on 2.5.303) con acceso a su sistema de archivos / configuración Docker; un host para el servidor MCP with a public HTTPS endpoint; and admin access to the Google Cloud Console of your Workspace.

Paso 1. Instalar el módulo de autenticación en Wiki.js

Docker: aña un volumn to el servicio de wiki y reinicia el contenedor:

services:
  wiki:
    image: ghcr.io/requarks/wiki:2.5.303
    volumes:
      - /opt/wikijs-mcp/wikijs-auth-module:/wiki/server/modules/authentication/mcpdelegation:ro

(el contenido de packages/wikijs-auth-module/ de este repo va placed in /opt/wikijs-mcp/wikijs-auth-module; el name del rectoryo destination must be exactly mcpdelegation)

Bare metal: copia packages/wikijs-auth-module/ in <wiki>/server/modules/authentication/mcpdelegation/ y reinicia Wiki.js.

Después name Configuration (step 3) el log de Wiki.js mostrar: Authentication Strategy MCP Delegation: [ OK ].

Paso 2. Generar las llaves de asertión

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.pem

La clave privada (mcp-assertion-key.pem) queda solo on the host del servidor мcp. La clve publica va a Wiki.js at the next stage.

Paso 3. Configurar la Estrategia in Admin de Wiki.js

Administración → AuthAñadir estrategiaMCP Delegación:

  • Llave pública de asertión (PEM) — the content of the mcp-assertion-key.pub.pem;

  • Conference / Auditorio (Expected Audience / Issuer) — mantén los valors por defecto (urn:wikijs:mcp-delegatión / urn:wikijs-mcp-google-uth);

  • Prioridad de busqueda de usuario (User Lookup Provaider) — el ordo de proveedores para resolvel el usuario por correo. Si su gente novembre entra a la wiki por Google/OIDC, Bil ese proveedor al principico (also accepted to the ko's module: google, oidc, loca);

  • (opcional) Autorregistro (Self-registration) + lista of dominios + grupos auto-inighup — para que los nuevos usuarios de Workspace escreen atuomáticamente la primera vez que accedan vía MCP;

  • Guardar.

La clave de instacia de la estrategia aparacen la lista (esto is WIKIJS_STRATEGY_KEY para el servidor MCP; e creaste manuamente por la interfaz of Web, Wiki.js generates an uuid — cópialo).

Las cuentas con TFA activado no se pueden usuarios: el servidor MCP devuelve un error claro.

Paso 4. Cren un clate OAuth de Googie

Google Cloud Console → APIs & Services → Credentials → Create credentales → ID de cliente de OAuth:

  • Tipo de aplición: plicación we;

  • URI de redirección autorizada: https://cp.comany.com/out (tu PULC_URL + /outh/googie/callback);

  • Pantalla de consent of OAuth: type Intera (only tu Wolvespace);

Guard el ID de cliente and the Client Secret.

Paso 5. Desplega el MCP

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 -d

El contenedr se ejecuta como usuaro node no root el archivo de clave montado debe poder ser leído por él (chmod 644); suclave (la privada es indeada... self contained by permissions from the host directory keys/.

Variables para .env:

| Varible | Valor | | ------- ------- | | MCP_PIMAGE | Etiquetada (imagen) — the workflow releases of the Release on main: The auto-publish of ghcr.io/<owner>/wikijs-mcp-server:vX.Y.Z when a bundle upgrade is merged to main, or compile locally: docker build -t wikijs-mcp-server:local . — hmm, actually need to include -f and path. Let me put exactly. | PUPLIC_URL | The public HTTPS URL of MCP. | WIKIJS_URL | Your Wiki.js URL (intena preferred). | | WIKIJS_STRATEGY_KEY | Strategy instance key from step 3 (mcpdelegation if you have it set that way) | | GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET | From step 4 | | GOOGLE_ALLOWED_DOMTAIN | Your Workspace domain, e.g., company.com — accounts outside it are rejected. |

La clave GOOGLE_CLIENT_ID... use exact.

Put a TLS reverse proxy in front of 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
  }
}

Verify: curl https://mcp.company.com/healthz{"ok":true}; curl https://mcp.company.com/.well-known/oauth-authorization-server → metadata OAuth.

Paso 6. Conectat clients

claude.ai (Team/Enterprise): Settings → Connectors → Add custom connector → URL: https://mcp.company.com/mcp. At the first use, the client performs OAuth: client registration → Google login → ready.

Claude Desktop: Settings → Connectors → Add custom connector with the same URL (or via mcp-remote for older versions).

MCP Inspector (diagnostics): npx @modelcontextprotocol/inspector → Transport: Streamable HTTP → URL https://mcp.company.com/mcp → Open Auth → go through the flow.

Step 7. Verify

In the LLM chat:

  1. "Who am I in the wiki?" → the whoami tool should show your email, groups and commitments of Wiki pages.

  2. Ask to find or open a page you have access to → OK.

  3. Ask for a page you have no permissions for → a clear rejection ("Wiki.js denied this operation…") and that page is also absent from search/list results.


Local development

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:down

Test properties: admin@example.com/admin1234!, john@example.com (Engineering, no access to /management/*), kate@example.com (Management). Every PR -->

  • A fasts checks (CI: lint + unit + build); the large docker e2e (e2e) and browser ui-e2e run only on pushes to dev/main, i.e., before merge, so they don't slow down the iterations.

Browser e2e (Playner) under roles

A separate docker stack deploy/docker-comose.e2e.yml includes a fake Google IdP emprovider (packages/e2e-ui/idp/ — a login portal with role selector instead of actual Google), Wiki.js, MCP server and a Playwright runner that covers all browser OAuth + consent flow under different roles (John/Kate/out-domain). Emulator and Playwright appear only in this e2e stack — never in the production/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 -v

Comprueba: iniciar sesión como un rol → la pantalla de consentimiento muestra el nombre del cliente → aprobar → whoami y páginas restringidas al rol (John no puede ver management/*, Kate sí); denegar → access_denied; una cuenta fuera del dominio se rechaza antes del consentimiento. Un flujo de trabajo de CI independiente (ui-e2e) hace esto en los pushes a dev/main.

Ejecutar el servidor MCP contra el banco de pruebas manualmente:

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/server

Lanzamientos

Los lanzamientos son automáticos. Incrementa version en el package.json raíz en dev, abre un PR de devmain y combínalo. El flujo de trabajo Release on main entonces, al hacer push a main, construye y publica ghcr.io/<owner>/wikijs-mcp-server:vX.Y.Z (+ :latest) y crea la etiqueta git vX.Y.Z y un GitHub Release, todo en una sola ejecución, usando únicamente el GITHUB_TOKEN integrado (no hay ningún PAT/secreto que configurar). Si la versión no cambia, la ejecución no hace nada, así que las fusiones normales a main no crean lanzamientos.

Ajustes del repositorio que se realizan una sola vez para que esto funcione: Configuración → Acciones → General → Permisos del flujo de trabajo = Permisos de lectura y escritura; y si proteges las etiquetas con un conjunto de reglas, permite que GitHub Actions cree etiquetas v*.

Notas de seguridad

  • Aserción: RS256, TTL 60 s, jti único, protección de reproducción; la clave privada reside únicamente en el servidor MCP. Una clave comprometida significa poder iniciar sesión como cualquier usuario de wiki — trátala como un secreto raíz y debes rotarla (nuevo par + actualiza la clave pública en la estrategia).

  • Identidad de Google: el identificador canónico es iss+sub; el correo electrónico es una búsqueda. El dominio hd se verifica a partir del id\_token firmado, no de los parámetros.

  • Defensa del confused deputy: antes de que se libere un código de autorización, el usuario pasa por una pantalla de consentimiento por cliente (solo se puede desactivar mediante requireConsent en un escenario de confianza de primera parte). Esto evita que un atacante que haya registrado su propio cliente OAuth a través de DCR obtenga silenciosamente el token de la víctima.

  • Límite de tasa de Wiki.js: authentication.login es 5 llamadas/min por IP, y todos los inicios de sesión de delegación provienen de la IP del servidor MCP. El broker guarda en caché los JWT (30 min por defecto) y espera y reintenta cuando se alcanza el límite, por lo que es invisible en el funcionamiento normal; durante el registro masivo de usuarios son posibles avisos de hasta un minuto.

  • Revocación: el /revoke estándar de OAuth (por token); desactivar un usuario en Wiki.js rompe el login delegado en la siguiente renovación del JWT (≤30 min); eliminar SESSION_STORE_FILE y reiniciar el servidor MCP elimina todas las sesiones a la vez.

  • Auditoría: cada deuda de herramienta se registra de forma estructurada (quién, qué herramienta, ok/denegado) sin contenido de la página.

  • Endpoint MCP: solo de portador, 120 solicitudes/min por token, cabeceras de seguridad; los endpoint OAuth están protegidos por la limitación de llamadas integrada del SDK.

Limitaciones y planes

  • La búsqueda RAG/semántica es un servicio futuro separado. El punto de integración está listo: search_wiki opera a través de la interfaz SearchBackend (src/search/ — v1 = búsqueda nativa de Wiki.js; el servicio RAG recibirá el JWT del usuario de Wiki.js y preservará el modelo ACL). Consulta docs/rag-integration.md.

  • Instancia única del servidor MCP (ContactRegistry + memstore). HA necesita un aviso compartido: https://hooks.adidas. Acepto la . ; populate` correct.

  • Wiki.js 3.x está fuera de este código — el módulo está orientado a 2.5.x.

Licencia

Apache-2.0

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP-native open-source Notion alternative: read & write pages, databases and kanban boards.

  • Confluence MCP — wraps the Confluence Cloud REST API v2 (OAuth)

  • Google Docs MCP Pack — read, create, and edit Google Docs via OAuth.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MaxPopov/wikijs-mcp-google-auth'

If you have feedback or need assistance with the MCP directory API, please join our Discord server