mcp-keycloak-admin
   
A Model Context Protocol (MCP) server to administer a Keycloak instance through its Admin REST API. Safe by default, configurable, and built with a clean, test-driven architecture.
Compatible with Keycloak 26.x (validated against 26.0.5).
Install
No install needed — run it straight from npm with npx:
npx -y mcp-keycloak-admin
The server speaks MCP over stdio, so you normally wire it into an MCP client rather than running it by hand — see Usage with an MCP client. New to it? The Quickstart spins up a local Keycloak and a client config in a couple of minutes.
Why
Administering Keycloak from an MCP client (an assistant, an IDE, a custom agent) means exposing day-to-day operations — searching users, managing roles, reading events — as MCP tools, without handing over a raw admin console. This server does that with strong guardrails so destructive actions never happen silently.
Features
- Two authentication modes, selectable by configuration:
service_account— a confidential client with a service account
(recommended; no admin password stored).
password— theadmin-cliclient with an admin username/password.- Safe by default:
READ_ONLYmode hides every write/destructive tool.ALLOWED_REALMSrestricts which realms the server may operate on.- Destructive operations require explicit confirmation (native MCP
elicitation, with a confirm: true parameter fallback for clients that do not support elicitation).
- Clean Architecture: a framework-free domain, application use cases, and
infrastructure adapters. No business concept travels as a raw string or number — every one is a validated value object.
Requirements
- Node.js >= 20
- A reachable Keycloak 26.x server
Usage with an MCP client
Add the server to your MCP client configuration:
{
"mcpServers": {
"keycloak-admin": {
"command": "npx",
"args": ["-y", "mcp-keycloak-admin"],
"env": {
"KEYCLOAK_BASE_URL": "http://localhost:8080",
"KEYCLOAK_REALM": "demo-realm",
"AUTH_MODE": "service_account",
"KC_CLIENT_ID": "mcp-admin",
"KC_CLIENT_SECRET": "your-secret"
}
}
}
}
See docs/setup-keycloak.md to create the mcp-admin client and grant it the least-privilege roles it needs.
Multiple Keycloak instances
Each server entry targets one Keycloak (one base URL + realm + auth). To manage several environments, add one entry per instance — each fully isolated, with its own credentials and guardrails:
{
"mcpServers": {
"kc-preprod": {
"command": "npx",
"args": ["-y", "mcp-keycloak-admin"],
"env": {
"KEYCLOAK_BASE_URL": "https://preprod.example.com",
"KEYCLOAK_REALM": "preprod-realm",
"AUTH_MODE": "service_account",
"KC_CLIENT_ID": "mcp-admin",
"KC_CLIENT_SECRET": "…",
"ALLOWED_REALMS": "preprod-realm"
}
},
"kc-prod": {
"command": "npx",
"args": ["-y", "mcp-keycloak-admin"],
"env": {
"KEYCLOAK_BASE_URL": "https://auth.example.com",
"KEYCLOAK_REALM": "prod-realm",
"AUTH_MODE": "service_account",
"KC_CLIENT_ID": "mcp-admin",
"KC_CLIENT_SECRET": "…",
"READ_ONLY": "true",
"ALLOWED_REALMS": "prod-realm"
}
}
}
}
The client namespaces the tools per server (e.g. kc-prod:keycloak_user_delete), so there's no risk of running an operation against the wrong environment. This is the recommended pattern: you can, for example, keep production READ_ONLY while preprod stays writable.
Configuration
| Variable | Required | Description | | ------------------- | --------------------- | -------------------------------------------------------- | | KEYCLOAK_BASE_URL | yes | Base URL of the Keycloak server (no trailing slash). | | KEYCLOAK_REALM | yes | Realm the server operates on. | | AUTH_MODE | yes | service_account or password. | | KC_CLIENT_ID | if service_account | Confidential client id (e.g. mcp-admin). | | KC_CLIENT_SECRET | if service_account | Client secret. | | KC_ADMIN_USERNAME | if password | Admin username. | | KC_ADMIN_PASSWORD | if password | Admin password. | | KC_ADMIN_REALM | no (default master) | Realm holding the admin user (password mode). | | READ_ONLY | no (default false) | When true, write/destructive tools are not registered. | | ALLOWED_REALMS | no | Comma-separated allow-list of realms. Empty = all. |
A full example lives in .env.example.
Tools
Levels: [R] read-only · [W] write · [D] destructive (requires confirmation). Every tool carries the matching MCP annotations (readOnlyHint / destructiveHint / idempotentHint).
Currently implemented:
Note: this table tracks the
mainbranch, which can run ahead of the latest npm release shown by the version badge above. To confirm what's available in your install, checknpm view mcp-keycloak-admin versionand pinmcp-keycloak-admin@latest.
| Tool | Level | Description | | ------------------------------------------- | ----- | ------------------------------------------------------------------- | | keycloak_user_search | R | Search realm users by email, username or free text. | | keycloak_user_get | R | Fetch a single user by id. | | keycloak_user_sessions_list | R | List a user's active sessions. | | keycloak_user_create | W | Create a realm user. | | keycloak_user_update | W | Update a user's email, name or enabled flag. | | keycloak_user_set_enabled | W | Enable or disable a user. | | keycloak_user_send_action_email | W | Send a required-actions email. | | keycloak_user_reset_password | D | Set a new password for a user. | | keycloak_user_logout | D | Revoke all of a user's sessions. | | keycloak_user_delete | D | Permanently delete a user (id + username must match). | | keycloak_role_list | R | List realm roles. | | keycloak_user_roles_get | R | List a user's realm roles. | | keycloak_user_role_assign | W | Grant a realm role to a user. | | keycloak_user_role_unassign | D | Revoke a realm role from a user. | | keycloak_client_roles_list | R | List the roles defined on a client. | | keycloak_user_client_roles_get | R | List a user's client roles. | | keycloak_user_client_role_assign | W | Grant a client role to a user. | | keycloak_user_client_role_unassign | D | Revoke a client role from a user. | | keycloak_client_list | R | List the realm clients. | | keycloak_client_create | W | Create a realm client. | | keycloak_client_update | W | Update a client (enabled, public, redirect URIs, CORS web origins). | | keycloak_client_delete | D | Delete a client. | | keycloak_client_get | R | Fetch a client by its clientId. | | keycloak_client_get_secret | R | Read a client secret (masked unless reveal). | | keycloak_client_scopes_list | R | List the realm's client scopes. | | keycloak_client_default_scopes_get | R | List a client's default scopes. | | keycloak_client_mappers_list | R | List a client's protocol mappers. | | keycloak_client_scope_assign | W | Add a default scope to a client. | | keycloak_client_scope_unassign | D | Remove a default scope from a client. | | keycloak_client_regenerate_secret | D | Regenerate a client secret (old one stops working). | | keycloak_group_list | R | List the realm's top-level groups. | | keycloak_group_members_list | R | List the members of a group. | | keycloak_user_groups_list | R | List the groups a user belongs to. | | keycloak_group_create | W | Create a top-level group. | | keycloak_group_member_add | W | Add a user to a group. | | keycloak_group_role_assign | W | Grant a realm role to a group. | | keycloak_group_member_remove | D | Remove a user from a group. | | keycloak_group_delete | D | Delete a group. | | keycloak_idp_list | R | List identity providers. | | keycloak_idp_get | R | Fetch an identity provider by alias. | | keycloak_idp_mappers_list | R | List an identity provider's mappers. | | keycloak_idp_create | W | Create an identity provider. | | keycloak_idp_delete | D | Delete an identity provider. | | keycloak_federation_list | R | List user federation (LDAP/Kerberos) providers. | | keycloak_federation_get | R | Fetch a federation provider by id. | | keycloak_federation_sync | W | Trigger a user sync (full or changed). | | keycloak_auth_flows_list | R | List authentication flows. | | keycloak_auth_required_actions_list | R | List required actions. | | keycloak_auth_required_action_set_enabled | W | Enable/disable a required action. | | keycloak_authz_resources_list | R | List a client's authorization resources. | | keycloak_authz_policies_list | R | List a client's authorization policies. | | keycloak_authz_permissions_list | R | List a client's authorization permissions. | | keycloak_events_login | R | Read recent login events (filterable). | | keycloak_events_admin | R | Read recent admin events. | | keycloak_realm_get_config | R | Read key realm configuration flags. | | keycloak_server_info | R | Read the Keycloak server version. |
See docs/users.md, docs/roles.md, docs/clients.md, docs/groups.md and docs/events-realm.md for parameters and examples, and docs/security.md for the safety model.
Roadmap
The architecture is designed to keep growing as thin use cases + tools. Remaining candidates: authorization policy/permission CRUD and evaluation, authentication flow mutation (copy/add executions), and advanced federation and identity-provider configuration. See docs/development.md for how to add one.
Development
npm install
npm test # unit tests
npm run test:integration # spins up a real Keycloak 26 via Testcontainers (needs Docker)
npm run check # typecheck + lint + format check + unit tests
npm run build # bundle to dist/
Releases are automated — see docs/releasing.md.
Contributing
Contributions are welcome — please read CONTRIBUTING.md.












