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: ``status`` (healthy / degraded / error),
``service``, ``version``, ``keycloak_url`` (configured base URL, empty if
unset), ``realm`` (configured realm), ``keycloak_version`` (None — not exposed
by a cheap call), and ``auth`` (ok / error / missing-env). On a degraded or
error result, ``detail`` carries the reason.
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.
无需输入参数。
Get total user count in the realm.
无需输入参数。
Search users by username, email, first name, or last name.
Args:
query: Search string (partial match).
max_results: Maximum results to return (default 20).
输入参数query必填max_results
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 ``attributes`` entirely). A
whitelisted key whose name looks credential-shaped (contains "password",
"secret", "token", etc. — see _looks_like_credential_key) is reported as
blocked rather than shown, as a safety net on top of the whitelist itself.
Args:
username: Exact username (e.g., [email protected]).
输入参数username必填
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.
输入参数password必填username必填temporary
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.
输入参数csv_text必填temporary
Get active sessions for a user.
Sessions are listed over several separate connections and merged, because
behind a load balancer a KeyCloak node that does not share sessions with the
others lists only its own (KEYCLOAK_SESSION_PROBES, default 8).
Args:
username: Exact username (email).
输入参数username必填
Force logout a user by removing all their active sessions.
Each probe opens its own connection, lists the user's sessions and logs the
user out on the node it reached when that node lists a session. Until one
logout has gone through it is sent even when the node lists nothing: it also
sets the user's ``notBefore`` in the database, so tokens issued before it are
rejected by every node. Probing goes
on until no session is seen on KEYCLOAK_LOGOUT_CLEAN_PROBES probes in a row
(default 10), at most KEYCLOAK_LOGOUT_MAX_PROBES (default 40), so that nodes
that do not share sessions behind a load balancer are all reached. The
resulting ``notBefore`` is reported. The whole run is bounded by
KEYCLOAK_DEADLINE; when it runs out or a request fails, the result says
verification is incomplete, with what was done so far.
Args:
username: Exact username (email).
输入参数username必填
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
``enabled`` flag is changed; custom attributes are preserved.
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 ``logout_user`` to end them immediately.
Args:
username: Exact username (email).
enabled: True to enable, False to disable.
输入参数enabled必填username必填
List the credential types configured for one user (password, otp, webauthn, …).
Use this to check a single user's MFA status: an ``otp`` credential means
TOTP/HOTP is configured. Reads ``/users/{id}/credentials`` (read-only; does
not create a session).
Args:
username: Exact username (email).
输入参数username必填
Report how many users have TOTP (OTP) configured across the realm.
Enumerates users and inspects each one's credentials for an ``otp`` entry.
KeyCloak has no bulk credential endpoint, so this makes one credential
request per user (N+1) — expect it to be slow on large realms; bound it with
``max_users`` (which also short-circuits the user enumeration). Users whose
credential lookup fails are counted separately and skipped, so a single
transient error does not abort the whole scan.
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. ``0`` (default) falls back to
KEYCLOAK_MAX_USERS (default 5000) rather than the whole realm.
The N+1 credential loop is also bounded by KEYCLOAK_DEADLINE, so
a large realm returns a disclosed sample. When capped, the
percentage covers only the sample, not the realm.
输入参数max_userslist_usersenabled_only
Check if a user is temporarily locked due to brute force detection.
Args:
username: Exact username (email).
输入参数username必填
List groups a user belongs to.
Args:
username: Exact username (email).
输入参数username必填
List all users in a group.
Args:
group_name: Group name (partial match).
max_results: Maximum results (default 100).
输入参数group_name必填max_results
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).
输入参数date_tousernameclient_iddate_fromevent_typeip_addressmax_results
Get login success/failure statistics with full pagination.
Time-bounded: this call stops after KEYCLOAK_DEADLINE seconds (default 45) and
returns what it has; the counts are then a lower bound. The result then starts with a "PARTIAL RESULT" warning.
Call again with a narrower window instead of retrying the same call. A wide window
on a busy day is what triggers it.
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.
输入参数date_todate_from
Get login statistics broken down by hour (local time).
Time-bounded: this call stops after KEYCLOAK_DEADLINE seconds (default 45) and
returns what it has; the counts are then a lower bound. The result then starts with a "PARTIAL RESULT" warning.
Call again with a narrower window instead of retrying the same call. A wide window
on a busy day is what triggers it.
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.
输入参数date_todate_from
Get login failure statistics broken down by source IP.
Time-bounded: this call stops after KEYCLOAK_DEADLINE seconds (default 45) and
returns what it has; the counts are then a lower bound. The result then starts with a "PARTIAL RESULT" warning.
Call again with a narrower window instead of retrying the same call. A wide window
on a busy day is what triggers it.
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).
输入参数topdate_todate_from
Exhaustive investigation of all activity from one source IP address.
Unlike `get_events(ip_address=...)`, which filters a single page and can
miss activity outside the most recent `max_results` events, this tool
fully paginates every requested event type (via `get_events_all`) before
filtering by IP, so the result is exhaustive over the requested date
range. Use this for brute-force / credential-stuffing / shared-workstation
investigations where `get_login_failures_by_ip` told you *which* IP to
look at and you now need the full picture for that one IP.
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.
use
输入参数date_todate_fromip_address必填event_typesmax_timeline
Detect password-spray sources and name the accounts they breached — one rule, one call.
For every EXTERNAL source IP (anything outside the ranges declared in
KEYCLOAK_SITES_INI) seen in LOGIN / LOGIN_ERROR events during the last
``hours``, compute distinct users and success rate. An IP is a spray source
when ``unique_users >= min_users`` AND ``success_rate < max_success_rate``.
Its successful logins are the breach CANDIDATES; whether they may be
called breached depends on the row's ``confidence``.
The breach list is built ONLY from LOGIN events whose source IP is the
flagged IP, inside the window. Every entry carries the evidence tuple
``{time, ip, username, user_id, client_id}``. A compromised account can
therefore never be reported without an actual login event from the spray
source — do not add names that are not in ``spray[].breached``.
``confidence`` separates a spray from a shared egress (school NAT, home
line, VDI) that merely looks like one by volume. It is "low" — treat the
successes as "verify with the owner", never publish them as breached —
when any of these ``signals`` holds: ``user_success_rate`` (distinct
users that logged in at least once ÷ distinct users) >=
``max_user_success_rate`` (real sprays sit at 0.0–0.06; a school NAT
with students retyping a mistyped domain sat at 0.47), or
``failure_concentration`` (share of failures on the single most-failing
username) >= ``max_failure_concentration`` (one locked-out user retrying
from a shared line produced 0.91), or the IP is in KEYCLOAK_KNOWN_EGRESS.
Only ``confidence: high`` rows are a breach verdict. Read
``top_failed_users`` and ``not_found_domains`` (domains of usernames that
do not exist — typos of the real domain are humans, not a scraped list)
before writing anything up.
Returns a fixed-shape dict:
window: {hours, since, until} actually scanned.
complete: False if event pag
输入参数hoursmin_usersmax_resolvesmax_success_ratemin_report_usersmax_user_success_ratemax_failure_concentration
get_login_stats_by_client
Get login statistics broken down by client (SP).
Time-bounded: this call stops after KEYCLOAK_DEADLINE seconds (default 45) and
returns what it has; the counts are then a lower bound. The result then starts with a "PARTIAL RESULT" warning.
Call again with a narrower window instead of retrying the same call. A wide window
on a busy day is what triggers it.
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.
输入参数date_todate_from
Detect users with rapid repeated logins (possible redirect loops).
Scans all LOGIN events and finds users who logged in more than `threshold`
times within `window_seconds`.
Time-bounded: this call stops after KEYCLOAK_DEADLINE seconds (default 45) and
returns what it has; the counts are then a lower bound. The result then starts with a "PARTIAL RESULT" warning.
Call again with a narrower window instead of retrying the same call. A wide window
on a busy day is what triggers it.
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.
输入参数topdate_todate_fromthresholdwindow_seconds
get_password_update_events
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).
输入参数date_todate_frommax_results
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 (``provisioning_flag``), role / group
assignments, client configuration changes. These are distinct from user
events (login / password change). Use this when ``UPDATE_PROFILE`` in
``get_events`` is empty but an attribute is known to have changed.
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.
输入参数date_tomax_reprdate_frommax_resultsresource_pathresource_typesoperation_types
get_user_attribute_history
Get admin-side attribute change history for a single user.
Queries admin events scoped to ``users/{userId}`` with UPDATE / ACTION
operations. Intended for tracking custom attribute changes such as
``provisioning_flag`` which are written by admin API and do **not** surface in
``get_events`` (which only shows user-driven events like LOGIN /
UPDATE_PASSWORD).
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.
输入参数date_tomax_reprusername必填date_frommax_results
Get active session count per client.
无需输入参数。
Get active sessions for a specific client (SP).
Args:
client_id: Client ID (e.g., 'xflow', 'shadowserver').
max_results: Maximum results (default 100).
输入参数client_id必填max_results
List all SAML/OIDC clients in the realm.
无需输入参数。
Show one client's configuration, including its authentication flow overrides.
Reports an explicit allowlist of fields rather than the raw client
representation. A client representation can carry ``secret``,
``registrationAccessToken`` and, for SAML clients, signing material under
``attributes``; ``attributes`` and ``protocolMappers`` are therefore omitted
entirely rather than filtered, so nothing credential-shaped reaches tool
output, hence LLM context.
The headline is ``authenticationFlowBindingOverrides``: pinning one client
to a non-default browser flow is how a single SP is made to require OTP
while the realm default stays untouched. KeyCloak stores those overrides as
flow IDs, so they are resolved to flow aliases here.
Args:
client_id: The clientId (not the internal UUID).
输入参数client_id必填
List all realm-level roles.
无需输入参数。
get_realm_security_defenses
Show the realm's security-defense settings (read-only).
Reports the realm-level security configuration that the admin console
groups under "Security defenses":
- Brute force detection: whether it is enabled, the lockout strategy,
and the thresholds (max login failures, wait increments, reset window).
- Password policy.
- Browser security headers.
Use this to verify that brute-force protection is actually turned on and
how aggressively it locks accounts — the per-user ``get_brute_force_status``
only reflects runtime state, not whether the policy itself is configured.
无需输入参数。
Compare the realm configuration now with a stored daily snapshot (read-only).
Covers realm settings (brute force detection, password and OTP policies, session and
token lifespans, flow bindings), event settings, realm roles and the contents of
composite roles, authentication flows and their executions, required actions,
clients (redirect URIs, flows allowed, flow overrides, protocol mappers), client
scopes, default client scopes, components and, when readable, identity providers.
Values under credential-named keys (``secret``, ``password``, ``privateKey``,
``apiKey``, ...) are replaced with ``<redacted>`` before anything is compared or stored,
so a changed secret does not show as a change.
The snapshots are written by ``daily_brief`` (the first run of each day); this tool
never writes one. Use it to see the full list when ``daily_brief`` reports [CONFIG]
changes, or to compare against an older day.
Args:
baseline_date: Snapshot to compare against (YYYY-MM-DD). Default: the latest
snapshot before today.
输入参数baseline_date
Run a morning Keycloak health check.
Checks (all scoped to the last ``since_hours`` hours):
- Login statistics (success / failure totals, top failing IPs)
- Active sessions by client
- Password update events
- Admin events (CREATE/UPDATE/DELETE on USER/CLIENT resources)
- Configuration: admin events that change roles, role mappings, flows, client
scopes, protocol mappers, components or the realm, and (when KEYCLOAK_STATE_DIR is
set) what changed since the last daily snapshot. The first run of each day records
that day's snapshot; ``get_config_changes`` lists every change.
A single IP with login failures >= ``ip_failure_threshold`` is flagged
as WARNING (possible brute-force). Independently, the same login events
are run through the ``spray_check`` rule (external IP, >= 10 distinct
users, success rate < 20%); a match is a [SPRAY] WARNING and the
"Spray check" section lists the breached accounts with their evidence
tuples (time / ip / username / client). Only accounts in that list may be
called breached — see ``spray_check`` for the full row shape and to widen
the window or tune the thresholds.
``since_hours`` defaults to 18 (≈ previous 15:00 for a 09:00 morning run).
Output tiers:
- CRITICAL — API connection failure
- WARNING — anomalies detected
- OK — clean
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).
输入参数since_hoursip_failure_threshold