Skip to main content
Glama
@mgcrea/mcp-keycloak

@mgcrea/mcp-keycloak

by mgcrea

@mgcrea/mcp-keycloak

A Model Context Protocol server for the Keycloak Admin REST API. It lets an agent explore and administer a Keycloak instance — realms, users, groups, roles, clients, sessions, events, client scopes, protocol mappers, identity providers and authentication flows.

The server is read-only by default. Mutating tools are not merely refused when writes are off — they are never registered, so an agent cannot call them at all.

Features

  • Curated tools across the whole admin surface, with descriptions that spell out Keycloak's traps (clientId vs id, search vs exact vs q, roles-by-name vs roles-by-id).

  • Read-only by default. KEYCLOAK_ALLOW_WRITES=1 adds the write tools; the destructive ones then additionally require an explicit confirm: true on every call.

  • Two auth grants: an OAuth client-credentials service account (recommended) or the password grant via admin-cli (handy for local testing). Tokens are cached, refreshed ahead of expiry, reused via the refresh token when Keycloak issues one, and re-fetched on a mid-session 401.

  • List results are summarized, so listing a few hundred users doesn't flood the context; get_* tools still return the full representation.

  • A keycloak_request escape hatch for any endpoint without a curated tool (GET-only unless writes are enabled).

  • Native fetch, no runtime dependencies beyond the MCP SDK and Zod.

Related MCP server: mcp-keycloak-admin

Install

No install step — run it straight from npm:

npx -y @mgcrea/mcp-keycloak

Or pull the image the CI publishes on every tag:

docker run --rm -i --env-file .env ghcr.io/mgcrea/mcp-keycloak:latest

To hack on it, see Development.

Configure

The server needs admin credentials for your Keycloak. Pick one of the two grants.

  1. In the realm you want to authenticate against, create a client (e.g. mcp-keycloak) with Client authentication: ON and Service accounts roles: ON.

  2. Grant it admin rights: Clients → your client → Service account roles → Assign role → filter by clients → realm-management, then pick the roles you want. realm-admin is the composite that grants everything; for a read-only server, view-realm, view-users, view-clients, view-events, view-identity-providers are enough.

  3. Copy the Client ID and Client secret into .env.

To administer other realms from one client, create it in master and give it the admin realm role instead.

(B) Password grant — for quick local testing

Set KEYCLOAK_CLIENT_ID=admin-cli (a public client — leave the secret empty) plus KEYCLOAK_USERNAME / KEYCLOAK_PASSWORD. This runs as that human admin, with everything their account can do.

cp .env.example .env

Variable

Required

Description

KEYCLOAK_URL

yes

Base URL, e.g. https://keycloak.example.com. No /auth prefix on Keycloak ≥ 17.

KEYCLOAK_REALM

no

Realm the tools operate on. Defaults to master. Every tool can override it per call.

KEYCLOAK_AUTH_REALM

no

Realm to authenticate against. Defaults to KEYCLOAK_REALM; set to master for cross-realm.

KEYCLOAK_CLIENT_ID

no

Defaults to admin-cli.

KEYCLOAK_CLIENT_SECRET

(A)

Service-account secret. Its presence selects the client_credentials grant.

KEYCLOAK_USERNAME / _PASSWORD

(B)

Admin credentials for the password grant.

KEYCLOAK_GRANT_TYPE

no

Force client_credentials or password. Otherwise inferred from the above.

KEYCLOAK_ALLOW_WRITES

no

Set to 1 to register the write tools. Off by default.

KEYCLOAK_MAX_RETRIES

no

Retry budget for 401 / 429 / 5xx. Defaults to 3.

KEYCLOAK_REFRESH_SKEW_SECONDS

no

Refresh this long before expiry. Defaults to 30, clamped to half the token's lifetime.

KEYCLOAK_DEBUG

no

Set to 1 to log debug output to stderr.

Run

npx -y @mgcrea/mcp-keycloak   # speaks JSON-RPC over stdio

Wire into Claude Code

Add to .mcp.json (project) or ~/.claude.json (global):

{
  "mcpServers": {
    "keycloak": {
      "command": "npx",
      "args": ["-y", "@mgcrea/mcp-keycloak"],
      "env": {
        "KEYCLOAK_URL": "https://keycloak.example.com",
        "KEYCLOAK_CLIENT_ID": "mcp-keycloak",
        "KEYCLOAK_CLIENT_SECRET": "..."
      }
    }
  }
}

Writes are off unless you add "KEYCLOAK_ALLOW_WRITES": "1" to that env block.

Inspect the tools

npx @modelcontextprotocol/inspector npx -y @mgcrea/mcp-keycloak

Development

pnpm install
pnpm build
pnpm start          # node dist/cli.js
pnpm test

