keycloak-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| KEYCLOAK_URL | Yes | Base URL of the Keycloak server, e.g. https://keycloak.example.com | |
| KEYCLOAK_REALM | No | Realm name | master |
| KEYCLOAK_CLIENT_ID | Yes | Service Account client ID | |
| KEYCLOAK_SITES_INI | No | Path to INI file for IP-to-site labeling | |
| KEYCLOAK_CLIENT_SECRET | Yes | Client secret | |
| KEYCLOAK_DEFAULT_DATE_FROM_HOURS | No | Default look-back window for event tools when date_from is omitted | 24 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| health_checkA | Report server version and KeyCloak backend connectivity / authentication. Call this at session start (or after a tool-call timeout) to confirm the MCP is up, see which version is running, and verify the KeyCloak Admin API is reachable and the service account can authenticate. Lightweight: it acquires an admin access token via the Client Credentials Grant (reusing the cached client) and does NOT enumerate users, events, or sessions. Always returns the same keys: This description is the only place those value sets are written down. The READMEs used to repeat them, which is three copies to keep in step and two that an LLM never reads — it is handed this text. |
| count_usersA | Get total user count in the realm. |
| search_usersA | Search users by username, email, first name, or last name. Args: query: Search string (partial match). max_results: Maximum results to return (default 20). |
| get_userA | Get detailed user information by exact username (email). If KEYCLOAK_USER_ATTRIBUTE_WHITELIST names any custom attribute keys, this
also does one extra by-ID lookup and appends whichever of those keys are
present on the user (the search endpoint used to resolve the username
returns a brief representation that omits Args: username: Exact username (e.g., user@example.com). |
| reset_passwordA | Reset a user's password. Args: username: Exact username (email). password: New password to set. temporary: If True, user must change password on next login. |
| reset_passwords_batchA | Reset passwords for multiple users from CSV text. Each line should be: username,password If password column is empty, a random 12-char password is generated and included in the response (the caller cannot recover it otherwise). Caller-supplied passwords are never echoed back. Args: csv_text: CSV text with username,password per line (header optional). temporary: If True, users must change password on next login. |
| get_user_sessionsC | Get active sessions for a user. Args: username: Exact username (email). |
| logout_userA | Force logout a user by removing all their active sessions. Args: username: Exact username (email). |
| set_user_enabledA | Enable or disable a user account. Disabling blocks all authentication (SSO logins) for the user — the
containment action for a compromised or decommissioned account. Only the
Disabling does not terminate existing sessions (an already-issued token
stays valid until it expires), so when disabling this reports how many
sessions remain and to run Args: username: Exact username (email). enabled: True to enable, False to disable. |
| get_user_credentialsA | List the credential types configured for one user (password, otp, webauthn, …). Use this to check a single user's MFA status: an Args: username: Exact username (email). |
| get_totp_usersA | Report how many users have TOTP (OTP) configured across the realm. Enumerates users and inspects each one's credentials for an Args:
enabled_only: Only scan enabled users (default True).
list_users: Include the list of usernames with TOTP (default True).
max_users: Cap the number of users scanned. |
| get_brute_force_statusA | Check if a user is temporarily locked due to brute force detection. Args: username: Exact username (email). |
| list_user_groupsA | List groups a user belongs to. Args: username: Exact username (email). |
| list_users_by_groupA | List all users in a group. Args: group_name: Group name (partial match). max_results: Maximum results (default 100). |
| get_eventsA | Get KeyCloak events with optional filters. Args: event_type: Event type filter (e.g., LOGIN, LOGIN_ERROR, UPDATE_PASSWORD). username: Filter by exact username (email). Resolved to user ID internally. client_id: Filter by client ID (SP name). ip_address: Filter events by source IP (client-side filter). date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). date_to: End date (YYYY-MM-DD). max_results: Maximum results (default 50). |
| get_login_statsA | Get login success/failure statistics with full pagination. Args: date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). date_to: End date (YYYY-MM-DD). Empty for all. |
| get_login_stats_by_hourA | Get login statistics broken down by hour (local time). Args: date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). date_to: End date (YYYY-MM-DD). Empty for all. |
| get_login_failures_by_ipB | Get login failure statistics broken down by source IP. Args: date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). date_to: End date (YYYY-MM-DD). Empty for all. top: Number of top IPs to show (default 20). |
| get_ip_activityA | Exhaustive investigation of all activity from one source IP address. Unlike Returns a fixed-shape dict (JSON), not formatted text — every key below is always present, even when zero events match. Returns:
error: None on success. Set to a descriptive message if event_types
resolved to no event types (e.g. empty or all-whitespace/commas);
every other key is still present, with an empty/zero result in
that case (no data was fetched).
ip_address: Echoes the input.
site: Site name from KEYCLOAK_SITES_INI, or null if unmatched or
unconfigured (see sites_configured to tell those apart).
sites_configured: True if KEYCLOAK_SITES_INI was loaded at all.
date_from / date_to: The resolved date range actually scanned.
event_types: The event types scanned (echoes the input, split).
summary: total_events, login_success, login_failure, unique_users,
unique_clients, first_seen/last_seen (ISO 8601, null if no match).
login_success/login_failure classify EVERY scanned event type by
whether its type ends in "_ERROR" (matching the users/clients
breakdown below), not just literal LOGIN/LOGIN_ERROR — so widening
event_types always keeps these numbers reconciled with the
per-user/per-client totals. Always computed over the FULL matched
set, unaffected by max_timeline truncation.
users: Per-user breakdown (success/failure counts, distinct error
codes), sorted by total activity descending. Note: successful
LOGIN events often carry only a userId (UUID) while LOGIN_ERROR
carries details.username — this tool keys on
username-or-userId-or-"unknown", so the same human can
legitimately appear under two different keys across success vs.
failure events.
clients: Per-client (SP) breakdown, same shape, sorted descending.
timeline: Chronological event list, capped at max_timeline (most
recent kept on overflow — see truncated). max_timeline<=0 returns
an empty timeline.
truncated: True if timeline was capped; summary/users/clients are
never affected by this cap.
events_capped: True if event pagination itself was cut short by the
wall-clock deadline (KEYCLOAK_DEADLINE) or the per-type cap
(KEYCLOAK_MAX_EVENTS) — i.e. the window was too wide and the WHOLE
result (summary/users/clients/timeline) is incomplete. Distinct from
Args: ip_address: Source IP to investigate. Compared against KeyCloak's recorded ipAddress field after normalizing both sides through Python's ipaddress module (so equivalent IPv6 notations like "::1" and "0:0:0:0:0:0:0:1" match); falls back to a raw string compare if either side doesn't parse as an IP. event_types: Comma-separated KeyCloak event types to scan (default "LOGIN,LOGIN_ERROR"). Widen with e.g. "LOGIN,LOGIN_ERROR,LOGOUT,UPDATE_PASSWORD,CLIENT_LOGIN,CLIENT_LOGIN_ERROR" for a broader sweep. Must resolve to at least one type. date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). Widening the window means fully paginating every event type over that window before filtering — expect it to be slower on large realms. date_to: End date (YYYY-MM-DD). Empty for open-ended. max_timeline: Cap on the number of most-recent timeline entries returned (default 200; <=0 means no timeline entries). Does not affect summary/users/clients. |
| get_login_stats_by_clientC | Get login statistics broken down by client (SP). Args: date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). date_to: End date (YYYY-MM-DD). Empty for all. |
| detect_login_loopsA | Detect users with rapid repeated logins (possible redirect loops). Scans all LOGIN events and finds users who logged in more than Args: date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). date_to: End date (YYYY-MM-DD). Empty for all. threshold: Minimum logins within the window to flag (default 10). window_seconds: Time window in seconds (default 60). top: Number of top users to show (default 20). Use 0 for all. |
| get_password_update_eventsA | Get password update events. Args: date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). date_to: End date (YYYY-MM-DD). max_results: Maximum results (default 100). |
| get_admin_eventsA | Get KeyCloak admin events (changes performed via the Admin REST API). Admin events record operations performed by service accounts or admin users
— e.g. custom user attribute updates ( Args: operation_types: Comma-separated list of CREATE, UPDATE, DELETE, ACTION. resource_types: Comma-separated list of USER, CLIENT, ROLE, GROUP, REALM_ROLE, etc. resource_path: Filter by resource path (e.g. "users/{userId}"). date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). date_to: End date (YYYY-MM-DD). max_results: Maximum results (default 50). max_repr: Max chars of the representation field. 0 = omit, -1 = full. |
| get_user_attribute_historyA | Get admin-side attribute change history for a single user. Queries admin events scoped to Args: username: Exact username (email). date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). date_to: End date (YYYY-MM-DD). max_results: Maximum results (default 100). max_repr: Max chars of the representation field. 0 = omit, -1 = full. |
| get_session_statsA | Get active session count per client. |
| get_client_sessionsA | Get active sessions for a specific client (SP). Args: client_id: Client ID (e.g., 'xflow', 'shadowserver'). max_results: Maximum results (default 100). |
| list_clientsA | List all SAML/OIDC clients in the realm. |
| get_realm_rolesA | List all realm-level roles. |
| get_realm_security_defensesA | Show the realm's security-defense settings (read-only). Reports the realm-level security configuration that the admin console groups under "Security defenses":
Use this to verify that brute-force protection is actually turned on and
how aggressively it locks accounts — the per-user |
| daily_briefA | Run a morning Keycloak health check. Checks (all scoped to the last
A single IP with login failures >=
Output tiers:
Args: since_hours: Look-back window in hours (default 18). ip_failure_threshold: Login failures from a single IP that triggers a WARNING (default 50). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/shigechika/keycloak-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server