Skycloak

oficial

Servidor de Model Context Protocol para Skycloak Keycloak gestionado. Administre clústeres, reinos, aplicaciones, SSO y usuarios desde cualquier cliente MCP.

¿Qué puedes hacer con Skycloak MCP?

Administra tus clústeres de Skycloak (Keycloak gestionado), reinos y SSO desde cualquier cliente MCP.

  • Revisión de actualizaciones de clúster — Pregunta qué clústeres están atrasados en las actualizaciones de Keycloak y obtén la ruta de actualización mediante list_cluster_upgrades y get_cluster_upgrade_path.
  • Aprovisionamiento de reinos — Crea un reino con inicio de sesión de Google y GitHub usando create_realm y create_identity_provider.
  • Reenvío de SIEM — Configura un destino SIEM que reenvíe eventos de administración a un webhook de Datadog mediante create_siem_destination.
  • Configuración de dominio personalizado — Agrega un dominio personalizado, obtén los registros DNS y verifícalo con create_domain y verify_domain.

Documentación

skycloak-mcp

Smithery

Servidor oficial del Protocolo de Contexto de Modelos para Skycloak (Keycloak gestionado): administra tus clústeres, dominios, aplicaciones y SSO desde cualquier cliente MCP (Claude Desktop, Claude Code, Cursor).

Estado: lanzamiento temprano. La cobertura de herramientas está creciendo; consulta el registro de cambios para ver lo que está disponible.

Inicio rápido

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

Sin clave de API, sin ID de cliente, sin configuración. Tu navegador se abre, inicias sesión en Skycloak y las herramientas aparecen. Cualquier cliente MCP que hable HTTP transmisible funciona de la misma manera: dale la URL y nada más.

Luego pide algo:

  • "¿Cuáles de mis clústeres de Keycloak están atrasados en actualizaciones?"
  • "Crea un dominio de staging en el clúster de la UE con inicio de sesión de Google y GitHub."
  • "¿Quién fue agregado al dominio de producción en la última semana?"
  • "Configura un destino SIEM que reenvíe eventos de administración a nuestro webhook de Datadog."

Autenticación y seguridad

  • HTTP alojado, con OAuth (sin credenciales que configurar). Apunta tu cliente a https://mcp.skycloak.io sin encabezado. El servidor responde 401 con un puntero a sus metadatos RFC 9728 en /.well-known/oauth-protected-resource, el cliente ejecuta el flujo de código de autorización del navegador contra el dominio de inicio de sesión de Skycloak, y el token de acceso que recibe se intercambia por una clave de API de corta duración y limitada al espacio de trabajo en la que se ejecuta la sesión. La clave dura una hora y se renueva automáticamente. No se almacena nada en la configuración de tu cliente.
  • HTTP alojado, con una clave de API. Crea una clave en el panel de Skycloak y envíala como Authorization: Bearer <key> (o API-Key: <key>). Cada solicitud lleva su propia credencial y actúa solo como el espacio de trabajo de esa credencial. El servidor no mantiene estado de sesión, por lo que una solicitud nunca hereda la de otro llamador. Las claves no se verifican antes de su uso: la API de Skycloak es la autoridad, por lo que una clave inválida aparece como un 401 en la primera llamada a una herramienta en lugar de al momento de la conexión.
  • Las herramientas coinciden con tu rol. Con OAuth, la lista de herramientas se recorta a lo que permiten los alcances de la sesión, por lo que un miembro del espacio de trabajo de solo lectura no ve herramientas de escritura que responderían 403. Con una clave de API, toda la superficie está registrada, porque los alcances de una clave no son visibles para el servidor, y una llamada no autorizada aparece como un 403 de la API.
  • Stdio local. Ejecuta skycloak-mcp init y aprueba en tu navegador (flujo de autorización de dispositivo OAuth 2.0). Genera una clave de API limitada al espacio de trabajo, la almacena en el llavero de tu sistema operativo y detecta tu espacio de trabajo predeterminado automáticamente (pasa --workspace <id> para elegir otro). skycloak-mcp logout elimina la clave almacenada.
  • Sin interfaz / CI. Establece la variable de entorno SKYCLOAK_API_KEY (crea una clave en el panel de Skycloak) para omitir el navegador por completo. Siempre tiene prioridad sobre el llavero.
  • Las escrituras están controladas por tu credencial, no por una bandera. El servidor alojado en https://mcp.skycloak.io se ejecuta con capacidad de escritura, y lo que realmente puedes cambiar está limitado por los alcances de tu clave y tu rol en el espacio de trabajo: un miembro de solo lectura no puede mutar nada, diga lo que diga la lista de herramientas. Agrega ?readonly=true a la URL para forzar una superficie de herramientas de solo lectura para una sesión. El binario local es al revés y no registra herramientas de escritura a menos que se inicie con --allow-writes.
  • Las credenciales del clúster son opcionales. get_cluster_credentials devuelve las credenciales de administrador de Keycloak de un clúster, que un asistente que tenga la clave vería, por lo que init no solicita ese alcance por defecto. Usa una clave que lo incluya: créala en el panel, o con stdio inicia sesión con skycloak-mcp init --allow-credentials. Sin ella, la herramienta devuelve un 403 que explica ambas rutas.
  • Las herramientas destructivas requieren confirmación: eliminar un dominio, por ejemplo, necesita un argumento explícito confirm=true.
  • Las solicitudes están limitadas por tasa según tu plan de Skycloak; en una respuesta 429 el servidor muestra Retry-After.

