Skycloak
官方適用於Skycloak託管Keycloak的Model Context Protocol伺服器。可從任何MCP客戶端管理叢集、領域、應用程式、SSO與使用者。
你可以用 Skycloak MCP 做什麼?
-
叢集升級審查 — 查詢哪些 Keycloak 叢集升級進度落後,並透過
list_cluster_upgrades和get_cluster_upgrade_path取得建議的後續路徑。 -
Realm 佈建 — 在特定叢集上建立具備已設定身分提供者的暫存 realm,使用
create_realm和create_identity_provider。 -
使用者活動稽核 — 找出最近被加入 realm 的使用者,並檢視管理員變更,利用
list_realm_users和query_events。 -
SIEM 整合設定 — 設定一個將管理員事件轉送至外部 webhook 的目的地,使用
create_siem_destination和test_siem_destination。 -
主題內容替換 — 在不遺失指派設定的情況下,就地更新自訂主題的封存檔,透過
update_theme_content並進行確認。 -
自訂網域路由 — 新增自訂網域、擷取需建立的 DNS 記錄、驗證這些記錄,並使用
create_domain和verify_domain將流量路由至 realm。
文件
skycloak-mcp
官方 Model Context Protocol 伺服器,用於 Skycloak(受管理的 Keycloak):從任何 MCP 用戶端(Claude Desktop、Claude Code、Cursor)管理您的叢集、領域、應用程式和 SSO。
狀態: 早期版本。工具涵蓋範圍持續成長;請參閱變更日誌以了解目前可用的功能。
快速開始
claude mcp add --transport http skycloak https://mcp.skycloak.io
無需 API 金鑰、無需用戶端 ID、無需設定。您的瀏覽器會開啟,您登入 Skycloak,工具就會出現。任何支援 streamable HTTP 的 MCP 用戶端都以相同方式運作:只需提供 URL,無需其他設定。
然後提出需求:
- 「我的哪些 Keycloak 叢集升級進度落後?」
- 「在 EU 叢集上建立一個 staging 領域,並啟用 Google 和 GitHub 登入。」
- 「上週有誰被加入 production 領域?」
- 「設定一個 SIEM 目的地,將管理事件轉發到我們的 Datadog webhook。」
驗證與安全性
- 託管 HTTP,使用 OAuth(無需設定憑證)。 將您的用戶端指向
https://mcp.skycloak.io,不需任何標頭。伺服器以401回應,並附上其 RFC 9728 中繼資料的指標,位於/.well-known/oauth-protected-resource,用戶端會針對 Skycloak 登入領域執行瀏覽器授權碼流程,取得的存取權杖會換成短期、限定工作區的 API 金鑰,供工作階段使用。金鑰有效期為一小時,並會自動更新。您的用戶端設定中不會儲存任何內容。 - 託管 HTTP,使用 API 金鑰。 在 Skycloak 儀表板 建立金鑰,並以
Authorization: Bearer <key>(或API-Key: <key>)傳送。每個請求都攜帶自己的憑證,且僅以該憑證的工作區身分運作。伺服器不保留工作階段狀態,因此請求絕不會繼承其他呼叫者的狀態。金鑰在使用前不會被驗證:Skycloak API 是權威來源,因此無效的金鑰會在第一次工具呼叫時以401呈現,而非在連線時。 - 工具符合您的角色。 透過 OAuth,工具清單會根據工作階段允許的範圍進行篩選,因此唯讀工作區成員不會看到會回應
403的寫入工具。使用 API 金鑰時,整個工具表面都會註冊,因為伺服器無法看到金鑰的範圍,未經授權的呼叫會以 API 的403呈現。 - 本機 stdio。 執行
skycloak-mcp init並在瀏覽器中核准(OAuth 2.0 裝置授權流程)。它會產生工作區限定的 API 金鑰,儲存在您作業系統的金鑰鏈中,並自動偵測您的預設工作區(傳遞--workspace <id>以選擇其他工作區)。skycloak-mcp logout會移除儲存的金鑰。 - 無頭模式 / CI。 設定
SKYCLOAK_API_KEY環境變數(在 Skycloak 儀表板 建立金鑰)以完全跳過瀏覽器。它永遠優先於金鑰鏈。 - 寫入操作由您的憑證控管,而非旗標。 位於
https://mcp.skycloak.io的託管伺服器以可寫入模式執行,您實際能變更的內容受限於金鑰的範圍和工作區角色:唯讀成員無法變更任何內容,無論工具清單顯示什麼。在 URL 中加入?readonly=true可強制工作階段使用唯讀工具表面。本機二進位檔則相反,除非以--allow-writes啟動,否則不會註冊任何寫入工具。 - 叢集憑證為選擇性加入。
get_cluster_credentials會傳回叢集的 Keycloak 管理員憑證,持有金鑰的助理會看到這些憑證,因此init預設不會要求該範圍。請使用攜帶該範圍的金鑰:在儀表板建立一個,或透過 stdio 以skycloak-mcp init --allow-credentials登入。沒有該範圍時,工具會傳回 403,並說明兩種途徑。 - 破壞性工具需要確認: 例如刪除領域需要明確的
confirm=true引數。 - 請求會根據您的 Skycloak 方案進行速率限制;在
429回應時,伺服器會呈現Retry-After。
工具
137 個工具:60 個唯讀和 77 個寫入。唯讀工具永遠可用。在託管伺服器上,寫入工具也會註冊,並由憑證的範圍控管;本機二進位檔僅在以 --allow-writes 啟動時註冊它們。
工具名稱帶有 skycloak_ 前綴,下表省略了該前綴,因此 list_clusters 在您的用戶端中是 skycloak_list_clusters。
| 區域 | 唯讀 | 寫入(--allow-writes) |
|---|---|---|
| 叢集 | list_clusters、get_cluster、list_cluster_locations、list_cluster_types、list_cluster_features、list_cluster_versions、list_cluster_upgrades、get_cluster_upgrade_path、get_cluster_credentials、get_cluster_insights、get_cluster_maintenance_window | create_cluster、update_cluster、delete_cluster、cancel_cluster_upgrade、restart_cluster_instances、set_cluster_maintenance_window、delete_cluster_maintenance_window |
| 邊緣安全 | get_cluster_security、list_cluster_captcha_domains | update_cluster_security、add_cluster_captcha_domain、remove_cluster_captcha_domain |
| 領域 | list_realms、get_realm | create_realm、update_realm、delete_realm |
| 應用程式 | list_applications、get_application、list_application_roles、list_application_sessions | create_application、update_application、delete_application、assign_application_role、remove_application_role、rotate_application_secret |
| 身分提供者 | list_identity_providers、get_identity_provider、list_identity_provider_templates、discover_oidc | create_identity_provider(OIDC)、update_identity_provider、delete_identity_provider、test_identity_provider |
| 使用者、角色與群組 | list_realm_users、get_realm_user、list_realm_roles、get_realm_role、list_realm_groups、get_realm_group、list_realm_group_members、list_user_roles、list_user_groups | create_realm_user、update_realm_user、delete_realm_user、create_realm_role、update_realm_role、delete_realm_role、create_realm_group、update_realm_group、delete_realm_group、assign_realm_user_role、remove_realm_user_role、add_realm_user_to_group、remove_realm_user_from_group |
| 自訂網域 | list_domains、get_domain、list_domain_routes、get_domain_route | create_domain、verify_domain、delete_domain、create_domain_route、update_domain_route、delete_domain_route |
| 品牌與主題 | list_themes、get_theme、get_theme_assignment、get_client_theme_assignment、get_login_branding、get_email_branding、download_theme_content、get_theme_settings | set_theme_assignment、set_client_theme_assignment、update_theme、update_theme_content、update_theme_settings、delete_theme、upsert_login_branding、delete_login_branding、upsert_email_branding、delete_email_branding |
| 擴充功能 | list_extensions、list_cluster_extensions | install_extension、upgrade_extension、update_extension、uninstall_extension、delete_extension |
| SMTP | get_smtp | upsert_smtp、delete_smtp、test_smtp |
| 匯出與日誌 | list_exports、get_export、get_logs、get_security_logs、query_events | create_export、delete_export、export_cluster_events |
| 領域匯入與匯出 | get_realm_export、get_realm_import | create_realm_export、create_realm_import、create_realm_import_upload_url |
| SIEM | list_siem_destinations、get_siem_destination | create_siem_destination、update_siem_destination、delete_siem_destination、test_siem_destination |
| Webhooks | list_webhook_event_types、list_webhook_subscriptions、get_webhook_subscription | create_webhook_subscription、update_webhook_subscription、delete_webhook_subscription、test_webhook_subscription |
慣例: 破壞性工具(delete_*、uninstall_extension、cancel_cluster_upgrade、update_theme_content、update_theme_settings、restart_cluster_instances)需要 confirm=true。update_theme_settings 為工作區開啟或關閉 exact_theme_names;呼叫者的 API 金鑰必須是為工作區擁有者或管理員產生的,否則即使有 themes:write,也會收到 403。開啟後,會在背景將現有主題移至其精確的服務名稱;若主題內容在其精確名稱下被取代,則 get_theme/list_themes/update_theme_content 會回報 restart_required: true,直到 restart_cluster_instances 滾動該叢集的 Keycloak 實例。重新啟動可能會延後到叢集的維護時段,而非立即套用,回報為 deferred: true,若已知則為 next_window。create_cluster 是非同步的:輪詢 get_cluster 直到叢集狀態為 available。create_domain 會傳回客戶必須建立的 DNS 記錄;verify_domain 會觸發 DNS 檢查。set_theme_assignment 會依 Keycloak 主題類型啟用自訂主題(空字串重設為內建預設值)。update_theme_content 會就地取代主題的封存檔(content_base64 中的 base64 ZIP 或 Keycloakify JAR),保留主題的 ID、名稱以及領域和應用程式指派,因此編輯主題不再需要刪除並重新上傳;它需要 confirm=true,因為被覆寫的封存檔無法復原,而 update_theme 仍只會變更名稱、描述和版本。請參閱 docs/theme-content-update.md 了解如何進行該呼叫。update_cluster_security 不會更動 CAPTCHA 設定。領域匯入/匯出會移動單一領域的設定,與 create_export 不同,後者會傾印整個叢集的資料庫:兩者都是非同步的,且領域封存檔永遠加密,因此匯出時使用的密碼在再次匯入時是必要的。領域可以直接從現有匯出(source_export_id)或從上傳的封存檔(create_realm_import_upload_url,PUT,然後 upload_s3_key)匯入;匯入會建立領域,並拒絕名稱衝突而非覆寫,且需要 confirm=true,因為它會帶入使用者和憑證。
提示詞
八個提示詞為您提供進入該工具表面的起點。用戶端會將它們呈現為斜線指令或建議動作;每個提示詞都接受引數(領域、叢集、時間視窗),並引導模型以正確順序使用正確的工具。
| 提示詞 | 功能 |
|---|---|
audit_self_registration | 找出仍允許自行註冊的每個領域,跨單一叢集或全部叢集 |
review_upgrades | 找出 Keycloak 版本落後的叢集,並規劃升級路徑 |
triage_failed_logins | 擷取領域最近的失敗登入,並依來源 IP 分組 |
review_identity_providers | 列出領域的 SSO 連線,並檢查特定連線是否啟用 |
review_admin_changes | 顯示領域近期誰變更了什麼,聚焦於登入和安全設定 |
provision_environment | 建立叢集、新增領域並設定身分提供者,逐步確認 |
set_up_custom_domain | 新增自訂網域、提供精確的 DNS 記錄、驗證並路由至領域 |
rotate_client_secret | 重新產生應用程式的用戶端密鑰,並先說明影響範圍 |
提示詞的控管方式與其命名的工具相同:三個會變更狀態的提示詞僅提供給能呼叫其參考之寫入工具的工作階段,且其指示會要求模型在變更任何內容前先與您確認。破壞性工具的 confirm=true 要求仍會額外套用。
技能
提示詞是起點,技能則是模型按需載入的完整操作手冊。伺服器提供四個技能,透過草案 SEP-2640 Skills 擴充功能 提供:它在能力中宣告 io.modelcontextprotocol/skills,回應 skills/list 和 skills/get,並將每個 SKILL.md 作為一般資源提供於 skill://<name>/SKILL.md,其清單項目中帶有 sha256 摘要。OpenAI 的外掛程式目錄正是以這種形式匯入技能。
| 技能 | 編碼內容 |
|---|---|
auth-incident-triage | 分流「使用者無法登入」問題:區分平台中斷、攻擊與設定變更,使用事件、WAF 日誌與叢集健康狀態。唯讀 |
enterprise-sso-rollout | 將企業 IdP 端對端接入 realm:issuer 驗證、上游應用程式註冊、broker 設定、連線測試,以及對照真實登入事件的驗證 |
keycloak-migration-doctor | 針對 Keycloak 匯出、匯入或遷移進行前置檢查,對照支援團隊實際遇到的阻礙(script 政策、舊版 /auth 路徑、部分匯出預期),並透過讀取真實的 error_message 來診斷失敗的工作,而非僅看一般儀表板通知 |
keycloak-upgrade-readiness | 評估版本漂移,釐清新版 Keycloak 會破壞哪些項目(擴充功能、主題),並以匯出作為復原計畫,跨環境安排部署順序 |
技能與其對應工具的閘控機制相同:三個圍繞寫入工具建構的工作流程在唯讀工作階段中會被隱藏,而限定範圍的工作階段只會提供其實際擁有之工具的技能。來源位於 internal/tools/skills/,每個技能一個目錄,採用標準的 Agent Skills 格式,因此也可以直接複製到本機技能目錄中使用。
連線
對於託管 HTTP,最簡單的路徑是 OAuth,完全不需要憑證:
claude mcp add --transport http skycloak https://mcp.skycloak.io
第一次呼叫會開啟您的瀏覽器,您在 Skycloak 登入頁面核准後,工具便會出現。如果您屬於多個工作區,請指定您要使用的那一個:
claude mcp add --transport http skycloak "https://mcp.skycloak.io?workspace=<workspace-id>"
否則,請在 Skycloak 儀表板建立 API 金鑰,並設定您的 MCP 用戶端將其作為 bearer token 傳送:
claude mcp add --transport http skycloak https://mcp.skycloak.io --header "Authorization: Bearer sk_sc_XXX"
這會將以下內容加入 .claude.json:
{
"mcpServers": {
"skycloak": {
"type": "http",
"url": "https://mcp.skycloak.io",
"headers": {
"Authorization": "Bearer sk_sc_XXX"
}
}
}
}
對於本機 stdio,請先登入一次,然後將您的用戶端指向 skycloak-mcp run:
skycloak-mcp init # one-time browser sign-in; stores a key in your keychain
Claude Desktop / Cursor(本機、stdio):
{
"mcpServers": {
"skycloak": {
"command": "skycloak-mcp",
"args": ["run", "--transport", "stdio"]
}
}
}
Claude Code:
claude mcp add skycloak -- skycloak-mcp run --transport stdio
對於無頭/CI 環境(無瀏覽器),請略過 init,改為傳入金鑰:在設定中加入 "env": { "SKYCLOAK_API_KEY": "sk_sc_..." },或使用 claude mcp add skycloak --env SKYCLOAK_API_KEY=sk_sc_... -- skycloak-mcp run --transport stdio。
僅在您打算進行變更時加入 --allow-writes(使用 skycloak-mcp init --allow-writes 登入,或使用具寫入權限的金鑰)。
在託管 HTTP URL 中加入 ?readonly=true 可僅對該 HTTP 工作階段暴露唯讀工具,或加入 ?readonly=false 以要求具寫入能力的工具介面。查詢參數預設為 false,但只有在伺服器以 --allow-writes 啟動時才會註冊寫入工具。
加入 ?workspace=<uuid> 以選擇 OAuth 工作階段操作的 workspace。僅在您屬於多個工作區時才需要;若只有單一工作區,伺服器會自動為您選擇;若您屬於多個工作區但未指定任何一個,連線會失敗並顯示列出這些工作區的訊息。
執行 HTTP 傳輸
skycloak-mcp run --transport http --http-addr :8080
它本身不需要憑證:呼叫端各自在請求中提供憑證,因此部署時不會注入任何內容。GET /healthz 和 GET /readyz 不需要驗證,僅回報程序正在執行;它們刻意不探查 Skycloak API,因此上游短暫故障不會同時導致所有副本的探測失敗。伺服器不保存工作階段狀態,因此副本不需要工作階段親和性,可以自由擴展或輪替。SIGTERM 會停止新連線並排空進行中的呼叫。
只要設定了 SKYCLOAK_ISSUER 和 SKYCLOAK_DASHBOARD_URL(預設為已設定),OAuth 路徑就會啟用。此時 GET /.well-known/oauth-protected-resource 會以未驗證方式提供服務,將 realm 命名為授權伺服器。其 resource 值在設定 SKYCLOAK_PUBLIC_URL 時取自該變數,否則取自請求本身的 Host 和 scheme,因此位於 ingress 後方的單主機部署不需要額外設定。Scheme 在存在 X-Forwarded-Proto 時取自該變數,否則對非 loopback 主機預設為 https,因為 TLS 在上游終止,發布 http:// 識別碼將無法對應用戶端連線的 URL。如果您的 ingress 改寫了 Host,請設定 SKYCLOAK_PUBLIC_URL。該文件也將 openid profile email 列為其 scopes_supported,而 WWW-Authenticate challenge 會將其重複作為 scope 參數,因此讀取任一文件的用戶端都會向 realm 請求這些參數:openid 是必需的,因為 token 交換會使儀表板呼叫 Keycloak 的 userinfo 端點,而 Keycloak 會拒絕未授予該參數的 token。未攜帶該參數的 token 會在驗證時以 401 和 challenge 被拒絕,而非被帶入無法成功的交換流程,因此仍持有先前授權的用戶端會停止重試並重新登入。將 issuer 或 dashboard 變數任一設為空白會完全關閉 OAuth,伺服器會恢復為僅要求 API 金鑰。
OPENAI_APPS_CHALLENGE_TOKEN 在 /.well-known/openai-apps-challenge 提供 OpenAI 的 plugin-directory 網域驗證 token,僅以純文字回傳,不含其他內容。若未設定,該路由不會註冊,路徑會回傳 404。
啟動時會記錄一行,顯示其解析的設定(oauth=、issuer=、dashboard=、public_url=、endpoint=、allow_writes=),因此無需重新部署即可發現設定錯誤的部署。每個在 OAuth 路徑上被拒絕的請求都會記錄一行,標明失敗的階段(verify、exchange 或 scopes)、呼叫端收到的狀態碼,以及底層錯誤。驗證失敗會加上拒絕 token 的檢查項目(expired、wrong_issuer、bad_signature、unknown_key_id、wrong_token_type、no_openid_scope 等);交換失敗會加上儀表板的狀態和所呼叫的主機。呼叫端在 token 驗證後會以 token 主體身分出現,絕不會以憑證身分出現:存取 token、Authorization 標頭和鑄造的 API 金鑰絕不會被記錄。
設定
| 環境變數 | 預設值 |
|---|---|
SKYCLOAK_API_KEY | 無(stdio 可選;HTTP 用戶端改為提供 API-Key 標頭) |
SKYCLOAK_ENDPOINT | https://api.skycloak.io |
SKYCLOAK_API_VERSION | 目前 API 版本 |
SKYCLOAK_ISSUER | https://login.app.skycloak.io/realms/skycloak(CLI 登入,以及 HTTP 傳輸驗證 token 所用的授權伺服器) |
SKYCLOAK_CLIENT_ID | skycloak-mcp(僅 CLI device flow) |
SKYCLOAK_DASHBOARD_URL | https://app.skycloak.io(鑄造 CLI 金鑰和 HTTP 工作階段金鑰) |
SKYCLOAK_PUBLIC_URL | 無(從每個請求推導;當 ingress 改寫 Host 時設定) |
OPENAI_APPS_CHALLENGE_TOKEN | 在 /.well-known/openai-apps-challenge 提供 OpenAI 的 plugin-directory 驗證 token。未設定時,該路徑回傳 404。 |
指令:init(瀏覽器登入)、run(提供服務)、logout(移除已儲存的金鑰)。init 接受 --workspace <id>、--allow-writes、--allow-credentials 和 --ttl-days(預設 90)。
| 旗標 | 預設值 | 說明 |
|---|---|---|
--transport | stdio | stdio 或 http |
--http-addr | :8080 | HTTP 傳輸的監聽位址 |
--allow-writes | false | 為 stdio 啟用變更工具,並允許帶有 readonly=false 的 HTTP 工作階段註冊寫入工具 |
開發
make build # build the server binary
make test # unit tests
make run # run on stdio for local testing
make inspector # MCP Inspector against the local binary
make lint # golangci-lint
make generate # regenerate the API client from the OpenAPI spec
位於 internal/apiclient 下的 API 用戶端是使用 oapi-codegen 從 Skycloak OpenAPI 規格產生的。
與 API 保持同步
位於 internal/apiclient 的用戶端是使用 oapi-codegen 從 internal/apiclient/openapi.yaml 產生的;執行 make generate 以重新整理。若已提交的產生程式碼與規格有差異,CI 會失敗。請求會在 429/5xx 時重試,並採用具 Retry-After 感知的退避策略。
發布
以 GitHub 二進位檔和每個標籤上的 ghcr.io/sky-cloak/skycloak-mcp 容器映像發布,並以 io.skycloak/skycloak-mcp 發布至 MCP Registry。大多數人兩者都不需要:託管伺服器無需安裝。
安全性
請私下回報漏洞。請參閱 SECURITY.md。
貢獻者
由 Guilliano Molaire、Neville Omangi 和 Aphilas 在 Skycloak 建置。儲存庫歷史在公開時已壓縮,因此提交記錄無法反映各部分的作者。
授權
Apache-2.0。internal/apiclient/openapi.yaml 中的 OpenAPI 描述是從 Skycloak 平台 API 產生的,版權歸 Skycloak 所有;將其納入是為了讓用戶端可以產生和驗證。請參閱 NOTICE。