Skycloak

io.skycloak由 skycloak.io 發布官方發布者v0.15.0更新於 Nov 3, 2026

Managed Keycloak from any MCP client: clusters, realms, apps, SSO, users, domains, audit events.

已驗證Streamable HTTP可網頁執行資料庫雲端與基礎設施安全與監控

概覽

AI 產生的概覽

Skycloak 官方 MCP 伺服器,可從任何 MCP 用戶端管理託管 Keycloak:叢集、領域、應用程式、SSO、使用者、網域與稽核事件。

可以做什麼
  • 檢視與管理 Keycloak 叢集:列出、建立、更新、刪除、重新啟動、規劃升級與維護時段,並在授權範圍內讀取叢集憑證。
  • 管理領域、應用程式、身分提供者以及使用者、角色與群組,包含建立、更新、刪除與角色指派。
  • 處理自訂網域、DNS 驗證與路由,以及主題、品牌、擴充套件與 SMTP 設定。
  • 檢視匯出、日誌、安全性日誌與稽核事件,並設定 SIEM 目的地與 Webhook 訂閱。
  • 提供稽核、升級整備、SSO 上線、故障排查與金鑰輪替等引導式提示與技能。
適用情境
當你透過 Skycloak 執行 Keycloak,希望助理回答叢集、領域、使用者與登入事件的問題,或執行建立領域、串接 SSO 提供者、輪替用戶端密鑰等管理操作時使用。
執行需求
遠端端點 streamable HTTP;可透過瀏覽器 OAuth 登入(無需設定憑證),或以 Authorization bearer 或 API-Key 標頭送出 API 金鑰。需要 Skycloak 帳號與工作區;屬於多個工作區時需在 URL 指定工作區 ID。另提供本機二進位檔供 stdio 使用,無瀏覽器情境可用 SKYCLOAK_API_KEY。
安裝前請注意
託管伺服器預設具備寫入能力,可變更範圍僅受金鑰作用域與工作區角色限制;若需安全工作階段,請使用唯讀成員、唯讀金鑰或 readonly URL 參數。破壞性工具需 confirm=true,主題內容更新會不可回復地覆寫封存檔。get_cluster_credentials 會把叢集管理員憑證暴露給助理,需明確開啟。領域匯入會帶入使用者與憑證,且領域封存檔以匯出密碼加密。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Skycloak,將其新增到工作區。
  2. 連接 所需的 憑證。它們會被私密儲存,絕不會在公開頁面上展示。
  3. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/io.skycloak%2Fskycloak-mcp/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。 客戶端會在首次連接時完成 OAuth 登入。

{
  "mcpServers": {
    "skycloak": {
      "type": "http",
      "url": "https://mcp.skycloak.io/"
    }
  }
}

README

skycloak-mcp

[Smithery]

Official Model Context Protocol server for Skycloak (managed Keycloak): manage your clusters, realms, applications, and SSO from any MCP client (Claude Desktop, Claude Code, Cursor).

Status: early release. Tool coverage is growing; see the changelog for what's available.

Quick start

bash
claude mcp add --transport http skycloak https://mcp.skycloak.io

No API key, no client ID, no configuration. Your browser opens, you sign in to Skycloak, and the tools appear. Any MCP client that speaks streamable HTTP works the same way: give it the URL and nothing else.

Then ask for something:

  • "Which of my Keycloak clusters are behind on upgrades?"
  • "Create a staging realm on the EU cluster with Google and GitHub sign-in."
  • "Who was added to the production realm in the last week?"
  • "Set up a SIEM destination that forwards admin events to our Datadog webhook."

