Keycloak MCP Server
Summary: The schema exposes only a minimal four-tool subset of this server — list realms, list/create/delete users — far short of the README's 24-tool, 7-toolset v1.0 feature set.
List realms (
list-realms) — enumerate all realms the configured account can access; no parameters.List users (
list-users) — list users in a given realm (realmrequired).Create user (
create-user) — add a user to a realm with username, email, first and last name (all required).Delete user (
delete-user) — remove a user byrealmanduserId.
Gaps versus the README:
Tool naming is the deprecated 0.x style (
create-user,delete-user,list-realms,list-users) instead of<domain>_<verb>(user_create,user_delete,realm_list,user_search), indicating a pre-1.0 server.No group, role, client, session, event or security tools; no
realm_get,user_get,user_update, oruser_send_actions_email.No
confirm: truepreview-then-confirm flow, no read-only/allowlist/master-write guardrails, and no output schemas or pagination visible.No prompts (
onboard_employee,offboard_employee,audit_realm_security,investigate_failed_logins) or MCP resources (keycloak://realms/...).No update capability at all — users can be created or deleted but not modified, disabled, or assigned groups/roles.
Provides tools for Keycloak administration, allowing management of users and realms including creating and deleting users, listing available realms, and viewing users within specific realms.
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., "@Keycloak MCP Serverlist all users in the 'customer' realm"
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.
Keycloak MCP Server
A Model Context Protocol (MCP) server for Keycloak administration. It lets an AI assistant such as Claude manage users, groups, roles and sessions, and inspect clients, events and the security posture of your realms, through the Keycloak Admin REST API, with least-privilege authentication and guardrails around every write.
This server acts with the permissions of the Keycloak account you give it. Use adedicated service-account client with only the roles you need, never the bootstrap admin. Every tool that changes data asks for confirmation by default, and a read-only mode is available. See Security.
Highlights
24 tools in 7 toolsets, enabled per toolset. The default set (
core,groups,roles) is small; everything else is opt-in.Least-privilege auth.
client_credentialswith a service account is the recommended grant; the password grant stays available. No credential defaults, so a missing setting fails fast.Guardrails. Read-only mode, realm allowlist, write protection for the
masterrealm, and a preview-then-confirm: trueflow for every change. Grants of administrative rights are detected through composite roles and parent groups.4 guided prompts (onboarding, offboarding, security audit, failed-login investigation) and MCP resources for realms and users, with realm-name completion.
Structured, paginated output with output schemas; secrets and credentials are never returned or logged.
Works with Claude Desktop, Claude Code, VS Code, Cursor and any stdio MCP client. Requires Node.js 22 or newer.
Related MCP server: User Management MCP Server
How it works
Your MCP client starts the server as a local child process and talks to it over stdio. Every tool call passes the guards, then goes through a single gateway that owns the Keycloak login and caches the access token.
What a confirmed call looks like
Every tool that changes data is destructive (it deletes or revokes) or sensitive (it changes identity, credentials, rights or protection mechanisms, for example user_update or user_role_assign). Called without confirm: true, such a tool only returns a preview of what would happen and changes nothing. After you approve, the assistant repeats the call with confirm: true.
The model can set confirm: true itself, even on its first call. The server then still computes the preview and returns it with the result, but only your client's approval prompt proves that a human agreed. All these tools carry destructiveHint, so clients that ask before destructive calls ask here too.
Quick start
Requirements: Node.js 22 or newer, a Keycloak server your machine can reach (tested with Keycloak 24.0 to 26.8), and an MCP client.
1. Prepare Keycloak (3 steps)
In the realm you want to administer (here demo):
Create a client
mcp-adminwith Client authentication on and only Service accounts roles enabled (turn off Standard flow and Direct access grants).Assign roles. On the client's Service accounts roles tab, assign client roles of
realm-management. For a first read-only trial:view-users,query-users,query-groups,view-realm.Copy the secret from the client's Credentials tab.
Step-by-step instructions with Admin Console click paths, kcadm.sh commands and a local Docker Keycloak: docs/getting-started.md.
2. Configure your MCP client
Example for Claude Code (other clients: docs/clients.md):
claude mcp add --transport stdio \
--env KEYCLOAK_URL=https://keycloak.example.com \
--env KEYCLOAK_AUTH_REALM=demo \
--env KEYCLOAK_CLIENT_ID=mcp-admin \
--env KEYCLOAK_CLIENT_SECRET="$KEYCLOAK_CLIENT_SECRET" \
keycloak -- npx -y keycloak-model-context-protocol@1Or as JSON (Claude Desktop, claude_desktop_config.json):
{
"mcpServers": {
"keycloak": {
"command": "npx",
"args": ["-y", "keycloak-model-context-protocol@1"],
"env": {
"KEYCLOAK_URL": "https://keycloak.example.com",
"KEYCLOAK_AUTH_REALM": "demo",
"KEYCLOAK_CLIENT_ID": "mcp-admin",
"KEYCLOAK_CLIENT_SECRET": "<client-secret>"
}
}
}
}3. Ask your first question
List the realms you can access, then show me the first 10 users of realm demo.
If you get an answer, you are done. If not, see docs/troubleshooting.md.
Configuration
All settings are environment variables. Only KEYCLOAK_URL and one set of credentials are required.
Variable | Default | Purpose |
| (required) | Base URL of the Keycloak server |
|
| Realm where the login account or client lives |
| none |
|
| none | Password grant login (client defaults to |
| auto |
|
|
| Enabled toolsets, or |
|
| Register read-only tools only |
| all | Comma-separated allowlist of target realms |
|
| Allow write tools in the |
|
| Destructive and sensitive tools need |
|
| HTTP timeout for Keycloak requests |
|
|
|
Full reference with examples, validation rules and the tool-to-role matrix: docs/configuration.md.
Toolsets and tools
Tools are named <domain>_<verb>. Only the default toolsets are enabled unless you set KEYCLOAK_MCP_TOOLSETS. In read-only mode only tools of kind read are registered.
Toolset | Default | Tools |
| yes |
|
| yes |
|
| yes |
|
| no |
|
| no |
|
| no |
|
| no |
|
Details for every tool (parameters, outputs, required roles): docs/tools-reference.md.
Prompts and resources
Prompts are guided workflows built on the tools. They appear in your client's prompt picker (in Claude Code as slash commands). The realm argument autocompletes.
Prompt | What it does |
| Create a user, add groups and roles, send the welcome e-mail |
| Review, end sessions and disable a departing employee's account (does not delete) |
| Read-only security review with prioritized findings |
| Analyze failed logins and lockout status without changing anything |
Resources are read-only JSON documents, filtered by the same realm allowlist:
URI | Content |
| Names of accessible realms |
| Safe subset of the realm settings |
| Brute-force, password policy, SSL, OTP, event flags, client exposure counts (no secrets) |
| One user's basic fields (no attributes, no credentials) |
Security
Least privilege first. Use a service-account client scoped to one realm with only the
realm-managementroles you need. A role matrix is in docs/configuration.md.Every change needs confirmation (
KEYCLOAK_MCP_REQUIRE_CONFIRMATION=true): destructive and sensitive tools show a preview first. Grants of administrative rights, also through composite roles and parent groups, profile changes and action e-mails for accounts with administrative rights, and changes to the server's own account need a confirmation thatKEYCLOAK_MCP_REQUIRE_CONFIRMATION=falsedoes not turn off. Role and group grants, profile changes and action e-mails for the server's own account are refused.Account takeover protection: a changed e-mail address is marked as unverified unless stated otherwise, action e-mail links are valid for at most 24 hours, and previews name the recipient address and whether the target account has administrative rights.
Blast-radius limits:
KEYCLOAK_MCP_READ_ONLY,KEYCLOAK_MCP_REALMS, and write protection formaster(off by default).No secrets in output or logs. Credentials are masked on stderr; tools never return client secrets, user credentials or attributes.
Prompt injection: treat names and descriptions coming from Keycloak as data. The shipped prompts say so explicitly; keep write tools disabled when you do not need them.
Threat model, hardening checklist and how to report a vulnerability: docs/security.md and SECURITY.md.
Example prompts
"Which realms can you see? Show me the settings of realm
demo.""Find all users in
demowhose e-mail ends with@example.comand who are disabled.""Create user
jdoe(Jane Doe, jane@example.com) indemo, add her to groupengineeringand send her an e-mail to set a password.""Who is in the group
ops, and which roles doesalicehave, including composite roles?""Run the
audit_realm_securityprompt fordemo." (needsclientsandeventstoolsets for the full audit)"There were many failed logins last night. Investigate realm
demo.""Offboard
bobindemo: end his sessions and disable the account."
Documentation
Document | Content |
Local Keycloak, service-account setup, first run, MCP Inspector | |
Environment reference, role matrix, role profiles, TLS | |
Claude Desktop, Claude Code, VS Code, Cursor, generic clients | |
Every tool in detail | |
Threat model and hardening | |
Symptoms, causes, fixes | |
Components, flows, design decisions | |
Release notes |
Upgrade from 0.x
Version 1.0 changes the defaults: credentials are required (no admin/admin fallback), destructive tools ask for confirmation, and the tools were renamed to <domain>_<verb> (for example create-user became user_create, delete-user became user_delete). The old KEYCLOAK_ADMIN and KEYCLOAK_ADMIN_PASSWORD variables still work but are deprecated. See the migration guide.
Contributing and license
Contributions are welcome. See CONTRIBUTING.md and the Code of Conduct. Released under the MIT License.
Available Tools
4 toolscreate-userC
Create a new user in a specific realm
| Name | Required | Description | Default |
|---|---|---|---|
| realm | Yes | ||
| username | Yes | ||
| Yes | |||
| firstName | Yes | ||
| lastName | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states 'Create' which implies a write/mutation operation, but doesn't mention permissions required, whether the operation is idempotent, what happens on duplicate entries, or any rate limits. This leaves significant gaps for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with zero wasted words. It's appropriately sized and front-loaded with the core purpose, making it easy to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with 5 parameters, 0% schema coverage, no annotations, and no output schema, the description is inadequate. It doesn't explain what happens after creation (e.g., returns user ID), error conditions, or behavioral nuances, leaving too many unknowns for effective tool use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 5 parameters with 0% description coverage, so the description must compensate. However, it only mentions 'realm' implicitly ('in a specific realm') and doesn't explain any parameters like email format requirements, username constraints, or the relationship between fields. This fails to add meaningful semantic context beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Create') and resource ('new user in a specific realm'), providing a specific verb+resource combination. However, it doesn't differentiate from sibling tools like 'add-user-to-group' or 'list-users', which would require explicit comparison to achieve a score of 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'add-user-to-group' or 'delete-user'. It mentions 'in a specific realm' which implies a context but doesn't specify prerequisites, exclusions, or when-not-to-use scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete-userC
Delete a user from a specific realm
| Name | Required | Description | Default |
|---|---|---|---|
| realm | Yes | ||
| userId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool performs a 'delete' operation, implying it's destructive and non-read-only, which is helpful. However, it lacks critical details: whether deletion is permanent or reversible, what permissions are required, if there are rate limits, what happens to associated data, or what the response looks like. For a destructive tool with zero annotation coverage, this is insufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence that efficiently conveys the core action without unnecessary words. It's front-loaded with the verb 'Delete' and avoids redundancy. Every word earns its place, making it easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (a destructive operation with 2 parameters), lack of annotations, 0% schema description coverage, and no output schema, the description is incomplete. It doesn't address critical aspects like error conditions, return values, side effects, or security implications. The agent is left with significant gaps in understanding how to use this tool safely and effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, so parameters 'realm' and 'userId' are undocumented in the schema. The description adds minimal value by implying 'realm' specifies where the user exists and 'userId' identifies the user, but doesn't explain what these parameters represent (e.g., realm as an organizational boundary, userId as a unique identifier), their formats, or examples. It fails to compensate for the schema's lack of documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Delete') and target resource ('a user from a specific realm'), making the purpose immediately understandable. It distinguishes this tool from sibling tools like 'create-user' or 'list-users' by specifying a destructive operation. However, it doesn't explicitly mention what 'delete' entails (e.g., permanent removal vs. deactivation), which prevents a perfect score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., user must exist), consequences of deletion, or relationships with sibling tools like 'create-user' or 'list-users'. The agent receives no help in deciding when this tool is appropriate versus other user management operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list-realmsB
List all available realms
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description should provide behavioral details. It only mentions listing all realms but lacks info on read-only behavior, pagination, authentication, or response format.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise with a single sentence front-loading the purpose. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with no parameters or output schema, the description is minimally adequate but lacks details on return structure or any potential filters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has no parameters and schema description coverage is 100%, so the description adds no param semantics. Baseline of 3 is appropriate for a no-parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'List all available realms' clearly states the action (list) and resource (realms), with 'available' implying no filtering. It is distinct from sibling tools like create-user or list-users.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool or when alternatives might be better. The description gives no context for exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list-usersC
List users in a specific realm
| Name | Required | Description | Default |
|---|---|---|---|
| realm | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It states 'list users' which implies a read-only operation, but does not disclose behavioral traits such as pagination, sorting, filtering beyond realm, authentication requirements, rate limits, or what the output format looks like. This is a significant gap for a tool with no annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence with zero waste. It is appropriately sized and front-loaded, directly stating the tool's purpose without unnecessary elaboration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, 0% schema coverage, no output schema, and a simple parameter structure, the description is incomplete. It lacks details on behavior, output, parameter meaning, and usage context, making it inadequate for an agent to reliably invoke the tool without additional assumptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It mentions 'in a specific realm', which hints at the 'realm' parameter's purpose, but does not explain what a realm is, its format, valid values, or how it affects the listing. With 1 undocumented parameter, the description adds minimal semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'list' and the resource 'users in a specific realm', which is specific and unambiguous. However, it does not distinguish this tool from potential siblings like 'list-groups' or 'list-clients' beyond the resource name, as all share the same 'list' pattern without explicit differentiation in the description.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It mentions 'in a specific realm' but does not specify prerequisites, exclusions, or compare it to other user-related tools like 'create-user' or 'list-client-roles', leaving usage context implied at best.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v1.0.0- Added
create-user - Added
delete-user - Added
list-realms - Added
list-users
TDQS
Scored across 4 tools
Each tool has a clearly distinct purpose with no overlap: create-user and delete-user handle user lifecycle actions, list-realms lists realms, and list-users lists users within a realm. The descriptions make it unambiguous which tool to use for each operation.
All tool names follow a consistent verb_noun pattern with hyphen separation (e.g., create-user, delete-user, list-realms, list-users). This uniformity makes the tool set predictable and easy to understand.
With only 4 tools, the set feels thin for a Keycloak server, which typically manages realms, users, roles, clients, and groups. While the tools cover basic user and realm operations, the scope is limited compared to the domain's complexity.
There are significant gaps in the tool surface for Keycloak management. Missing operations include updating users, managing roles, handling clients, and performing authentication flows. This incomplete coverage will likely cause agent failures when trying to perform common administrative tasks.
Maintenance
Related MCP Connectors
Managed Keycloak from any MCP client: clusters, realms, apps, SSO, users, domains, audit events.
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent framework to 100+ accounting systems, HRIS platforms, file storage providers, and more through one integration. More information https://www.apideck.com/mcp-server
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Related MCP Servers
- AlicenseBqualityDmaintenanceA Model Context Protocol server that enables management of Keycloak users and realms through a standardized interface, providing tools for user creation, deletion, role assignment, and group management.975 npm13MIT
- AlicenseCqualityDmaintenanceA Model Context Protocol server demonstrating user management capabilities with tools for creating, retrieving, and generating random user data.2ISC
- AlicenseAqualityAmaintenanceAn MCP server for Keycloak Admin REST API, enabling user, group, event, and security management through service account authentication.3382 PyPIMIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server that provides a natural language interface for managing Keycloak identity and access management through its REST API.MIT