wikijs-mcp-google-auth
wikijs-mcp-google-auth
기존 Wiki.js 2.5.x 위에 두는 MCP 계층: 기업 사용자가 Google Workspace로 로그인하고, LLM 클라이언트(claude.ai, Claude Desktop, 모든 MCP 클라이언트)를 통해 위키를 사용할 수 있습니다 — 자신의 Wiki.js 권한 범위 안에서만.
핵심 원칙: Wiki.js가 권한 판정의 단일 진실 원천(source of truth)입니다. MCP 서버에는 자체 사용자/그룹/권한이 없고 전역 API 키도 없습니다. 모든 작업은 개별 사용자의 네이티브 Wiki.js JWT로 수행되며, 허용/거부 결정(그룹 / 권한 / 페이지 규칙)은 Wiki.js 자체가 내립니다.
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)구성 요소
디렉터리 | 설명 |
| Wiki.js 2.5.x용 커스텀 인증 모듈 — MCP 서버가 서명한 RS256 애서션(assertion)을 검증하고 네이티브 Wiki.js JWT를 반환합니다 (상세) |
| 원격 MCP 서버(Streamable HTTP): Google OIDC 기반 MCP 클라이언트용 OAuth 2.1 인가 서버 + 토큰 브로커 + 도구 |
| 테스트 전용: 브라우저 UI e2e (Playwright) 및 독립 실행형 가짜 Google IdP 에뮬레이터 |
| 격리된 테스트 스탠드 (Wiki.js 2.5.303 + Postgres + ACL 초기 데이터) — 개발/CI 전용 |
| 전체 UI e2e 스택 (가짜 IdP + Wiki.js + MCP + Playwright) — 테스트 전용 |
| 프로덕션 배포: MCP 서버만 실행하며, 기존 Wiki.js를 바라봅니다 |
| 테스트 스탠드를 시딩하는 진입점 ( |
Related MCP server: Yandex Wiki MCP
동작 방식
MCP 클라이언트가
https://mcp.company.com/mcp에 연결하고 OAuth 2.1(Dynamic Client Registration + PKCE)을 수행합니다. Google은 DCR을 지원하지 않으므로, MCP 서버가 클라이언트에게는 인가 서버 역할을 하고, Google은 인간 사용자를 인증하는 데에만 사용됩니다. Google 토큰은 서버를 벗어나지 않으며, 클라이언트는 MCP 서버 자체의 불투명(opaque) 토큰을 받습니다. Google 로그인 후 사용자에게는 애플리케이션 이름과 리다이렉트 URI가 표시되는 **동의 화면(consent screen)**이 나타납니다 — 혼동된 대리인(confused deputy) 방어를 위한 것입니다 (타사에 등록된 클라이언트가 사용자의 동의 없이 토큰을 얻을 수 없도록). 승인은 사용자별 · 클라이언트별로 기억됩니다.Google의
id_token이 검증됩니다(서명,iss,aud,email_verified,hd= 사용자의 Workspace 도메인).MCP 서버의 토큰 브로커가 Google 신원을 네이티브 Wiki.js JWT로 교환합니다. 짧은 수명의 RS256 애셜레이션(TTL 60초, 고유한
jti)에 서명하고,mcpdelegation전략으로 표준 GraphQL mutationauthentication.login을 호출합니다. Wiki.js 모듈이 애셜레이션을 검증하고, 이메일로 사용자를 확인한 뒤, 표준refreshToken()흐름을 통해 JWT를 반환합니다. JWT는 캐시되고 만료 전에 갱신됩니다.모든 도구 호출은
Authorization: Bearer <사용자 JWT>와 함께 Wiki.js GraphQL로 전송됩니다. 권한이 없는 페이지는 읽거나 변경할 수 없고, 검색/목록에도 나타나지 않습니다 — e2e 테스트로 검증됩니다(서로 다른 그룹의 두 사용자에 대한 허용/차단 매트릭스).
도구
도구 | 설명 |
| 사용자 신원 + Wiki.js 그룹 및 권한 (접근 진단) |
| 전문 검색; 결과는 사용자 권한에 따라 필터링됩니다 |
| id 또는 경로로 페이지 조회 (메타데이터 + 전체 markdown) |
| 사용자에게 표시되는 페이지 (경로 접두어로 필터링) |
| 페이지 생성 (markdown) |
| 읽기-병합-쓰기; 지정되지 않은 필드는 유지됩니다 |
| 삭제 (파괴적 작업; |
Wiki.js에 통합하기: 단계별 안내
필요 사항: Wiki.js 파일 시스템/Docker 설정에 접근할 수 있는 2.5.x (2.5.303에서 테스트됨); 공개 HTTPS 엔드포인트가 있는 MCP 서버 호스트; Workspace의 Google Cloud Console 관리자 권한.
1단계. Wiki.js에 인증 모듈 설치하기
Docker: wiki 서비스에 볼륨을 추가하고 컨테이너를 재시작합니다:
services:
wiki:
image: ghcr.io/requarks/wiki:2.5.303
volumes:
- /opt/wikijs-mcp/wikijs-auth-module:/wiki/server/modules/authentication/mcpdelegation:ro(이 저장소의 packages/wikijs-auth-module/ 내용은 /opt/wikijs-mcp/wikijs-auth-module로 마운트됩니다. 대상 디렉토리 이름은 정확히 mcpdelegation이어야 합니다)
베어 메탈: packages/wikijs-auth-module/를 <wiki>/server/modules/authentication/mcpdelegation/로 복사하고 Wiki.js를 재시작합니다.
설정(3단계) 후 Wiki.js 로그에 Authentication Strategy MCP Delegation: [ OK ]가 표시됩니다.
2단계. Assertion 키 생성하기
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개인 키(mcp-assertion-key.pem)는 오직 MCP 서버 호스트에만 둡니다. 공개 키는 다음 단계에서 Wiki.js에 넣습니다.
3단계. Wiki.js 관리자에서 전략 구성
관리자 메뉴 → Auth → Add Strategy → MCP Delegation:
Assertion Public Key (PEM) —
sir-assertion-key.pub.pem의 내용;Expected Audience / Issuer — 기본값 유지 (
urn:wikijs:mcp-delegation/urn:wikijs-mcp-google-auth);User Lookup Provider Priority — 이메일로 사용자를 조회할 공급자 우선순위. 위키에 Google/OIDC로 로그인한다면 해당 공급자를 첫 번째로 둡니다 (모듈 키
google,oidc,local도 허용);(선택) Self-registration + 도메인 화이트리스트 + 자동 그룹 등록 — 첫 MCP 요청 시 새 Workspace 사용자가 자동 생성되도록 설정;
저장.
전략 인스턴스 키가 목록에 표시됩니다(이 키가 MCP 서버의 WIKIJS_STRATEGY_KEY입니다. UI에서 수동 생성 시 Wiki.js가 uuid를 생성하며, 이를 복사하십시오).
TFA(2단계 인증)가 활성화된 계정은 위임을 통해 사용할 수 없습니다. MCP 서버가 명확한 오류를 반환합니다.
4단계. Google OAuth 클라이언트 만들기
Google Cloud Console → APIs & Services → Credentials → Create credentials → OAuth client ID:
Application type: Web application;
Authorized redirect URI:
https://mcp.company.com/oauth/google/callback(즉,PUBLIC_URL+/oauth/google/callback);OAuth consent screen: type Internal (Workspace 내부 전용).
클라이언트 ID와 클라이언트 시크릿을 저장합니다.
5단계. 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컨테이너는 루트가 아닌
node사용자로 실행됩니다. 마운트한 키 파일은 해당 사용자가 읽을 수 있어야 하며(chmod 644), 개인 키 자체는 호스트keys/디렉토리의 권한으로 보호됩니다.
.env 변수:
변수 | 값 |
| 태그된 이미지 ( |
| MCP 서버의 공개 HTTPS URL |
| Wiki.js URL (내부 망 주소를 권장) |
| 3단계의 전략 인스턴스 키 ( |
| 4단계에서 생성한 값 |
| 예: |
포트 8000 앞에 TLS 리버스 프록시를 둡니다. 최소 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
}
}확인: curl https://mcp.company.com/healthz → {"ok":true}; curl https://mcp.company.com/.well-known/oauth-authorization-server → OAuth 메타데이터.
6단계. 클라이언트 연결
claude.ai (Team/Enterprise): Settings → Connectors → Add custom connector → URL: https://mcp.company.com/mcp. 처음 사용할 때 클라이언트가 OAuth를 수행합니다: 클라이언트 등록 → Google 로그인 → 완료.
Claude Desktop: Settings → Connectors → 같은 URL로 custom connector 추가 (또는 이전 버전은 mcp-remote 사용)
MCP Inspector (진단): npx @modelcontextprotocol/inspector → Transport: Streamable HTTP → URL https://mcp.company.com/mcp → Open Auth → 흐름을 따라 진행합니다.
7단계. 검증
LLM 채팅에서:
"내가 위키에서 누구인가?" →
whoami도구가 사용자의 이메일, 그룹, 권한을 Wiki.js에서 가져와 표시해야 합니다.접근 가능한 페이지를 찾거나 열도록 요청 → 정상 동작.
권한이 없는 페이지를 요청 → 명확한 거부("Wiki.js denied this operation…") 메시지가 표시되고, 해당 페이지는 검색/목록에서도 제외됩니다.
로컬 개발
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테스트 스탠드: admin@example.com/admin1234!, john@example.com (Engineering, /management/* 접근 불가), kate@example.com (Management). 모든 PR은 빠른 검사(CI: lint + unit + build)를 실행합니다. 무거운 docker e2e(e2e) 및 브라우저 ui-e2e는 dev/main에 푸시될 때만 실행되므로(즉, 머지 전) PR 반복 속도를 늦추지 않습니다.
브라우저 UI e2e (Playwright) — 역할별
별도의 docker 스택 deploy/docker-compose.e2e.yml이 가짜 Google IdP 에뮬레이터(packages/e2e-ui/idp/ — 실제 Google 대신 역할 선택 화면이 있는 로그인 페이지)와 Wiki.js, MCP 서버, Playwright 러너를 띄웁니다. Playwright 러너는 서로 다른 역할(John/Kate/out-of-domain)로 브라우저 OAuth+동의 플로우를 전체 수행합니다. 에뮬레이터와 Playwright는 이 e2e 스택에서만 함께 동작하며, 프로덕션/개발 이미지에는 포함되지 않습니다.
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다음을 확인합니다: 역할로 로그인 → 동의 화면이 클라이언트를 명시 → 승인 → whoami와 해당 역할 범위로 제한된 페이지(John은 management/*를 볼 수 없고, Kate는 볼 수 있음); 거부하면 → access_denied; 도메인 밖 계정은 동의 전에 거부됩니다. 별도의 CI 워크플로(ui-e2e)가 dev/main으로의 푸시에서 이 테스트를 수행합니다.
테스트 스탠드(stand)를 대상으로 MCP 서버를 수동 실행:
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
릴리스는 자동으로 이루어집니다. dev에서 루트 package.json의 version을 올리고, dev → main PR을 연 뒤 병합하세요. 그러면 main으로의 푸시 시 Release on main 워크플로가 빌드하여 ghcr.io/<owner>/wikijs-mcp-server:vX.Y.Z(+ :latest)로 푸시하고, git 태그 vX.Y.Z와 GitHub Release을 생성합니다—모두 한 번의 실행으로 처리되며 내장된 GITHUB_TOKEN만 사용합니다(설정할 PAT/secret 없음). 버전이 변경되지 않으면 실행은 no-op이므로, main으로의 일반적인 병합은 릴 것을 만들지 않습니다.
이 기능이 동작하려면 일회성 저장소 설정이 필요합니다: Settings → Actions → General → Workflow permissions = Read and write permissions, 그리고 태그를 ruleset으로 보호한다면
v*태그를 생성하도록 GitHub Actions를 허용하세요.
보안 참고 사항
Assertion: RS256, TTL 60초, 고유한
jti, 재생 방지 기능이 적용됩니다. 프라이빗 키는 MCP 서버에만 존재합니다. 키가 유출되면 어느 위키 사용자로든 로그인할 수 있으므로, 최상위 시크릿으로 취급하고 교체하세요(새 키 쌍 + 전략의 공개 키 업데이트).Google identity: 정식 식별자는
iss+sub이며, 이메일은 조회 용도입니다.hd도메인은 서명된 id_token에서 검증되며, 파라미터에서 가져오지 않습니다.Confused-deputy 방어: 인가 코드가 발급되기 전에 사용자는 클라이언트별 동의 화면을 거칩니다(신뢰되는 퍼스트파티 시나 리오에서만
requireConsent로 비활성화 가능). 이는 DCR을 통해 자신의 OAuth 클라이언트를 등록한 공격자가 피해자의 토큰을 조용히 획득하는 것을 막습니다.Wiki.js rate limit:
authentication.login는 IP당 분당 5건이며, 모든 위임 로그인은 MCP 서버의 IP에서 발생합니다. 브로커는 JWT를 캐시(기본 30분)하고 한도에 걸리면 대기 후 재시도하므로, 정상 동작에서는 나타나지 않습니다. 대량 온보딩 중에는 최대 1분 정도의 지연이 발생할 수 있습니다.Revocation: 표준 OAuth
/revoke(토큰별); Wiki.js에서 사용자를 비활성화하면 다음 JWT 갱신(≤30분) 시 위임이 중단되고,SESSION_STORE_FILE을 삭제하고 MCP 서버를 재시작하면 모든 세션이 한 번에 해제됩니다.Audit: 모든 도구 호출은 페이지 내용 없이 구조화된 형태(누가, 어떤 도구, ok/denied)로 기록됩니다.
MCP endpoint: bearer-only, 토큰당 120 requests/min, 보안 헤더; OAuth 엔드포인트는 SDK에 내장된 rate limiting으로 보호됩니다.
제한 사항 및 계획
RAG/의미론적 검색은 별도의 향후 서비스입니다. 연결 지점은 준비되어 있습니다.
search_wiki는SearchBackend인터페이스(src/search/— v1 = 네이티브 Wiki.js 검색; RAG 서비스는 사용자의 Wiki.js JWT를 받아 ACL 모델을 유지합니다)를 통해 동작합니다.docs/rag-integration.md를 참조하세요.단일 MCP 서버 인스턴스(FileStore + 인메모리 리플레이 캐시). HA를 위해서는 공유 저장소(Redis)가 필요하며 —
KVStore인터페이스는 이미 추출되어 있습니다.Wiki.js 3.x은 다른 인증 메커니즘을 사용합니다 — 이 모듈은 2.5.x를 대상으로 합니다.
라이선스
Apache-2.0
This server cannot be installed
Maintenance
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
- AlicenseAqualityDmaintenanceMCP server for Google Workspace APIs - Docs, Sheets, Drive, Gmail, and Calendar. Enables reading, creating, and editing Google Docs and Sheets, managing comments, reading emails, and viewing calendar events.344517MIT
- AlicenseAqualityBmaintenanceEnables reading, creating, updating, and appending content to Yandex Wiki pages via MCP. Supports both read-write and read-only modes.79MIT
- AlicenseNot gradedqualityCmaintenanceMCP server for Wiki.js integration, enabling AI assistants to create, read, update, delete, search, and move wiki pages via natural language.1MIT
- AlicenseNot gradedqualityAmaintenanceMCP server for accessing Wiki.js through its GraphQL API, enabling page management, search, tags, and system info operations.MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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