Point a client at a working tree with "command": "node", "args": ["/absolute/path/to/mcp-keycloak/dist/cli.js"].

Tools

Every tool takes an optional realm to override the configured default. Tools marked W exist only when KEYCLOAK_ALLOW_WRITES=1; those marked ⚠️ are destructive and additionally require confirm: true.

Start with keycloak_whoami. It reports which realm you authenticated against, as whom, and which realm-management roles the token actually carries — which is what a 403 from any other tool is nearly always about.

Area

Tools

Realms

whoami, get_server_info, list_realms, get_realm · W create_realm, update_realm, ⚠️ delete_realm

Users

list_users, count_users, get_user, get_user_groups, get_user_role_mappings, get_user_sessions · W create_user, update_user, send_user_action_email, set_user_groups, set_user_realm_roles, set_user_client_roles, ⚠️ delete_user, ⚠️ reset_user_password, ⚠️ logout_user

Groups

list_groups, get_group, get_group_members, get_group_role_mappings · W create_group, update_group, set_group_realm_roles, ⚠️ delete_group

Roles

list_realm_roles, get_realm_role, get_realm_role_members, get_role_composites, list_client_roles · W create_realm_role, update_realm_role, create_client_role, ⚠️ delete_realm_role

Clients

list_clients, get_client, get_client_secret, get_client_service_account_user, get_client_installation_config · W create_client, update_client, ⚠️ delete_client, ⚠️ regenerate_client_secret

Sessions & events

get_realm_session_stats, get_client_sessions, get_client_session_count, get_events_config, list_events, list_admin_events · W ⚠️ delete_session, ⚠️ logout_all_sessions, ⚠️ clear_events

Scopes & mappers

list_client_scopes, get_client_scope, get_client_assigned_scopes, list_protocol_mappers, evaluate_client_scopes · W create_client_scope, update_client_scope, assign_client_scope, unassign_client_scope, create_protocol_mapper, ⚠️ delete_client_scope, ⚠️ delete_protocol_mapper

Identity providers

list_identity_providers, get_identity_provider, list_identity_provider_mappers · W create_identity_provider, update_identity_provider, create_identity_provider_mapper, ⚠️ delete_identity_provider

Auth flows

list_authentication_flows, get_authentication_flow_executions, list_required_actions, get_realm_flow_bindings · W create_authentication_flow, copy_authentication_flow, update_authentication_execution, ⚠️ delete_authentication_flow

Escape hatch

keycloak_request — any admin endpoint. GET-only unless writes are enabled.

All names are prefixed keycloak_.

Sensitive: keycloak_get_client_secret returns a client's secret in plain text (it needs manage-clients to work at all). It's registered as a read tool because it is a GET; to put it out of reach entirely, move its registration inside the allowWrites block in src/tools/clients.ts.

Notes on Keycloak

A few things the tool descriptions repeat, because they cause most of the confusion:

  • clientId is not id. Every /clients/{id}/… endpoint wants the client's UUID, while the console only ever shows the clientId string. List tools return both.

  • Searching users: search is a loose match over username/name/email; username + exact is a precise lookup; q ("key:value") is the only way to match custom attributes.

  • Events are off by default. A realm with logging disabled returns an empty list rather than an error, so list_events checks and tells you when that's what happened. There is no backfill.

  • Access tokens live ~60 seconds. The token provider refreshes ahead of expiry and clamps its skew to half the token's lifetime, so a short lifespan doesn't mean re-authenticating on every call.

Develop

pnpm dev           # rebuild on change
pnpm test          # vitest
pnpm lint          # oxlint
pnpm format        # oxfmt
pnpm typecheck     # tsc --noEmit

License

MIT

Available Tools

44 tools
keycloak_auth_statusA
Read-only

Report whether this server has working Keycloak credentials, which realm and account it acts as, whether writes are enabled, and — when something is missing — exactly what to set. Call this first when a tool you expected is not listed: an absent tool here means missing configuration rather than a bug.

Inputs: no named parameters.

keycloak_count_usersA
Read-only

Count users matching a filter, without fetching them.

Inputs: q, email, exact, realm, +6 more.

keycloak_evaluate_client_scopesA
Read-only

Generate the access token a client would actually issue, without logging anyone in. The direct way to answer 'why is this claim missing from my JWT?'.

Inputs: clientUuid (required), realm, scope, userId.

keycloak_get_authentication_flow_executionsA
Read-only

Get the ordered steps inside a flow and whether each is REQUIRED, ALTERNATIVE, CONDITIONAL or DISABLED. This is what determines what a user is actually asked for when logging in (password, OTP, ...).

Inputs: flowAlias (required), realm.

keycloak_get_clientA
Read-only

Get a client's full configuration: flows, redirect URIs, web origins, and its attributes (including token lifespans). Its secret, if any, is redacted — use keycloak_get_client_secret to read it.