Authentication & safety

  • Hosted HTTP, with OAuth (no credential to configure). Point your client at https://mcp.skycloak.io with no header. The server answers 401 with a pointer to its RFC 9728 metadata at /.well-known/oauth-protected-resource, the client runs the browser authorization-code flow against the Skycloak login realm, and the access token it gets back is exchanged for a short-lived, workspace-scoped API key that the session runs on. The key lasts an hour and is renewed automatically. Nothing is stored in your client configuration.
  • Hosted HTTP, with an API key. Create a key in the Skycloak dashboard and send it as Authorization: Bearer <key> (or API-Key: <key>). Every request carries its own credential and acts only as that credential's workspace. The server keeps no session state, so a request never inherits another caller's. Keys are not verified before use: the Skycloak API is the authority, so an invalid key surfaces as a 401 on the first tool call rather than at connect time.
  • Tools match your role. Over OAuth, the tool list is trimmed to what the session's scopes allow, so a read-only workspace member is not shown write tools that would answer 403. With an API key the whole surface is registered, because a key's scopes are not visible to the server, and an unauthorized call surfaces as a 403 from the API.
  • Local stdio. Run skycloak-mcp init and approve in your browser (OAuth 2.0 device authorization flow). It mints a workspace-scoped API key, stores it in your operating-system keychain, and detects your default workspace automatically (pass --workspace <id> to pick another). skycloak-mcp logout removes the stored key.
  • Headless / CI. Set the SKYCLOAK_API_KEY environment variable (create a key in the Skycloak dashboard) to skip the browser entirely. It always takes precedence over the keychain.
  • Writes are gated by your credential, not by a flag. The hosted server at https://mcp.skycloak.io runs write-capable, and what you can actually change is bounded by your key's scopes and your workspace role: a read-only member cannot mutate anything, whatever the tool list says. Add ?readonly=true to the URL to force a read-only tool surface for a session. The local binary is the opposite way round and registers no write tools unless started with --allow-writes.
  • Cluster credentials are opt-in. get_cluster_credentials returns a cluster's Keycloak admin credentials, which an assistant holding the key would then see, so init does not request that scope by default. Use a key that carries it: create one in the dashboard, or over stdio sign in with skycloak-mcp init --allow-credentials. Without it the tool returns a 403 that explains both routes.
  • Destructive tools require confirmation: deleting a realm, for example, needs an explicit confirm=true argument.
  • Requests are rate limited according to your Skycloak plan; on a 429 response the server surfaces Retry-After.

Tools

137 tools: 60 read-only and 77 write. Read-only tools are always available. On the hosted server the write tools are registered too and gated by your credential's scopes; the local binary registers them only when started with --allow-writes.

Tool names carry a skycloak_ prefix that the table below omits, so list_clusters is skycloak_list_clusters in your client.

AreaRead-onlyWrite (--allow-writes)
Clusterslist_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_windowcreate_cluster, update_cluster, delete_cluster, cancel_cluster_upgrade, restart_cluster_instances, set_cluster_maintenance_window, delete_cluster_maintenance_window
Edge securityget_cluster_security, list_cluster_captcha_domainsupdate_cluster_security, add_cluster_captcha_domain, remove_cluster_captcha_domain
Realmslist_realms, get_realmcreate_realm, update_realm, delete_realm
Applicationslist_applications, get_application, list_application_roles, list_application_sessionscreate_application, update_application, delete_application, assign_application_role, remove_application_role, rotate_application_secret
Identity providerslist_identity_providers, get_identity_provider, list_identity_provider_templates, discover_oidccreate_identity_provider (OIDC), update_identity_provider, delete_identity_provider, test_identity_provider
Users, roles & groupslist_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_groupscreate_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
Custom domainslist_domains, get_domain, list_domain_routes, get_domain_routecreate_domain, verify_domain, delete_domain, create_domain_route, update_domain_route, delete_domain_route
Branding & themeslist_themes, get_theme, get_theme_assignment, get_client_theme_assignment, get_login_branding, get_email_branding, download_theme_content, get_theme_settingsset_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
Extensionslist_extensions, list_cluster_extensionsinstall_extension, upgrade_extension, update_extension, uninstall_extension, delete_extension
SMTPget_smtpupsert_smtp, delete_smtp, test_smtp
Exports & logslist_exports, get_export, get_logs, get_security_logs, query_eventscreate_export, delete_export, export_cluster_events
Realm import & exportget_realm_export, get_realm_importcreate_realm_export, create_realm_import, create_realm_import_upload_url
SIEMlist_siem_destinations, get_siem_destinationcreate_siem_destination, update_siem_destination, delete_siem_destination, test_siem_destination
Webhookslist_webhook_event_types, list_webhook_subscriptions, get_webhook_subscriptioncreate_webhook_subscription, update_webhook_subscription, delete_webhook_subscription, test_webhook_subscription

