Skip to main content
Glama
shigechika

keycloak-mcp

by shigechika

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

count_users

Total user count in the realm

search_users

Partial-match search (username / email / name)

get_user

Full detail for an exact username

reset_password

Reset one user's password

reset_passwords_batch

Bulk reset from CSV (username,password per line; blank password is generated)

get_user_sessions

Active sessions for one user, timestamps in local time

logout_user

Kill all active sessions for one user

set_user_enabled

Enable or disable one user; disabling blocks all logins (custom attributes preserved)

MFA / Credentials

Tool

Description

get_user_credentials

Credential types configured for one user; an otp entry means TOTP/HOTP is set up

get_totp_users

Realm-wide TOTP adoption: how many users have an otp credential, with percentage and (optionally) the user list. Enumerates users and reads each one's credentials (N+1; bound with max_users)

Groups

Tool

Description

list_user_groups

Which groups a user belongs to

list_users_by_group

Members of a group

Security

Tool

Description

get_brute_force_status

Whether a user is currently locked by brute-force detection

get_realm_security_defenses

Realm-level security policy: whether brute-force detection is enabled and its thresholds, the password policy, and browser security headers

get_login_failures_by_ip

Failure breakdown by source IP (site-labeled when KEYCLOAK_SITES_INI is set)

get_ip_activity

Exhaustive investigation of one source IP: success/failure counts, affected users/clients, timeline. Returns structured JSON.

spray_check

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 time / ip / username / user_id / client_id) are the breach candidates. Each row carries a confidence: high is a breach verdict; low means the volume rule fired on a shared egress (school NAT, home line, VDI) — signalled by user_success_rate (distinct users that logged in ÷ distinct users, ≥ 0.2), failure_concentration (share of failures on one username, ≥ 0.5) or a KEYCLOAK_KNOWN_EGRESS match — and the logins are to be verified with the owner, not published. top_failed_users and not_found_domains show who kept failing and which mistyped domains produced user_not_found. Fixed-shape JSON, complete: false when the window was truncated.

detect_login_loops

Flag users who logged in too many times in a short window (redirect loops)

Events

Tool

Description

get_events

Filter by type, username, client, IP, and date range. Username is resolved to user ID internally. Failure events include KeyCloak's error field (e.g. invalid_user_credentials).

get_login_stats

Login success/failure totals, paginated across all results

get_login_stats_by_hour

Logins bucketed by hour of day (local time)

get_login_stats_by_client

Logins bucketed by client / SP

get_password_update_events

UPDATE_PASSWORD history

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

get_admin_events

Filter by operation (CREATE / UPDATE / DELETE / ACTION), resource type (USER / CLIENT / ROLE / GROUP / …), resource path, and date range

get_user_attribute_history

UPDATE/ACTION events scoped to one user — handy for tracking when a custom attribute (e.g. provisioning_flag) was written by an automated pipeline

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

get_session_stats

Active session count per client

get_client_sessions

Active sessions for one client (SP)

list_clients

SAML and OIDC clients in the realm

get_client

One client's configuration, including its authentication flow overrides (the per-SP MFA switch). Omits attributes and protocolMappers, so no client secret or SAML signing material reaches tool output.

get_realm_roles

Realm-level roles

Morning Patrol

Tool

Description

health_check

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 status, auth, and the configured URL/realm. The tool's own description enumerates the values those fields can take, and is the one place that does.

daily_brief

One-shot morning health check: login stats, brute-force IPs, spray check (same rule as spray_check, with breached accounts and evidence), active sessions, password updates, and admin events in a single Markdown summary. IPs exceeding ip_failure_threshold failures (default 50) and spray sources are flagged WARNING; API errors surface as CRITICAL. since_hours controls the look-back window (default 18 h).

Related MCP server: mcp-keycloak

Setup

# uv
uv pip install keycloak-mcp

# pip
pip install keycloak-mcp

From source:

git clone https://github.com/shigechika/keycloak-mcp.git
cd keycloak-mcp

# uv
uv sync

# pip
pip install -e .

Configuration

Variable

Description

Default

KEYCLOAK_URL

Base URL, e.g. https://keycloak.example.com

required

KEYCLOAK_REALM

Realm name

master