Inputs: clientUuid (required), realm.

keycloak_get_client_assigned_scopesA
Read-only

Show which client scopes are assigned to a client, split into default (always applied) and optional (applied only when the request asks for them).

Inputs: clientUuid (required), realm.

keycloak_get_client_installation_configA
Read-only

Get the ready-to-use adapter config (keycloak.json) for a client — issuer URL, realm, credentials. Handy for wiring an app up to this client.

Inputs: clientUuid (required), realm.

keycloak_get_client_scopeA
Read-only

Get one client scope with its protocol mappers.

Inputs: scopeId (required), realm.

keycloak_get_client_secretA
Read-only

Get a confidential client's CURRENT SECRET IN PLAIN TEXT. This is a live credential — it will appear in the conversation. Requires manage-clients. (To keep it out of reach entirely, move this tool's registration behind KEYCLOAK_ALLOW_WRITES.)

Inputs: clientUuid (required), realm.

keycloak_get_client_service_account_userA
Read-only

Get the service-account user backing a client. That user is where the client's admin roles are assigned, so this is the way to check what a client can actually do.

Inputs: clientUuid (required), realm.

keycloak_get_client_session_countA
Read-only

Count the active sessions for one client.

Inputs: clientUuid (required), realm.

keycloak_get_client_sessionsA
Read-only

List the active user sessions for one client.

Inputs: clientUuid (required), max, first, realm.

keycloak_get_events_configA
Read-only

Show whether event logging is enabled for the realm, which event types are recorded, and how long they are kept. Check this first if the event tools come back empty.

Inputs: realm.

keycloak_get_groupA
Read-only

Get one group with its attributes and subgroups.

Inputs: groupId (required), realm.

keycloak_get_group_membersA
Read-only

List the users in a group.

Inputs: groupId (required), max, first, realm, +1 more.

keycloak_get_group_role_mappingsA
Read-only

Get the roles mapped to a group. Every member of the group inherits these roles.

Inputs: groupId (required), realm.

keycloak_get_identity_providerA
Read-only

Get one identity provider's full config — endpoints, trust settings, sync mode. Its client secret is redacted.

Inputs: alias (required), realm.

keycloak_get_realmA
Read-only

Get a realm's full configuration: token lifespans, login/registration settings, password policy, SSO session timeouts, and the flow bindings.

Inputs: realm.

keycloak_get_realm_flow_bindingsA
Read-only

Show which flow is bound to each authentication entry point of the realm — i.e. which flow actually runs on a browser login, a direct grant, a registration, a password reset.

Inputs: realm.

keycloak_get_realm_roleA
Read-only

Get one realm role by name, with its attributes and composite flag.

Inputs: roleName (required), realm.

keycloak_get_realm_role_membersA
Read-only

List the users who have a given realm role — i.e. 'who has this role?'.

Inputs: roleName (required), max, first, realm.

keycloak_get_realm_session_statsA
Read-only

Count active sessions per client across the realm — who is logged in, and where.

Inputs: realm.

keycloak_get_role_compositesA
Read-only

List the roles contained in a composite role. Takes the role's UUID (not its name) — get it from keycloak_get_realm_role.

Inputs: roleId (required), realm.

keycloak_get_server_infoA
Read-only

Keycloak server version, uptime, JVM/memory info and enabled feature flags. The raw endpoint also dumps every SPI provider and theme (~1MB); this returns only the useful head of it.

Inputs: no named parameters.

keycloak_get_userA
Read-only

Get one user's full representation, including custom attributes.

Inputs: userId (required), realm.

keycloak_get_user_groupsA
Read-only

List the groups a user belongs to.

Inputs: userId (required), max, first, realm.

keycloak_get_user_role_mappingsA
Read-only

Get a user's role mappings. By default returns only roles assigned DIRECTLY to the user; set effective to also include roles inherited from groups and from composite roles — that is the set that actually lands in their token.

Inputs: userId (required), realm, effective.

keycloak_get_user_sessionsA
Read-only

List a user's active SSO sessions (where and when they are logged in).

Inputs: userId (required), realm.

keycloak_list_admin_eventsA
Read-only

Search admin events — the audit trail of changes made to the realm itself (who created this user, who changed that client). Requires admin event logging to be enabled.

Inputs: max, first, realm, dateTo, +6 more.

keycloak_list_authentication_flowsA
Read-only

List the realm's authentication flows — the step-by-step login pipelines (browser, direct grant, registration, reset credentials).

Inputs: realm.

keycloak_list_client_rolesA
Read-only

List the roles defined by a client. Note these are distinct from realm roles — realm-management's roles (view-users, manage-users, ...) are client roles.

Inputs: clientUuid (required), max, first, realm, +1 more.

keycloak_list_clientsA
Read-only