Conventions: destructive tools (delete_*, uninstall_extension, cancel_cluster_upgrade, update_theme_content, update_theme_settings, restart_cluster_instances) require confirm=true. update_theme_settings turns exact_theme_names on or off for the workspace; the caller's API key must have been minted for a workspace owner or admin, or it gets 403 even with themes:write. Turning it on moves existing themes to their exact served names in the background; a theme whose content was replaced under its exact name reports restart_required: true from get_theme/list_themes/update_theme_content until restart_cluster_instances rolls that cluster's Keycloak instances. A restart may be deferred to the cluster's maintenance window instead of applying immediately, reported as deferred: true and, when known, next_window. create_cluster is asynchronous: poll get_cluster until the cluster is available. create_domain returns the DNS records the customer must create; verify_domain triggers a DNS check. set_theme_assignment activates a custom theme per Keycloak theme type (empty string resets to the built-in default). update_theme_content replaces a theme's archive in place (base64 ZIP or Keycloakify JAR in content_base64), keeping the theme's ID, name and realm and application assignments, so editing a theme no longer means deleting and re-uploading it; it needs confirm=true because the archive it overwrites is not recoverable, and update_theme still changes only the name, description and version. See docs/theme-content-update.md for how that call is made. update_cluster_security leaves CAPTCHA settings untouched. Realm import/export moves one realm's configuration and is separate from create_export, which dumps a whole cluster's database: both are asynchronous, and the realm archive is always encrypted, so the password used to export it is needed to import it again. A realm can be imported straight from an existing export (source_export_id) or from an uploaded archive (create_realm_import_upload_url, PUT, then upload_s3_key); importing creates a realm and refuses a name collision rather than overwriting, and needs confirm=true because it brings users and credentials with it.

Cluster locations: location on create_cluster, and in what list_clusters, get_cluster and list_cluster_locations return, is one of us (US East), us-west (US West), ca (Canada), eu (Europe) or au (Australia), in any case. us always means US East. us-west is only open to workspaces that have been granted access to it: list_cluster_locations lists every location with available set for your workspace, and creating a cluster in a location you cannot use returns the API's 400 "location not available".

Prompts

Eight prompts give you a starting point into that tool surface. Clients surface them as slash commands or suggested actions; each one takes arguments (realm, cluster, time window) and walks the model through the right tools in the right order.

PromptWhat it does
audit_self_registrationFind every realm that still allows self-registration, across one cluster or all of them
review_upgradesSpot clusters behind on their Keycloak version and lay out the upgrade path
triage_failed_loginsPull recent failed logins for a realm and group them by source IP
review_identity_providersList a realm's SSO connections and check whether a specific one is enabled
review_admin_changesShow who changed what in a realm recently, focused on login and security settings
provision_environmentCreate a cluster, add a realm, and wire up an identity provider, confirming each step
set_up_custom_domainAdd a custom domain, hand back the exact DNS records, verify, and route it to a realm
rotate_client_secretRegenerate an application's client secret with the blast radius spelled out first

Prompts are gated the same way as the tools they name: the three that mutate are only offered to sessions that could call the write tools they reference, and their instructions tell the model to confirm with you before changing anything. The confirm=true requirement on destructive tools still applies on top.

Skills

Where a prompt is a starting point, a skill is a full operational playbook the model loads on demand. The server ships four, served over the draft SEP-2640 Skills extension: it declares io.modelcontextprotocol/skills in its capabilities, answers skills/list and skills/get, and serves each SKILL.md as an ordinary resource at skill://<name>/SKILL.md with a sha256 digest in its listing entry. OpenAI's plugin directory imports skills in exactly this shape.

SkillWhat it encodes
auth-incident-triageTriage "users cannot log in": separate platform outages from attacks and from configuration changes, using events, WAF logs and cluster health. Read-only
enterprise-sso-rolloutWire an enterprise IdP into a realm end to end: issuer validation, the upstream app registration, broker config, connection testing, and verification against real login events
keycloak-migration-doctorPreflight a Keycloak export, import or migration against the blockers support actually sees (script policies, the legacy /auth path, partial-export expectations), and diagnose a failed job by reading its real error_message instead of the generic dashboard notice
keycloak-upgrade-readinessAssess version drift, work out what the new Keycloak version breaks (extensions, themes), and sequence the rollout across environments with an export as the rollback plan

Skills follow the same gating as the tools they name: the three workflows built around write tools are withheld from read-only sessions, and a scoped session is only offered a skill whose tools it actually has. The sources live in internal/tools/skills/, one directory per skill, in the standard Agent Skills format, so they also work copied straight into a local skills directory.

Connecting

For hosted HTTP the simplest route is OAuth, which needs no credential at all:

bash
claude mcp add --transport http skycloak https://mcp.skycloak.io