KEYCLOAK_CLIENT_ID

Service Account client ID

required

KEYCLOAK_CLIENT_SECRET

Client secret

required

KEYCLOAK_SITES_INI

INI file for IP-to-site labeling (see below)

unset

KEYCLOAK_KNOWN_EGRESS

Comma-separated CIDRs of known shared egress points (VDI, VPN concentrators, partner proxies). spray_check labels matching IPs known_egress: true and marks them confidence: low; they are never excluded

unset

KEYCLOAK_DEFAULT_DATE_FROM_HOURS

Default look-back window for event tools when date_from is omitted. Set to 0 to scan full history (can hang on large realms).

24

KEYCLOAK_DEADLINE

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. 0 or negative disables.

45

KEYCLOAK_MAX_EVENTS

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. 0 or negative disables.

200000

KEYCLOAK_MAX_USERS

Default cap on users scanned by get_totp_users when its max_users argument is 0 (each user costs one credential call). 0 or negative disables (whole realm, bounded only by KEYCLOAK_DEADLINE).

5000

KEYCLOAK_USER_ATTRIBUTE_WHITELIST

Comma-separated custom user-attribute keys that get_user is allowed to surface. Unset by default: get_user only ever returns username/name/email/enabled/created, since the search endpoint it resolves the username through returns a brief representation with no attributes at all. Opting a key in makes get_user do one extra by-ID lookup and append that attribute's value when present. Everything else stays out of tool output. As a safety net, a whitelisted key whose name looks credential-shaped (contains password, secret, token, etc.) is reported as blocked rather than shown — not a guarantee, since a credential attribute named outside that pattern list still gets through.

unset

KeyCloak client setup

  1. Create a new client in the KeyCloak admin console.

  2. Turn on Client authentication and Service account roles.

  3. 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

reset_password

PUT /users/{id}/reset-password

reset_passwords_batch

the same call, once per CSV row

set_user_enabled

PUT /users/{id} with enabled toggled

logout_user

POST /users/{id}/logout

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-realm

Exit 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/12

One 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-mcp

The 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-mcp

CLI

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.json
  • The window is [DATE 00:00, DATE+1 00:00) in --tz (default: the host's zone). Use the zone the KeyCloak server logs in, because dateFrom / dateTo are 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_check shape with every external IP that has at least one event carrying a username in external_ips (min_report_users=1), plus external_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_version and sites_ini_sha256. Treat a day as final only when both *_complete flags are true and neither gap is large; a gap at one end usually means --tz differs from the KeyCloak server's zone.

  • It refuses to run when KEYCLOAK_SITES_INI yields no ranges (every IP would count as external) unless --allow-no-sites is given, and when KEYCLOAK_KNOWN_EGRESS has an entry that is not a CIDR.

  • Its own limits apply (--deadline 900, --max-events 1000000, --max-resolves 2000), not KEYCLOAK_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 --traceback
  • Read-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); --traceback still 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.py is 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 tools
count_usersA

