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?

  • Revisión de actualización de clúster — Pregunte qué clústeres de Keycloak están atrasados en actualizaciones y obtenga la ruta recomendada a seguir mediante list_cluster_upgrades y get_cluster_upgrade_path.

  • Aprovisionamiento de reinos — Cree un reino de staging en un clúster específico con proveedores de identidad configurados, usando create_realm y create_identity_provider.

  • Auditoría de actividad de usuarios — Encuentre quién fue agregado recientemente a un reino y revise los cambios de administración, aprovechando list_realm_users y query_events.

  • Configuración de integración SIEM — Configure un destino que reenvíe eventos de administración a un webhook externo, usando create_siem_destination y test_siem_destination.

  • Reemplazo de contenido de tema — Actualice el archivo de un tema personalizado en su lugar sin perder sus asignaciones, mediante update_theme_content con confirmación.

  • Enrutamiento de dominio personalizado — Agregue un dominio personalizado, recupere los registros DNS a crear, verifíquelos y enrute el tráfico a un reino usando create_domain y verify_domain.

Documentación

skycloak-mcp

Smithery

Servidor oficial del Protocolo de Contexto de Modelos para Skycloak (Keycloak gestionado): gestiona 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 añadido 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 cabecera. 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 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 401 en la primera llamada a una herramienta en lugar de al conectar.
  • 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 403 desde 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. Añade ?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 podría ver, por lo que init no solicita ese alcance por defecto. Usa una clave que lo tenga: 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

137 herramientas: 60 de solo lectura y 77 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, restart_cluster_instances, 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_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
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, update_theme_content, update_theme_settings, restart_cluster_instances) requieren confirm=true. update_theme_settings activa o desactiva exact_theme_names para el espacio de trabajo; la clave de API del llamador debe haber sido emitida para un propietario o administrador del espacio de trabajo, o recibe 403 incluso con themes:write. Activarlo mueve los temas existentes a sus nombres servidos exactos en segundo plano; un tema cuyo contenido fue reemplazado bajo su nombre exacto informa restart_required: true desde get_theme/list_themes/update_theme_content hasta que restart_cluster_instances reinicia las instancias de Keycloak de ese clúster. Un reinicio puede diferirse a la ventana de mantenimiento del clúster en lugar de aplicarse inmediatamente, informado como deferred: true y, cuando se conoce, next_window. create_cluster es asíncrono: 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 (la cadena vacía restablece el valor predeterminado integrado). update_theme_content reemplaza el archivo de un tema en su lugar (ZIP base64 o JAR de Keycloakify en content_base64), manteniendo el ID, nombre y asignaciones de dominio y aplicación del tema, por lo que editar un tema ya no significa eliminarlo y volver a subirlo; necesita confirm=true porque el archivo que sobrescribe no es recuperable, y update_theme aún cambia solo el nombre, la descripción y la versión. Consulta docs/theme-content-update.md para saber cómo se realiza esa llamada. update_cluster_security deja intactos los ajustes 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 puede importarse 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.

Prompts

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

PromptQué hace
audit_self_registrationEncuentra todos los dominios que aún permiten 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 inicios de sesión fallidos recientes para 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 ajustes de inicio de sesión y seguridad
provision_environmentCrea un clúster, añade un dominio y configura un proveedor de identidad, confirmando cada paso
set_up_custom_domainAñade un dominio personalizado, devuelve 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

Los prompts están controlados de la misma manera que las herramientas que nombran: los 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 nada. El requisito confirm=true en herramientas destructivas sigue aplicándose además.

Habilidades

Donde un prompt 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 plugins de OpenAI importa habilidades exactamente con esta forma.

HabilidadQué codifica
auth-incident-triageTriage de "los usuarios no pueden iniciar sesión": separar caídas de plataforma de ataques y de cambios de configuración, usando eventos, registros WAF y salud del clúster. Solo lectura
enterprise-sso-rolloutConectar un IdP empresarial a un realm 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-doctorPreflight de una exportación, importación o migración de Keycloak contra los bloqueadores que soporte realmente ve (políticas de script, la ruta legacy de /auth, expectativas de exportación parcial), y diagnosticar un trabajo fallido leyendo su error_message real en lugar del aviso genérico del dashboard
keycloak-upgrade-readinessEvaluar la deriva de versiones, determinar qué rompe la nueva versión de Keycloak (extensiones, temas) y secuenciar el despliegue entre entornos con una exportación como plan de reversión