The first call opens your browser, you approve in the Skycloak login page, and the tools appear. If you belong to more than one workspace, name the one you want:

bash
claude mcp add --transport http skycloak "https://mcp.skycloak.io?workspace=<workspace-id>"

Otherwise, create an API key in the Skycloak dashboard and configure your MCP client to send it as a bearer token:

bash
claude mcp add --transport http skycloak https://mcp.skycloak.io --header "Authorization: Bearer sk_sc_XXX"

This adds the following to .claude.json:

json
{  "mcpServers": {    "skycloak": {      "type": "http",      "url": "https://mcp.skycloak.io",      "headers": {        "Authorization": "Bearer sk_sc_XXX"      }    }  }}

Gemini CLI installs the hosted server as an extension, from the manifest in this repository:

bash
gemini extensions install https://github.com/sky-cloak/skycloak-mcp

For local stdio, sign in once, then point your client at skycloak-mcp run:

bash
skycloak-mcp init        # one-time browser sign-in; stores a key in your keychain

Claude Desktop / Cursor (local, stdio):

jsonc
{  "mcpServers": {    "skycloak": {      "command": "skycloak-mcp",      "args": ["run", "--transport", "stdio"]    }  }}

Claude Code:

bash
claude mcp add skycloak -- skycloak-mcp run --transport stdio

For headless / CI (no browser), skip init and pass the key instead: add "env": { "SKYCLOAK_API_KEY": "sk_sc_..." } to the config, or claude mcp add skycloak --env SKYCLOAK_API_KEY=sk_sc_... -- skycloak-mcp run --transport stdio.

Add --allow-writes only when you intend to make changes (sign in with skycloak-mcp init --allow-writes, or use a write-scoped key).

Add ?readonly=true to a hosted HTTP URL to expose only read-only tools for that HTTP session, or ?readonly=false to request the write-capable tool surface. The query parameter defaults to false, but write tools are registered only when the server was started with --allow-writes.

Add ?workspace=<uuid> to pick which workspace an OAuth session acts on. It is only needed when you belong to more than one; with a single workspace the server picks it for you, and if you belong to several and name none, the connection fails with a message listing them.

Running the HTTP transport

bash
skycloak-mcp run --transport http --http-addr :8080

It needs no credential of its own: callers supply theirs per request, so nothing is injected at deploy time. GET /healthz and GET /readyz are unauthenticated and report only that the process is up; they deliberately do not probe the Skycloak API, so an upstream blip cannot fail every replica's probe at once. The server holds no session state, so replicas need no session affinity and can be scaled or rolled freely. SIGTERM stops new connections and drains in-flight calls.

The OAuth path is on whenever SKYCLOAK_ISSUER and SKYCLOAK_DASHBOARD_URL are set, which they are by default. GET /.well-known/oauth-protected-resource is then served unauthenticated, naming the realm as the authorization server. Its resource value is taken from SKYCLOAK_PUBLIC_URL when set, and otherwise from the request's own Host and scheme, so a single-host deployment behind an ingress needs no extra configuration. The scheme comes from X-Forwarded-Proto when present, and otherwise defaults to https for anything but a loopback host, since TLS terminates upstream and publishing an http:// identifier would not match the URL the client connected on. Set SKYCLOAK_PUBLIC_URL if your ingress rewrites Host. The document also lists openid profile email as its scopes_supported, and the WWW-Authenticate challenge repeats them as a scope parameter, so a client reading either one asks the realm for them: openid is required, because the token exchange makes the dashboard call Keycloak's userinfo endpoint and Keycloak refuses a token granted without it. A token that arrives without it is refused at verification with a 401 and the challenge, rather than carried to an exchange that cannot succeed, so a client still holding a grant from before stops retrying and signs in again. Blanking either of the issuer or dashboard variables turns OAuth off entirely, and the server goes back to challenging for an API key and nothing else.

OPENAI_APPS_CHALLENGE_TOKEN serves OpenAI's plugin-directory domain verification token at /.well-known/openai-apps-challenge, as plain text and nothing else. Unset, the route is not registered and the path 404s.

Startup logs one line with the wiring it resolved (oauth=, issuer=, dashboard=, public_url=, endpoint=, allow_writes=), so a misconfigured deployment can be spotted without a redeploy. Every request refused on the OAuth path logs one line naming the stage that failed (verify, exchange or scopes), the status the caller got, and the underlying error. A verification failure adds the check that rejected the token (expired, wrong_issuer, bad_signature, unknown_key_id, wrong_token_type, no_openid_scope, and so on); an exchange failure adds the dashboard's status and the host called. The caller appears as the token's subject once it is verified, and never as a credential: the access token, the Authorization header and the minted API key are never logged.