Get total user count in the realm.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
since_hoursNo
ip_failure_thresholdNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNo
date_toNo
date_fromNo
thresholdNo
window_secondsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses the scanning behavior (all LOGIN events), the algorithm (threshold and window), and parameter defaults. It does not explicitly state read-only or safety traits, but the detection nature is clear and non-destructive. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured: a concise one-sentence summary, a brief paragraph explaining the scanning logic, and a clear list of parameters. Every sentence adds value without redundancy. The purpose is front-loaded, making it easy for an agent to quickly understand.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (5 parameters with defaults) and the presence of an output schema, the description covers all necessary aspects: purpose, algorithm, parameter details, and behavior. No information is missing for an agent to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 5 parameters with zero description coverage. The tool's description compensates fully by providing detailed explanations for each parameter including defaults (date_from, date_to, threshold, window_seconds, top). This adds significant meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Detect users with rapid repeated logins (possible redirect loops).' It specifies the verb (detect), resource (users), and context (rapid repeated logins). This distinguishes it from sibling tools like get_brute_force_status or get_login_stats, which have different focuses.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the tool scans all LOGIN events and flags users exceeding a threshold within a time window. This implicitly guides usage for detecting redirect loops. However, it does not explicitly mention when to avoid this tool or provide direct comparisons to alternatives like get_brute_force_status, slightly limiting the agent's decision-making.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
date_toNo
max_reprNo
date_fromNo
max_resultsNo
resource_pathNo
resource_typesNo
operation_typesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
usernameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
client_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
client_idYes
max_resultsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
date_toNo
usernameNo
client_idNo
date_fromNo
event_typeNo
ip_addressNo
max_resultsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters5/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
date_toNo
date_fromNo
ip_addressYes
event_typesNoLOGIN,LOGIN_ERROR
max_timelineNo

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It extensively discloses behavior: full pagination, fixed-shape JSON return, edge cases (error, events_capped, truncated), reconciliation of login success/failure counts across event types, keying on username-or-userId-or-'unknown', IP normalization fallback, and caps (max_timeline, KEYCLOAK_DEADLINE, etc.). Every return field is explained with conditions. This provides exceptional transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-structured with sections for overall description, return values, and parameters. It is front-loaded with purpose and usage. However, there is some redundancy (e.g., explaining truncated vs events_capped in two places) and the parameter descriptions are somewhat interleaved with return descriptions. While no sentence is wasted, it could be more compact by consolidating some explanations. Still, the structure is logical and clear.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (5 parameters, no output schema, no annotations), the description is remarkably complete. It covers every aspect: purpose, usage, return shape with all keys and edge cases, parameter behavior, and limitations (caps, deadlines). There are no obvious gaps. The tool's behavior is fully specified, enabling an agent to use it correctly without additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% (no descriptions in input schema), so the description must fully document parameters. It does: ip_address (normalization and fallback), event_types (defaults, examples, resolution requirement), date_from (default window, performance warning), date_to (open-ended), max_timeline (default, effect on timeline, independence from summary/users/clients). Each parameter's semantics are clearly described, adding substantial value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Exhaustive investigation of all activity from one source IP address.' It specifies the verb (investigate), the resource (activity from an IP), and distinguishes from sibling tool `get_events(ip_address=...)` by noting that this tool fully paginates all event types, providing an exhaustive result over the date range. It also gives concrete use cases (brute-force, credential-stuffing, shared-workstation investigations), aligning with sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells when to use: '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.' It contrasts with `get_events` (single page filter). It advises on narrowing date ranges when events_capped is true, and warns about performance on wide windows. This provides clear guidance on when and why to use this tool versus alternatives.

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_ipB

Get login failure statistics broken down by source IP.

Args: date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). date_to: End date (YYYY-MM-DD). Empty for all. top: Number of top IPs to show (default 20).

ParametersJSON Schema
NameRequiredDescriptionDefault
topNo
date_toNo
date_fromNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, and description does not disclose behavioral traits beyond parameter details. Lacks clarity on read-only nature, side effects, or data sources.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Description is concise, using args format. Could be more front-loaded but overall efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers parameter usage adequately. Output schema exists, but description does not mention output structure. Completeness is adequate for this tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Description adds meaning to each parameter beyond the schema (e.g., format, defaults, meaning of top). Schema coverage is 0%, so description compensates well.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb and resource: 'Get login failure statistics broken down by source IP'. Distinct from sibling tools like get_brute_force_status or get_events.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

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. Does not mention use conditions or exclusions.

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.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
date_toNo
date_fromNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must cover behavioral traits. It implies read-only stats retrieval, but does not clarify pagination behavior, result limits, or whether it is a simple query. This is adequate but not detailed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Description is extremely concise: one line for purpose and a structured Args section. Every sentence provides value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has only 2 optional parameters and an output schema, the description completes the picture for basic usage. It explains parameter defaults and pagination, though could mention what aggregate stats include.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description adds significant meaning: explains date_from defaults to last 24h (with KEYCLOAK_DEFAULT_DATE_FROM_HOURS) and date_to empty for all time. This goes beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'Get login success/failure statistics with full pagination', which distinguishes it from siblings like get_login_failures_by_ip and get_login_stats_by_client, as it focuses on overall stats with pagination.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Description mentions pagination but provides no explicit guidance on when to use this tool versus alternatives. The context of sibling tools implies differentiation, but the description itself lacks direct usage advice.

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_clientC

Get login statistics broken down by client (SP).