Herramientas

129 herramientas: 58 de solo lectura y 71 de escritura. Las herramientas de solo lectura están siempre disponibles. En el servidor alojado, las herramientas de escritura también están registradas y controladas por los alcances de tu credencial; el binario local las registra solo cuando se inicia con --allow-writes.

Los nombres de las herramientas llevan un prefijo skycloak_ que la tabla siguiente omite, por lo que list_clusters es skycloak_list_clusters en tu cliente.

ÁreaSolo lecturaEscritura (--allow-writes)
Clústereslist_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, set_cluster_maintenance_window, delete_cluster_maintenance_window
Seguridad perimetralget_cluster_security, list_cluster_captcha_domainsupdate_cluster_security, add_cluster_captcha_domain, remove_cluster_captcha_domain
Dominioslist_realms, get_realmcreate_realm, update_realm, delete_realm
Aplicacioneslist_applications, get_application, list_application_roles, list_application_sessionscreate_application, update_application, delete_application, assign_application_role, remove_application_role, rotate_application_secret
Proveedores de identidadlist_identity_providers, get_identity_provider, list_identity_provider_templates, discover_oidccreate_identity_provider (OIDC), update_identity_provider, delete_identity_provider, test_identity_provider
Usuarios, roles y gruposlist_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
Dominios personalizadoslist_domains, get_domain, list_domain_routes, get_domain_routecreate_domain, verify_domain, delete_domain, create_domain_route, update_domain_route, delete_domain_route
Marca y temaslist_themes, get_theme, get_theme_assignment, get_client_theme_assignment, get_login_branding, get_email_branding, download_theme_contentset_theme_assignment, set_client_theme_assignment, update_theme, delete_theme, upsert_login_branding, delete_login_branding, upsert_email_branding, delete_email_branding
Extensioneslist_extensions, list_cluster_extensionsinstall_extension, upgrade_extension, update_extension, uninstall_extension, delete_extension
SMTPget_smtpupsert_smtp, delete_smtp, test_smtp
Exportaciones y registroslist_exports, get_export, get_logs, get_security_logs, query_eventscreate_export, delete_export, export_cluster_events
Importación y exportación de dominiosget_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