What the server sends to the Skycloak API

The hosted server and the local binary send the same headers to the Skycloak API (SKYCLOAK_ENDPOINT):

HeaderValueWhy
API-Keyyour API key or the session's minted keyauthenticates the request
API-VersionSKYCLOAK_API_VERSIONpins the API contract the server was built against
User-Agentskycloak-mcp/<version>identifies the client
X-MCP-Toolthe tool's registered name, for example skycloak_list_realmssays which tool made the request
X-MCP-Call-Ida random UUID made once per tool callgroups every request of one call

X-MCP-Tool and X-MCP-Call-Id are sent only on requests made while serving a tool call. One call can make several requests, once per cluster when cluster_id is omitted and again when a 429 or 5xx is retried, and they all share the call's ID. Skycloak uses the pair to count how often each tool is used, which tells us which tools to improve, document or retire. They carry no arguments, results or anything about you beyond what the API key already identifies, and they go only to the Skycloak API, never to your Keycloak clusters or anywhere else. Requests made outside a tool call, such as signing in and minting API keys, carry neither.

Configuration

Env varDefault
SKYCLOAK_API_KEYnone (optional for stdio; HTTP clients provide API-Key headers instead)
SKYCLOAK_ENDPOINThttps://api.skycloak.io
SKYCLOAK_API_VERSIONcurrent API version
SKYCLOAK_ISSUERhttps://login.app.skycloak.io/realms/skycloak (CLI sign-in, and the authorization server the HTTP transport verifies tokens against)
SKYCLOAK_CLIENT_IDskycloak-mcp (CLI device flow only)
SKYCLOAK_DASHBOARD_URLhttps://app.skycloak.io (mints CLI keys and HTTP session keys)
SKYCLOAK_PUBLIC_URLnone (derived from each request; set it when the ingress rewrites Host)
OPENAI_APPS_CHALLENGE_TOKENServes OpenAI's plugin-directory verification token at /.well-known/openai-apps-challenge. Unset, that path 404s.

Commands: init (browser sign-in), run (serve), logout (remove the stored key). init accepts --workspace <id>, --allow-writes, --allow-credentials, and --ttl-days (default 90).

FlagDefaultDescription
--transportstdiostdio or http
--http-addr:8080listen address for the HTTP transport
--allow-writesfalseenable mutating tools for stdio and permit HTTP sessions with readonly=false to register write tools

Development

bash
make build      # build the server binarymake test       # unit testsmake run        # run on stdio for local testingmake inspector  # MCP Inspector against the local binarymake lint       # golangci-lintmake generate   # regenerate the API client from the OpenAPI spec

The API client under internal/apiclient is generated from the Skycloak OpenAPI specification with oapi-codegen.

Keeping in sync with the API

The client in internal/apiclient is generated from internal/apiclient/openapi.yaml with oapi-codegen; run make generate to refresh it. CI fails if the committed generated code drifts from the spec. Requests are retried on 429/5xx with Retry-After-aware backoff.

Distribution

Released as GitHub binaries and a ghcr.io/sky-cloak/skycloak-mcp container image on each tag, and published to the MCP Registry as io.skycloak/skycloak-mcp. Most people do not need either: the hosted server needs no install.

Security

Please report vulnerabilities privately. See SECURITY.md.

Contributors

Built at Skycloak by Guilliano Molaire, Neville Omangi and Aphilas. The repository history was squashed when it was opened up, so the commit log does not reflect who wrote what.

License

Apache-2.0. The OpenAPI description in internal/apiclient/openapi.yaml is generated from the Skycloak platform API and is (c) Skycloak; it is included here so the client can be generated and verified. See NOTICE.

來源:README.md,提交 feb4504

工具

0
該伺服器需要登入,因此 SourceWeft 無法在沒有帳號的情況下讀取其工具,也未收錄。已連接帳號所能看到的內容可能因帳號及其權限而異。

版本歷史

5
  1. v0.15.0最新Nov 3, 2026
  2. v0.14.1Oct 23, 2026
  3. v0.14.0Oct 17, 2026
  4. v0.13.3Sep 21, 2026
  5. v0.13.2Sep 16, 2026

評分

已滿足適用檢查項的 85%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分