Args: date_from: Start date (YYYY-MM-DD). Defaults to last 24h when omitted (KEYCLOAK_DEFAULT_DATE_FROM_HOURS). date_to: End date (YYYY-MM-DD). Empty for all.

ParametersJSON Schema
NameRequiredDescriptionDefault
date_toNo
date_fromNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description bears full responsibility for behavioral disclosure. It notes that date_from defaults to last 24h when omitted, but does not mention authentication requirements, rate limits, data scope, or pagination. The return format is vague ('login statistics broken down by client') without detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the main purpose. Parameter descriptions are structured as bullet points. However, the first sentence could be more precisely worded to avoid ambiguity about 'SP'. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema (not shown but present), so return values are covered externally. The description is adequate for a simple parameterized listing tool but lacks usage context and behavioral traits. Given the presence of sibling tools focused on login stats, more context on when to use this variant would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides only names and types (string) with defaults. The description adds format (YYYY-MM-DD) and clarifies that empty date_to means 'all' and omitted date_from defaults to last 24h. Given 0% schema description coverage, this adds meaningful semantic value, though it could explain edge cases (e.g., valid ranges).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves login statistics grouped by client (SP). The verb 'Get' and resource 'login stats broken down by client' are specific. However, it does not distinguish from similar tools like 'get_login_stats' or 'get_login_stats_by_hour', which could cause confusion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides parameter details (date range, format, defaults) but offers no guidance on when to use this tool versus alternatives like 'get_login_stats' or 'get_login_stats_by_hour'. No exclusions or context for appropriate invocation are given.

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).

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
date_toNo
date_fromNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description must carry the full burden. It mentions 'local time' and default/empty behaviors for date_from and date_to, but does not disclose rate limits, authentication needs, or whether the operation is read-only (implied by 'Get'). For a simple read tool, this is adequate but not comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with a single purpose line and a two-item parameter list. Every sentence is functional, front-loaded, and free of fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (2 optional parameters, output schema present) and no annotations, the description covers purpose, parameter semantics, and defaults. It lacks explicit mention of timezone handling but 'local time' provides sufficient context for typical use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description adds essential meaning: date format (YYYY-MM-DD), default behavior for date_from (last 24h when omitted), and behavior for date_to (empty for all). This compensates well for the lack of schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Get login statistics broken down by hour (local time)', specifying the verb (Get), resource (login statistics), and breakdown dimension (hour). This differentiates it from sibling tools like get_login_stats (overall) and get_login_stats_by_client (by client).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for hourly login statistics but does not explicitly state when to use this tool versus alternatives like get_login_stats or get_login_stats_by_client. No guidance on exclusions or when not to use is provided.

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
date_toNo
date_fromNo
max_resultsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
max_usersNo
list_usersNo
enabled_onlyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
usernameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
date_toNo
max_reprNo
usernameYes
date_fromNo
max_resultsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
usernameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
usernameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
usernameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
group_nameYes
max_resultsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
usernameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
passwordYes
usernameYes
temporaryNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
csv_textYes
temporaryNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes
max_resultsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
enabledYes
usernameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
hoursNo
min_usersNo
max_resolvesNo
max_success_rateNo
min_report_usersNo
max_user_success_rateNo
max_failure_concentrationNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it succeeds comprehensively. It discloses partial-result behavior via complete=False, resolve caps and unresolved_user_ids, internal-event exclusion, known-egress labeling without exclusion, and the rule that breached entries require actual LOGIN events. This is far more than a typical tool description provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long, but appropriately so: there is no output schema and no annotations, so it must document return fields, edge cases, and semantics. It is front-loaded with the core purpose and organized into clear paragraphs and an Args list, with no filler or redundant sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

