keycloak-mcp
This server exposes an MCP interface to Keycloak's Admin REST API for user/group/session/event investigation and security patrol, authenticating via a service account (Client Credentials Grant).
Users: count, search, get details, reset password (single/batch CSV), enable/disable, active sessions, and force logout.
MFA/Credentials: inspect a user's credential types (TOTP/HOTP) and realm-wide TOTP adoption with
get_totp_users.Groups: list a user's groups and list members of a group.
Security: brute-force status, realm security defenses (policies/thresholds), login failures by IP, exhaustive per-IP activity investigation, password-spray detection with breach evidence, and login-loop detection.
Events: query user events (LOGIN, LOGIN_ERROR, UPDATE_PASSWORD, etc.), login stats by total/hour/client, and paginated event filtering by type/user/client/IP/date.
Admin Events: query admin operations (CREATE/UPDATE/DELETE/ACTION) and track custom user-attribute change history.
Sessions & Clients: session counts per client, client sessions, list/get clients (with auth flow overrides), and realm roles.
Morning Patrol:
health_checkfor connectivity/version anddaily_brieffor a one-shot Markdown security summary.State-changing tools (require
manage-users):reset_password,reset_passwords_batch,set_user_enabled,logout_user; everything else is read-only.
Provides tools for managing Keycloak users, groups, security, events, sessions, and clients through the Keycloak Admin REST API via service account authentication.
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-mcpsearch for user john.doe"
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
English | 日本語
An MCP (Model Context Protocol) server for the KeyCloak Admin REST API.
Documentation: https://shigechika.github.io/keycloak-mcp/
Authenticates via a Service Account (Client Credentials Grant), so no human password or TOTP is involved. Also Infinispan-safe — it never creates user sessions and never hits the userinfo endpoint.
Features
Users
Tool | Description |
| Total user count in the realm |
| Partial-match search (username / email / name) |
| Full detail for an exact username |
| Reset one user's password |
| Bulk reset from CSV ( |
| Active sessions for one user, timestamps in local time |
| Kill all active sessions for one user |
| Enable or disable one user; disabling blocks all logins (custom attributes preserved) |
MFA / Credentials
Tool | Description |
| Credential types configured for one user; an |
| Realm-wide TOTP adoption: how many users have an |
Groups
Tool | Description |
| Which groups a user belongs to |
| Members of a group |
Security
Tool | Description |
| Whether a user is currently locked by brute-force detection |
| Realm-level security policy: whether brute-force detection is enabled and its thresholds, the password policy, and browser security headers |
| Failure breakdown by source IP (site-labeled when |
| Exhaustive investigation of one source IP: success/failure counts, affected users/clients, timeline. Returns structured JSON. |
| Password-spray detection with the breach list built in: every external IP with ≥ 10 distinct users and < 20 % login success is a spray source, and its successful logins (evidence tuple |
| Flag users who logged in too many times in a short window (redirect loops) |
Events
Tool | Description |
| Filter by type, username, client, IP, and date range. Username is resolved to user ID internally. Failure events include KeyCloak's |
| Login success/failure totals, paginated across all results |
| Logins bucketed by hour of day (local time) |
| Logins bucketed by client / SP |
|
|
Admin Events
get_events only sees user events. Actions driven by an admin — or by a service account writing custom attributes — don't show up there. The admin-event endpoint fills that gap.
Tool | Description |
| Filter by operation (CREATE / UPDATE / DELETE / ACTION), resource type (USER / CLIENT / ROLE / GROUP / …), resource path, and date range |
| UPDATE/ACTION events scoped to one user — handy for tracking when a custom attribute (e.g. |
Both tools accept max_repr to control the representation payload: positive = truncate to N chars (default 500), 0 = omit, negative = include in full.
Sessions & Clients
Tool | Description |
| Active session count per client |
| Active sessions for one client (SP) |
| SAML and OIDC clients in the realm |
| One client's configuration, including its authentication flow overrides (the per-SP MFA switch). Omits |
| Realm-level roles |
Morning Patrol
Tool | Description |
| Report the running server version and verify the KeyCloak backend is reachable and the service account can authenticate. Lightweight (one token request; no user/event/session scans). Returns a fixed-shape dict with |
| One-shot morning health check: login stats, brute-force IPs, spray check (same rule as |
Related MCP server: mcp-keycloak
Setup
# uv
uv pip install keycloak-mcp
# pip
pip install keycloak-mcpFrom source:
git clone https://github.com/shigechika/keycloak-mcp.git
cd keycloak-mcp
# uv
uv sync
# pip
pip install -e .Configuration
Variable | Description | Default |
| Base URL, e.g. | required |
| Realm name |
|
| Service Account client ID | required |
| Client secret | required |
| INI file for IP-to-site labeling (see below) | unset |
| Comma-separated CIDRs of known shared egress points (VDI, VPN concentrators, partner proxies). | unset |
| Default look-back window for event tools when |
|
| Per-call wall-clock budget (seconds) for the heavy event/TOTP tools. When a wide window / large realm would exceed it, the tool stops and returns a disclosed partial (⚠️ warning) instead of running past the client's ~60s gateway timeout and hammering KeyCloak. Each request's timeout is also capped at the time left, and nothing is retried past the deadline, so one slow page cannot run a call past it. |
|
| Per-pagination cap on events fetched by the event tools (also bounds how deep the slow high-offset pagination goes). Over the cap the result is a disclosed partial. |
|
| Default cap on users scanned by |
|
| Comma-separated custom user-attribute keys that | unset |
KeyCloak client setup
Create a new client in the KeyCloak admin console.
Turn on Client authentication and Service account roles.
Give it
view-users,view-events,view-clients, and — only if you need password reset —manage-users.
Write operations
Four tools change state. Everything else only reads.
Tool | Admin API call |
|
|
| the same call, once per CSV row |
|
|
|
|
All four need manage-users on the Service Account. Leave that role off and the
server is read-only: those four tools fail with 403 and every other tool keeps
working, so a realm can be handed to Claude for investigation without granting any
ability to modify it. Grant manage-users only when account recovery or
containment is part of the job.
Verify your setup
After setting the environment variables, run --check to confirm authentication works before wiring it into an MCP client:
export KEYCLOAK_URL=https://keycloak.example.com
export KEYCLOAK_REALM=my-realm
export KEYCLOAK_CLIENT_ID=keycloak-mcp
export KEYCLOAK_CLIENT_SECRET=your-secret
keycloak-mcp --check
# HTTP Request: POST https://keycloak.example.com/realms/my-realm/protocol/openid-connect/token "HTTP/1.1 200 OK"
# OK: authenticated to https://keycloak.example.com/admin/realms/my-realmExit codes: 0 success, 1 configuration error (missing variable), 2 authentication error.
IP-to-site labeling (optional)
Point KEYCLOAK_SITES_INI at an INI file if you want IP addresses in tool output to be tagged with your site names. Tools like get_user_sessions, get_events, and get_login_failures_by_ip pick it up automatically; anything outside your declared ranges is labeled external. Leave the variable unset and IPs are shown as-is.
See sites.ini.example. A minimal file:
[hq]
name = HQ (Tokyo)
ipv4 = 192.0.2.0/24, 198.51.100.0/24
ipv6 = 2001:db8:1::/48
[vpn]
name = VPN
ipv4 = 10.0.0.0/8, 172.16.0.0/12One site per [section]. name is the display label (falls back to the section name). ipv4 / ipv6 take comma-separated CIDRs; a single host is /32 or /128. Matching is first-match in file order — put specific ranges before broad ones.
Usage
Claude Code (plugin)
This repository doubles as a single-plugin marketplace, so Claude Code can install the server for you:
/plugin marketplace add shigechika/keycloak-mcp
/plugin install keycloak-mcp@keycloak-mcpThe plugin launches uvx keycloak-mcp and reads the same environment variables
described in Configuration; export them before starting Claude
Code. KEYCLOAK_REALM falls back to master and KEYCLOAK_SITES_INI may stay
unset.
uvx must be on the PATH of the process that runs Claude Code — a login
shell usually has it, but a GUI-launched app may not; install
uv system-wide if the plugin fails to start.
Claude Code (manual)
In .mcp.json:
{
"mcpServers": {
"keycloak-mcp": {
"type": "stdio",
"command": "keycloak-mcp",
"env": {
"KEYCLOAK_URL": "https://keycloak.example.com",
"KEYCLOAK_REALM": "my-realm",
"KEYCLOAK_CLIENT_ID": "keycloak-mcp",
"KEYCLOAK_CLIENT_SECRET": ""
}
}
}
}Claude Desktop
In claude_desktop_config.json:
{
"mcpServers": {
"keycloak-mcp": {
"command": "keycloak-mcp",
"env": {
"KEYCLOAK_URL": "https://keycloak.example.com",
"KEYCLOAK_REALM": "my-realm",
"KEYCLOAK_CLIENT_ID": "keycloak-mcp",
"KEYCLOAK_CLIENT_SECRET": ""
}
}
}
}From a shell
export KEYCLOAK_URL=https://keycloak.example.com
export KEYCLOAK_REALM=my-realm
export KEYCLOAK_CLIENT_ID=keycloak-mcp
export KEYCLOAK_CLIENT_SECRET=your-secret
keycloak-mcpCLI
keycloak-mcp --version # Print version and exit
keycloak-mcp --help # Show usage and required environment variables
keycloak-mcp --check # Verify env vars and authentication, then exit
keycloak-mcp # Run the MCP STDIO server (default)No-argument mode is the normal one — that's how MCP clients launch it.
Daily spray report (batch)
spray_check looks at a rolling window ending now, which is right for a patrol but cannot be archived day by day. For that, run the same analysis over one calendar day from a scheduled job:
keycloak-mcp spray-report --date 2026-09-17 --tz Asia/Tokyo > 2026-09-17.jsonThe window is
[DATE 00:00, DATE+1 00:00)in--tz(default: the host's zone). Use the zone the KeyCloak server logs in, becausedateFrom/dateToare interpreted there. Events are cut to the window by timestamp on both ends.One JSON document goes to stdout; errors go to stderr with a non-zero exit (2 = configuration, 1 = fetch/auth), and nothing is written to stdout in that case.
The output is the
spray_checkshape with every external IP that has at least one event carrying a username inexternal_ips(min_report_users=1), plusexternal_totals, which counts LOGIN / LOGIN_ERROR for every external IP — including IPs whose failures carry no username at all and therefore have no row,fetch_complete,resolve_complete,coverage(first_event,last_event,head_gap_seconds,tail_gap_seconds),schema,keycloak_mcp_versionandsites_ini_sha256. Treat a day as final only when both*_completeflags are true and neither gap is large; a gap at one end usually means--tzdiffers from the KeyCloak server's zone.It refuses to run when
KEYCLOAK_SITES_INIyields no ranges (every IP would count as external) unless--allow-no-sitesis given, and whenKEYCLOAK_KNOWN_EGRESShas an entry that is not a CIDR.Its own limits apply (
--deadline 900,--max-events 1000000,--max-resolves 2000), notKEYCLOAK_DEADLINE/KEYCLOAK_MAX_EVENTS, which are sized for a tool call behind an HTTP gateway.The output contains source IPs and usernames. Keep it out of anything published.
Development
git clone https://github.com/shigechika/keycloak-mcp.git
cd keycloak-mcp
# uv
uv sync --dev
uv run pytest -v
uv run ruff check .
# pip
python3 -m venv .venv
.venv/bin/pip install -e . && .venv/bin/pip install pytest pytest-cov respx ruff
.venv/bin/pytest -v
.venv/bin/ruff check .Live smoke test
pytest checks logic against fixtures; it cannot tell you that a tool has
stopped returning real data. scripts/smoke_test.py runs every registered
tool against the configured realm and fails on empty, malformed or error
answers:
# needs KEYCLOAK_URL / KEYCLOAK_CLIENT_ID / KEYCLOAK_CLIENT_SECRET
uv run python scripts/smoke_test.py
uv run python scripts/smoke_test.py --only login_stats --tracebackRead-only. Every state-changing tool (
reset_password,logout_user,set_user_enabled,reset_passwords_batch) is skipped by name, and a test enforces that. The report prints tool names and statuses only — never payloads, and server-authored error text is redacted too (KeyCloak quotes the username it was asked about);--tracebackstill shows the full text on the operator's own terminal.Arguments that would identify real users, groups or IPs are discovered at run time, never written into
scripts/smoke_probes.py.CI enforces the cheap half: a tool registered without a probe spec fails the build (
tests/test_smoke_probes.py), so adding a tool forces the question "how would we know it works?".scripts/smoke_harness.pyis the engine and holds no KeyCloak knowledge: it is kept identical across the servers that share it, so fix engine bugs once and sync the file rather than patching this copy.
License
MIT
Available Tools
32 toolscount_usersA
Get total user count in the realm.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so description carries the burden. It implies a safe read operation but does not specify performance, whether disabled users are included, or if the count is cached. Lacks detail beyond the obvious.
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?
Single sentence, no extraneous text. Front-loaded and efficient.
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 tool with no parameters and an output schema available, the description sufficiently defines the purpose. The output schema likely explains the return format. Complete for this simple case.
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?
No parameters exist, so schema coverage is 100%. The description adds no parameter information, but none is needed. Baseline for 0 params is 4.
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 ('get') and the resource ('total user count in the realm'). It distinguishes from sibling tools like 'search_users' which returns user details or 'get_user' which returns a single user.
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 explicit guidance on when to use this tool versus alternatives (e.g., counting via search_users). For a simple tool, some context about use cases (e.g., quick overview vs detailed search) would be helpful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
daily_briefA
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)
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).
| Name | Required | Description | Default |
|---|---|---|---|
| since_hours | No | ||
| ip_failure_threshold | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden, and it delivers: it discloses output tiers (CRITICAL/WARNING/OK), default thresholds, scoping to since_hours, the independent brute-force and spray-check rules, and the caveat that only accounts in the Spray check list may be called breached. It even explains the evidence tuple shape.
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?
Although longer than average, the description is well structured with bullets, sections, and an Args block. It front-loads the purpose, groups checks logically, and every sentence adds meaningful information about thresholds, defaults, output tiers, or routing to spray_check.
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 tool with two parameters, an existing output schema, and non-trivial detection logic, the description is complete: it covers all checks, thresholds, defaults, output tiers, and the exact semantics of the two arguments. It also points to spray_check for further tuning and row details, so an agent has everything needed to invoke and interpret results.
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%, and the description fully compensates by explaining both parameters semantically: since_hours is the look-back window with a default and morning-run rationale, while ip_failure_threshold is the single-IP failure count that triggers a WARNING. This goes well beyond the bare integer 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?
Description opens with a specific verb and resource: 'Run a morning Keycloak health check.' It then enumerates the exact checks, making clear this is an aggregate tool that sits above granular siblings like get_login_stats, get_session_stats, and get_admin_events, and it explicitly references spray_check for the spray-detection portion.
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?
It gives clear usage context as a morning health check, with since_hours defaulting to 18 to approximate a previous-day window for a 09:00 run. It also directs users to spray_check when they need the full row shape or want to widen the window/tune thresholds, but it does not explicitly enumerate when to prefer the granular sibling tools over this aggregate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
detect_login_loopsA
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.
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | ||
| date_to | No | ||
| date_from | No | ||
| threshold | No | ||
| window_seconds | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it discloses the KEYCLOAK_DEADLINE time bound (default 45s), that results may be partial with a 'PARTIAL RESULT' prefix, that counts become a lower bound, and the correct retry strategy. This is exactly the kind of non-obvious behavior an agent needs before calling.
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?
Front-loaded with the purpose, then a well-structured args list. The deadline paragraph is slightly long but every sentence (partial results, retry advice, trigger cause) earns its place. Minor verbosity only.
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 5-param detection tool with an output schema already covering return values, this description covers purpose, all parameters, time-bounding behavior, and failure handling. Nothing an agent needs to call it correctly is missing.
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 coverage is 0%, so the description must compensate, and it documents all five parameters: date formats (YYYY-MM-DD), defaults, the meaning of threshold/window_seconds, and 'Use 0 for all' for top. It fully fills the gap left by 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?
States a specific verb+resource+scope: 'Detect users with rapid repeated logins (possible redirect loops).' This is immediately distinguishable from siblings like spray_check and get_login_failures_by_ip, which target different attack patterns.
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?
Usage is implied by the detection description, and it gives good operational guidance ('Call again with a narrower window instead of retrying'), but it never explicitly says when to choose this over a sibling like spray_check or get_login_stats. No when-not or alternative routing is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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 (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.
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | No | ||
| max_repr | No | ||
| date_from | No | ||
| max_results | No | ||
| resource_path | No | ||
| resource_types | No | ||
| operation_types | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of disclosure. It discloses meaningful behavioral context: admin events reflect service-account/admin operations, the default date_from is last 24h, and max_repr semantics. It does not explicitly discuss read-only status or auth requirements, but 'Get' plus the audit-query framing make these less critical.
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 front-loaded with the purpose paragraph and followed by a compact, scannable Args list. Every sentence adds value; there is no padded language or repetition of the input schema.
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?
The tool has 7 parameters and zero schema-level parameter descriptions, but the text covers all seven, provides defaults and enums in prose, and gives a why/when not to use. Because an output schema exists, not explaining return values is acceptable, and there is no significant explanatory gap.
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 provides only parameter names and defaults (0% description coverage), so this description is the only source of parameter meaning. The Args section thoroughly defines every parameter, including enum-like values for operation_types and resource_types, a resource_path example, date format, and default behavior for max_results and max_repr.
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 opens with a specific verb + resource ('Get KeyCloak admin events') and immediately clarifies the scope: changes performed via the Admin REST API. It explicitly distinguishes these from user events and references sibling 'get_events', so the agent can disambiguate among similar tools.
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?
It provides an explicit 'Use this when...' trigger: when UPDATE_PROFILE in get_events is empty but an attribute is known to have changed. It also differentiates admin events from user events, giving clear selection guidance for this tool versus related event-retrieval tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_brute_force_statusA
Check if a user is temporarily locked due to brute force detection.
Args: username: Exact username (email).
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It states the operation is a 'check' (implying read-only) but does not disclose potential side effects, permissions, or error handling. Lacks detail on output behavior, though output schema exists.
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?
Two sentences: one for purpose, one for parameter documentation. No redundant words; front-loaded with actionable information.
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?
Despite having an output schema, the description does not clarify what 'locked' means (e.g., duration) or how results map to tool selection among similar siblings. Adequate but incomplete.
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 coverage is 0%, so description must compensate. It adds 'Exact username (email)' to the parameter, clarifying expected format, but no examples or constraints. Minimal added value beyond 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 uses the verb 'check' and specifies the resource 'if a user is temporarily locked due to brute force detection,' clearly distinguishing it from sibling tools like get_user or get_login_stats.
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 implies when to use (to check lock status) but does not provide explicit guidance on when not to use or alternatives among siblings like get_login_failures_by_ip.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_clientA
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).
| Name | Required | Description | Default |
|---|---|---|---|
| client_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so thoroughly: it discloses that the tool returns an allowlist rather than raw client representation, explains that attributes and protocolMappers are omitted to keep credential-shaped data out of output and LLM context, and notes that flow IDs are resolved to aliases. This is far beyond the minimum disclosure.
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 front-loaded with the core purpose and then builds detail in a logical order: output shape, security rationale, domain semantics, and the argument definition. Every sentence adds actionable context rather than repeating schema or title information.
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 single-parameter read tool, the description covers the key selection and invocation facts: what the tool returns, why certain fields are omitted, how flow overrides are presented, and which identifier to pass. The presence of an output schema means the explicit allowlist fields need not be enumerated in prose.
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 only says client_id is a string, but the description adds the crucial distinction: 'The clientId (not the internal UUID).' This prevents a likely mis-invocation and gives the agent exactly the semantic needed for correct lookup.
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 opening sentence states a specific verb and resource: 'Show one client's configuration, including its authentication flow overrides.' It clearly distinguishes from siblings like list_clients and get_client_sessions by emphasizing the singular client and the configuration focus.
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 makes the scope clear—'one client's configuration'—which implies this is for retrieving a single client's full config rather than listing clients or sessions. However, it does not explicitly name alternatives or say when not to use this tool, so there is room for sharper routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| client_id | Yes | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description must disclose behavioral traits. It only mentions 'active sessions' but omits details like data freshness, pagination, error handling, or rate limits.
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 succinct with two sentences plus an Args list. Every phrase adds value, and the structure is front-loaded with the main action.
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 absence of annotations and output schema visibility, the description covers parameter semantics but lacks behavioral context. With two simple parameters and an output schema present, it is minimally complete but could elaborate on result behavior.
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%, but the description provides examples for client_id ('xflow', 'shadowserver') and clarifies max_results default (100). This adds meaningful 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 verb 'Get' and the resource 'active sessions for a specific client (SP)'. It distinguishes from sibling tools like get_user_sessions by specifying client sessions, making the purpose unambiguous.
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 is provided on when to use this tool versus alternatives such as get_user_sessions or get_session_stats. Agents have no basis for tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | No | ||
| username | No | ||
| client_id | No | ||
| date_from | No | ||
| event_type | No | ||
| ip_address | No | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It explains parameter behaviors (e.g., date_from defaults to last 24h, username resolved internally, ip_address is client-side filter). However, it does not disclose whether the operation is read-only, authentication requirements, or rate limits, leaving some gaps.
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 structured with a clear lead sentence followed by a detailed args list. All sentences are informative, but the list format is slightly verbose. It is front-loaded with the purpose, which is good.
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?
The description covers parameters well and output schema exists, so return values need not be explained. However, it lacks guidance on when to use this tool among many similar siblings and does not mention any limitations or edge cases.
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 explains all 7 parameters with additional context such as default values, internal resolution, and filter nature, providing significant value 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 'Get KeyCloak events with optional filters', using a specific verb and resource. It does not explicitly distinguish from sibling tools like get_admin_events, but the name and context make the purpose reasonably clear.
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 explicit guidance on when to use this tool versus alternatives such as get_admin_events or get_password_update_events. It lists filters but does not explain the appropriate context or conditions for selecting this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_ip_activityA
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.
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
truncated, which only trims the timeline of an otherwise-complete
scan. Narrow date_from when this is true.
Time-bounded: this call stops after KEYCLOAK_DEADLINE seconds (default 45) and
returns what it has; the counts are then a lower bound. The returned dict then has
events_capped: true (no warning text); narrow date_from / date_to.
Call again with a narrower window instead of retrying the same call. A wide window
on a busy day is what triggers it.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | No | ||
| date_from | No | ||
| ip_address | Yes | ||
| event_types | No | LOGIN,LOGIN_ERROR | |
| max_timeline | No |
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, and it delivers substantial context: the wall-clock deadline (KEYCLOAK_DEADLINE, default 45s), the distinction between events_capped (whole result incomplete) and truncated (timeline-only trim), and empty-input handling. It stops short of permission/auth requirements, but the pagination and deadline semantics are unusually well disclosed.
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?
Well front-loaded — purpose, sibling comparison, and use case precede the return-shape detail — and every section earns its place given there is no output schema. It is nonetheless very long, with the extensive per-key Returns block dominating the text; that length is defensible only because it has nowhere else to live.
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?
With no output schema and 0% parameter coverage, the description is the sole carrier of both argument and return semantics, and it covers the fixed-shape dict, the capped/incomplete flags, and the deadline-driven lower-bound behavior. Nothing an agent needs to call this correctly or interpret the result is missing.
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, and it does for every parameter: ip_address with IPv6 normalization details, event_types with default and a widening example, date_from default (last 24h), date_to open-ended semantics, and max_timeline default/<=0 behavior. This is exactly the compensating detail a low-coverage schema needs.
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?
States a specific verb+resource ('Exhaustive investigation of all activity from one source IP address') and immediately distinguishes itself from the sibling get_events(ip_address=...) by explaining the full-pagination behavior. An agent can tell it apart from get_login_failures_by_ip without opening either schema.
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?
Explicitly names when to use it (brute-force / credential-stuffing / shared-workstation investigations) and the sibling workflow that leads here ('where get_login_failures_by_ip told you which IP to look at'). It also explains the alternative and its limitation (get_events filters a single page and can miss activity).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_login_failures_by_ipA
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).
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | ||
| date_to | No | ||
| date_from | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and does so well: it discloses the KEYCLOAK_DEADLINE timeout (default 45s), that results are truncated with counts becoming a lower bound, that the result is prefixed with a 'PARTIAL RESULT' warning, and the correct retry strategy. This is non-obvious failure-mode and output-shape information an agent could not get from the schema.
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?
Purpose is front-loaded in the first sentence, followed by the deadline/partial-result caveat and a compact Args block. The multi-sentence timeout passage is slightly verbose but each sentence carries actionable content, and the Args block adds real value given the empty schema descriptions.
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 3-parameter, zero-annotation tool with an output schema present, the definition covers the main behavioral risk (timeout/partial results) and the parameter semantics. It omits permission/auth requirements and any note on how the per-IP breakdown is ordered or bounded by top, but these are minor gaps given an output schema exists.
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 and largely does: it supplies the format (YYYY-MM-DD) for date_from/date_to, the semantics of an empty date_to ('all'), the 24h default for date_from, and clarifies that top is the number of top IPs to show. All three parameters are covered, though the interaction between date_to empty and date_from default is not fully spelled out.
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?
States a specific verb and resource with an explicit aggregation dimension: 'login failure statistics broken down by source IP.' This is clearly distinguishable from siblings like get_login_stats_by_client and get_ip_activity, though it never names those alternatives directly, so sibling routing is left to inference rather than stated.
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?
Gives concrete condition-based guidance for the partial-result case: a wide window on a busy day triggers the deadline, and the correct recovery is to re-call with a narrower window rather than retry. It does not, however, say when to prefer this tool over the other login/client/IP statistics siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_login_statsA
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.
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | No | ||
| date_from | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | 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, and it delivers real behavioral context: a 45s deadline, partial results returned as a lower bound, and an explicit 'PARTIAL RESULT' warning marker. It omits auth/permission requirements, but the timeout semantics are the key non-obvious trait and are well disclosed.
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?
Front-loads the purpose, then the timeout behavior, then args — a logical order with no filler sentences. Slightly verbose with env-var names, and the Args block restates parameter names already in the schema.
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?
An output schema exists, so return-value documentation is not needed. The description covers purpose, defaults, and the failure mode adequately; the main omission is routing guidance relative to the many sibling stats tools.
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, and it does: date_from defaults to the last 24h (KEYCLOAK_DEFAULT_DATE_FROM_HOURS) and empty date_to means 'all'. Format (YYYY-MM-DD) is also stated. Minor gap is that the interaction between the two dates is not explained.
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?
States a specific verb and resource (login success/failure statistics) plus a scope note about pagination. However, it never distinguishes itself from close siblings like get_login_stats_by_client, get_login_stats_by_hour, or get_login_failures_by_ip, which an agent must choose between.
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?
Gives solid operational guidance for the timeout case (call again with a narrower window rather than retrying), but offers no guidance on when to pick this aggregate tool over the by-client, by-hour, or by-IP siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_login_stats_by_clientA
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.
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | No | ||
| date_from | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the KEYCLOAK_DEADLINE time bound, that counts become a lower bound on truncation, and that output is prefixed with a "PARTIAL RESULT" warning. It omits auth/permission requirements, but for a read-only stats tool that gap is minor.
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?
Purpose is front-loaded in one line, the time-bound caveat follows, and the Args block is compact. Nothing is filler, though the deadline paragraph could be trimmed by a sentence without losing meaning.
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?
An output schema exists so return structure needn't be restated, and the description covers the non-obvious failure mode (partial results under deadline). Missing only permission/scope framing and explicit sibling routing; otherwise complete for a 2-param stats tool.
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, and it does: date_from gets a format (YYYY-MM-DD) and a default (last 24h via KEYCLOAK_DEFAULT_DATE_FROM_HOURS), and date_to gets a format plus the "empty for all" semantics. The "empty for all" wording is slightly ambiguous but the essential semantics are covered.
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?
States a specific verb+resource ("Get login statistics") plus the aggregation dimension ("broken down by client (SP)"), which is exactly what separates it from siblings get_login_stats and get_login_stats_by_hour. An agent can route to it without opening the schema.
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?
Gives useful operational guidance for the timeout case ("call again with a narrower window instead of retrying") and explains what triggers a partial result. It never says when to prefer this tool over get_login_stats or get_login_stats_by_hour, so the alternative-selection guidance is only implied by the breakdown dimension.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_login_stats_by_hourA
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.
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | No | ||
| date_from | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly: it discloses a hard deadline (KEYCLOAK_DEADLINE, default 45s), partial results with a 'PARTIAL RESULT' warning, counts being a lower bound, the trigger condition (wide window on a busy day), and the recommended recovery action. This is rich behavioral context that an agent needs to interpret results correctly.
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?
Front-loads the purpose, then adds a focused behavioral block, then an Args section. Every sentence earns its place, and the structure makes the critical timeout behavior easy to find.
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, an output schema (so return values need not be explained), and 0% schema description coverage, the description is nearly complete: it covers purpose, timeout behavior, and both parameters. The main gap is the absence of sibling-selection guidance, but for calling the tool correctly, an agent has what it needs.
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 does by documenting the date format (YYYY-MM-DD), the default for date_from (last 24h via KEYCLOAK_DEFAULT_DATE_FROM_HOURS), and the meaning of an empty date_to ('for all'). The only slight ambiguity is that 'Empty for all' could be clearer, but overall it supplies the missing parameter semantics.
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?
States a specific verb, resource, and granularity ('login statistics broken down by hour') that distinguishes it from the aggregate get_login_stats and the by-client variant. However, it does not explicitly name any sibling tool, so it relies on the agent to infer the difference from the name alone.
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?
Provides retry guidance for partial results ('call again with a narrower window'), but gives no guidance on when to use this tool versus alternatives like get_login_stats or get_login_stats_by_client. There is no explicit selection criteria or exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | No | ||
| date_from | No | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description must carry the full burden. It reveals parameter behavior (date range, default) but omits traits like read-only nature, rate limits, or response format. It partially covers behavioral context.
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 concise: one line for purpose followed by parameter documentation. It is front-loaded and efficient, though the parameter section is a bit verbose with repetition of 'Args:' and parameter names.
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?
The description covers parameter details and purpose but lacks context about the tool's scope (e.g., realm-wide vs user-specific) and does not mention that the tool is read-only. With an output schema present, return values are not required, but additional behavioral context would improve completeness.
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?
With 0% schema coverage, the description compensates by specifying date format (YYYY-MM-DD) and defaults for date_from and max_results. It adds meaning beyond the schema's basic type/default fields, though the meaning of max_results is not fully explained.
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 tool retrieves 'password update events', a specific resource. The name and description differentiate it from sibling tools like 'get_events' (generic) and 'get_admin_events'.
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 parameter defaults and date format but does not explicitly state when to use this tool versus alternatives. The usage context is implied by the tool's name and purpose, not explicitly guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_realm_rolesA
List all realm-level roles.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description implies a read-only operation but does not explicitly disclose behavioral traits such as permissions, side effects, or rate limits. With no annotations, it partially meets the burden but lacks detail.
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 sentence with no wasted words. It is front-loaded and efficiently conveys the tool's purpose.
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 simplicity (no parameters, output schema exists), the description is fully complete. It tells the agent exactly what the tool does, and the output schema provides the return structure.
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 tool has no parameters, so the description does not need to add meaning beyond the schema. Baseline score of 4 is appropriate as the schema already covers everything.
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 uses a specific verb 'List' and clearly identifies the resource 'realm-level roles', making the purpose unambiguous. It distinguishes itself from sibling tools like 'list_clients' or 'list_user_groups'.
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 is provided on when to use this tool versus alternatives. The description simply states what it does without any when-to-use or when-not-to-use context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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":
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description declares the tool is read-only and details exactly what it reports (brute force detection, password policy, browser headers) without side effects, fully transparent given no annotations.
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 well-structured with bullet points, but slightly verbose; still concise enough to be effective.
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 zero parameters and an output schema, the description fully explains what the tool returns and its purpose, including usage context relative to siblings.
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?
No parameters, baseline 4. The description adds no parameter info, but none is needed.
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 it shows realm security-defense settings (read-only) and distinguishes from sibling get_brute_force_status by noting it reports policy configuration, not runtime state.
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?
It explicitly says to use this tool to verify brute-force protection is enabled and configured, and contrasts with get_brute_force_status for runtime state, providing clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_session_statsA
Get active session count per client.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must fully disclose behavioral traits. It only states the basic purpose without mentioning whether the count is real-time, cached, scoped to a time range, or requires specific permissions. This leaves behavioral uncertainty.
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 concise sentence that effectively communicates the tool's function with no extraneous words. It is front-loaded and efficient.
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 simple nature of the tool (no parameters, has output schema), the description is minimally adequate. However, it lacks details such as whether counts are for all clients or filtered, time scope, and how results are returned, which would be helpful for full understanding.
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 tool has no parameters, and schema coverage is 100%. The description adds no parameter details because none exist. The baseline for zero parameters is 4, and the description is clear about what the tool does, justifying the score.
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 'Get active session count per client' clearly states the verb 'Get' and the resource 'active session count per client', which distinguishes it from sibling tools like get_client_sessions or get_login_stats. It is specific and unambiguous.
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 usage guidance is provided. The description does not indicate when to use this tool versus alternatives such as get_client_sessions or get_login_stats_by_client, nor does it specify prerequisites or limitations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_totp_usersA
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.
| Name | Required | Description | Default |
|---|---|---|---|
| max_users | No | ||
| list_users | No | ||
| enabled_only | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses key behaviors: N+1 queries, slowness on large realms, error handling for credential lookup failures, and short-circuiting via max_users. It provides sufficient behavioral context for an agent.
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 well-structured with front-loaded purpose, then performance and parameter details. While somewhat lengthy, every sentence adds value. Minor redundancy could be trimmed.
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 and 0% schema coverage, the description covers purpose, performance, parameter behavior, and error handling. Output schema exists, so return value explanation is not needed. The tool is well-described for agent 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?
Schema coverage is 0%, and the description fully explains all three parameters: enabled_only, list_users, and max_users. It adds important details like default fallback to KEYCLOAK_MAX_USERS and sample coverage when capped.
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 tool reports the count of users with TOTP configured across the realm. It uses specific verbs ('Report') and resource ('users with TOTP'), and distinguishes from sibling tools like 'count_users' and 'get_user_credentials'.
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 explains when to use this tool (to get TOTP user count), but lacks explicit alternatives or 'when not to use' guidance. However, the performance warning and parameter 'max_users' provide usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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 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., user@example.com).
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full transparency burden. It goes beyond a simple getter by disclosing the extra by-ID lookup, the omission of attributes in the search endpoint, and the credential-key blocking safety net. It does not cover all possible error cases, but the disclosed behavior is substantial.
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 structured with a crisp one-sentence summary followed by a necessary behavioral clarification paragraph and an Args block. The detail about the whitelist and credential-blocking is somewhat long but earns its place by explaining non-obvious tool behavior.
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?
The tool has an output schema, so return-value documentation is not required. The description covers the key contextual points: exact-match lookup, custom attribute handling, and safety filtering. It is adequate for selecting and invoking the tool, though it leaves error behavior unspecified.
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%, but the description compensates with an explicit Args section: 'username: Exact username (e.g., user@example.com).' This adds format and exactness semantics that the bare schema lacks, though there is only one parameter to explain.
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 first sentence clearly states the action ('Get detailed user information') and the target ('by exact username (email)'). It is specific enough to distinguish from sibling tools like get_user_sessions or search_users, though it does not explicitly contrast with those alternatives.
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 implies the tool should be used when you have an exact username or email. It does not explicitly state when to prefer this over search_users or other lookup tools, nor does it mention exclusions or alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_attribute_historyA
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.
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | No | ||
| max_repr | No | ||
| username | Yes | ||
| date_from | No | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full transparency burden. It discloses that the tool queries admin events scoped to users/{userId} with UPDATE/ACTION operations, explains default date-from behavior, and clarifies max_repr semantics. It does not mention authentication, rate limits, or pagination, but it gives strong operational detail for a read-only query 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 well-structured: a one-sentence purpose, a brief context paragraph explaining why the tool exists relative to get_events, and a compact Args list. Every sentence adds value, and the format is easy to scan.
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 there is an output schema, the description need not explain return values. It covers purpose, scope, operation types, defaults, parameter semantics, and the key differentiator from get_events. This is complete for a focused admin-history query tool.
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 fully compensate. The Args section documents all five parameters with practical semantics: username is exact email, date_from defaults to last 24h, max_results defaults to 100, and max_repr values (0 omit, -1 full) are explained. This goes well 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 opens with a specific verb and resource: 'Get admin-side attribute change history for a single user.' It clearly distinguishes itself from siblings by contrasting with get_events, which only surfaces user-driven events, making the tool's unique purpose immediately understandable.
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 gives clear usage context by stating it is 'Intended for tracking custom attribute changes' written by admin API and explicitly notes these do not surface in get_events. It provides a when-to-use rationale and names the relevant alternative, though it does not exhaustively enumerate when not to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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 otp credential means
TOTP/HOTP is configured. Reads /users/{id}/credentials (read-only; does
not create a session).
Args: username: Exact username (email).
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses that it is read-only ('Reads', 'does not create a session'), which is crucial for behavioral understanding. It does not detail error handling or permissions, but for a simple read operation this is adequate.
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 concise, front-loaded with the main purpose, followed by a usage example, technical detail, and parameter description. Every sentence adds value with 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?
The tool is simple with one parameter well-described. An output schema exists (not provided), so return values need not be explained. Minor lack of error handling info, but overall sufficiently complete for its complexity.
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 adds meaning by specifying that 'username' must be an exact username (email), which is not in the schema. This fully clarifies the parameter semantics.
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 uses a specific verb 'List' and resource 'credential types configured for one user', giving examples and clarifying it's for checking a single user's MFA status. This clearly distinguishes it from sibling tools like search_users or reset_password.
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 explicitly states to use this for checking a single user's MFA status, providing clear context. It does not give explicit exclusions or alternatives, but the use case is well-defined and sensible among the sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_sessionsC
Get active sessions for a user.
Args: username: Exact username (email).
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description must carry behavioral disclosure. It does not mention whether the call is read-only, requires authentication, or handles missing users. Only the action is stated.
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?
Very concise—two sentences. Front-loaded with the main action. The 'Args' section is slightly redundant given the schema but provides useful extra detail.
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?
Tool has output schema, so return value details are not required. However, given low complexity, the description is adequate but could mention that only active sessions are returned.
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 coverage is 0%, but description adds meaning by specifying 'Exact username (email)'. However, it does not clarify case sensitivity, format expectations, or error behaviors for invalid usernames.
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 states 'Get active sessions for a user', clearly specifying the verb and resource. It distinguishes from siblings like get_client_sessions and logout_user, though it could be more precise about the scope (e.g., active vs all sessions).
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 vs alternatives like get_session_stats or when not to use it. Missing context about prerequisites or exclusion cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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: 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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the burden. It discloses the OAuth2 Client Credentials Grant, cached client reuse, lightweight nature, exact return keys, value sets (e.g., 'status: healthy/degraded/error'), and even notes keycloak_version is None due to cost. This is exceptionally transparent.
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 front-loaded with purpose, then usage, then return contract – well structured. However, the closing paragraph about READMEs is meta-commentary irrelevant to an AI agent invoking the tool, adding slight bloat. Otherwise, every sentence earns its place.
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?
Despite having no output schema, the description fully specifies return keys, possible values, and meanings (including 'detail' for errors). It also covers deployment-specific fields like keycloak_url and realm. For a zero-parameter health check, this is complete and self-sufficient.
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 tool has zero parameters, and the schema confirms this. The description correctly doesn't waste space on parameter details. Per rubric, a 0-param tool gets a baseline of 4, and there is no additional semantic burden to meet.
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 'Report server version and KeyCloak backend connectivity / authentication' – a specific verb with a precise resource. It immediately distinguishes this from sibling tools (none of which are health/connectivity checks). The purpose is unambiguous and well-scoped.
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?
Explicitly instructs when to call: 'at session start (or after a tool-call timeout)' and explains what it confirms. It also states what it does NOT do ('does NOT enumerate users, events, or sessions'), giving a clear when-not boundary. This fully satisfies the 'when/when-not' criterion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_clientsA
List all SAML/OIDC clients in the realm.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It only states 'list all clients' with no mention of side effects, pagination, ordering, or rate limits. The existence of an output schema helps, but behavioral safety (read-only) is implied but not stated.
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?
Single, clear sentence that is front-loaded and contains no unnecessary verbiage. Every word earns its place.
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 and an output schema, the description is complete enough to inform the agent of the tool's purpose. The return structure is covered by the output schema.
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?
There are zero parameters, so schema coverage is 100%. The description adds no parameter information, but since no parameters exist, the baseline of 4 applies. The description doesn't need to add more.
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?
Description clearly states verb 'list', resource 'SAML/OIDC clients', and scope 'in the realm'. It is specific and distinguishes from sibling tools (no other list clients tool).
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 versus alternatives. While no similar list client tools exist in siblings, the description does not provide context for when to use or not use it (e.g., if filtering is needed).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_user_groupsA
List groups a user belongs to.
Args: username: Exact username (email).
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must convey behavioral traits. The description implies a simple read operation, but it doesn't disclose potential behaviors like pagination, rate limits, or required permissions. However, for a straightforward listing, it is minimally adequate.
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 only two sentences: the first states the purpose, the second lists the parameter and its meaning. No unnecessary 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?
Given that there is an output schema (not shown), the description need not explain return values, but it lacks context on the scope of groups (e.g., all groups or filtered). It is minimally complete for a simple one-parameter tool.
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, but the description adds crucial information: 'username: Exact username (email).' This clarifies the format of the parameter beyond the schema's type string, providing clear usage guidance.
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 tool's purpose: 'List groups a user belongs to.' This is a specific verb-resource combination that distinguishes it from sibling tools like get_user or search_users, which focus on user details or search rather than group membership.
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. For example, it doesn't mention when to use list_user_groups over get_user, or any prerequisites or context for calling it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_users_by_groupA
List all users in a group.
Args: group_name: Group name (partial match). max_results: Maximum results (default 100).
| Name | Required | Description | Default |
|---|---|---|---|
| group_name | Yes | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses only that group_name supports partial match and max_results defaults to 100, but does not mention read-only nature, permission requirements, or behavior on missing groups. It also does not describe the return structure, though an output schema exists.
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 minimal and efficient, using two short lines for parameters. No fluff.
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 simplicity (2 params, output schema present), the description covers the essential parameters and their behavior. It could mention case sensitivity or result ordering, but overall it is sufficient for basic usage.
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 description adds 'partial match' to group_name and clarifies max_results as a maximum limit, which goes beyond the bare schema and compensates for the schema's 0% description coverage.
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 uses a specific verb ('List') with a clear resource ('all users in a group'), and the parameter 'group_name' clarifies scope. It distinguishes itself from sibling tool 'list_user_groups' by focusing on users within a group rather than the groups themselves.
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 explicit guidance on when to use this tool versus alternatives like 'search_users' or 'get_user'. The description provides no context or exclusions, leaving the agent to infer usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
logout_userA
Force logout a user by removing all their active sessions.
Args: username: Exact username (email).
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | 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 clearly states the destructive effect ('removing all their active sessions'), which is transparent. However, it does not mention potential side effects like token invalidation or reversibility.
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?
Two short sentences: the first delivers the main action, the second documents the parameter. No wasted words, front-loaded with the key behavior.
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?
The tool has a single required parameter and an output schema. The description covers the core behavior and parameter semantics completely. No additional details are needed given the output schema exists.
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?
With 0% schema description coverage, the description fully compensates by specifying that 'username' requires an exact email. The schema only had a title 'Username', so the description adds essential meaning.
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 states a specific verb ('Force logout') and resource ('user by removing all their active sessions'). It clearly distinguishes from sibling tools like get_user_sessions (view only) or reset_password (different action).
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 implies admin usage ('Force logout') but does not explicitly state when to use this tool over alternatives like get_user_sessions or reset_password. No exclusion criteria or alternative suggestions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| password | Yes | ||
| username | Yes | ||
| temporary | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Covers the basic effect of resetting and temporary flag behavior, but lacks disclosure on required permissions, notification side effects, or logging. Without annotations, more behavioral context is expected.
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?
Concise, front-loaded purpose, each sentence adds value. No redundant information.
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?
Adequately complete for a single-password reset tool; output schema exists so return value not needed. Could add usage scenario notes or prerequisites, but not essential.
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?
Adds meaning beyond schema for all three parameters: username is exact email, password is new password, temporary description explains forced change on login. Schema description coverage is 0%, so description fully compensates.
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?
Clearly states 'Reset a user's password' with specific verb and resource. Distinguishes from sibling 'reset_passwords_batch' which operates on multiple 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?
Explains the 'temporary' parameter effect but does not provide guidance on when to use this tool versus alternatives like 'reset_passwords_batch' or other user management tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| csv_text | Yes | ||
| temporary | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description covers key behaviors: passwords not echoed, random generation, temporary flag effect. Missing error handling details, but overall good transparency.
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?
Concise yet informative, front-loads the purpose, and every line adds value. Structured with a clear Args section.
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?
The description is complete for a batch tool with two parameters and an output schema. It covers input format, behavior, and edge cases without needing to duplicate output schema info.
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 description explains both parameters well: csv_text format and temporary meaning. Despite 0% schema coverage, the Args section provides full semantics.
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 it resets passwords for multiple users from CSV text, and it distinguishes itself from the sibling tool reset_password which handles single 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?
The description gives detailed usage instructions including CSV format, password generation behavior, and the temporary flag. It contrasts with reset_password implicitly but lacks explicit when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided. The description implies a read-only search operation with partial matching, but does not disclose any side effects, permissions, or response structure beyond the implicit search behavior.
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?
Extremely concise and well-structured. Two sentences plus clear argument descriptions. Every detail earns its place.
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?
Has an output schema, so return values need no further explanation. The description covers core functionality and parameters, but lacks usage guidelines or behavioral notes. Adequate for a simple tool.
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 adds crucial meaning: 'query' is a partial match string, and 'max_results' has a default of 20. This fully compensates for the lack of schema descriptions.
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 'Search users' and specifies the fields: username, email, first name, last name. It effectively distinguishes from siblings like 'get_user' (single user) and 'count_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 explicit guidance on when to use this tool versus alternatives like 'get_user' or 'list_users_by_group'. It does not mention context or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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
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.
| Name | Required | Description | Default |
|---|---|---|---|
| enabled | Yes | ||
| username | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: blocking SSO logins, preserving custom attributes, not terminating existing sessions, and reporting remaining sessions. This is comprehensive and transparent.
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 concise and well-structured, with a clear opening sentence, bulleted args, and no wasted words. It front-loads the key action and follows with important details.
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 presence of an output schema and many sibling tools, the description is complete. It explains the tool's behavior, side effects, and relationship to logout_user, covering all necessary aspects for correct invocation.
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 coverage is 0%, so the description must explain parameters. It describes 'username' as exact username (email) and 'enabled' as True/False. While this adds minimal value beyond the schema types, it is sufficient and contextually correct.
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 explicitly states the tool enables or disables a user account, using a specific verb and resource. It distinguishes from siblings like logout_user by explaining that disabling blocks authentication but does not end existing sessions, making the purpose clear and unique.
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 explicitly states when to use this tool (disabling a compromised or decommissioned account) and mentions an alternative (logout_user) for terminating existing sessions. This provides clear guidance on when to use versus other tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
spray_checkA
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 pagination was cut short (KEYCLOAK_DEADLINE /
KEYCLOAK_MAX_EVENTS). When False, treat the result as a lower bound
and do NOT publish a definitive verdict; narrow hours and retry.
spray: flagged IPs (see external_ips for the row shape), each with
breached = list of evidence tuples; confidence: high rows
first.
external_ips: every external IP with at least min_report_users
distinct users, flagged or not, sorted flagged-first, then
high-confidence first, then by ascending success rate — so
near-misses (e.g. 8 users at 14%) are visible without a second
rule. Row: ip, known_egress, flagged, confidence ("high"/"low"),
signals (list of the reasons for "low"), unique_users,
users_with_success, user_success_rate, failure_concentration,
top_failed_users (up to 5 {username, failures}),
not_found_domains (domain -> count for user_not_found
usernames), attempts, successes, failures, success_rate, errors
(error-code counter; user_not_found mixed with
invalid_user_credentials on many DIFFERENT names indicates a
scraped username list — on the same few names it is a human
retyping), first_seen, last_seen, unresolved_user_ids, breached.
breached_total: number of evidence tuples across all flagged IPs.
breached_low_confidence: how many of those sit on confidence: low
rows (candidates to verify, not breaches).
internal_events_excluded: events dropped because the IP is internal.
resolves_used / resolve_capped: how many GET /users/{id} lookups were
spent resolving success userIds, and whether max_resolves (or
the shared deadline) stopped further lookups. A row's
unresolved_user_ids counts successes keyed by bare userId; if
that is non-zero on a flagged row, unique_users may be
slightly over-counted and breached[].username is the id.
known_egress_configured: whether KEYCLOAK_KNOWN_EGRESS is set. IPs in
those ranges are LABELED known_egress: true, never excluded —
a shared VDI/VPN/proxy egress with many real users is expected to
show a high success rate and usually is not flagged anyway.
Users are keyed by lowercased username on both sides: LOGIN_ERROR carries
details.username; LOGIN usually carries only userId. userIds are
mapped from the fetched events first (any event carrying both fields),
then via GET /users/{id} — only for IPs below the success-rate ceiling
(the only ones that can be flagged), at most max_resolves times, and
never past the shared KEYCLOAK_DEADLINE.
Time-bounded: this call stops after KEYCLOAK_DEADLINE seconds (default 45) and
returns what it has; the counts are then a lower bound. The returned dict then has
complete: false (no warning text); use a smaller hours.
Call again with a narrower window instead of retrying the same call. A wide window
on a busy day is what triggers it.
Args:
hours: Look-back window (default 24 — sized for a once-a-day patrol).
min_users: Distinct users an IP must touch to count as a spray (default 10).
max_success_rate: Success-rate ceiling for a spray (default 0.2).
min_report_users: Distinct users an IP needs to appear in
external_ips at all (default 3; clamped to min_users).
max_resolves: Cap on GET /users/{id} lookups per call (default 200).
max_user_success_rate: user_success_rate at or above this marks
the row confidence: low (default 0.3).
max_failure_concentration: failure_concentration at or above this
marks the row confidence: low (default 0.5).
| Name | Required | Description | Default |
|---|---|---|---|
| hours | No | ||
| min_users | No | ||
| max_resolves | No | ||
| max_success_rate | No | ||
| min_report_users | No | ||
| max_user_success_rate | No | ||
| max_failure_concentration | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so exhaustively: it discloses the deadline/time-bounded behavior, the complete:false lower-bound semantics, confidence labeling rules, known-egress labeling (never excluded), resolve caps and shared-deadline stopping, and the invariant that breaches come only from actual LOGIN events.
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 purpose and interpretation guidance are front-loaded, but the block is very long and dense, with the return-shape enumeration and several repeated cautions (publish/lower-bound) that could be tightened. Detail is largely warranted given no output schema, but it is closer to a wall of text than a crisp definition.
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?
There is no output schema, so the description must explain returns, and it does so thoroughly (window, complete, spray, external_ips, breached_total, resolves_used, etc.), along with the KEYCLOAK env dependencies and interpretation rules. An agent has everything needed to call and read this tool correctly.
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 and largely does: all seven parameters are documented in the Args block with defaults and meaning (including the min_report_users clamping to min_users). One inconsistency weakens it: max_user_success_rate is documented as default 0.3 while the schema declares 0.2.
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?
States a specific verb and resource ('Detect password-spray sources and name the accounts they breached') with a clear scope via the detection rule (unique_users >= min_users AND success_rate < max_success_rate). This distinguishes it from generic siblings like get_login_failures_by_ip and get_brute_force_status, which lack breach-naming and confidence semantics.
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?
Gives strong operational context: read top_failed_users and not_found_domains before writing up, treat low-confidence successes as 'verify with the owner', and re-call with a narrower window rather than retrying. It never explicitly names which sibling to use instead, so the when-to-use-vs-alternative routing is implied rather than stated.
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.
1 tool update
v0.20.0- Added
get_client
1 tool update
v0.19.0- Added
spray_check
1 tool update
v0.14.3- Added
list_users_by_group
12 tool updates
v0.14.1- Added
count_users - Added
daily_brief - Added
get_events - Added
get_realm_roles - Added
get_realm_security_defenses - Added
get_totp_users - Added
get_user_credentials - Added
list_clients - Added
list_user_groups - Added
logout_user - Added
reset_password - Added
set_user_enabled
13 tool updates
v0.13.1- Removed
count_users - Removed
daily_brief - Removed
get_events - Removed
get_realm_roles - Removed
get_realm_security_defenses - Removed
get_totp_users - Removed
get_user_credentials - Removed
list_clients - Removed
list_user_groups - Removed
list_users_by_group - Removed
logout_user - Removed
reset_password - Removed
set_user_enabled
1 tool update
v0.13.0- Added
set_user_enabled
2 tool updates
v0.11.0- Added
get_ip_activity - Added
get_realm_security_defenses
3 tool updates
v0.9.0- Added
get_totp_users - Added
get_user_credentials - Added
health_check
24 tool updates
v0.1.0- First observed
count_users - First observed
daily_brief - First observed
detect_login_loops - First observed
get_admin_events - First observed
get_brute_force_status - First observed
get_client_sessions - First observed
get_events - First observed
get_login_failures_by_ip - First observed
get_login_stats - First observed
get_login_stats_by_client - First observed
get_login_stats_by_hour - First observed
get_password_update_events - First observed
get_realm_roles - First observed
get_session_stats - First observed
get_user - First observed
get_user_attribute_history - First observed
get_user_sessions - First observed
list_clients - First observed
list_user_groups - First observed
list_users_by_group - First observed
logout_user - First observed
reset_password - First observed
reset_passwords_batch - First observed
search_users
TDQS
Scored across 32 tools
Most tools are clearly distinct by resource and dimension (e.g., login stats by client/hour vs. IP, user vs. client vs. session stats). Some overlap exists in event retrieval (get_events, get_admin_events, get_password_update_events) and session inspection, but the detailed descriptions help an agent differentiate them.
Names predominantly follow a consistent snake_case verb_noun pattern (get_*, list_*, reset_*, set_*, search_*). A few report-style tools (daily_brief, spray_check, health_check) deviate from strict verb_noun, but casing and readability remain consistent.
32 tools is excessive for a single MCP server; many event and statistics tools (e.g., get_login_stats, get_login_stats_by_client, get_login_stats_by_hour, get_login_failures_by_ip) could be consolidated via parameters. This volume increases navigation overhead and cognitive load for an agent.
The server covers security monitoring and containment well (events, stats, disable user, logout, password reset) but lacks core administrative CRUD operations like create/delete user, group membership management, client/role creation, and clearing brute-force lockouts. These are notable gaps for a Keycloak admin surface.
Maintenance
Related MCP Connectors
- SkycloakOAuthio.skycloak
Managed Keycloak from any MCP client: clusters, realms, apps, SSO, users, domains, audit events.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
An MCP server that provides an API to LLMs to manage their JumpCloud resources.
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.984 npm13MIT
- 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
- AlicenseAqualityDmaintenanceAn MCP server that lets an AI assistant inspect and modify Keycloak realm, client, and protocol-mapper configuration across multiple Keycloak hosts.784 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables administration of Keycloak identity and access management through MCP, allowing management of realms, clients, users, roles, groups, identity providers, and sessions from any MCP client.56 npmApache 2.0