Skycloak
公式Skycloak管理型Keycloak用のModel Context Protocolサーバー。任意のMCPクライアントからクラスター、レルム、アプリケーション、SSO、ユーザーを管理できます。
Skycloak MCPで何ができますか?
任意MCPクライアントからSkycloak(マネージドKeycloak)クラスター、レルム、SSOを管理できます。
- クラスターアップグレードレビュー — Keycloakアップグレードが遅れているクラスターを確認し、
list_cluster_upgradesとget_cluster_upgrade_pathでアップグレードパスを取得します。 - レルムプロビジョニング —
create_realmとcreate_identity_providerを使用して、GoogleおよびGitHubサインイン対応のレルムを作成します。 - SIEM転送 —
create_siem_destinationを使用して、管理者イベントをDatadogウェブフックに転送するSIEM宛先を設定します。 - カスタムドメイン設定 —
create_domainとverify_domainでカスタムドメインを追加し、DNSレコードを取得して検証します。
ドキュメント
skycloak-mcp
Skycloak(マネージドKeycloak)向けの公式Model Context Protocolサーバーです。クラスター、レルム、アプリケーション、SSOを任意のMCPクライアント(Claude Desktop、Claude Code、Cursor)から管理できます。
ステータス: 早期リリース。ツールのカバレッジは拡大中です。利用可能な内容についてはチェンジログを参照してください。
クイックスタート
claude mcp add --transport http skycloak https://mcp.skycloak.io
APIキーもクライアントIDも設定も不要です。ブラウザが開き、Skycloakにサインインするとツールが表示されます。ストリーミングHTTPに対応したMCPクライアントはどれも同じように動作します。URLだけを渡せばよいのです。
その後、次のようなことを依頼できます:
- 「アップグレードが遅れているKeycloakクラスターはどれですか?」
- 「EUクラスターにGoogleとGitHubのサインインを備えたステージングレルムを作成してください。」
- 「先週、本番レルムに追加されたユーザーは誰ですか?」
- 「管理イベントをDatadogウェブフックに転送するSIEM送信先を設定してください。」
認証と安全性
- ホステッドHTTP、OAuth対応(設定する認証情報は不要)。 クライアントをヘッダーなしで
https://mcp.skycloak.ioにポイントします。サーバーは401で、/.well-known/oauth-protected-resourceにあるRFC 9728メタデータへのポインターで応答します。クライアントはSkycloakログインレルムに対してブラウザの認可コードフローを実行し、取得したアクセストークンはセッションが使用する短命のワークスペーススコープ付きAPIキーと交換されます。キーは1時間有効で、自動的に更新されます。クライアント設定には何も保存されません。 - ホステッド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を表面化します。
ツール
129のツール: 読み取り専用58、書き込み71。読み取り専用ツールは常に利用可能です。ホステッドサーバーでは書き込みツールも登録され、認証情報のスコープによって制御されます。ローカルバイナリは--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, 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 | set_theme_assignment, set_client_theme_assignment, update_theme, 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 |
| ウェブフック | 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)にはconfirm=trueが必要です。create_clusterは非同期です。クラスターがavailableになるまでget_clusterをポーリングします。create_domainは顧客が作成する必要があるDNSレコードを返します。verify_domainはDNSチェックをトリガーします。set_theme_assignmentはKeycloakテーマタイプごとにカスタムテーマをアクティブ化します(空文字列は組み込みのデフォルトにリセット)。update_cluster_securityはCAPTCHA設定を変更しません。レルムのインポート/エクスポートは1つのレルムの設定を移動し、クラスター全体のデータベースをダンプするcreate_exportとは別です。両方とも非同期で、レルムアーカイブは常に暗号化されているため、エクスポートに使用したパスワードが再インポートに必要です。レルムは既存のエクスポート(source_export_id)またはアップロードされたアーカイブ(create_realm_import_upload_url、PUT、その後upload_s3_key)から直接インポートできます。インポートはレルムを作成し、上書きではなく名前の衝突を拒否し、ユーザーと認証情報を伴うためconfirm=trueが必要です。
プロンプト
8つのプロンプトがツールサーフェスへの出発点を提供します。クライアントはこれらをスラッシュコマンドまたは推奨アクションとして表示します。各プロンプトは引数(レルム、クラスター、時間枠)を受け取り、モデルを正しい順序で適切なツールに導きます。
| プロンプト | 機能 |
|---|---|
audit_self_registration | 1つのクラスターまたはすべてのクラスターで、自己登録をまだ許可しているすべてのレルムを検索します |
review_upgrades | Keycloakバージョンで遅れているクラスターを特定し、アップグレードパスを提示します |
triage_failed_logins | レルムの最近の失敗したログインを取得し、送信元IPごとにグループ化します |
review_identity_providers | レルムのSSO接続を一覧表示し、特定の接続が有効かどうかを確認します |
review_admin_changes | 最近レルムで誰が何を変更したかを表示し、ログインとセキュリティ設定に焦点を当てます |
provision_environment | クラスターを作成し、レルムを追加し、アイデンティティプロバイダーを接続し、各ステップを確認します |
set_up_custom_domain | カスタムドメインを追加し、正確なDNSレコードを返し、検証し、レルムにルーティングします |
rotate_client_secret | 影響範囲を事前に明示してアプリケーションのクライアントシークレットを再生成します |
プロンプトは、名前が示すツールと同じ方法で制御されます。変更を加える3つは、参照する書き込みツールを呼び出せるセッションにのみ提供され、その指示はモデルに変更前に確認するよう求めます。破壊的なツールのconfirm=true要件はその上に引き続き適用されます。
スキル
プロンプトが出発点であるのに対し、スキルはモデルがオンデマンドで読み込む完全な運用プレイブックです。サーバーには4つが同梱され、ドラフトの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をレルムにエンドツーエンドで接続: 発行者検証、アップストリームアプリ登録、ブローカー設定、接続テスト、実際のログインイベントに対する検証 |
keycloak-migration-doctor | Keycloakエクスポート、インポート、または移行を、サポートが実際に確認するブロッカー(スクリプトポリシー、レガシーの/authパス、部分エクスポートの期待)に対して事前チェックし、一般的なダッシュボード通知ではなく実際のerror_messageを読んで失敗したジョブを診断します |
keycloak-upgrade-readiness | バージョンのずれを評価し、新しいKeycloakバージョンが何を壊すか(拡張機能、テーマ)を把握し、ロールバック計画としてエクスポートを使用して環境全体の展開を順序付けます |
スキルは、名前が示すツールと同じ制御に従います。書き込みツールを中心に構築された3つのワークフローは読み取り専用セッションからは提供されず、スコープ付きセッションには実際に持っているツールのスキルのみが提供されます。ソースはinternal/tools/skills/にあり、スキルごとに1つのディレクトリで、標準の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クライアントがベアラートークンとして送信するように設定します:
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セッションが操作するワークスペースを選択できます。これは複数のワークスペースに所属している場合にのみ必要です。単一のワークスペースの場合はサーバーが自動的に選択します。複数に所属していて名前を指定しない場合、接続はそれらを列挙したメッセージとともに失敗します。
HTTPトランスポートの実行
skycloak-mcp run --transport http --http-addr :8080
これ自体には資格情報は不要です。呼び出し元がリクエストごとに資格情報を提供するため、デプロイ時に何も注入されません。GET /healthz と GET /readyz は認証不要で、プロセスが稼働していることのみを報告します。これらは意図的にSkycloak APIをプローブしないため、上流の障害がすべてのレプリカのプローブを同時に失敗させることはありません。サーバーはセッション状態を保持しないため、レプリカにセッションアフィニティは不要で、自由にスケールまたはロールアウトできます。SIGTERM は新しい接続を停止し、実行中の呼び出しをドレインします。
OAuthパスは、SKYCLOAK_ISSUER と SKYCLOAK_DASHBOARD_URL が設定されている場合(デフォルトで設定されています)に有効になります。その場合、GET /.well-known/oauth-protected-resource は認証不要で提供され、レルムを認可サーバーとして指定します。その resource 値は、設定されている場合は SKYCLOAK_PUBLIC_URL から取得され、それ以外の場合はリクエスト自身の Host とスキームから取得されます。そのため、イングレスの背後にある単一ホストのデプロイでは追加設定は不要です。スキームは、X-Forwarded-Proto が存在する場合はそこから取得され、それ以外の場合はループバックホスト以外では https にデフォルト設定されます。これは、TLSが上流で終端され、http:// 識別子を公開してもクライアントが接続したURLと一致しないためです。イングレスが Host を書き換える場合は、SKYCLOAK_PUBLIC_URL を設定します。ドキュメントには openid profile email もその scopes_supported としてリストされ、WWW-Authenticate チャレンジはそれらを scope パラメータとして繰り返すため、どちらかを読み取るクライアントはレルムにそれらを要求します:openid は必須です。トークン交換によりダッシュボードがKeycloakのユーザー情報エンドポイントを呼び出すため、Keycloakはそれなしで付与されたトークンを拒否します。それなしで到着したトークンは、成功しない交換に運ばれるのではなく、401 とチャレンジで検証時に拒否されるため、以前からの付与をまだ保持しているクライアントは再試行を停止して再度サインインします。発行者またはダッシュボード変数のいずれかを空白にすると、OAuthは完全にオフになり、サーバーはAPIキーのみを要求するチャレンジに戻ります。
OPENAI_APPS_CHALLENGE_TOKEN は、OpenAIのプラグインディレクトリのドメイン検証トークンを /.well-known/openai-apps-challenge でプレーンテキストとしてのみ提供します。未設定の場合、ルートは登録されず、パスは404を返します。
起動時には、解決された配線(oauth=、issuer=、dashboard=、public_url=、endpoint=、allow_writes=)を含む1行がログに記録されるため、誤って設定されたデプロイを再デプロイなしで検出できます。OAuthパスで拒否されたすべてのリクエストは、失敗したステージ(verify、exchange、または scopes)、呼び出し元が受け取ったステータス、および基になるエラーを名前付きで1行ログに記録します。検証の失敗は、トークンを拒否したチェック(expired、wrong_issuer、bad_signature、unknown_key_id、wrong_token_type、no_openid_scope など)を追加します。交換の失敗は、ダッシュボードのステータスと呼び出されたホストを追加します。呼び出し元は、検証されるとトークンのサブジェクトとして表示され、資格情報としては決して表示されません。アクセストークン、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トランスポートがトークンを検証する認可サーバー) |
SKYCLOAK_CLIENT_ID | skycloak-mcp(CLIデバイスフローのみ) |
SKYCLOAK_DASHBOARD_URL | https://app.skycloak.io(CLIキーとHTTPセッションキーを発行) |
SKYCLOAK_PUBLIC_URL | なし(各リクエストから導出。イングレスが Host を書き換える場合に設定) |
OPENAI_APPS_CHALLENGE_TOKEN | OpenAIのプラグインディレクトリ検証トークンを /.well-known/openai-apps-challenge で提供。未設定の場合、そのパスは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 コンテナイメージとしてリリースされ、MCP Registry に io.skycloak/skycloak-mcp として公開されます。ほとんどの人はどちらも必要ありません。ホスト型サーバーはインストール不要です。
セキュリティ
脆弱性は非公開で報告してください。SECURITY.md を参照してください。
コントリビューター
Skycloak でGuilliano Molaire、Neville Omangi、Aphilasによって構築されました。リポジトリの履歴は公開時にスカッシュされたため、コミットログは誰が何を書いたかを反映していません。
ライセンス
Apache-2.0。internal/apiclient/openapi.yaml のOpenAPI記述はSkycloakプラットフォームAPIから生成され、(c) Skycloakに帰属します。クライアントを生成および検証できるようにするためにここに含まれています。NOTICE を参照してください。