It covers the algorithm, confidence classification, return shape, resolution limits, pagination caveats, and egress behavior — essentially everything needed to call the tool correctly without annotations or an output schema. It is not a 5 because of the max_user_success_rate default discrepancy, which introduces avoidable ambiguity, and because it never explicitly contrasts itself with similar sibling tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All 7 parameters are given real meaning with defaults, thresholds, and behavioral implications, which is essential because schema description coverage is 0%. However, the description states max_user_success_rate defaults to 0.3 while the input schema declares 0.2, an inconsistency that could mislead an agent during invocation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a precise verb and resource: 'Detect password-spray sources and name the accounts they breached'. The 'one rule, one call' framing and the explicit focus on EXTERNAL source IPs in LOGIN/LOGIN_ERROR events distinguish it clearly from generic login-stat or IP-lookup siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear operational context: it is for password-spray detection over external IPs, with explicit thresholds, confidence logic, and caveats. It does not explicitly name sibling tools or state when not to use it, so it falls just short of a 5, but the intended use is evident and actionable.

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. 1 tool updatev0.20.0
    • Addedget_client
  2. 1 tool updatev0.19.0
    • Addedspray_check
  3. 1 tool updatev0.14.3
    • Addedlist_users_by_group
  4. 12 tool updatesv0.14.1
    • Addedcount_users
    • Addeddaily_brief
    • Addedget_events
    • Addedget_realm_roles
    • Addedget_realm_security_defenses
    • Addedget_totp_users
    • Addedget_user_credentials
    • Addedlist_clients
    • Addedlist_user_groups
    • Addedlogout_user
    • Addedreset_password
    • Addedset_user_enabled
  5. 13 tool updatesv0.13.1
    • Removedcount_users
    • Removeddaily_brief
    • Removedget_events
    • Removedget_realm_roles
    • Removedget_realm_security_defenses
    • Removedget_totp_users
    • Removedget_user_credentials
    • Removedlist_clients
    • Removedlist_user_groups
    • Removedlist_users_by_group
    • Removedlogout_user
    • Removedreset_password
    • Removedset_user_enabled
  6. 1 tool updatev0.13.0
    • Addedset_user_enabled
  7. 2 tool updatesv0.11.0
    • Addedget_ip_activity
    • Addedget_realm_security_defenses
  8. 3 tool updatesv0.9.0
    • Addedget_totp_users
    • Addedget_user_credentials
    • Addedhealth_check
  9. 24 tool updatesv0.1.0
    • First observedcount_users
    • First observeddaily_brief
    • First observeddetect_login_loops
    • First observedget_admin_events
    • First observedget_brute_force_status
    • First observedget_client_sessions
    • First observedget_events
    • First observedget_login_failures_by_ip
    • First observedget_login_stats
    • First observedget_login_stats_by_client
    • First observedget_login_stats_by_hour
    • First observedget_password_update_events
    • First observedget_realm_roles
    • First observedget_session_stats
    • First observedget_user
    • First observedget_user_attribute_history
    • First observedget_user_sessions
    • First observedlist_clients
    • First observedlist_user_groups
    • First observedlist_users_by_group
    • First observedlogout_user
    • First observedreset_password
    • First observedreset_passwords_batch
    • First observedsearch_users

TDQS

A3.6/5.0

Scored across 32 tools

Disambiguation4/5

Most tools have clearly distinct purposes: get_login_stats_by_client, by_hour, by_ip, and get_events are well-separated. The one potential ambiguity is get_user_attribute_history vs get_admin_events — the former is a specialized subset of the latter, but its description explains the differentiation clearly.

Naming Consistency4/5

The vast majority follow a consistent verb_noun snake_case pattern (get_, list_, search_, reset_, set_, count_, detect_, health_check). The only deviation is daily_brief, which is a noun phrase rather than a verb-led name, making the set mildly inconsistent but still highly readable.

Tool Count2/5

With 32 tools, the server exceeds the 25+ threshold that indicates an overly large surface. While many tools serve legitimate sub-tasks in security monitoring, the count feels heavy and could likely be consolidated (e.g., several login-stat variants and overlapping analysis helpers).

Completeness4/5

For the apparent domain of Keycloak security monitoring and incident response, the surface is thorough: detection (spray_check, detect_login_loops), investigation (get_ip_activity, get_user_attribute_history), and response (set_user_enabled, logout_user, reset_password). Minor gaps exist (no user create/delete or client management), but these fall outside the likely intended purpose.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    A 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.
    9
    109 npm
    13
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol (MCP) server that provides a natural language interface for managing Keycloak identity and access management through its REST API.
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    An MCP server that lets an AI assistant inspect and modify Keycloak realm, client, and protocol-mapper configuration across multiple Keycloak hosts.
    7
    109 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables 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.
    29 npm
    Apache 2.0