Skycloak
公式Skycloak管理型Keycloak用のModel Context Protocolサーバー。任意のMCPクライアントからクラスター、レルム、アプリケーション、SSO、ユーザーを管理できます。
Skycloak MCPで何ができますか?
-
クラスターアップグレードレビュー — どのKeycloakクラスターがアップグレードに遅れているかを確認し、
list_cluster_upgradesとget_cluster_upgrade_pathを使用して推奨される進め方を取得します。 -
レルムプロビジョニング —
create_realmとcreate_identity_providerを使用して、アイデンティティプロバイダーを設定したステージングレルムを特定のクラスター上に作成します。 -
ユーザーアクティビティ監査 —
list_realm_usersとquery_eventsを活用して、最近レルムに追加されたユーザーを特定し、管理者の変更を確認します。 -
SIEM統合セットアップ —
create_siem_destinationとtest_siem_destinationを使用して、管理者イベントを外部Webhookに転送する宛先を設定します。 -
テーマコンテンツの置き換え —
update_theme_contentを確認付きで使用し、割り当てを失うことなくカスタムテーマのアーカイブをその場で更新します。 -
カスタムドメインルーティング —
create_domainとverify_domainを使用して、カスタムドメインを追加し、作成するDNSレコードを取得して検証し、トラフィックをレルムにルーティングします。
ドキュメント
skycloak-mcp
Skycloak(マネージドKeycloak)向けの公式Model Context Protocolサーバーです。あらゆるMCPクライアント(Claude Desktop、Claude Code、Cursor)から、クラスター、レルム、アプリケーション、SSOを管理できます。
ステータス: 早期リリース。ツールのカバレッジは拡大中です。利用可能な内容についてはチェンジログを参照してください。
クイックスタート
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を表面化します。
ツール
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 |
| ウェブフック | 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が返されます。オンにすると、既存のテーマはバックグラウンドで正確な配信名に移動されます。正確な名前でコンテンツが置き換えられたテーマは、restart_cluster_instancesがそのクラスターのKeycloakインスタンスをロールするまで、get_theme/list_themes/update_theme_contentからrestart_required: trueを報告します。再起動は即時適用ではなく、クラスターのメンテナンスウィンドウに延期される場合があり、deferred: trueとして報告され、既知の場合はnext_windowとして報告されます。create_clusterは非同期です。クラスターがavailableになるまでget_clusterをポーリングします。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設定には触れません。レルムのインポート/エクスポートは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のuserinfoエンドポイントを呼び出し、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クライアントは、Skycloak OpenAPI仕様からoapi-codegenで生成されます。
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を参照してください。