Convenciones: las herramientas destructivas (delete_*, uninstall_extension, cancel_cluster_upgrade) requieren confirm=true. create_cluster es asíncrona: consulta get_cluster hasta que el clúster esté available. create_domain devuelve los registros DNS que el cliente debe crear; verify_domain activa una verificación de DNS. set_theme_assignment activa un tema personalizado por tipo de tema de Keycloak (cadena vacía restablece el valor predeterminado integrado). update_cluster_security deja intacta la configuración de CAPTCHA. La importación/exportación de dominios mueve la configuración de un dominio y es independiente de create_export, que vuelca la base de datos de un clúster completo: ambas son asíncronas, y el archivo del dominio siempre está cifrado, por lo que la contraseña utilizada para exportarlo se necesita para importarlo de nuevo. Un dominio se puede importar directamente desde una exportación existente (source_export_id) o desde un archivo subido (create_realm_import_upload_url, PUT, luego upload_s3_key); importar crea un dominio y rechaza una colisión de nombres en lugar de sobrescribir, y necesita confirm=true porque trae usuarios y credenciales consigo.

Indicaciones

Ocho indicaciones te dan un punto de partida en esa superficie de herramientas. Los clientes las muestran como comandos de barra o acciones sugeridas; cada una toma argumentos (dominio, clúster, ventana de tiempo) y guía al modelo a través de las herramientas correctas en el orden correcto.

IndicaciónQué hace
audit_self_registrationEncuentra todos los dominios que aún permiten el auto-registro, en un clúster o en todos
review_upgradesDetecta clústeres atrasados en su versión de Keycloak y traza la ruta de actualización
triage_failed_loginsObtiene los inicios de sesión fallidos recientes de un dominio y los agrupa por IP de origen
review_identity_providersLista las conexiones SSO de un dominio y verifica si una específica está habilitada
review_admin_changesMuestra quién cambió qué en un dominio recientemente, centrado en la configuración de inicio de sesión y seguridad
provision_environmentCrea un clúster, agrega un dominio y conecta un proveedor de identidad, confirmando cada paso
set_up_custom_domainAgrega un dominio personalizado, entrega los registros DNS exactos, verifica y lo enruta a un dominio
rotate_client_secretRegenera el secreto de cliente de una aplicación con el radio de impacto explicado primero

Las indicaciones están controladas de la misma manera que las herramientas que nombran: las tres que mutan solo se ofrecen a sesiones que podrían llamar a las herramientas de escritura que referencian, y sus instrucciones le dicen al modelo que confirme contigo antes de cambiar cualquier cosa. El requisito confirm=true en herramientas destructivas aún se aplica además.

Habilidades

Donde una indicación es un punto de partida, una habilidad es un manual operativo completo que el modelo carga bajo demanda. El servidor incluye cuatro, servidas a través del borrador de la extensión de Habilidades SEP-2640: declara io.modelcontextprotocol/skills en sus capacidades, responde skills/list y skills/get, y sirve cada SKILL.md como un recurso ordinario en skill://<name>/SKILL.md con un resumen sha256 en su entrada de listado. El directorio de complementos de OpenAI importa habilidades exactamente con esta forma.

HabilidadQué codifica
auth-incident-triageTriage de "los usuarios no pueden iniciar sesión": separa interrupciones de plataforma de ataques y de cambios de configuración, usando eventos, registros WAF y salud del clúster. Solo lectura
enterprise-sso-rolloutConecta un IdP empresarial a un dominio de extremo a extremo: validación del emisor, registro de la aplicación upstream, configuración del broker, prueba de conexión y verificación contra eventos de inicio de sesión reales
keycloak-migration-doctorPreverifica una exportación, importación o migración de Keycloak contra los bloqueadores que el soporte realmente ve (políticas de script, la ruta heredada /auth, expectativas de exportación parcial), y diagnostica un trabajo fallido leyendo su error_message real en lugar del aviso genérico del panel
keycloak-upgrade-readinessEvalúa la deriva de versiones, determina qué rompe la nueva versión de Keycloak (extensiones, temas) y secuencia el despliegue entre entornos con una exportación como plan de reversión

Las habilidades siguen el mismo control que las herramientas que nombran: los tres flujos construidos alrededor de herramientas de escritura se retienen de sesiones de solo lectura, y una sesión con alcance limitado solo recibe una habilidad cuyas herramientas realmente tiene. Las fuentes viven en internal/tools/skills/, un directorio por habilidad, en el formato estándar de Habilidades de Agente, por lo que también funcionan copiadas directamente en un directorio local de habilidades.