List the realm's clients (applications). Returns both id (the UUID every other client tool needs) and clientId (the name shown in the console).

Inputs: max, first, realm, search, +2 more.

keycloak_list_client_scopesB
Read-only

List the realm's client scopes. A client scope is a reusable bundle of protocol mappers and role scope — it's what decides which claims end up in a token.

Inputs: realm.

keycloak_list_eventsA
Read-only

Search user events — logins, logouts, failed logins, registrations. The way to answer 'why can't this user log in?'. Requires user event logging to be enabled on the realm.

Inputs: max, type, user, first, +5 more.

keycloak_list_groupsA
Read-only

List the realm's groups. Groups are a tree — top-level groups are returned with their subGroups nested inside.

Inputs: q, max, exact, first, +3 more.

keycloak_list_identity_provider_mappersA
Read-only

List an identity provider's mappers — the rules translating claims from the external IdP into Keycloak users, roles and groups.

Inputs: alias (required), realm.

keycloak_list_identity_providersA
Read-only

List the realm's identity providers (external login sources: Google, GitHub, a corporate SAML or OIDC IdP). Their client secrets are redacted.

Inputs: realm.

keycloak_list_protocol_mappersA
Read-only

List the protocol mappers on a client or on a client scope. Mappers are what put claims into a token (a user attribute, group membership, an audience, a hardcoded value).

Inputs: realm, scopeId, clientUuid.

keycloak_list_realm_rolesA
Read-only

List the realm-level roles defined in a realm.

Inputs: max, first, realm, search, +1 more.

keycloak_list_realmsA
Read-only

List the realms this token can see.

Inputs: briefRepresentation.

keycloak_list_required_actionsA
Read-only

List the realm's required actions (Update Password, Verify Email, Configure OTP) and whether each is enabled or applied to new users by default.

Inputs: realm.

keycloak_list_usersA
Read-only

Search users in a realm. Use search for a loose match across name/username/email, username/email + exact for a precise lookup, or q to match custom attributes.

Inputs: q, max, email, exact, +10 more.

keycloak_requestA
Read-only

Escape hatch: call any Keycloak Admin REST endpoint directly. Use it when no curated tool fits — user federation components, authorization policies, organizations, partial import/export, credentials. path is relative to the realm (users/123/credentials resolves under /admin/realms/{realm}/), or pass an absolute admin path starting with /admin/ (e.g. /admin/serverinfo). Writes are DISABLED: only GET is permitted. Set KEYCLOAK_ALLOW_WRITES=1 to allow mutations.

Inputs: path (required), body, query, realm, +1 more.

keycloak_whoamiA
Read-only

Show who the server is authenticated as and what it is actually allowed to do: the issuing realm, the client, the acting user, token expiry, and the realm + 'realm-management' roles that govern admin access. The roles are read from the account's role mappings on the server, not from the token — Keycloak issues tokens with no role claims to some clients, so the token alone proves nothing. Call this FIRST when another tool returns 403.

Inputs: no named parameters.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 44 tools

    Disambiguation5/5

    Each tool maps to a distinct Keycloak resource and action, and the list/get/count/evaluate distinctions are consistently clear. Even the two diagnostic tools differ: auth_status covers configuration readiness while whoami reports effective admin roles.

    Naming Consistency5/5

    Every tool follows the keycloak_<verb>_<resource> snake_case convention, with verbs mostly limited to list, get, count, and evaluate. The few one-offs like auth_status, whoami, and request are conventional and do not break the overall pattern.

    Tool Count2/5

    At 44 tools, this is a very heavy surface for an agent to hold in context, even though each tool maps to a legitimate Keycloak endpoint. The count exceeds the point where a tool set feels curated and starts to resemble a reference dump.

    Completeness3/5

    Read-side coverage is broad, including users, groups, roles, clients, scopes, sessions, events, flows, and identity providers. However, curated create/update/delete operations are almost entirely absent for core resources, and the keycloak_request escape hatch is the only path for writes and advanced features like credentials or authorization.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      C
      quality
      D
      maintenance
      Enables management of Keycloak identity and access management through the Keycloak Admin REST API, providing 299 tools for operations like user management, client configuration, and realm administration via natural language.
      100
      3
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Enables administrators to manage Keycloak realms, users, roles, clients, groups, and more through its Admin REST API, with safe-by-default configuration and destructive operation confirmation.
      56
      106 npm
      3
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Exposes Keycloak admin operations as tools via the Model Context Protocol, allowing management of users, clients, groups, roles, and more through natural language.
      87 npm
      MIT
    • A
      license
      C
      quality
      D
      maintenance
      A comprehensive MCP server for Keycloak administration, offering 80+ tools to manage users, realms, clients, roles, groups, sessions, events, organizations, and more directly from AI assistants.
      86
      47 npm
      MIT