Las habilidades siguen el mismo control de acceso que las herramientas que nombran: los tres flujos de trabajo construidos alrededor de herramientas de escritura se omiten en sesiones de solo lectura, y una sesión con alcance solo recibe una habilidad cuyas herramientas realmente posee. Las fuentes viven en internal/tools/skills/, un directorio por habilidad, en el formato estándar de Agent Skills, 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 credencial alguna:

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 aparecen las herramientas. Si perteneces a más de un workspace, nombra el que quieras:

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

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

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

Esto añade 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 headless / CI (sin navegador), omite init y pasa la clave en su lugar: añade "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.

Añade --allow-writes solo cuando tengas intención de hacer cambios (inicia sesión con skycloak-mcp init --allow-writes, o usa una clave con alcance de escritura).

Añade ?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 por defecto es false, pero las herramientas de escritura solo se registran cuando el servidor se inició con --allow-writes.

Añade ?workspace=<uuid> para elegir sobre qué workspace actúa una sesión OAuth. Solo es necesario cuando perteneces a más de uno; con un solo workspace el servidor lo elige por ti, y si perteneces a varios y no nombras ninguno, la conexión falla con un mensaje que los lista.

Ejecutando el transporte HTTP

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

No necesita credencial propia: los llamadores proporcionan la suya por solicitud, por lo que no se inyecta nada en el momento del despliegue. GET /healthz y GET /readyz no están autenticados y solo informan que el proceso está activo; deliberadamente no sondean la API de Skycloak, por lo que un problema upstream no puede hacer fallar la sonda de cada réplica 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 por defecto. GET /.well-known/oauth-protected-resource se sirve entonces sin autenticación, nombrando el realm 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 por defecto es https para cualquier cosa que no sea un host de loopback, ya que TLS termina upstream y publicar un identificador http:// no coincidiría con la URL a la que se conectó el cliente. Configura SKYCLOAK_PUBLIC_URL si tu ingress reescribe Host. El documento también lista openid profile email como su scopes_supported, y el desafío WWW-Authenticate los repite como parámetro scope, por lo que un cliente que lea cualquiera de ellos le pide al realm que los proporcione: openid es obligatorio, porque el intercambio de tokens hace que el dashboard llame al endpoint 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 tenga una concesión anterior deja de reintentar e inicia sesión de nuevo. Vaciar cualquiera de las variables de emisor o dashboard apaga OAuth por completo, y el servidor vuelve a desafiar por una clave API y nada más.

OPENAI_APPS_CHALLENGE_TOKEN sirve el token de verificación del directorio de plugins 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 el path devuelve 404.

El inicio registra una línea con el cableado resuelto (oauth=, issuer=, dashboard=, public_url=, endpoint=, allow_writes=), por lo que un despliegue mal configurado se puede detectar sin un redeploy. Cada solicitud rechazada en la ruta OAuth registra una línea nombrando la etapa que falló (verify, exchange o scopes), el estado que recibió el llamador y el error subyacente. Una falla de verificación añade 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 añade el estado del dashboard 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 API acuñada nunca se registran.

Configuración

Variable de entornoPor defecto
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 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úralo cuando el ingress reescribe Host)
OPENAI_APPS_CHALLENGE_TOKENSirve el token de verificación del directorio de plugins de OpenAI en /.well-known/openai-apps-challenge. Si no está configurado, ese path 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 (por defecto 90).

FlagPor defectoDescripció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 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 API bajo 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; ejecuta make generate para actualizarlo. CI falla si el código generado comprometido 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 tag, y publicado en el MCP Registry como io.skycloak/skycloak-mcp. La mayoría de las personas no necesitan ninguno: el servidor alojado no requiere instalación.

Seguridad

Por favor, reporta vulnerabilidades de forma privada. Consulta SECURITY.md.

Contribuidores

Construido en Skycloak por Guilliano Molaire, Neville Omangi y Aphilas. El historial del repositorio se aplastó cuando se abrió, por lo que el registro de commits 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. Consulta NOTICE.