Conexión

Para HTTP alojado, la ruta más simple es OAuth, que no necesita ninguna credencial:

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

La primera llamada abre tu navegador, apruebas en la página de inicio de sesión de Skycloak y las herramientas aparecen. Si perteneces a más de un espacio de trabajo, nombra el que quieras:

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

De lo contrario, crea una clave de API en el panel de Skycloak y configura tu cliente MCP para enviarla como token de portador:

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

Esto agrega lo siguiente a .claude.json:

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

Para stdio local, inicia sesión una vez y luego apunta tu cliente a skycloak-mcp run:

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

Claude Desktop / Cursor (local, stdio):

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

Claude Code:

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

Para entornos headless / CI (sin navegador), omita init y pase la clave en su lugar: agregue "env": { "SKYCLOAK_API_KEY": "sk_sc_..." } a la configuración, o claude mcp add skycloak --env SKYCLOAK_API_KEY=sk_sc_... -- skycloak-mcp run --transport stdio.

Agregue --allow-writes solo cuando tenga la intención de realizar cambios (inicie sesión con skycloak-mcp init --allow-writes, o use una clave con alcance de escritura).

Agregue ?readonly=true a una URL HTTP alojada para exponer solo herramientas de solo lectura para esa sesión HTTP, o ?readonly=false para solicitar la superficie de herramientas con capacidad de escritura. El parámetro de consulta tiene como valor predeterminado false, pero las herramientas de escritura se registran solo cuando el servidor se inició con --allow-writes.

Agregue ?workspace=<uuid> para elegir sobre qué espacio de trabajo actúa una sesión OAuth. Solo es necesario cuando pertenece a más de uno; con un solo espacio de trabajo, el servidor lo elige por usted, y si pertenece a varios y no nombra ninguno, la conexión falla con un mensaje que los enumera.

Ejecución del transporte HTTP

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

No necesita credenciales propias: los llamadores proporcionan las suyas por solicitud, por lo que no se inyecta nada en el momento del despliegue. GET /healthz y GET /readyz no están autenticados e informan solo que el proceso está activo; deliberadamente no sondean la API de Skycloak, por lo que una interrupción ascendente no puede hacer fallar la sonda de todas las réplicas a la vez. El servidor no mantiene estado de sesión, por lo que las réplicas no necesitan afinidad de sesión y pueden escalarse o rotarse libremente. SIGTERM detiene nuevas conexiones y drena las llamadas en curso.

La ruta OAuth está activa siempre que SKYCLOAK_ISSUER y SKYCLOAK_DASHBOARD_URL estén configuradas, que es el valor predeterminado. GET /.well-known/oauth-protected-resource se sirve entonces sin autenticación, nombrando el reino como servidor de autorización. Su valor resource se toma de SKYCLOAK_PUBLIC_URL cuando está configurado, y de lo contrario de la propia Host y el esquema de la solicitud, por lo que un despliegue de un solo host detrás de un ingress no necesita configuración adicional. El esquema proviene de X-Forwarded-Proto cuando está presente, y de lo contrario tiene como valor predeterminado https para cualquier cosa que no sea un host de bucle local, ya que TLS termina en el upstream y publicar un identificador http:// no coincidiría con la URL a la que se conectó el cliente. Configure SKYCLOAK_PUBLIC_URL si su ingress reescribe Host. El documento también enumera openid profile email como su scopes_supported, y el desafío WWW-Authenticate los repite como un parámetro scope, por lo que un cliente que lea cualquiera de ellos le pide al reino que los proporcione: openid es obligatorio, porque el intercambio de tokens hace que el panel llame al endpoint de userinfo de Keycloak y Keycloak rechaza un token otorgado sin él. Un token que llega sin él se rechaza en la verificación con un 401 y el desafío, en lugar de llevarse a un intercambio que no puede tener éxito, por lo que un cliente que aún tiene una concesión anterior deja de reintentar e inicia sesión nuevamente. Dejar en blanco cualquiera de las variables de emisor o panel desactiva OAuth por completo, y el servidor vuelve a solicitar una clave de API y nada más.

