identity-aiops
Operate and audit self-hosted Keycloak/authentik identity estates through governed MCP tools for diagnostics, reads, and audited writes.
Run RCAs and audits: login-failure cause classification, stale/dormant access, OAuth client misconfiguration, and MFA coverage.
Read identity state: users, groups, clients, sessions, credentials, realm settings, identity providers, login events, admin events, and overview.
Perform governed writes: disable/enable users, revoke sessions, require password reset, replace redirect URIs, and rotate client secrets.
Preview writes with dry-run, apply/list undo tokens, and rely on audit logging, risk tiers, and masked prior-state recording.
Work across Keycloak and authentik, with some Keycloak-only capabilities returning definitive platform errors on authentik.
Provides governed identity operations for authentik: listing and inspecting users, groups, clients, identity providers, sessions, and authentication events; analyzing login failures, stale access, client misconfigurations, and MFA coverage; and performing audited write actions such as disabling or enabling users and revoking user sessions.
Provides governed identity operations for Keycloak: listing and inspecting users, clients, groups, sessions, and events; analyzing login failures, stale access, client misconfigurations, and MFA coverage; and performing audited, reversible write actions such as disabling users, revoking sessions, requiring password resets, updating client redirect URIs, and rotating client secrets.
Identity AIops
Audit availability: Real writes require a committed
pendingaudit row and stop before contacting the platform if storage is unavailable. Reads and previews may continue with a warning; new audit rows store outcome summaries rather than full responses.
Governed AI-ops for self-hosted identity providers — Keycloak + authentik.
identity-aiops gives AI agents (and the humans supervising them) a safe,
audited way to operate the identity plane of self-built and small/mid-size
infrastructure: who can sign in, what failed and why, which OAuth clients are
misconfigured, and who still has no second factor. It is built for teams
running their own Keycloak or authentik who want agent-driven identity
operations with receipts — every tool call is audited, and writes carry
risk-tier labels with dry-run previews and undo tokens.
Verification status: modelled on the public Keycloak admin REST API and authentik API v3 and exercised against mocked responses; there is no recorded end-to-end run against a live instance yet.
identity-aiops doctoris the fastest live check — seedocs/VERIFICATION.md.
What it does
Area | Tools |
Realm / system | overview, realm settings (brute-force protection, password/OTP policy), identity providers |
Users | list/search, detail, count, sessions, credentials (MFA surface), groups, members, lockout status |
Events | authentication events, admin/config-change events |
Clients | list, detail, per-client sessions, session stats |
Flagship RCA |
|
Governed writes |
|
29 MCP tools: 21 reads (including the 4 analyses) + 6 governed writes + 2 undo
tools (undo_list, undo_apply). The
same tools work on both platforms — a per-target platform field selects the
API shape (auth flow + resource paths).
Related MCP server: firewall-aiops
Supported platforms
Platform | API | Auth |
keycloak | Admin REST API ( | OAuth2 client-credentials grant against |
authentik | API v3 ( | Long-lived API token (Bearer) |
Platform notes: require_password_reset, rotate_client_secret,
client_sessions, client_session_stats, and user_lockout_status are
Keycloak-shaped (authentik has no equivalent endpoint — the tools return a
teaching error there). authentik contributes the global session list used by
the stale-access audit's orphaned-session check.
Missing a platform (Authelia, Zitadel, Ory...), an endpoint, or an analysis you need? 缺功能提 issue/PR 欢迎留言 — open an issue or PR at https://github.com/AIops-tools/Identity-AIops, feature requests welcome.
What this tool does, and does not, decide
It delivers identity-provider operations — reads and writes — accurately and
records every one of them. It does not decide whether a write is allowed to
happen. That is the agent's judgement, or the permission of the account you
connect it with: give the Keycloak service account (or authentik token) only
the roles you want the agent to have — view-users / view-events /
view-clients and no manage-* — and the writes fail at the server, the place
that actually owns the permission.
So there is no read-only switch, no policy file, no approval gate to configure.
The one thing the tool guarantees is that nothing is silent: every call, over
MCP and over the CLI alike, lands an audit row in
~/.identity-aiops/audit.db, and reversible writes still capture their
before-state (fetched, never guessed) and record a replayable inverse.
Each tool declares a
risk_level, carried into the audit row as a descriptive tier — so a reviewer can see at a glance that a row was, say, a high-risk secret rotation. It is a label, not a gate.
Running a smaller / local model? See agent-guardrails.md — it lists the guardrails this tool now enforces for you (so you don't spend prompt budget restating them) and gives a ready-made system prompt for what's left.
Quick start
As a Claude Code plugin
One install gives an agent both the skill and the MCP server:
/plugin marketplace add AIops-tools/marketplace
/plugin install identity-aiops@aiops-toolsThe MCP server is fetched with uv and pinned to the
package version this plugin declares, so an audit row can be traced back to the
code that wrote it. Credentials are still configured with identity-aiops init — see below.
As an OpenClaw plugin
The same bundle is published on ClawHub, where one install delivers the skill and its MCP server together:
openclaw plugins install clawhub:@zw008/identity-aiops
openclaw skills info identity-aiops # expect: Visible to model: yesRestart the OpenClaw gateway afterwards so it loads the plugin. The MCP server is
fetched with uv, pinned to this exact release, so
uvx has to be on PATH — without it the skill still installs but reports
Visible to model: no. Credentials are configured exactly as below.
As a CLI or standalone MCP server
uv tool install identity-aiops # or: pipx install identity-aiops
identity-aiops init # wizard: target + realm + credential (encrypted)
identity-aiops doctor # token acquisition + user-count probe per target
identity-aiops overview # one-shot estate summaryFor Keycloak, create a confidential client with Service accounts roles
enabled and grant its service account the realm-management roles you want the
agent to have (start with view-users, view-events, view-clients; add
manage-users / manage-clients only if you want the governed writes). For
authentik, create an API token for a (least-privileged) admin user.
CLI surface: users (list/show/sessions/credentials + disable/enable/
revoke-sessions/require-reset), clients (list/show + set-redirect-uris/
rotate-secret), events, overview, doctor, secret, init, mcp.
Write commands take --dry-run and always double-confirm; execution is
delegated to the governed MCP twins so CLI writes land in the audit log too.
MCP configuration
{
"mcpServers": {
"identity-aiops": {
"command": "uvx",
"args": ["--from", "identity-aiops", "identity-aiops-mcp"],
"env": {
"IDENTITY_AIOPS_MASTER_PASSWORD": "<master password for secrets.enc>"
}
}
}
}env-block caveat: MCP clients launch the server with a minimal environment — variables from your shell profile are NOT inherited. Anything the server needs (
IDENTITY_AIOPS_MASTER_PASSWORD, an alternateIDENTITY_AIOPS_HOME,IDENTITY_AUDIT_APPROVED_BYto attribute writes on the audit trail) must be set in theenvblock above.
Governance
Every MCP tool runs through the vendored governance harness
(identity_aiops/governance/, zero external dependencies):
Audit — every call (including errors) lands in
~/.identity-aiops/audit.dbwith params, status, and risk level, plus any optional approver/rationale annotation. It records; it does not authorize.Budget — per-session call/time budgets and a runaway breaker (
IDENTITY_MAX_TOOL_CALLS,IDENTITY_MAX_TOOL_SECONDS,IDENTITY_RUNAWAY_MAX) — a safety backstop, not an authorization gate.Risk tier — reads are
low; containment/hygiene writes (disable_user,revoke_user_sessions,require_password_reset) aremedium; access-granting or boundary-replacing writes (enable_user,update_client_redirect_uris,rotate_client_secret) arehigh. The tier is a descriptive label carried onto the audit row, not a gate — whether a write runs is the agent's judgement or the connecting account's permissions.IDENTITY_AUDIT_APPROVED_BY/IDENTITY_AUDIT_RATIONALEare optional annotations recorded when set, never required.Undo — reversible writes capture the REAL prior state (fetched before mutating, never guessed) and record a replayable inverse descriptor in
~/.identity-aiops/undo.db. Irreversible writes (revoke_user_sessions,rotate_client_secret) record priorState only — the secret is stored masked, never in clear.Sanitize — every string an IdP returns is folded through an injection-safe normaliser (bounded length, control characters stripped) before an agent sees it.
Secrets — credentials live Fernet-encrypted (scrypt-derived key) in
~/.identity-aiops/secrets.enc, never plaintext on disk; a legacyIDENTITY_<TARGET>_SECRETenv var is honoured as fallback andidentity-aiops secret migratemoves it in. TLS verification defaults ON.
Configuration
~/.identity-aiops/config.yaml (created by init):
targets:
- name: sso1
platform: keycloak
base_url: https://sso.example.com
realm: master
username: identity-aiops-agent # the confidential client's client_id
verify_ssl: true
- name: ak1
platform: authentik
base_url: https://auth.example.com
verify_ssl: trueSet IDENTITY_AIOPS_HOME to relocate all state (config, secrets, audit,
undo). IDENTITY_AIOPS_CONFIG points the MCP server at an alternate
config file.
Development
uv sync
uv run pytest -q
uv run ruff check .MIT License. Part of the AIops-tools line — governed AI-ops tooling for self-hosted infrastructure.
Available Tools
29 toolsadmin_eventsARead-only
[READ] Recent admin/config-change events (who changed what, from where).
Args: max_results: Page bound (default 200, max 500). target: IdP target name from config; omit for the default.
Returns {"events": [...], "returned": N, "limit": L, "truncated": bool}, with truncated measured rather than guessed. On authentik the single event feed is post-filtered to admin actions, so truncated also reports feed rows that were never examined.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true is corroborated by the [READ] tag, and the description adds genuinely non-obvious behavior: truncated is measured rather than guessed, and on authentik post-filtering means truncated also counts feed rows never examined. Important caveat for interpreting results, though permissions/scoping are not covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the [READ] tag and one-line purpose, then Args and Returns sections. Well organized, though the final sentence about post-filtered feed rows is slightly convoluted and could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description appropriately documents the return object (events, returned, limit, truncated) and the meaning of truncated. Combined with the annotation, an agent has what it needs; only pagination continuation semantics are left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description carries the full burden and largely meets it: it explains max_results as a page bound with default 200 and a max of 500 (the 500 cap is absent from the schema), and target as an IdP target name with omission meaning default. The target explanation is terse but sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (recent admin/config-change events) and enriches it with the four W questions (who/what/from where), which clearly separates it from the login_events sibling. It never names an alternative tool, but the audit-of-admin-actions scope is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is for auditing admin/config changes rather than login activity, and 'omit for the default' hints at when to pass target. There is no explicit when-to-use / when-not-to-use guidance against the many sibling audit tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
client_detailARead-only
[READ] One client's normalized detail by internal id.
Args: client_id: Internal id (Keycloak UUID / authentik provider pk), from list_clients. target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| client_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already declares the safe-read profile, and the '[READ]' prefix merely restates it. The description does add useful context — the id is a Keycloak UUID / authentik provider pk and results are 'normalized' — but says nothing about what normalization means, error behavior for unknown ids, or return shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence followed by two tight arg annotations; every line adds information and nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-param read tool with no output schema, the description covers inputs and read-only status adequately, but 'normalized detail' is left undefined, so an agent cannot anticipate the returned fields or whether related data (sessions, redirect URIs) is included.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden, and it does well: it identifies client_id's format/provenance (internal id from list_clients) and target's meaning plus the omit-for-default convention. Only the exact IdP target name format is unstated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource+scope: fetch one client's normalized detail keyed by internal id. The [READ] tag and 'by internal id' clearly separate it from list_clients, though the description never explicitly names that sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It routes the agent to list_clients as the source of client_id and explains the default-target behavior, implying single-client lookup. But it never states when to prefer this over list_clients or related siblings (client_sessions, client_misconfig_audit).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
client_misconfig_auditARead-only
[READ] Ranked OAuth/OIDC client risk: wildcard/http redirect URIs, public clients with secrets, implicit flow, missing PKCE, password grant — per-client riskScore with evidence and actions.
Args: max_clients: Clients to pull (default 200). target: IdP target name from config; omit for the default.
Returns "inputsTruncated": true when the client list hit max_clients — a clean result over a clipped list is not evidence of a clean estate.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| max_clients | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true, and the description adds real behavioral context beyond that: it discloses the per-client riskScore-plus-evidence-plus-actions shape and, critically, that inputsTruncated=true signals a clipped list — warning the agent that a clean result over a truncated estate is misleading. It does not cover pagination or auth prerequisites.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the risk taxonomy, then the args, then the truncation caveat — logical ordering with little waste. The truncation warning is slightly verbose but earns its place given how easily it prevents a false-clean conclusion.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-output-schema audit tool, it discloses the return shape (riskScore, evidence, actions) and the truncation sentinel. What it omits — auth/preconditions and how risk findings should be acted on — are secondary for a read-only audit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the load. It does explain target ('IdP target name from config; omit for the default'), which the schema does not, but for max_clients it largely restates the schema default (200) without explaining the truncation trade-off it drives. Partial compensation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (audit) and resource (OAuth/OIDC client misconfig) and enumerates the exact risk classes checked (wildcard/http redirect URIs, public clients with secrets, implicit flow, missing PKCE, password grant). This clearly distinguishes it from raw-listing siblings like list_clients and client_detail.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The '[READ]' tag and the risk-framing imply this is the config-hygiene audit path, but there is no explicit when-to-use guidance and no named alternative (e.g., 'use stale_access_audit for token age, list_clients for raw inventory'). Usage is inferable from the risk categories rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
client_sessionsARead-only
[READ] Active user sessions on one client (Keycloak).
KEYCLOAK ONLY. authentik has no per-provider session listing, so on an authentik target this returns {"error": "Resource 'client_sessions' is not mapped for platform 'authentik'..."}. That is a platform-capability answer, not a fault: switch approach (user_sessions per user) rather than retrying or reporting the tool as broken.
Args: client_id: Internal id, from list_clients. max_results: Page bound (default 200). target: IdP target name from config; omit for the default.
Returns {"sessions": [...], "returned": N, "limit": L, "truncated": bool}, with truncated measured rather than guessed.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| client_id | Yes | ||
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, yet the description adds substantial behavior the annotations cannot: a platform-capability failure mode with the literal error string, the instruction to treat it as an answer rather than a fault, pagination semantics, and that 'truncated' is measured rather than guessed. This goes well beyond the structured safety hint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the read marker, then the platform caveat, args, and return shape in a clear scanned order. The pseudo-signature Args/Returns block is slightly verbose for three parameters but every line carries actionable information, so waste is minimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description fills that gap by specifying the return object keys (sessions, returned, limit, truncated) and the meaning of 'truncated'. Combined with the platform caveat and parameter sourcing, an agent has everything needed to call and interpret this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% (properties carry only titles), so the description must compensate and does: client_id is an 'Internal id, from list_clients' (a concrete source), max_results is a 'Page bound (default 200)', and target is the 'IdP target name from config; omit for the default'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+scope: '[READ] Active user sessions on one client (Keycloak).' It is immediately distinguishable from user_sessions (per-user) and client_session_stats (aggregates) by naming the client-scoped listing explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-not-to-use guidance: 'KEYCLOAK ONLY', spells out the exact error returned on authentik targets, and tells the agent to 'switch approach (user_sessions per user) rather than retrying or reporting the tool as broken.' That is a full when/when-not/alternative triad.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
client_session_statsARead-only
[READ] Active-session counts per client, busiest first (Keycloak).
KEYCLOAK ONLY. authentik has no per-client session rollup, so on an authentik target this returns {"error": "Resource 'client_session_stats' is not mapped for platform 'authentik'..."}. A platform-capability answer, not a fault — do not retry.
Args: target: IdP target name from config; omit for the default.
Returns {"clients": [...], "returned": N, "truncated": false} — the rollup is unbounded, so this listing is always complete.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint=true, it discloses the platform-capability limitation verbatim (including the error payload the agent will see), that the condition is not a fault and should not be retried, and that the rollup is unbounded so results are always complete. This is exactly the context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the verb+resource+scope, then a clearly delimited KEYCLOAK ONLY warning and Args/Returns blocks. The quoted error string is somewhat long, but it earns its place by preventing a retry loop.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description supplies the return shape ({"clients", "returned", "truncated"}) and states truncation can never occur. Combined with the platform caveat, an agent has everything needed to call and interpret this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% for the single 'target' parameter, so the description must compensate — and it does, explaining the value comes from config ('IdP target name from config') and that omitting it selects the default. Minor gap: no note on what happens with an unknown target name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource with scope and ordering ('Active-session counts per client, busiest first') and names the platform it applies to (Keycloak). An agent can distinguish it from siblings like client_sessions or user_sessions without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when NOT to use it (KEYCLOAK ONLY; authentik returns a mapping error) and instructs 'do not retry', which prevents wasted calls. It does not, however, route the agent to a specific alternative (e.g. client_sessions) for the unsupported platform.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disable_userADestructive
[WRITE][risk=medium] Disable a user (blocks sign-in); reversible.
The containment move for a compromised/stale account. Reads the user first so the harness records an undo that restores the prior enabled state. Live sessions survive — pair with revoke_user_sessions. Pass dry_run=True to preview.
Refuses to disable the account this tool authenticates as — including under dry_run, which must report a refusal rather than preview a call that will be refused.
Args: user_id: User id (Keycloak UUID / authentik pk), from list_users. dry_run: If True, preview without changing. target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| dry_run | No | ||
| user_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations (readOnlyHint=false, destructiveHint=true) by disclosing that it reads the user first to record an undo, that live sessions are unaffected, that it refuses to disable its own authenticating account, and that even dry_run must report that refusal rather than preview. This is unusually rich behavioral context for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well front-loaded with the verb and effect, then behavior, then args. It is slightly verbose and the Args block repeats some behavior already stated above, but every line carries useful information and no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no output schema, the description covers the safety profile, reversibility/undo, the refusal edge case, session side effects, and every parameter. An agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the burden, and it does: it documents all three parameters (user_id format and source from list_users, dry_run preview behavior, and target as IdP name from config with default-omit semantics). Nothing is left ambiguous.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Disable a user (blocks sign-in)') plus the key effect, and the reversibility qualifier separates it from the sibling enable_user. An agent can tell exactly what this does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly frames the tool as 'the containment move for a compromised/stale account' and names the required companion action ('pair with revoke_user_sessions') since live sessions survive. It also calls out the dry_run preview path, giving clear when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enable_userADestructive
[WRITE][risk=high] Re-enable a user (restores sign-in); reversible.
Re-granting access reverses a containment action, so it is tagged risk=high on the audit row (a descriptive label, not a gate). Whether it should run is the agent's judgement or the connecting account's permissions, not the tool's. Pass dry_run=True to preview.
Args: user_id: User id, from list_users. dry_run: If True, preview without changing. target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| dry_run | No | ||
| user_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations it discloses reversibility, the restored sign-in effect, the audit-only nature of the risk=high label, the dry-run preview, and that execution authority rests with the agent/connecting account. These are valuable traits the annotations do not convey. Minor tension remains: annotations mark destructiveHint=true while the description stresses 'reversible'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded [WRITE][risk=high] tag followed by effect, rationale, and a scannable Args block. The middle paragraph about the risk label is slightly editorial but conveys decision-relevant context, so waste is minimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutating tool with annotations but no output schema, the description covers effect, reversibility, preview, and all params. It omits what happens when the user is already enabled (relevant given idempotentHint=false), a minor but real gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden and largely does: it documents all three params, tells where user_id comes from (list_users), explains target's config origin and default-omit behavior, and clarifies dry_run. It adds real provenance beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource ('Re-enable a user') and clarifies the effect ('restores sign-in'), which cleanly contrasts it with the sibling disable_user. It does not explicitly name the sibling alternative, keeping it just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies when to use it ('reverses a containment action') and offers the dry_run=True preview, but never names alternatives such as disable_user or undo_apply, nor states exclusions. Usage is implied rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
group_membersARead-only
[READ] Members of one group, normalized user rows.
Args: group_id: Group id, from list_groups. max_results: Page bound (default 200). target: IdP target name from config; omit for the default.
Returns {"members": [...], "returned": N, "limit": L, "truncated": bool}, with truncated measured rather than guessed.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| group_id | Yes | ||
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so safety is covered. The description adds real behavioral value beyond that: max_results is described as a page bound with a default of 200, and truncation is explicitly 'measured rather than guessed', which tells the agent how pagination state can be trusted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the purpose, then separates Args and Returns in a compact structure with no filler. The prose is tight, though the fragment 'Members of one group, normalized user rows' is slightly terse for an action statement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by describing the return shape (members, returned, limit, truncated). All three parameters are documented and pagination behavior is explained, leaving only minor ambiguity about what 'normalized' user rows contain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% (titles only), so the description carries the burden and does so: group_id's source, max_results' role as a page bound and default, and target as an IdP target name from config with omission meaning the default. This meaningfully supplements bare titles like 'Target' and 'Max Results'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the specific resource and scope: members of a single group, returned as normalized user rows, with an explicit [READ] marker. It clearly differs from list_groups (which yields the group list) and list_users (which yields users, not memberships), though it never names those siblings directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear invocation context by specifying that group_id comes 'from list_groups', establishing the prerequisite workflow step. It does not state exclusions or contrast against alternatives such as list_users, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
identity_overviewARead-only
[READ] One-shot summary: platform/realm, user/client/IdP counts, and the size of the recent failed-login feed. Lead with this.
Args: target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
annotations already declare readOnlyHint=true, and the '[READ]' tag merely restates that. The description does add value by disclosing the returned content categories, but says nothing about auth requirements, cost, or freshness of the failed-login feed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short blocks, front-loaded with the return contents and the priority hint. Every phrase (content list, 'lead with this', arg default) earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description appropriately enumerates the return shape itself. With a single optional parameter and a read-only annotation, nothing critical is missing, though the meaning of 'target' for IdP-scoped counts could be sharpened.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the only field is a nullable target string, so the description carries the full burden. It explains that target is an IdP target name sourced from config and that omission selects the default, which the schema does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('one-shot summary') and enumerates exactly what is summarized: platform/realm, user/client/IdP counts, and the failed-login feed size. It is clearly the aggregate entry point versus the specialized sibling audits, though it never names a sibling to differentiate against.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Lead with this' is an explicit priority directive that tells the agent to call this before the specialized audits. It also explains the target arg's default behavior, but gives no when-not-to-use condition or explicit alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_clientsARead-only
[READ] OAuth/OIDC clients in the realm, normalized (redirect URIs, public/confidential, grant flags, PKCE method).
Args: max_results: Page bound (default 200). target: IdP target name from config; omit for the default.
Returns {"clients": [...], "returned": N, "limit": L, "truncated": bool}, with truncated measured rather than guessed. Fields the IdP did not return are null — a null pkceMethod means no PKCE method is pinned.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint=true, the description adds real behavioral detail: results are normalized, 'truncated' is measured rather than guessed, and missing IdP fields are null with a specific interpretation ('a null pkceMethod means no PKCE method is pinned'). It does not discuss auth requirements or paging mechanics beyond max_results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the [READ] marker and the core purpose, then Args and Returns in tight sections. The Returns block is somewhat verbose for a two-parameter read, but it earns its place given there is no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly supplies the return envelope (clients, returned, limit, truncated) and the null-field convention. Combined with the read-only annotation, an agent has everything needed to call and interpret this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the burden and it largely does: max_results is a page bound with default 200, and target is defined as an IdP target name from config that may be omitted for the default. Both parameters are explained, though max_results adds little beyond the field name and default already in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: listing OAuth/OIDC clients in the realm, plus what the listing is normalized to (redirect URIs, public/confidential, grant flags, PKCE method). That is well beyond a restatement of the name. It does not explicitly differentiate itself from the sibling client_detail or client_misconfig_audit, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: '[READ]' and the field summary make it obvious this is the enumeration entry point, and 'omit for the default' tells the agent when target is unneeded. There is no explicit when-to-use-this-vs-alternative guidance pointing at client_detail or client_misconfig_audit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_groupsARead-only
[READ] Groups in the realm.
Args: max_results: Page bound (default 200). target: IdP target name from config; omit for the default.
Returns {"groups": [...], "returned": N, "limit": L, "truncated": bool}, with truncated measured rather than guessed.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds genuinely useful behavior beyond that: the default page bound, the return envelope, and the note that 'truncated' is measured rather than guessed, which tells the agent it can trust the flag.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded '[READ]' tag, then compact Args and Returns sections with no filler. Every line carries information, though the Args/Returns formatting is slightly verbose for two parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema present, the description carries the return format itself, including the envelope keys and the truncation flag, and documents both parameters despite zero schema coverage. It is close to complete for a simple list tool, lacking only detail on group object fields and how to fetch subsequent pages.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate and largely does: it explains max_results as a page bound with default 200 and clarifies target as an IdP target name from config that should be omitted for the default. It does not define target's valid values or how paging continues, keeping it below a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The '[READ] Groups in the realm' opening, reinforced by the name list_groups, makes the resource and operation clear enough to distinguish it from group_members or list_users. However, it states the resource as a bare noun phrase rather than an explicit verb like 'list', so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus siblings such as group_members or list_users, and no prerequisites or exclusions are stated. The only context is the '[READ]' tag, which describes operation type rather than usage conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_identity_providersARead-only
[READ] Federated identity providers / sources configured on the IdP.
Args: target: IdP target name from config; omit for the default.
Returns {"identityProviders": [...], "returned": N, "truncated": false} — the IdP returns the complete set, so this listing is never clipped.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true already covering the safety profile, the description still adds real value: the return envelope keys and the behavioral guarantee that the IdP returns the complete set and the listing is 'never clipped.' That is genuine disclosure beyond annotations. One caveat: the never-clipped claim sits awkwardly against the max_results parameter in the schema, which is never reconciled.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight blocks — read tag, args, returns — with no filler and the purpose front-loaded. Every sentence carries information the agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by describing the return shape and completeness, which is exactly what is needed. The remaining gap is the undocumented max_results parameter, which matters given the truncation claim.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the parameter burden. It handles target well by naming its source (config) and the omit-for-default behavior, which the schema does not say. It says nothing about max_results, however, and its 'never clipped' statement arguably conflicts with that parameter's existence.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: '[READ] Federated identity providers / sources configured on the IdP.' An agent immediately knows this enumerates IdP-side federated identity providers. However, it offers no explicit differentiation from the many sibling list_* tools (list_clients, list_users, list_groups), so it falls short of the 5-level sibling routing cue.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied by the resource type, and the args note ('target: IdP target name from config; omit for the default') gives a selection rule for the target parameter. But there is no explicit when-to-use/when-not, no mention of alternatives such as identity_overview or realm_info, and no prerequisites stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_usersARead-only
[READ] Users in the realm, normalized across Keycloak/authentik.
Args: search: Optional username/email search string. max_results: Page bound (default 200). target: IdP target name from config; omit for the default.
Returns {"users": [...], "returned": N, "limit": L, "truncated": bool}. truncated is measured (one extra user is fetched); when true, more users exist — re-run with a higher max_results before drawing a realm-wide conclusion. Fields the IdP did not return are null, never "".
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | ||
| target | No | ||
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true is consistent with the '[READ]' tag, and the description goes well beyond it: it discloses that truncation is measured via one extra fetched user, that missing IdP fields come back as null rather than empty string, and that the default page bound is 200. With no output schema, this is exactly the behavioral load the description should carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the one-line purpose, then an Args block, then the return contract. Every sentence earns its place — the truncation and null-handling notes are non-obvious and actionable, not filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return shape (users/returned/limit/truncated) and the semantics of truncated and null fields. For a 3-parameter, no-required-arg listing tool, nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it documents all three parameters: search (optional username/email), max_results (page bound, default 200), and target (IdP target name from config, omit for default). This adds meaning the bare schema titles do not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (list) and resource (users) with an explicit scope constraint ('in the realm') and normalization note across Keycloak/authentik. This clearly separates it from user_count, user_detail, and list_groups without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives operational context: search is an optional username/email filter, target defaults when omitted, and it explicitly instructs re-running with a higher max_results before drawing a realm-wide conclusion when truncated is true. It does not name alternatives (e.g., when to prefer user_detail), so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
login_eventsARead-only
[READ] Recent authentication events, normalized (time/type/user/ip/client/error).
Args: event_type: Platform vocabulary — Keycloak LOGIN / LOGIN_ERROR, authentik login / login_failed (case-insensitive). user: Optional username / user-id filter. max_results: Page bound (default 200, max 500). target: IdP target name from config; omit for the default.
Returns {"events": [...], "returned": N, "limit": L, "truncated": bool}. truncated is measured (one extra event is fetched), not guessed — when it is true, more events exist; re-run with a higher max_results rather than treating the partial feed as the whole picture. Optional fields an event did not carry are null, never "".
| Name | Required | Description | Default |
|---|---|---|---|
| user | No | ||
| target | No | ||
| event_type | No | ||
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, and the '[READ]' prefix plus normalized-field list is consistent with that. It adds beyond the annotations by explaining that truncation is measured via an extra fetched event rather than guessed, and that absent optional fields are null rather than empty string — genuinely useful behavioral detail. It does not cover permissions or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Structured into a purpose line, an Args block, and a Returns block, with the core identity front-loaded. Slightly long for a four-parameter read tool, but each sentence carries distinct information rather than restating the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, but the description describes the return envelope (events, returned, limit, truncated) and the meaning of the truncated flag and null optional fields. Combined with full parameter coverage and the read-only profile, an agent has everything needed to call and interpret this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage and no enums declared in the schema, the description fully carries parameter meaning: it enumerates the platform event_type values (Keycloak LOGIN/LOGIN_ERROR, authentik login/login_failed, case-insensitive), explains user and target semantics, and gives max_results bounds (default 200, max 500). Nothing about the parameters is left undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource and scope: '[READ] Recent authentication events, normalized' plus the normalized field set (time/type/user/ip/client/error). This is enough to separate it from siblings like admin_events and login_failure_rca, which serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives real operational guidance — the event_type vocabulary per IdP, that target should be omitted for the default, and how to act on truncated results (re-run with higher max_results). However, it never states when to choose this tool over the adjacent login_failure_rca or admin_events sibling, so alternative selection is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
login_failure_rcaARead-only
[READ] RCA over the failed-auth feed: separates brute-force (spray or targeted) from a misconfigured client from an expired-credential storm and a lockout storm — each finding carries its numbers, cause, and action.
Args: window_minutes: Trailing analysis window (default 60). max_events: Failed-login events to pull (default 500). target: IdP target name from config; omit for the default.
Returns "feedTruncated": true when the event feed hit max_events — every count is then a lower bound; re-run with a higher max_events before concluding a threshold was not reached.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| max_events | No | ||
| window_minutes | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover readOnlyHint=true, which the [READ] tag restates. The description adds substantial behavioral context beyond that: findings carry numbers, cause and action; and critically it explains the feedTruncated return flag and that every count becomes a lower bound once max_events is hit. That truncation semantics is exactly the kind of non-obvious behavior an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the [READ] tag and the one-line purpose, then clean Args and Returns sections. Every sentence adds information — the defaults, the config-source note for target, and the truncation caveat — with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the return-value burden and does so by describing what each finding contains and the feedTruncated flag's meaning. All three parameters are documented, giving an agent everything needed to call it correctly and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry all param meaning, and it does: window_minutes (trailing analysis window, default 60), max_events (events to pull, default 500), and target (IdP target name from config; omit for default). Each parameter's purpose and default are stated, fully compensating for the empty schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (root-cause analysis) over a specific resource (the failed-auth feed) and enumerates the distinct causes it separates (brute-force spray/targeted, misconfigured client, expired-credential storm, lockout storm). This is unambiguous and distinctive, though it never names the sibling it complements (e.g. login_events for the raw feed), so sibling differentiation is left implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the framing ('RCA over the failed-auth feed') and by the in-tool guidance to re-run with a higher max_events before concluding a threshold was not reached. However, it never states when to prefer this over alternatives like login_events (raw events), client_misconfig_audit, or user_lockout_status, nor any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mfa_coverage_analysisARead-only
[READ] Second-factor coverage: overall %, the users without MFA, and the factor types counted. Pulls one credential list per user (bounded).
Args: max_users: Users to sample (default 200 — one API call each). target: IdP target name from config; omit for the default.
Returns "inputsTruncated": true when the realm is larger than max_users — coveragePct then describes the sample, not the realm.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| max_users | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, it discloses the cost model ('one credential list per user', 'one API call each'), the bound (max_users default 200), and the truncation contract ('Returns "inputsTruncated": true when the realm is larger than max_users — coveragePct then describes the sample, not the realm'). That last point is exactly the kind of correctness-critical caveat annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the [READ] marker and one-line purpose, then a tight Args block and a return caveat. Every sentence earns its place; the formatting is slightly mechanical but not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the key return semantics (coveragePct, inputsTruncated). It stops short of naming the full returned structure (e.g., the without-MFA user list and factor-type breakdown fields), but the essentials for correct interpretation are present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden, and it does: max_users is defined as the sample size with default and per-call cost, target as the config IdP name with omit-for-default behavior. It falls short only on enumerating valid target values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource and scope: 'Second-factor coverage: overall %, the users without MFA, and the factor types counted.' No sibling covers MFA coverage, so an agent can route here unambiguously from the tool name plus this line.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied (an audit/reporting read) but there is no explicit when-to-use, when-not-to-use, or named alternative among the audit siblings like identity_overview or stale_access_audit. The truncation note hints at when the result is partial, but the agent must infer the selection context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
realm_infoBRead-only
[READ] Realm / instance settings relevant to identity hygiene (brute-force protection, password policy, OTP policy, registration).
Args: target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the '[READ]' prefix mostly restates structured data. The description does add genuine context the annotation lacks: the enumerated categories of settings returned, and that 'target' falls back to a default when omitted. No mention of auth requirements, rate limits, or what the response shape is.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the read tag and resource, then the returned setting families, then the one argument; every line earns its place. Slightly terse on the argument side but there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-parameter read tool with no output schema, the definition covers what is fetched but not what comes back, and there is no fallback behavior documented for invalid targets. The gap is modest but real given there is no output schema to carry the return-value burden.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the single parameter has no description in the schema, so the description carries the burden and partially meets it: it says the value is an 'IdP target name from config' and that omission selects the default. It does not say what happens on an unknown target or what valid values look like, leaving a real gap for a config-derived identifier.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (read) plus resource (realm/instance settings) and enumerates the setting families returned: brute-force protection, password policy, OTP policy, registration. It is easy to distinguish from siblings like list_clients or mfa_coverage_analysis, which cover different scopes. It stops short of stating why an agent would pick this over the similarly-named identity_overview.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No statement of when to use this tool versus alternatives, nor any prerequisites or exclusions. The '[READ]' tag and the 'identity hygiene' framing imply the use case, but the agent must infer it. Nothing tells the agent whether this is a good first step before an audit tool or a follow-up to one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
require_password_resetADestructive
[WRITE][risk=medium] Require a password reset at next sign-in (Keycloak required actions); reversible — the undo clears the flag only if this call set it. Pass clear=True to remove a pending requirement instead.
Args: user_id: User id, from list_users. clear: If True, REMOVE the pending reset requirement (the undo path). dry_run: If True, preview without changing. target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| clear | No | ||
| target | No | ||
| dry_run | No | ||
| user_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag readOnlyHint=false, destructiveHint=true and idempotentHint=false, so the write nature is known; the description goes further by declaring '[WRITE][risk=medium]', that the action is reversible, and the sharp caveat that the undo clears the flag only if this call set it, which explains the non-idempotent hint. It stops short of naming required permissions/auth or whether the user is notified, so not a 5. The 'reversible' wording sits in mild tension with destructiveHint=true but does not contradict it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the write/risk tags and the reversibility rule before the argument list, and each sentence contributes meaning. The Args block is necessary given the 0% schema coverage, though it duplicates structure that could live in the schema, adding slight length without new information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a medium-risk mutation with no output schema and an undescribed schema, the description covers effect, reversibility, the undo caveat, dry-run preview, and parameter provenance — which is most of what an agent needs. Missing pieces are permission/auth prerequisites and any statement about the response or whether the reset is enforced at next login.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full semantic load, and it defines all four parameters: the inverse-mode clear flag ('REMOVE the pending reset requirement'), dry_run ('preview without changing'), target ('IdP target name from config; omit for the default'), and user_id with its source. It omits the accepted format/validation of user_id and target, which keeps it out of 5 territory.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb+resource effect: 'Require a password reset at next sign-in (Keycloak required actions)', and immediately discloses the dual mode (set vs. clear). Nothing in the sibling list (disable_user, revoke_user_sessions, etc.) could be confused with this operation. An agent can identify the effect and its mechanism without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear in-tool routing: 'Pass clear=True to remove a pending requirement instead', plus dry_run as a preview path and provenance for user_id ('from list_users') and target ('from config; omit for the default'). It does not state when to prefer this tool over a sibling such as revoke_user_sessions or disable_user, so usage is well-contextualized but not fully exclusive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
revoke_user_sessionsADestructive
[WRITE][risk=medium] Revoke ALL of a user's sessions. IRREVERSIBLE — no undo; the prior session count is recorded (audit shows the blast radius).
Args: user_id: User id whose sessions to revoke, from list_users. dry_run: If True, preview without revoking. target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| dry_run | No | ||
| user_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=false, yet the description goes further: it declares the action IRREVERSIBLE with no undo and notes that the prior session count is recorded so the audit trail shows blast radius. That is real behavioral context beyond the structured hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The severity tag [WRITE][risk=medium] and the irreversibility warning are front-loaded ahead of the args, and each line of the args block adds a distinct fact with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter destructive tool with no output schema, the definition covers required input provenance, the safe preview path, target selection, and the irreversibility/audit consequences. Nothing an agent needs before invoking it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden, and it does: user_id is traced to its source (list_users), dry_run is explained as a non-destructive preview, and target is described as an IdP config name with default fallback when omitted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (revoke) and resource (ALL of a user's sessions), with the scope emphasized in caps. It is immediately distinguishable from read-oriented siblings like user_sessions or client_sessions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage through the args block (user_id sourced from list_users, dry_run as a preview) but never states when to choose this over adjacent mutation tools such as disable_user, nor any prerequisites or when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rotate_client_secretADestructive
[WRITE][risk=high] Rotate a client's secret. IRREVERSIBLE — the old secret is invalidated; only masked fingerprints are recorded/returned, never the value.
Refuses to rotate the client this tool authenticates as: that would revoke its own credential with no undo to fall back on — including under dry_run, which must report a refusal rather than preview a call that will be refused. Rotate that one from the admin console and re-store it with 'identity-aiops secret set'.
Every deployment using this client must be updated with the new secret (fetch it from the admin console over a trusted channel). Pass dry_run=True to preview.
Args: client_id: Client internal id, from list_clients. dry_run: If True, preview without rotating. target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| dry_run | No | ||
| client_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this destructive/non-idempotent, and the description adds substantive beyond-annotation context: irreversibility, that only masked fingerprints are recorded/returned, the self-rotation refusal, and that the refusal also applies under dry_run (reporting a refusal rather than previewing). This is exactly the behavioral detail an agent needs before an irreversible write.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the [WRITE][risk=high] tag and the IRREVERSIBLE warning, which is the right ordering. Slightly verbose in places (the admin console is referenced twice and the refusal rationale is belabored), but every paragraph carries actionable content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still explains what is returned (masked fingerprints, never the value). Combined with prerequisite handling, side effects, the dry_run caveat, and full arg coverage, nothing an agent needs to invoke this safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry all parameter meaning and does: client_id (from list_clients), dry_run (preview semantics), and target (IdP target name from config, omit for default). Each parameter's role and sourcing are made explicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (rotate a client's secret) and immediately qualifies it with the consequence (IRREVERSIBLE, old secret invalidated). This is clearly distinguishable from sibling writes like update_client_redirect_uris or disable_user.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when/when-not rules: it refuses to rotate the client it authenticates as, and tells the agent to use the admin console plus 'identity-aiops secret set' for that case. It also directs where to source client_id (list_clients) and what to do with the new secret (update every deployment).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stale_access_auditARead-only
[READ] Dormant-access audit: enabled users idle > N days, accounts that never signed in, service accounts with interactive logins, and sessions orphaned by disabled/unknown users.
Args: stale_days: Idle threshold in days (default 90). max_users: Users to pull (default 500). target: IdP target name from config; omit for the default.
Returns "inputsTruncated" per input feed and "truncated" when a finding list was capped at maxRows; the *Count fields are always the full totals.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| max_users | No | ||
| stale_days | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations supply only readOnlyHint, so the description usefully adds the [READ] marker plus real behavioral detail: 'inputsTruncated' per feed, 'truncated' when a finding list hits maxRows, and that *Count fields are always full totals. That truncation/counting contract is exactly the kind of context annotations cannot convey, though auth requirements are still unstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with [READ] and the purpose, then two compact labelled blocks for Args and Returns. No filler; every line supplies either scope, parameter meaning, or return semantics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must cover returns and it does explain truncation flags and count-field semantics, and it enumerates the finding categories. Reasonably complete for a 3-param read audit; only auth/permission prerequisites and finding object shape are left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden and it does document all three parameters: stale_days as idle threshold (default 90), max_users as users to pull (default 500), and target as an IdP name from config where omission means the default. Meaningful compensation for a completely undescribed schema, short of full 5 only because the interaction between max_users and truncation isn't spelled out.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Dormant-access audit') and enumerates the exact finding categories it produces (idle enabled users, never-signed-in accounts, service accounts with interactive logins, orphaned sessions). This clearly distinguishes it from audit siblings like mfa_coverage_analysis and client_misconfig_audit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the audit framing and the finding categories, but the description never says when to reach for this versus list_users, user_sessions, or identity_overview, and offers no exclusions. Adequate but with a clear guidance gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
undo_applyADestructive
[WRITE][risk=medium] Apply a recorded undo by dispatching its inverse tool.
The inverse runs through its own governed tool, so it is audited and carries its own risk tier there. Pass dry_run=True to preview the inverse call without executing it. A token can only be applied once.
Args:
undo_id: The undoId from undo_list (or an _undo_id in a write result).
dry_run: If True, preview the inverse tool + params without running it.
target: Passed through to the inverse tool when it accepts a target.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| dry_run | No | ||
| undo_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true, idempotentHint=false, so the safety profile is covered. The description adds genuine context beyond them: the inverse runs through its own governed/audited tool with its own risk tier, and the token is single-use, which sharpens the non-idempotent semantics. It doesn't state whether the applied undo is itself reversible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the [WRITE][risk=medium] signal, then the core behavior in one sentence, followed by a compact Args block. Every sentence earns its place given the 0% schema coverage; slight redundancy between the prose and the staged dry_run note keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-param write tool with no output schema, the definition covers action, mechanism, idempotency limit, preview mode, and all parameters. The one unaddressed item is what a successful (non-dry_run) call returns, but with no output schema and dry_run described, the agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description carries the burden and mostly succeeds: undo_id is documented with its source (undo_list or _undo_id), dry_run is defined as previewing the inverse tool+params, and target is described as passed through only when the inverse tool accepts one. Minor gaps remain on target's type/format, but all three params get meaningful semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Apply a recorded undo by dispatching its inverse tool') and immediately distinguishes itself from the similarly named sibling undo_list by defining apply as the execution counterpart to listing. An agent can tell exactly what this does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent where to get the required undo_id ('from undo_list (or an _undo_id in a write result)') and documents the dry_run preview path as an alternative to executing. It stops short of stating when NOT to apply an undo, but the routing to undo_list covers the main selection question.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
undo_listARead-only
[READ] List recorded, not-yet-applied undo tokens (most recent first).
Each entry names the original tool, the inverse tool that undo_apply
would run, and a human note. Use the undoId with undo_apply.
Returns {"undos": [...], "returned": N, "limit": L, "truncated": bool}.
truncated is measured (one extra row is fetched), not guessed from a
length coincidence: when it is true there are MORE tokens than shown, so
re-run with a higher limit rather than reporting the list as complete.
Each entry carries effectVerified. False means the original write lost
its response, so the change it reverses is PROBABLE, not confirmed — check
the live state before applying, and do not report the result as a restore
of a state that may never have been reached.
Args: limit: Max rows to return (default 50, capped at 500). target: Unused (undo state is host-local); accepted for CLI uniformity.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| target | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply readOnlyHint=true; the description goes well beyond that by disclosing the return shape, that truncation is *measured* via an extra-row fetch, and that effectVerified=false means the reversed change is only PROBABLE, with a caution to check live state and not over-report. This is meaningful operational context the annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the sibling handoff, then structured paragraphs for return value and the effectVerified caveat. Every sentence carries information, though the emphasis on truncation being 'measured, not guessed from a length coincidence' is slightly verbose for the value it adds.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema present, the description supplies the return JSON shape, the meaning of every field an agent must act on (returned, limit, truncated, effectVerified), and the follow-up behavior for truncation. Nothing needed to call or interpret it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and no param has an enum, so the description must compensate, and it does fully: limit is documented as default 50 / capped at 500, and target is documented as ignored with the reason (host-local undo state, kept for CLI uniformity).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List recorded, not-yet-applied undo tokens') plus ordering ('most recent first'). The [READ] tag and the reference to undo_apply make it clearly distinguishable from the sibling that actually applies tokens.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: 'Use the undoId with undo_apply.' and tells it to re-run with a higher limit when truncated rather than reporting a partial list as complete. It lacks an explicit 'when not to use this' condition, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_client_redirect_urisADestructive
[WRITE][risk=high] REPLACE a client's redirect-URI list; reversible — the prior list is captured and the undo replays it.
Redirect URIs are the OAuth flow's security boundary, so this is tagged risk=high on the audit row (a descriptive label, not a gate). Pass the FULL desired list (this replaces, not appends) and dry_run=True to preview.
Args: client_id: Client internal id, from list_clients. redirect_uris: The complete new redirect-URI list. dry_run: If True, preview without changing. target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| dry_run | No | ||
| client_id | Yes | ||
| redirect_uris | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, destructiveHint=true, idempotentHint=false), the description discloses traits the annotations cannot: that the prior list is captured and can be replayed via undo, that risk=high is a descriptive audit label rather than a gate, and that dry_run provides a safe preview path. This is exactly the kind of undo/reversibility and security-boundary context an agent needs before overwriting OAuth configuration.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The [WRITE][risk=high] tag and the replace-not-append rule are front-loaded, and the Args block is compact. The parenthetical explaining that risk=high is 'a descriptive label, not a gate' is a slight digression but it does preempt a real misreading, so it largely earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter write tool with no output schema, the description covers semantics, safety, reversibility, and the preview mechanism well enough to call it correctly. The only gap is the response shape on success/failure, which is minor given the absence of an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden — and it does: client_id (source: list_clients), redirect_uris (the complete new list, replacing rather than appending), dry_run (preview semantics), and target (IdP name from config, omit for default). Every one of the four parameters gains meaning not present in the bare schema titles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('REPLACE a client's redirect-URI list') and pins down the scope with 'this replaces, not appends'. The write/risk tag is front-loaded, so an agent can immediately tell this mutating tool apart from read-oriented siblings like client_detail or list_clients.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete operating guidance — pass the FULL desired list and use dry_run=True to preview — plus the retrieval path for the required client_id ('from list_clients'). It does not, however, route the agent to alternatives or state when not to use this tool (e.g., versus undo_apply for reverting), so it stops short of explicit when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
user_countARead-only
[READ] Total user count in the realm (the cheap health probe).
Args: target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the '[READ]' tag is largely redundant. The description does add useful cost context ('cheap'), but it omits return format, behavior on unknown target, and any auth/rate considerations. With annotations carrying the safety profile, this modest addition justifies a 3.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight lines with the core purpose front-loaded and an explicit Args section for the single parameter. No wasted prose, though the '[READ]' tag duplicates the annotation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a trivial single-optional-param count tool with no output schema, the description covers purpose and the one parameter's semantics adequately. It stops short of explaining the count's scope nuances (e.g., active vs total) but the base need is met.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: it explains 'target' is an IdP target name from config and that omitting it yields the default. That resolves both the parameter's meaning and its default semantics beyond what the bare schema reveals.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('total user count in the realm') and tags it '[READ]', making it clearly distinct from enumeration siblings like list_users and user_detail. An agent can tell this is a scalar count query, not a listing, without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical 'the cheap health probe' implies when this tool is appropriate (lightweight checks over full listings), but it never names an alternative or states explicit when/when-not conditions versus list_users. Usage is implied rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
user_credentialsARead-only
[READ] A user's configured credentials/authenticators — the MFA surface.
Args: user_id: User id, from list_users. target: IdP target name from config; omit for the default.
Returns {"credentials": [...], "returned": N, "truncated": false, "secondFactors": N} — always the user's complete credential set.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| user_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true is already declared, so the '[READ]' tag adds nothing, but with no output schema the description carries the return contract: the object shape (credentials/returned/truncated/secondFactors) and the guarantee that it is 'always the user's complete credential set.' That completeness guarantee is real behavioral context an agent could not infer from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the resource and read marker, then Args and Returns in compact form; every line carries information. The '[READ]' prefix is mildly redundant with the annotation, otherwise there is no waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter read tool with no output schema, the description covers what the tool returns, the shape of the payload, and the meaning of both arguments. Missing only alternative-tool routing and any auth/permission expectations for reading another user's MFA configuration.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must supply all parameter meaning, and it does for both: user_id is sourced 'from list_users,' and target is defined as an IdP target name from config with an explicit omit-for-default rule. Only marginal detail (valid target values) is missing.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names the exact resource — a user's configured credentials/authenticators — and tags it as 'the MFA surface,' which separates it from sibling user tools like user_sessions, user_lockout_status, and user_detail. It stops short of an explicit verb or sibling comparison, but the scope is unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance or exclusion: nothing says to prefer this over mfa_coverage_analysis, user_detail, or list_users for MFA inspection. The only usage signal is a provenance hint ('from list_users'), which is parameter origin, not tool selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
user_detailARead-only
[READ] One user's full detail (enabled state, required actions, attributes).
Args: user_id: User id (Keycloak UUID / authentik pk), from list_users. target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| user_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already declares the safety profile, so the bar is lower. The [READ] tag and the field enumeration (enabled state, required actions, attributes) add real context about what the read returns, but nothing about error behavior or permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a [READ] tag, then a tight Args block. Every line earns its place with no filler, though the bracketed tag and header formatting are slightly redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-record read with no output schema, the description is nearly sufficient: it names the id source, the target default, and the returned field families. Lack of any mention of the target's valid values or failure modes is the only gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden and does so well: user_id is documented with its format (Keycloak UUID / authentik pk) plus provenance, and target is explained with the default-omission behavior. Only missing the enum of valid target values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: retrieving one user's full detail, and enumerates what 'full detail' means (enabled state, required actions, attributes). 'One user's' implicitly distinguishes it from list_users, but no sibling is named explicitly to sharpen the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied. The workflow hint 'from list_users' tells the agent where to obtain the id, which is genuinely useful, but there is no statement of when to prefer this over user_credentials or user_lockout_status for overlapping data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
user_lockout_statusARead-only
[READ] Brute-force lockout status for one user (Keycloak attack-detection).
KEYCLOAK ONLY. authentik keeps no per-user lockout register, so on an authentik target this returns {"error": "Resource 'user_lockout' is not mapped for platform 'authentik'..."}. That is a definitive answer about the platform, not a fault: do not retry it and do not report the tool as broken — use login_failure_rca on the failed-auth feed instead.
Args: user_id: User id, from list_users. target: IdP target name from config; omit for the default.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| user_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this read-only, and the description goes well beyond that: it discloses the exact error shape returned on authentik and interprets it as a definitive platform answer rather than a fault. That is a real behavioral trait an agent could not infer from the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the read marker and the core purpose, then the platform caveat, then the args. Every sentence earns its place, though the authentik warning runs a little long for the information it conveys.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-param read-only status tool with no output schema, the description covers the platform constraint, the failure response shape, and both arguments. It stops short of describing the success payload, but nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry the params, and it does: user_id is sourced from list_users and target is an IdP name from config, omittable for the default. It adds provenance and default behavior, though it gives no format hints for the target value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (brute-force lockout status for one user) and scopes it precisely to Keycloak attack-detection. It also names what it is not (per-user lockout on authentik), so an agent can distinguish it from siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly gives when-to-use (Keycloak targets), when-not (authentik, which keeps no lockout register), and the alternative to use instead (login_failure_rca on the failed-auth feed). It even preempts the wrong reaction ('do not retry, do not report as broken').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
user_sessionsARead-only
[READ] A user's active sessions (id, IP, start/last access, clients).
Args: user_id: User id, from list_users. target: IdP target name from config; omit for the default.
Returns {"sessions": [...], "returned": N, "truncated": false} — the IdP returns the user's whole session set, so this listing is always complete.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | ||
| user_id | Yes | ||
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation it adds genuinely new behavioral facts: the [READ] marker, the exact return envelope ({"sessions": [...], "returned": N, "truncated": false}), and the guarantee that the IdP returns the user's whole session set so results are never partial. That completeness guarantee is information the annotation does not carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the resource and a [READ] tag, then a compact Args block and a single return-value sentence. Every sentence earns its place and there is no filler, though it is slightly longer than strictly needed for two documented params.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates well by spelling out the return envelope and the completeness guarantee, so an agent knows what comes back. The only gap is the unexplained max_results and its relationship to the claimed "always complete" listing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the load; it documents user_id (source: list_users) and target (IdP name, omit for default), which is real added meaning. However max_results is never mentioned, and it is the one parameter that interacts with the description's "always complete / truncated: false" claim, leaving an ambiguity about capping.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
It names the resource and its scope precisely: "A user's active sessions (id, IP, start/last access, clients)", which is enough to distinguish it from client-scoped siblings like client_sessions. The action verb (list/fetch) is implied by the parenthetical field listing rather than stated, but an agent can still tell what it returns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives useful precondition guidance for parameters ("user_id: User id, from list_users", "omit for the default" target), which tells the agent how to supply inputs. It never states when to choose this tool over client_sessions or revoke_user_sessions, so usage context is implied rather than defined.
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.
2 tool updates
v0.8.5- Changed
list_identity_providers1 field changed- added
Input schema / properties / max_resultsAdded value: +{ + "default": 200, + "title": "Max Results", + "type": "integer" +}
- Changed
user_sessions1 field changed- added
Input schema / properties / max_resultsAdded value: +{ + "default": 200, + "title": "Max Results", + "type": "integer" +}
29 tool updates
v0.6.0- First observed
admin_events - First observed
client_detail - First observed
client_misconfig_audit - First observed
client_session_stats - First observed
client_sessions - First observed
disable_user - First observed
enable_user - First observed
group_members - First observed
identity_overview - First observed
list_clients - First observed
list_groups - First observed
list_identity_providers - First observed
list_users - First observed
login_events - First observed
login_failure_rca - First observed
mfa_coverage_analysis - First observed
realm_info - First observed
require_password_reset - First observed
revoke_user_sessions - First observed
rotate_client_secret - First observed
stale_access_audit - First observed
undo_apply - First observed
undo_list - First observed
update_client_redirect_uris - First observed
user_count - First observed
user_credentials - First observed
user_detail - First observed
user_lockout_status - First observed
user_sessions
TDQS
Scored across 29 tools
Tools are mostly cleanly separated by resource and action: user_* (list/detail/count/sessions/credentials), client_* (list/detail/sessions/session_stats), group_*, and event tools. The main friction is between aggregate analyses (mfa_coverage_analysis, login_failure_rca) and the raw listings that feed them (user_credentials, login_events), and between client_sessions (per-client) and user_sessions (per-user) — but descriptions consistently clarify each. No two tools genuinely do the same thing.
Consistently snake_case throughout with no camelCase or arbitrary mixing. It alternates between verb_noun (list_users, revoke_user_sessions, disable_user) and noun_qualifier (user_detail, user_count, client_sessions), but stays internally predictable within each resource family. Minor deviation from a single verb_noun pattern only.
29 tools is on the heavy side and nudges past the well-scoped range, but the domain genuinely spans users, clients, groups, sessions, events, five distinct audits, write/remediation actions, and an undo subsystem. Each tool maps to a real operation, so it is borderline-heavy rather than bloat.
Read coverage is strong (users, clients, groups, sessions, events, IdP/realm config) and the write/undo surface covers containment and remediation with reversibility tracking. Gaps are lifecycle writes — no create/delete user or client, no group membership or attribute mutation — though those may be intentionally out of scope for an audit-and-containment server.
Maintenance
Related MCP Connectors
Fail-closed policy guardrails for AI agents running kubectl, terraform, helm, and argocd.
Remote MCP for Copilot CLI switch gate MCP, structured receipts, audit logs, and reviewer-ready evid
Managed Keycloak from any MCP client: clusters, realms, apps, SSO, users, domains, audit events.
Zero-secret MCP gateway for AI agents: risk-scored, audited calls with human-in-the-loop approval.
Related MCP Servers
- AlicenseAqualityAmaintenanceGoverned Prometheus + Grafana operations — firing-alert and scrape-target RCA, alert noise/flapping analysis, silences, and dashboards, with unbypassable audit logging (MCP + CLI), budget/runaway guards, dry-run, and undo/rollback.39MIT
- AlicenseAqualityAmaintenanceGoverned OPNsense + pfSense firewall operations — gateway-health, rule-shadow, and blocked-traffic RCA, with guarded rule/alias writes, unbypassable audit logging (MCP + CLI), budget/runaway guards, dry-run, and undo/rollback.351MIT
- AlicenseAqualityAmaintenanceGoverned CI/CD operations for self-hosted GitLab and Gitea — pipeline-failure, runner, artifact-bloat, and stale-branch RCA, with unbypassable audit logging (MCP + CLI), budget/runaway guards, dry-run, and undo/rollback.28MIT
- AlicenseAqualityAmaintenanceGoverned MinIO object-storage operations — capacity, exposure-surface audit, lifecycle, and healing RCA, with guarded bucket writes, unbypassable audit logging (MCP + CLI), budget/runaway guards, dry-run, and undo/rollback.48MIT