@mgcrea/mcp-keycloak
This MCP server lets an agent explore and administer a Keycloak instance through curated tools — read-only by default, with optional write operations behind KEYCLOAK_ALLOW_WRITES.
Inspect access:
keycloak_auth_statusandkeycloak_whoamireport credentials, acting identity, enabled writes, and actual admin roles.Realms & server: view server info, list realms, and read full realm configuration.
Users: search, filter, count, and fetch users; list their groups, role mappings, and active sessions.
Groups: list groups, get group details, membership, and inherited role mappings.
Roles: list/get realm and client roles, view role members and composite role contents.
Clients: list/get clients, read client secrets, service-account users, and installation configs.
Sessions & events: realm/client session stats, event and admin-event logs, plus event logging config.
Scopes & mappers: inspect client scopes, assigned scopes, protocol mappers, and evaluate what claims a client would issue.
Identity providers: list/get IdPs and their mappers.
Auth flows: list authentication flows, flow executions, required actions, and flow bindings.
Escape hatch:
keycloak_requestcalls any admin REST endpoint (GET-only unless writes are enabled).Write mode: with
KEYCLOAK_ALLOW_WRITES=1, create/update/delete tools appear for realms, users, groups, roles, clients, scopes, mappers, IdPs, and flows; destructive actions also requireconfirm: true.
Provides tools to explore and administer a Keycloak instance, covering realms, users, groups, roles, clients, sessions, events, client scopes, protocol mappers, identity providers, and authentication flows. Read-only by default, with optional write operations.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@mgcrea/mcp-keycloak List all users in the master realm and their enabled status"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@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 (
clientIdvsid,searchvsexactvsq, roles-by-name vs roles-by-id).Read-only by default.
KEYCLOAK_ALLOW_WRITES=1adds the write tools; the destructive ones then additionally require an explicitconfirm: trueon 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_requestescape 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-keycloakOr pull the image the CI publishes on every tag:
docker run --rm -i --env-file .env ghcr.io/mgcrea/mcp-keycloak:latestTo hack on it, see Development.
Configure
The server needs admin credentials for your Keycloak. Pick one of the two grants.
(A) Service account — recommended
In the realm you want to authenticate against, create a client (e.g.
mcp-keycloak) with Client authentication: ON and Service accounts roles: ON.Grant it admin rights: Clients → your client → Service account roles → Assign role → filter by clients →
realm-management, then pick the roles you want.realm-adminis the composite that grants everything; for a read-only server,view-realm,view-users,view-clients,view-events,view-identity-providersare enough.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 .envVariable | Required | Description |
| yes | Base URL, e.g. |
| no | Realm the tools operate on. Defaults to |
| no | Realm to authenticate against. Defaults to |
| no | Defaults to |
| (A) | Service-account secret. Its presence selects the |
| (B) | Admin credentials for the password grant. |
| no | Force |
| no | Set to |
| no | Retry budget for 401 / 429 / 5xx. Defaults to |
| no | Refresh this long before expiry. Defaults to |
| no | Set to |
Run
npx -y @mgcrea/mcp-keycloak # speaks JSON-RPC over stdioWire 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-keycloakDevelopment
pnpm install
pnpm build
pnpm start # node dist/cli.js
pnpm testPoint 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 |
|
Users |
|
Groups |
|
Roles |
|
Clients |
|
Sessions & events |
|
Scopes & mappers |
|
Identity providers |
|
Auth flows |
|
Escape hatch |
|
All names are prefixed keycloak_.
Sensitive:
keycloak_get_client_secretreturns a client's secret in plain text (it needsmanage-clientsto 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 theallowWritesblock in src/tools/clients.ts.
Notes on Keycloak
A few things the tool descriptions repeat, because they cause most of the confusion:
clientIdis notid. Every/clients/{id}/…endpoint wants the client's UUID, while the console only ever shows theclientIdstring. List tools return both.Searching users:
searchis a loose match over username/name/email;username+exactis 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_eventschecks 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 --noEmitLicense
MIT
Available Tools
44 toolskeycloak_auth_statusARead-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_usersARead-only
Count users matching a filter, without fetching them.
Inputs: q, email, exact, realm, +6 more.
keycloak_evaluate_client_scopesARead-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_executionsARead-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_clientARead-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_scopesARead-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_configARead-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_scopeARead-only
Get one client scope with its protocol mappers.
Inputs: scopeId (required), realm.
keycloak_get_client_secretARead-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_userARead-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_countARead-only
Count the active sessions for one client.
Inputs: clientUuid (required), realm.
keycloak_get_client_sessionsARead-only
List the active user sessions for one client.
Inputs: clientUuid (required), max, first, realm.
keycloak_get_events_configARead-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_groupARead-only
Get one group with its attributes and subgroups.
Inputs: groupId (required), realm.
keycloak_get_group_membersARead-only
List the users in a group.
Inputs: groupId (required), max, first, realm, +1 more.
keycloak_get_group_role_mappingsARead-only
Get the roles mapped to a group. Every member of the group inherits these roles.
Inputs: groupId (required), realm.
keycloak_get_identity_providerARead-only
Get one identity provider's full config — endpoints, trust settings, sync mode. Its client secret is redacted.
Inputs: alias (required), realm.
keycloak_get_realmARead-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_bindingsARead-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_roleARead-only
Get one realm role by name, with its attributes and composite flag.
Inputs: roleName (required), realm.
keycloak_get_realm_role_membersARead-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_statsARead-only
Count active sessions per client across the realm — who is logged in, and where.
Inputs: realm.
keycloak_get_role_compositesARead-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_infoARead-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_userARead-only
Get one user's full representation, including custom attributes.
Inputs: userId (required), realm.
keycloak_get_user_groupsARead-only
List the groups a user belongs to.
Inputs: userId (required), max, first, realm.
keycloak_get_user_role_mappingsARead-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_sessionsARead-only
List a user's active SSO sessions (where and when they are logged in).
Inputs: userId (required), realm.
keycloak_list_admin_eventsARead-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_flowsARead-only
List the realm's authentication flows — the step-by-step login pipelines (browser, direct grant, registration, reset credentials).
Inputs: realm.
keycloak_list_client_rolesARead-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_clientsARead-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_scopesBRead-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_eventsARead-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_groupsARead-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_mappersARead-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_providersARead-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_mappersARead-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_rolesARead-only
List the realm-level roles defined in a realm.
Inputs: max, first, realm, search, +1 more.
keycloak_list_realmsARead-only
List the realms this token can see.
Inputs: briefRepresentation.
keycloak_list_required_actionsARead-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_usersARead-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_requestARead-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_whoamiARead-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
Scored across 44 tools
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.
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.
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.
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
Related MCP Connectors
Every Canopy public API operation as a tool, run as you after a browser sign-in or on an API key.
OAuth 2.1 short-link tools for AI agents with scoped tokens, approvals, audit logs, and revocation.
Access Pollinations models and API capabilities through agent tools.
Read-only HopBase AI gateway tools: models, limits, docs search, balance and usage for your API key.
Related MCP Servers
- AlicenseCqualityDmaintenanceEnables 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.1003MIT
- AlicenseAqualityCmaintenanceEnables 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.56106 npm3MIT
- AlicenseNot gradedqualityDmaintenanceExposes Keycloak admin operations as tools via the Model Context Protocol, allowing management of users, clients, groups, roles, and more through natural language.87 npmMIT
- AlicenseCqualityDmaintenanceA 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.8647 npmMIT