OPENAI_APPS_CHALLENGE_TOKEN sirve el token de verificación del dominio del directorio de complementos de OpenAI en /.well-known/openai-apps-challenge, como texto plano y nada más. Si no está configurado, la ruta no se registra y la ruta devuelve 404.

El inicio registra una línea con el cableado que resolvió (oauth=, issuer=, dashboard=, public_url=, endpoint=, allow_writes=), por lo que un despliegue mal configurado se puede detectar sin un redespliegue. Cada solicitud rechazada en la ruta OAuth registra una línea que nombra la etapa que falló (verify, exchange o scopes), el estado que recibió el llamador y el error subyacente. Una falla de verificación agrega la comprobación que rechazó el token (expired, wrong_issuer, bad_signature, unknown_key_id, wrong_token_type, no_openid_scope, y así sucesivamente); una falla de intercambio agrega el estado del panel y el host llamado. El llamador aparece como el sujeto del token una vez verificado, y nunca como una credencial: el token de acceso, el encabezado Authorization y la clave de API acuñada nunca se registran.

Configuración

Variable de entornoPredeterminado
SKYCLOAK_API_KEYninguno (opcional para stdio; los clientes HTTP proporcionan encabezados API-Key en su lugar)
SKYCLOAK_ENDPOINThttps://api.skycloak.io
SKYCLOAK_API_VERSIONversión actual de la API
SKYCLOAK_ISSUERhttps://login.app.skycloak.io/realms/skycloak (inicio de sesión CLI, y el servidor de autorización contra el que el transporte HTTP verifica los tokens)
SKYCLOAK_CLIENT_IDskycloak-mcp (solo flujo de dispositivo CLI)
SKYCLOAK_DASHBOARD_URLhttps://app.skycloak.io (acuña claves CLI y claves de sesión HTTP)
SKYCLOAK_PUBLIC_URLninguno (derivado de cada solicitud; configúrelo cuando el ingress reescribe Host)
OPENAI_APPS_CHALLENGE_TOKENSirve el token de verificación del directorio de complementos de OpenAI en /.well-known/openai-apps-challenge. Si no está configurado, esa ruta devuelve 404.

Comandos: init (inicio de sesión en navegador), run (servir), logout (eliminar la clave almacenada). init acepta --workspace <id>, --allow-writes, --allow-credentials y --ttl-days (predeterminado 90).

IndicadorPredeterminadoDescripción
--transportstdiostdio o http
--http-addr:8080dirección de escucha para el transporte HTTP
--allow-writesfalsehabilita herramientas de mutación para stdio y permite que las sesiones HTTP con readonly=false registren herramientas de escritura

Desarrollo

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

El cliente de API en internal/apiclient se genera a partir de la especificación OpenAPI de Skycloak con oapi-codegen.

Mantenerse sincronizado con la API

El cliente en internal/apiclient se genera a partir de internal/apiclient/openapi.yaml con oapi-codegen; ejecute make generate para actualizarlo. CI falla si el código generado confirmado se desvía de la especificación. Las solicitudes se reintentan en 429/5xx con retroceso consciente de Retry-After.

Distribución

Publicado como binarios de GitHub y una imagen de contenedor ghcr.io/sky-cloak/skycloak-mcp en cada etiqueta, y publicado en el Registro MCP como io.skycloak/skycloak-mcp. La mayoría de las personas no necesitan ninguno: el servidor alojado no requiere instalación.

Seguridad

Informe las vulnerabilidades de forma privada. Consulte SECURITY.md.

Contribuyentes

Construido en Skycloak por Guilliano Molaire, Neville Omangi y Aphilas. El historial del repositorio se comprimió cuando se abrió, por lo que el registro de confirmaciones no refleja quién escribió qué.

Licencia

Apache-2.0. La descripción OpenAPI en internal/apiclient/openapi.yaml se genera a partir de la API de la plataforma Skycloak y es (c) Skycloak; se incluye aquí para que el cliente pueda generarse y verificarse. Consulte NOTICE.