mcpAD
You can inspect and audit Active Directory/LDAP data through read-only MCP tools covering identity, directory objects, security posture, and policy configuration.
Test AD connectivity, identify the bound identity, and check server health.
Search and retrieve users, groups, computers, contacts, OUs, and arbitrary entries by DN.
Inspect group membership, user groups, nested membership, and admin/privileged group membership.
Audit account risk and hygiene: disabled/locked accounts, inactive/stale objects, password flags, expired accounts, SPNs, Kerberos pre-auth, adminCount, and missing email.
Inspect domain settings, password policies, fine-grained password policies, privileged groups, FSMO roles, trusts, sites, domain controllers, and GPOs.
Find empty OUs/groups, recently created/modified objects, and summarize computer OS inventory.
Run custom read-only LDAP searches for queries not covered by typed tools.
Scope many searches by domain and optional base DN, with result limits capped by the server.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcpADfind disabled user accounts in the Sales department"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcpAD
A FastMCP server that exposes the
msad Active Directory / LDAP library as MCP tools.
Built with Python 3.14 and uv. It reuses the typed, public msad API
(search users/groups, memberships, account status, read-only security audits).
All tools are read-only by default; optional group-membership write tools are
disabled unless MCPAD_ALLOW_WRITE is enabled (see Write tools).
Tools
Tool | Description |
| Find users by name/surname/mail/sam/department/city/state/country (ANDed, |
| Get a single user (exact match) |
| Find groups ( |
| Get a single group (exact match) |
| Find computers by name/dns/os ( |
| Get a single computer (sAMAccountName/cn/dNSHostName) |
| Find AD contact objects by cn/mail/displayName ( |
| Find organizational units by name ( |
| Get a single OU by its |
| List objects under an OU (optionally filtered by |
| Organizational units with no nested sub-OU (hygiene/audit) |
| Find users whose last logon is older than |
| Find computers whose last logon is older than |
| List disabled user accounts (audit; counterpart of |
| List locked-out user accounts (audit; counterpart of |
| List users whose password never expires (audit) |
| List users whose ACCOUNT (not password) never expires |
| List users whose |
| Risk: users with the |
| Risk: users not requiring Kerberos pre-auth (AS-REP roasting exposure) |
| Risk: accounts flagged "sensitive and cannot be delegated" |
| Risk: users with a Service Principal Name set (Kerberoasting exposure) |
| Users with |
| Enabled users who must change their password at next logon ( |
| Data-quality check: users with no |
| Members of well-known privileged groups (admin-account audit) |
| Owners of the five FSMO roles (schema, domain-naming, PDC, RID, infrastructure) |
| Domain trust relationships ( |
| Active Directory sites (from the Configuration naming context) |
| Domain controllers (computer accounts flagged |
| Count of computer accounts grouped by operating system |
| Groups with no direct members (hygiene/audit) |
| List security-enabled groups, optionally by |
| List distribution groups (complement of |
| Group Policy Objects ( |
| A single GPO by its |
| Fine-grained password policies (PSOs) |
| Objects whose |
| Objects whose |
| Domain object: security-relevant settings and metadata (audit) |
| Default domain password policy (audit) |
| Users whose password violates the policy (audit) |
| Well-known privileged groups with member counts (audit) |
| Fetch any entry directly by its DN (resolve |
| Resolve a sAMAccountName (or DN) to a distinguished name |
| Run a raw, read-only LDAP search with a custom filter (power-user escape hatch) |
| List group members (direct or |
| List a user's groups (nested by default) |
| Is a user a (nested) member of a group? |
| Is an account disabled? |
| Is an account locked? |
| Test AD connectivity and bind (returns ok/target/auth/error) |
| Identity bound as (RFC 4532 "Who Am I?"); works with Kerberos too |
| Server health check (server name, msad version, connectivity) |
The find_users, find_groups, find_computers and find_ous tools accept an
optional base (a DN, e.g. an OU) to restrict the search to that subtree
instead of the whole domain.
Tool annotations
Every tool advertises standard MCP behavior hints so a client can reason about
its risk without parsing the name or docstring. All the tools above are
read-only (readOnlyHint: true); the optional write tools (see below) are
marked destructiveHint: true (and readOnlyHint: false).
Returned attributes
By default get_user / find_users return a useful attribute set: identity
fields plus manager — the distinguished name (DN) of the user's manager,
e.g. CN=Anna Bianchi,OU=Staff,DC=group,DC=example,DC=com — as well as
memberOf (direct group DNs), userAccountControl, accountExpires,
lastLogonTimestamp and whenCreated. Group lookups include managedBy (the
DN of the group's owner), member, groupType and whenCreated.
To expand a manager (or any DN-valued field) into a full record, call
get_by_dn with that DN. This is a direct, efficient lookup (the DN is used as
the search base), so an agent can do: get_user("mrossi") → read manager →
get_by_dn("<that DN>").
Decoded attributes
By default the server also adds decoded companion keys next to the raw attributes, so a client doesn't have to interpret AD's opaque numbers and binary blobs:
userAccountControl_decoded— a flag list plus booleans (disabled,locked,password_never_expires, ...);groupType_decoded—scope(global / domain_local / universal) and security vs. distribution;objectSid_decoded/objectGUID_decoded— canonicalS-1-5-.../ GUID strings;<attr>_iso— an ISO-8601 timestamp for FILETIME attributes (accountExpires,lastLogonTimestamp,pwdLastSet,lockoutTime, ...), omitted for the "never"/unset sentinels.
The raw attributes are always preserved. Decoding is on by default; set
MCPAD_DECODE_ATTRS to a falsy value (0, false, no, off) to return raw
attributes only.
Write tools
The tools above are all read-only. Two optional write tools modify AD
group membership and are therefore disabled by default. They are registered
only when the MCPAD_ALLOW_WRITE environment variable is set to a truthy value
(1, true, yes, on):
Tool | Description |
| Add a user to a group (both as sAMAccountName or DN) |
| Remove a user from a group (both as sAMAccountName or DN) |
| Unlock a locked-out user account (resets |
MCPAD_ALLOW_WRITE=1 uv run mcpad # write tools registered
uv run mcpad # read-only (default)The service account used by msad must have the directory permissions to
modify the target groups; otherwise the call fails with an MsadError. When
writes are disabled the tools are not advertised at all, so an agent cannot
invoke them.
Two-phase confirmation
All write tools are two-phase. The first call (confirm=false, the
default) makes no change and returns a preview:
{ "status": "confirmation_required", "ok": false, "group": "Sales", "user": "jdoe",
"message": "Would add user 'jdoe' to group 'Sales'. Re-call with confirm=true ..." }Call again with confirm=true — only after explicit human approval — to apply
the change. An agent must never set confirm=true on its own.
Safety guard-rails
Even with writes enabled, membership changes that touch sensitive objects are
refused (returned as status: "error"), regardless of confirm:
Protected accounts —
administrator,admin,krbtgt,guest,system, plus any name matching a service/machine pattern (*$machine accounts,svc_*,service_*,sa_*,adm_*,sys_*).Protected groups —
Domain Admins,Enterprise Admins,Schema Admins,Administrators, the operator groups,Group Policy Creator Owners,DnsAdmins, andDomain Users(critical system group).
Matching is case-insensitive and works whether you pass a sAMAccountName or a
full DN. Extend or tune via environment variables:
Variable | Effect |
| Comma-separated extra account names to protect |
| Comma-separated extra group names to protect |
| Set truthy to turn the checks off (not recommended) |
Related MCP server: RedHatLDAP-MCP
Audit logging
Set MCPAD_AUDIT_LOG to a file path to record every tool call (read-only
and write alike) as one JSON object per line (JSON-lines). Logging is off by
default.
MCPAD_AUDIT_LOG=/var/log/mcpad/audit.log uv run mcpadEach entry carries the UTC timestamp, the tool name, the (redacted) arguments, the status, the business outcome, the duration, and — on failure — the error:
{"ts": "2026-10-18T20:09:34.029995+00:00", "tool": "add_group_member",
"params": {"group": "Sales", "user": "jdoe", "confirm": true},
"status": "ok", "outcome": "applied", "duration_ms": 12.4}Notes:
Sensitive argument values (
password,new_password,old_password,token, ...) are replaced with***REDACTED***.statusrecords only whether the Python call returned (ok) or raised (error). Theoutcomefield records what actually happened:completed— a read-only tool returned normally (the common case);preview— a two-phase write returned its confirmation preview and changed nothing (confirm=false);blocked— a safety guard-rail refused the write;applied— a write was confirmed and executed;failed— the call raised (paired withstatus: "error").
The parent directory is created if needed; if the path cannot be opened the server logs a warning and continues without audit logging (tool calls are never blocked by an unwritable log).
Result limits
Every tool's limit argument is clamped to a hard ceiling so a single call
can't pull an unbounded number of rows from a domain controller. The default
ceiling is 1000; a limit above it — or limit=0, which the underlying
msad library treats as "no limit" — is rewritten to the ceiling. A limit
below the ceiling is used as-is.
MCPAD_MAX_LIMIT=500 uv run mcpad # lower the ceiling to 500MCPAD_MAX_LIMIT must be a positive integer; a missing, empty, non-numeric or
non-positive value falls back to the default of 1000. The effective (capped)
value is what appears in the audit log.
Prompts
The server ships a few MCP prompts — reusable, read-only workflows that guide an agent through multi-step tasks using the tools above. They produce instructions only and never modify anything.
Prompt | Description |
| Walk a read-only domain security audit (policy, admins, stale/violating accounts) and summarize by risk |
| Find and triage inactive users and stale computers (parameter: |
| Report direct vs. nested membership and the owner of a given |
Authentication & connection
The server has no connection settings of its own: it reuses the msad
configuration file, ~/.msad.toml by default (create it with msad init).
Each tool call opens a short-lived connection through msad.connect().
Domain parameters (~/.msad.toml)
[defaults]
domain = "group" # used when a tool call omits `domain`
[domains.group]
host = "dc.example.com" # hostname only (no scheme, no :port)
base = "dc=group,dc=example,dc=com"
port = 636 # default: 389
use_ssl = true # default: false (true = LDAPS)
# user = "svc_account" # optional (see auth below)
# password = "..." # optional
# A second domain (here using user/password auth):
[domains.lab]
host = "dc.lab.example.com"
base = "dc=lab,dc=example,dc=com"
port = 636
use_ssl = true
user = "svc_reader"
password = "s3cr3t"You can declare several [domains.<name>] blocks and pick one per call with the
tool's domain argument, or globally via MSAD_DOMAIN. For example, an agent
can call find_users(surname="Rossi", domain="lab") to target the lab domain
while [defaults].domain stays group.
Overrides via environment
MSAD_DOMAIN— default domain when a tool call omitsdomainMSAD_CONFIG_FILE— path to an alternative TOML configMSAD_HOST,MSAD_BASE,MSAD_PORT,MSAD_USE_SSL,MSAD_USER,MSAD_PASSWORD,MSAD_QUERY_TIMEOUT— override individual connection fields on top of the TOML file (env always wins); same mechanism used by restAD and graphqlAD, so credentials can be injected at runtime without ever being written to~/.msad.toml.
These MSAD_* variables can be set directly in the env block of your MCP
client config — see
Registering the server with an MCP client / agent
for a full mcp.json example.
Authentication modes
The mode is chosen automatically from the domain block:
Kerberos (SASL) — when
user/passwordare not both set (the default). Requires installing mcpAD with the optionalkerberosextra (see Running with uvx or Installation below), which pulls inmsad'sgssapidependency. Obtain a ticket first:kinit # or: kinit <user>@REALMThe server relies on the system Kerberos ticket cache (or a keytab via
KRB5_CLIENT_KTNAME). If the ticket is missing or expired, tools fail with a cleanMsadConnectionErrormessage. When running as a background/remote service, make sure that process can see a valid ticket or keytab.Platform note — do you need
kinit? The Kerberos ticket is obtained by whichever backend msad'skerberosextra installs for your platform (see msad's README):gssapion macOS/Linux,winkerberoson Windows.On macOS/Linux the
gssapicredential cache is empty until you runkinit(or supply a keytab), so a ticket is required.On Windows,
winkerberoswraps native SSPI directly: a domain-joined machine running as a domain user reuses the ticket from the interactive logon, giving real SSO with nokinitneeded. This has not been verified end-to-end by this project against a real AD on Windows — validate it yourself (e.g. with msad'swhoami/test-connectionCLI commands) before relying on it. Windows still needs an explicit ticket/keytab when the host is not domain-joined, when running as a local/service account, or in other contexts without a logon ticket — which is the common case for an unattended/remote (streamable-http) deployment.User / password — when both
userandpasswordare set. Simple LDAP bind. The password is stored in clear text in the TOML, so restrict the file permissions (chmod 600 ~/.msad.toml).Note: setting only one of
user/passwordsilently falls back to Kerberos. Set both, or neither.
Use LDAPS (port = 636, use_ssl = true) whenever possible.
Installation
uvx mcpad
# or, from a checkout:
uv syncKerberos (SASL/GSSAPI) authentication is optional: msad's gssapi
dependency is a native extension that needs the system Kerberos dev headers
to build:
Debian/Ubuntu:
libkrb5-dev(+krb5-config)RHEL/Fedora:
krb5-develmacOS (Homebrew):
krb5
If you only authenticate with user/password, skip it entirely. To enable
Kerberos, install/sync the kerberos extra instead — see
Running with uvx below for the exact command.
Running
Running with uvx
No installation step needed; uvx downloads and runs mcpAD on the fly.
# User/password auth only (no Kerberos, no system headers needed):
uvx mcpad
# With Kerberos support (needs the system Kerberos dev headers above):
kinit # get a ticket first
uvx --from 'mcpad[kerberos]' mcpad
# Latest from Git instead of the PyPI release:
uvx --from 'mcpad[kerberos] @ git+https://github.com/matteoredaelli/mcpAD' mcpadFor an MCP client config (stdio), the equivalent command/args is:
{
"mcpServers": {
"mcpAD": {
"command": "uvx",
"args": ["--from", "mcpad[kerberos]", "mcpad"]
}
}
}The spawned process inherits the environment of whoever launches it, so a Kerberos ticket obtained with
kinitmust be valid in that session (see Local (stdio) below).
Keeping up to date.
uvxresolves the latest version only on its first invocation of a given spec; after that it reuses the cached environment indefinitely, even once a newer release is published (uv docs). Restarting your MCP client (which just re-spawns the sameuvxcommand) will not pick up a new mcpAD/msad release on its own. To force an update:# one-off: refreshes the cache, future launches reuse the new version uvx --refresh --from 'mcpad[kerberos]' mcpad --help # or: always re-check on every launch (small startup overhead) uvx --refresh --from 'mcpad[kerberos]' mcpadFor an MCP client config, add
--refreshtoargsif you want every restart to auto-update:"args": ["--refresh", "--from", "mcpad[kerberos]", "mcpad"]After updating, call the
healthtool to confirm the newmcpad_version/msad_version.
From a checkout (Makefile)
The Makefile wraps the common cases. Transport, host and port are
configurable:
make start-stdio # stdio (for local MCP clients)
make start-http # streamable-http on 127.0.0.1:8000
make start-http HOST=0.0.0.0 PORT=9000 # bind elsewhere
make start-sse # sse transport
make start TRANSPORT=streamable-http PORT=9000 # generic formEquivalent raw commands (the server reads MCP_TRANSPORT / MCP_HOST /
MCP_PORT from the environment):
uv run mcpad # stdio (default)
MCP_TRANSPORT=streamable-http MCP_PORT=9000 uv run mcpadRegistering the server with an MCP client / agent
MCP clients (Claude Desktop, IDE agents, custom agents, ...) usually accept a
JSON config with a mcpServers map. Two deployment styles:
Local (stdio) — the client launches the server
The client spawns the process and talks to it over stdio. This is the simplest setup and keeps everything on your machine (including your Kerberos ticket).
{
"mcpServers": {
"mcpAD": {
"command": "uv",
"args": [
"run",
"--directory", "/path/to/mcpAD",
"mcpad"
],
"env": {
"MSAD_DOMAIN": "group"
}
}
}
}To connect without a ~/.msad.toml, set the MSAD_* connection variables
directly in the env block — the server reads them live on every tool call
(env always wins over the TOML file). This example uses Kerberos (no
MSAD_USER / MSAD_PASSWORD):
{
"mcpServers": {
"mcpAD": {
"command": "uvx",
"args": ["--from", "mcpad[kerberos]", "mcpad"],
"env": {
"MSAD_HOST": "dc.example.com",
"MSAD_BASE": "dc=example,dc=com",
"MSAD_PORT": "636",
"MSAD_USE_SSL": "true",
"MSAD_QUERY_TIMEOUT": "30"
}
}
}
}For a user/password bind instead, add both MSAD_USER and
MSAD_PASSWORD to the same env block:
"env": {
"MSAD_HOST": "dc.example.com",
"MSAD_BASE": "dc=example,dc=com",
"MSAD_PORT": "636",
"MSAD_USE_SSL": "true",
"MSAD_USER": "svc_reader",
"MSAD_PASSWORD": "s3cr3t"
}Notes on the env block:
MSAD_HOSTandMSAD_BASEare the only required connection fields;MSAD_PORTdefaults to389andMSAD_USE_SSLtofalse.All values are strings (JSON has no bare integers/booleans here):
"636","true"/"false"(also1/0,yes/no,on/off) are coerced bymsad.Authentication mode is implicit: with
MSAD_USER/MSAD_PASSWORDunset (or only one set) the server uses Kerberos (see Authentication modes andkinit); set both for a user/password bind. Avoid committing a plaintextMSAD_PASSWORDto a shared config — prefer Kerberos or inject it from a secret store.MSAD_DOMAIN/MSAD_CONFIG_FILEstill work here to pick a domain or an alternative TOML when you do keep a config file.
Notes:
--directorymakesuvuse this project's environment regardless of the client's working directory.Kerberos: the spawned process inherits your environment, so a ticket obtained with
kinitin the same user session is used automatically. For an unattended client, point it at a keytab (e.g. add"KRB5_CLIENT_KTNAME": "/path/to.keytab"toenv).Prefer not to keep a checkout around? Use
uvxinstead — see the Running with uvx JSON example above (sameenvnotes apply).
Remote (streamable-http) — the server runs as a service
Start the server as a long-running HTTP service, then point the client at its URL. Useful when the server runs on a host that has AD/Kerberos access while the client runs elsewhere.
Start the service:
make start-http HOST=0.0.0.0 PORT=9000
# serves the MCP endpoint at http://<host>:9000/mcpClient config referencing the URL:
{
"mcpServers": {
"mcpAD": {
"transport": "http",
"url": "http://mcp-host.example.com:9000/mcp"
}
}
}Notes:
The default streamable-http path is
/mcp.The server itself performs no client authentication; if you expose it beyond localhost, put it behind a reverse proxy / network controls and treat the AD credentials on that host accordingly.
Kerberos runs where the server runs: that host needs a valid ticket or a keytab, not the client.
Development
uv sync
uv run python -c "import asyncio; from mcpad import mcp; print(asyncio.run(mcp.list_tools()))"The msad dependency can be installed
from its Git repository, or as an editable local path during development so that
library changes are picked up immediately.
Available Tools
54 toolsaudit_admin_accountsAudit Admin AccountsARead-only
Audit administrative accounts: members of well-known privileged groups.
Builds on get_privileged_groups (Domain Admins, Enterprise Admins,
Administrators, ...) and returns, per group that exists, its attributes,
member_count and the expanded members list. Set nested=False to list
only direct members instead of recursing into nested groups.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | ||
| nested | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 real behavioral context beyond that: recursion into nested groups by default, the `nested=False` opt-out, and that only groups that actually exist are returned with `member_count`. It does not mention cost/latency of recursive expansion or permission requirements, which keeps it below a 5.
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 sentences: purpose first, then what is returned, then the single parameter behavior that changes results. No filler and nothing buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be documented, and the description covers the key behavioral dimension (recursion) plus the group-existence filter. The remaining hole is the undocumented `domain` parameter, which an agent must guess at.
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 `nested` well ('list only direct members instead of recursing'), but `domain` is never mentioned in either the description or the schema — its null default and what null means are left entirely to inference.
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 ('Audit administrative accounts: members of well-known privileged groups') and immediately clarifies how it differs from the sibling `get_privileged_groups` by adding per-group attributes, `member_count` and expanded `members`. An agent can distinguish it from `get_privileged_groups`, `group_members` and `is_member` without opening a 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 phrase 'Builds on `get_privileged_groups`' implies the relationship, and the `nested=False` sentence gives one concrete usage switch. However, it never states explicitly when to choose this over `get_privileged_groups` or `group_members`, nor any prerequisites (e.g. domain must be reachable). Usage is inferable but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disabled_usersDisabled UsersARead-only
List disabled user accounts (userAccountControl flag 2).
Audit counterpart of is_disabled: returns every disabled account instead
of checking a single user. Pass base (a DN) to scope to an OU, or
extra_filter to AND an extra raw LDAP clause (must be pre-escaped).
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No | ||
| extra_filter | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already establishes the safety profile, and the description adds genuinely non-obvious behavior: the exact flag being matched, that base scopes to an OU, and that extra_filter is ANDed and must be pre-escaped — a real correctness hazard. It stops short of mentioning the default limit of 100 or any truncation behavior, which matters for an enumeration 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?
Three short sentences, front-loaded with the definition, then the sibling disambiguation, then the parameter guidance. Every clause carries information the schema does not.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-shape explanation is correctly omitted, and the tool's core semantics and filter-safety caveat are covered. The remaining gap is the undocumented limit/domain parameters and any pagination or truncation note for a bulk 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 parameter burden and it only partially does: base is clarified as a DN and extra_filter as a raw pre-escaped LDAP clause. The limit and domain parameters get no mention at all, so the agent must infer their meaning and defaults from bare schema types.
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 disabled user accounts') and even grounds it in the LDAP implementation detail (userAccountControl flag 2), so the agent knows exactly which predicate defines membership. The second sentence explicitly distinguishes it from the sibling is_disabled, which otherwise looks near-identical.
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?
Names the alternative tool (is_disabled) and the condition that selects this one: bulk enumeration of disabled accounts versus a single-user check. It also gives the two narrowing strategies (scope by OU via base, AND an extra clause via extra_filter), but does not state when this tool is the wrong choice, e.g. relative to locked_users or find_inactive_users.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
expired_accountsExpired AccountsBRead-only
List users whose accountExpires date is in the past (excluding "never").
Pass base (a DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 the meaningful semantics of the filter (past accountExpires, never excluded), but says nothing about result volume, default limit behavior, or multi-domain resolution.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core predicate before the scoping note. No wasted words, though the second sentence is the only parameter information provided and could have been extended cheaply.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the core filter is unambiguous. However, two of three parameters and the default result cap are undocumented, leaving real gaps for a 3-parameter tool at 0% schema coverage.
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 all parameter meaning. It only explains `base` (a DN scoping to an OU); `limit` and `domain` are entirely undocumented, and even `base` gets no format example or default-scope statement.
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 users) and pins the predicate precisely: accountExpires in the past, excluding 'never'. That distinguishes it from never_expiring_accounts, though it does not name the sibling outright.
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 exclusion of 'never'-expiring accounts implies usage context, and 'Pass `base` (a DN) to scope to an OU' gives one usage pattern. There is no explicit when-to-use versus never_expiring_accounts or find_inactive_users, and no guidance on the default unscoped behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_admin_count_accountsFind Admin Count AccountsBRead-only
Find users with adminCount=1 (current or stale protected-admin marker).
AD sets adminCount=1 via AdminSDHolder on members of protected groups
(Domain Admins, Enterprise Admins, ...) and does not automatically clear
it once the account is later removed from every such group. Accounts
that still carry adminCount=1 but are no longer privileged keep a
non-inherited, hardened ACL and are a common audit finding. Pass base
(a DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true, so the description adds real operational context: how AdminSDHolder sets the flag, that it is not auto-cleared on group removal, and that stale accounts retain a hardened non-inherited ACL. That is meaningful auditing-domain behavior an agent would not get from structured fields. It stops short of describing result limits or ordering.
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 core definition is front-loaded in the first sentence, followed by the mechanism and the reason it matters. Every sentence carries information; the ellipsis in the protected-group list is a minor informality but not 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?
With an output schema present and readOnlyHint covering safety, the description needn't explain return values. However, for a 3-parameter tool with zero schema doc coverage, leaving `limit` and `domain` unexplained leaves an agent guessing about scope and result size.
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% across 3 parameters, so the description must compensate. It explains only `base` (a DN that scopes to an OU) and leaves `limit` and `domain` completely undocumented in both places.
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 concrete verb+resource: find users whose adminCount=1, including stale markers. It defines exactly what class of object this returns, but does not distinguish it from the sibling `audit_admin_accounts`, which plausibly overlaps.
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 via the audit-finding framing ('common audit finding') and the `base` scoping hint. There is no explicit when-to-use versus `audit_admin_accounts` or `find_users`, and no stated exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_computersFind ComputersARead-only
Find AD computers by cn (name), dNSHostName (dns) or operatingSystem (os).
Criteria are ANDed; values may contain * wildcards. Set
exclude_domain_controllers=True to drop domain controllers from the
results. Pass base (a DN, e.g. an OU) to restrict the search to a
subtree.
| Name | Required | Description | Default |
|---|---|---|---|
| os | No | ||
| dns | No | ||
| base | No | ||
| name | No | ||
| limit | No | ||
| domain | No | ||
| exclude_domain_controllers | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint, and the description adds real behavioral context on top: matching semantics (AND), wildcard support, the effect of exclude_domain_controllers, and the subtree restriction from base. That is exactly the value-add beyond structured fields this dimension rewards.
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?
Four tight sentences, front-loaded with the core capability, then progressively detail matching semantics, the boolean flag, and the subtree scope. No redundant restatement and no wasted prose.
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 7-param read-only search with an output schema (so return shape needs no explanation), the description covers the mechanics an agent needs to build a correct query: AND semantics, wildcards, DC exclusion, and subtree scoping. The minor limit/domain omissions do not block correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description must carry parameter meaning, and it does for most: it translates name/dns/os to their AD attributes, defines base as a DN/OU, states the wildcard syntax, and explains the boolean flag. However, it never documents limit (default 100) or domain, leaving truncation/domain-selection behavior to inference.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Find AD computers') and then maps each filter argument to the underlying AD attribute (cn, dNSHostName, operatingSystem), which lets an agent distinguish this search tool from single-object siblings like get_computer and from narrower searches like find_stale_computers.
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 explains how to combine criteria (ANDed), that wildcards are supported, how to exclude domain controllers, and how to scope to a subtree — clear operational guidance. It stops short of explicit when-to-use/when-not guidance against siblings such as get_computer or find_stale_computers, so it lands at 4 rather than 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_contactsFind ContactsARead-only
Find AD contact objects by cn/mail/displayName (supports * wildcards).
Passing no string matches every contact. Pass base (a DN, e.g. an OU)
to restrict the search to a subtree.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No | ||
| string | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 — wildcard matching syntax and the fact that omitting `string` matches every contact, which is a non-obvious blast-radius signal. It stops short of describing result capping or how `limit` truncates 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?
Two short sentences, front-loaded with purpose then the parameters that change scope. No filler; each clause conveys a distinct search semantic.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be explained, and the wildcard/scope semantics are well covered. However, for a paged search tool, the absence of any mention of `limit` behavior and `domain` targeting leaves real gaps an agent must guess at.
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 covers only two of four parameters: `string` (attributes matched, `*` wildcards) and `base` (DN subtree). `limit` and `domain` are left completely undocumented anywhere, including whether `domain` selects a different domain controller or naming context.
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 (find) and resource (AD contact objects) plus the searchable attributes (cn/mail/displayName), which cleanly separates it from the many sibling finders like find_users, find_groups, and find_computers. An agent can route to it without inspecting 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?
It explains the behavior of the optional filters (no `string` returns everything, `base` narrows to a subtree), which is useful invocation guidance. But it gives no when-to-use/when-not guidance relative to alternatives such as search_ldap or get_by_dn, which are plausible substitutes for a broad LDAP-style lookup.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_distribution_groupsFind Distribution GroupsBRead-only
List distribution groups (complement of find_security_groups).
Pass base (a DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 only that base scopes to an OU; it says nothing about the default limit of 100, whether results are truncated/paginated, or what domain does, which is meaningful context the annotation cannot supply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with purpose then the key parameter hint. Efficient, though the parenthetical could be a plain clause and the second sentence deserves a companion note on limit/domain.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the primary filter is explained. However, with 0% schema coverage the description should have covered limit and domain; an agent must guess their effect and defaults.
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% across 3 parameters, so the description must carry the load. It clarifies base is a DN and scopes to an OU, but limit and domain receive no explanation at all, leaving two-thirds of the parameters undocumented anywhere.
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 distribution groups') and explicitly positions it against the closest sibling ('complement of find_security_groups'). An agent can distinguish it from find_groups and find_security_groups without opening a 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 complement framing with find_security_groups gives implicit routing guidance, but there are no explicit when-to-use/when-not rules, and the broader alternative find_groups (all groups) is never mentioned. It also does not say when scoping by base is advisable versus omitting it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_empty_ousFind Empty OusARead-only
Find organizational units with no nested sub-OU (hygiene/audit).
Matches OUs whose ou attribute has no children. Pass base (a DN) to
scope to a parent OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe query, so the bar is lower. The description earns some credit by defining 'empty' as 'no children on the `ou` attribute', which is real semantic content the annotations don't provide, but it says nothing about result size, default limits, or domain scoping.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, with the core purpose front-loaded before the operational detail. The second sentence restates the same 'no children' idea at slightly greater precision, which is mildly redundant but not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the readOnly annotation covers safety. The definition of 'empty' plus the `base` scoping rule is enough to call the tool correctly; only the `limit` and `domain` semantics are left uncovered.
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 burden. It explains `base` well (a DN that scopes results to a parent OU), but leaves `limit` (default 100) and `domain` entirely undocumented in both schema and prose — a partial compensation only.
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 ('Find organizational units') plus a precise qualifier ('with no nested sub-OU'), which distinguishes it from the sibling find_ous and get_ou_contents. It could have named those siblings explicitly to make the contrast unmistakable, but the intent 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?
'(hygiene/audit)' gestures at the use case, and the note about passing `base` gives a scoping hint. However, it never states when to prefer this over find_ous or get_ou_contents, and there are no exclusions or prerequisites beyond that scoping remark.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_groupsFind GroupsBRead-only
Find AD groups by cn/name/sAMAccountName/displayName (supports * wildcards).
Pass base (a DN, e.g. an OU) to restrict the search to a subtree.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No | ||
| string | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already establishes the safe-read profile, so the description's added burden is lower. It does contribute useful behavior beyond annotations: wildcard support in the match string and subtree scoping via base. It says nothing about result capping despite a `limit` default of 100, though the output schema covers the 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?
Two short sentences, search-key semantics front-loaded before the optional scoping hint, with no filler. Slightly under-specified rather than padded, but structurally sound.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema exists, so return values need not be described, and the core matching behavior is covered. Still, with four parameters and no schema descriptions, an agent is left guessing about `domain` (multi-domain targeting?) and `limit` truncation behavior, and lacks any signal for choosing this over sibling group-listing tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the load. It explains the required search string in useful detail (matched against cn/name/sAMAccountName/displayName, wildcards allowed) and clarifies that `base` takes a DN such as an OU and narrows scope to a subtree. However, `limit` and `domain` are left entirely unexplained, so half the parameters remain 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?
States a specific verb (find) and resource (AD groups) plus the exact attributes matched: cn/name/sAMAccountName/displayName with wildcard support. That is clear, but it does not differentiate from near siblings such as find_security_groups, find_distribution_groups, or search_ldap, which an agent must disambiguate on its own.
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 only guidance is a parameter refinement ('Pass `base` ... to restrict the search to a subtree'), which is really parameter semantics rather than usage routing. There is no statement of when to prefer this tool over find_security_groups, find_distribution_groups, or search_ldap, and no exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_inactive_usersFind Inactive UsersARead-only
Find users whose last logon is older than days (default 90).
Matches lastLogonTimestamp at or before the cutoff. Set
include_never=True to also return users that never logged on. Pass
base (a DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| days | No | ||
| limit | No | ||
| domain | No | ||
| include_never | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint, so the description carries most of the burden and does add real semantics: the cutoff rule (at or before the cutoff), the default of 90 days, and the opt-in behavior for never-logged-on accounts. It omits that `lastLogonTimestamp` is replicated with lag (so results can be misleading), and says nothing about result capping via `limit`.
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?
Four short sentences, front-loaded with the core predicate, then the matching rule, then the two behavioral switches. Nothing repeats the schema verbatim 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?
An output schema exists, so return values need no explanation, and readOnlyHint covers the safety profile. Still, for a 5-parameter tool with zero schema descriptions, the missing `limit` and `domain` semantics leave an agent unable to control result size or target a specific domain.
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 does explain `days` (with default), `include_never`, and that `base` is a DN. However `limit` (a result cap, which is behaviorally important) and `domain` are never mentioned, leaving two of five parameters undocumented anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with a precise predicate: users whose last logon is older than `days`, matched on `lastLogonTimestamp`. That is enough for an agent to distinguish it from generic `find_users` or `disabled_users` in the sibling list, though no sibling is named 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 conditional usage for two parameters ("Set `include_never=True` to also return...", "Pass `base` (a DN) to scope to an OU"), which implies how to shape the query. But there is no guidance on when to prefer this over `find_users`, `disabled_users`, or `find_stale_computers`, nor any exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_must_change_passwordFind Must Change PasswordARead-only
Find enabled users who must change their password at next logon.
Matches pwdLastSet=0, excluding disabled accounts. Pass base (a DN) to
scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 genuinely useful behavioral detail by disclosing the exact result-set definition (pwdLastSet=0, disabled accounts excluded). It stops short of noting the default result cap or what a broad unscoped search costs, so not a 5.
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 short sentences, front-loaded with the purpose, then the matching rule, then the scoping parameter. No filler and nothing redundant with the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the tool is a read-only query with no destructive risk. However, an agent still lacks the meaning of `limit` and `domain` and any indication that results are capped at 100 by default — material gaps for a search tool that can be scoped.
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% across three parameters, so the description carries the full burden — yet it only explains `base` (a DN), omitting any meaning for `limit` (default 100) or `domain`. The one parameter it does explain is handled well, but two thirds of the signature remains undocumented in both places.
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?
Names a specific verb and resource ('Find enabled users who must change their password at next logon') and pins the exact LDAP predicate (pwdLastSet=0, excluding disabled accounts). This makes it readily distinguishable from nearby siblings such as never_expires_password, password_not_required, and expired_accounts.
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 one concrete usage hint — pass `base` (a DN) to scope to an OU — which implies the default searches the whole domain. But it states no when-not conditions, no alternatives to use instead, and no guidance on when to leave `base` or `domain` unset, leaving selection largely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_ousFind OusBRead-only
Find AD organizational units (OUs) by name (matches ou; may contain *).
Pass base (a DN) to search under a specific parent OU instead of the
whole domain.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| name | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint=true annotation already establishes the safety profile, so the description only needs to add search-behavior context. It contributes the wildcard-in-name behavior and the base-DN scoping model, but is silent on what happens when `name` is omitted, how `limit` (default 100) affects results, and whether results are truncated or paginated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core action and immediately followed by the scoping knob; nothing is padding. The phrasing "matches `ou`" is slightly terse/ambiguous (attribute name vs. parameter) but does not waste space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The presence of an output schema relieves the description of explaining return values, and readOnlyHint covers safety. But with four undocumented schema parameters and no input-schema descriptions, an agent still cannot tell what `domain` does or how `limit` governs results — meaningful gaps for a search tool with 0% schema coverage.
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 only partly discharges it: `name` (matches `ou`, wildcards allowed) and `base` (a DN) are explained, which are the two decision-relevant params. `limit` and `domain` — half the parameters — get no explanation at all, including how `domain` interacts with `base`.
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 ("Find AD organizational units (OUs) by name") and adds the wildcard matching behavior, which distinguishes it as a search rather than a single-object fetch like get_ou. It stops short of naming its closest siblings (find_empty_ous, get_ou, get_ou_contents), so the differentiation is implied rather than explicit.
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 second sentence gives real scoping guidance — pass `base` to narrow to a parent OU versus searching the whole domain — which implies the when-to-use context. However, no alternative sibling tool is named and there is no when-not-to-use guidance (e.g., when to prefer get_ou or find_empty_ous).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_recently_createdFind Recently CreatedARead-only
Find objects whose whenCreated is within the last days days (default 7).
Pass object_class (e.g. "user", "group", "computer") to restrict to one
object type, and base (a DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| days | No | ||
| limit | No | ||
| domain | No | ||
| object_class | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safe-read profile is covered. The description adds the meaningful detail that results are keyed on the LDAP whenCreated attribute and that the window defaults to 7 days. It says nothing about the effect of `limit` (default 100), truncation behavior, or whether `domain` falls back to a default — gaps for a query that can silently return partial 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?
Two short sentences plus one clarifying sentence, no filler. The core predicate and the non-obvious 7-day default are front-loaded, with the optional narrowing parameters after.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation. However, for a 5-parameter read with no schema descriptions, the omission of `limit` and `domain` leaves the agent guessing about result caps and domain resolution.
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% with 5 parameters, so the description must carry the semantics. It does explain days (with default), object_class (with example values), and base (as a DN), but leaves `limit` and `domain` entirely undocumented. Partial compensation puts it at the baseline rather than below.
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 (find), a specific resource (objects), and a precise predicate — the whenCreated attribute within the last `days` days. That attribute-level predicate is exactly what separates it from the sibling find_recently_modified and from generic listings like find_users or search_ldap.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives narrowing instructions ('pass object_class to restrict to one type', 'pass base to scope to an OU'), which is implied how-to-use guidance. It never states when to choose this over find_recently_modified or search_ldap, nor offers any exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_recently_modifiedFind Recently ModifiedARead-only
Find objects whose whenChanged is within the last days days (default 7).
Useful for a "what changed recently in AD" audit. Pass object_class
(e.g. "user", "group", "computer") to restrict to one object type, and
base (a DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| days | No | ||
| limit | No | ||
| domain | No | ||
| object_class | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 the relevant behavioral detail that results are based on the AD `whenChanged` attribute and that the default lookback is 7 days.
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 gives the audit use case, then the key filtering parameters. Every sentence earns its place with no redundant restatement.
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?
Output schema exists, so return values need not be explained. The description is mostly complete for a read-only AD query, though it omits semantics for `limit` and `domain`.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains `days`, `object_class`, and `base`, but leaves `limit` and `domain` undocumented in both schema and description.
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: find objects whose whenChanged falls within the last `days` days. The `whenChanged` timestamp and AD audit framing clearly distinguish it from siblings such as find_recently_created.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the audit use case and how to restrict by `object_class` or scope by `base` DN. It does not explicitly contrast with find_recently_created or other search tools, but the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_security_groupsFind Security GroupsARead-only
List security-enabled groups (as opposed to distribution groups).
Pass scope to restrict to one group scope: "global", "domain_local" or
"universal" (None returns security groups of any scope). Pass base (a
DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| scope | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe read. The description adds useful domain context that only security-enabled groups are returned, but says nothing about result volume, the default limit of 100, or domain behavior across parameters.
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 paragraphs, front-loaded with the core distinction, then parameter guidance. No wasted sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described, and the safety profile is covered by annotations. However, with zero schema description coverage, the undefined 'limit' and 'domain' parameters leave meaningful gaps for an otherwise simple lookup 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% across 4 params, so the description must compensate. It does document 'scope' with its three allowed values and 'base' as a DN, but leaves 'limit' and 'domain' entirely unexplained, so half the parameters remain 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?
States a specific verb and resource ('List security-enabled groups') and immediately distinguishes the concept from distribution groups. It does not name the sibling tool find_distribution_groups or find_groups, but the semantic distinction is clear enough for an agent to choose correctly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains how to use the two filtering parameters (scope values, base DN) which implies when to use it, but never states when to prefer this over find_groups or find_distribution_groups, nor any prerequisites. Usage is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_service_accountsFind Service AccountsBRead-only
Risk: list users with a Service Principal Name (SPN) set.
Any account with an SPN can have a Kerberos service ticket requested for
it by any authenticated user, then cracked offline ("Kerberoasting") if
its password is weak. Pass base (a DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already establishes that this is a safe read operation. The description adds useful contextual risk information about SPNs and Kerberoasting, but does not describe return behavior, pagination, or how `limit` and `domain` affect 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?
The description is short, front-loaded with the core action, and each sentence earns its place by either defining the search criterion or explaining why it matters. There is no wasted text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema and readOnly annotation, reducing the description burden. Still, with three parameters and 0% schema description coverage, the description is incomplete because it does not explain `limit` or `domain` semantics.
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 parameter meaning. It explains only `base` as a DN used to scope to an OU, while `limit` and `domain` remain undocumented in both the schema and the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that it lists users with an SPN set, which is a specific verb and resource. It distinguishes the scope from generic user listing by tying results to the Service Principal Name attribute, though it does not explicitly contrast with sibling search/find tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the Kerberoasting risk context and the note to pass `base` to scope to an OU. However, there is no explicit guidance on when to use this instead of alternatives such as `find_users` or `search_ldap`, nor are exclusions stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_stale_computersFind Stale ComputersBRead-only
Find computers whose last logon is older than days (default 90).
Matches lastLogonTimestamp at or before the cutoff. Set
include_never=True to also return computers that never logged on. Pass
base (a DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| days | No | ||
| limit | No | ||
| domain | No | ||
| include_never | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe read. The description adds genuinely useful semantics beyond that: the comparison is against `lastLogonTimestamp` at or before the cutoff, 90 days is the default, and never-logged-on machines are excluded unless `include_never=True`. It omits the notable behavioral fact that `limit` defaults to 100, so results may be silently truncated - a relevant gap for an audit 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?
Three short sentences with the core criterion front-loaded in the first clause, followed by the matching rule and the optional parameters. No filler or redundant restatement, though the parameter notes could be organized more tightly rather than as a prose run-on.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and annotations cover safety, so those needs are met. However, for a 5-parameter tool with zero schema descriptions, the description leaves `limit` (default 100, truncation risk) and `domain` (needed in multi-domain environments) entirely unexplained, which is a real completeness gap for an agent that must call it correctly on the first try.
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 only partially delivers: it explains `days` (semantics plus default), `include_never`, and `base` ('a DN' that scopes to an OU). The `limit` and `domain` parameters are never mentioned, leaving 2 of 5 parameters undocumented anywhere.
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 ('Find'), resource ('computers') and the exact selection criterion ('last logon older than `days`'), which clearly separates it from find_computers (all computers) and find_inactive_users (users, not computers). It never names a sibling explicitly, but the scoping condition makes the distinction inferable 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?
Guidance is limited to parameter-level usage notes: when to set `include_never` and when to pass `base` to scope to an OU. There is no explicit statement of when this tool should be preferred over find_computers, search_ldap or find_recently_modified, and no prerequisites or exclusions. Usage is implied by the tool's name and criterion rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_usersFind UsersBRead-only
Find AD users by field. Criteria are ANDed; values may contain * wildcards.
city/state/country match the l/st/co attributes. Pass base
(a DN, e.g. an OU) to restrict the search to a subtree.
| Name | Required | Description | Default |
|---|---|---|---|
| sam | No | ||
| base | No | ||
| city | No | ||
| No | |||
| name | No | ||
| limit | No | ||
| state | No | ||
| domain | No | ||
| country | No | ||
| surname | No | ||
| department | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already establishes the safety profile. The description adds useful search behavior: ANDed criteria, wildcard matching, city/state/country attribute mappings, and base-subtree restriction, but it omits limit behavior and other execution details.
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 compact sentences, front-loaded with the core purpose and followed by matching semantics. There is no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and readOnlyHint covers safety. However, with 11 undocumented schema parameters, the description does not fully compensate for the lack of parameter-level documentation.
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% across 11 parameters. The description clarifies base and the city/state/country mappings, but does not explain sam, mail, name, surname, department, domain, or limit semantics beyond the general 'by field' statement.
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: find AD users by field. This clearly distinguishes it from group/computer/contact searches, but it does not explicitly differentiate it from specialized siblings such as find_inactive_users or search_ldap.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains how criteria combine (AND) and how to use wildcards and the base parameter, but gives no explicit guidance on when to choose find_users instead of get_user, find_inactive_users, or search_ldap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_users_without_emailFind Users Without EmailARead-only
Data-quality check: list users with no mail attribute set.
Accounts without an email address often can't receive password-expiry
notices, MFA prompts or other automated notifications. Pass base (a DN)
to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The `readOnlyHint` annotation already establishes that this is a safe read operation, and the description adds useful context about why the check matters. It does not describe result limits or pagination behavior, but the output schema is present to cover return structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first sentence, followed by concise rationale and the key `base` scoping note. Every sentence adds value 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 simple read-only tool with an output schema, the description gives enough context to understand the check and its main scoping parameter. However, with 0% schema description coverage, it should also explain `limit` and `domain` to be complete enough for reliable invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter meaning, but it only explains `base` as a DN for OU scoping. The `limit` and `domain` parameters are not mentioned at all, leaving two of three parameters 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?
The description states a specific verb and resource: list users with no `mail` attribute set. The absence condition distinguishes it from the generic `find_users` sibling even though no sibling is named 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?
It frames the tool as a data-quality check and explains why missing email matters, which gives clear usage context. It does not explicitly state when not to use it or name alternatives such as `find_users` or `search_ldap`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_by_dnGet By DnARead-only
Fetch any AD entry directly by its distinguished name (DN).
Use this to resolve DN-valued attributes into full records, e.g. the
manager of a user or the managedBy owner of a group. Returns None if
the DN does not exist.
| Name | Required | Description | Default |
|---|---|---|---|
| dn | Yes | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 a genuine behavioral fact beyond that: it 'Returns None if the DN does not exist,' which is important for an agent deciding how to handle a miss. It does not mention permission requirements or the effect of the optional `domain` selector, so 4 not 5.
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 short sentences, all front-loaded: the core action first, then the motivating use case, then the miss behavior. No filler and no repetition of schema or annotation 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?
An output schema exists and annotations cover read-only semantics, so the description needn't explain return structure. The main gap is the unexplained `domain` parameter, which matters for a tool that says it fetches 'any AD entry' in what may be a multi-domain setup.
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 has to compensate. It clarifies that `dn` means a distinguished name and that any AD entry type is valid for it, but the optional `domain` parameter is never mentioned and its scope (which domain the DN is resolved in) is left entirely 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?
The description opens with a specific verb and resource: 'Fetch any AD entry directly by its distinguished name (DN).' That clearly separates it from typed lookups like get_user or get_group, which require a different key. It stops short of naming those siblings or explaining when a DN-based fetch beats search_ldap, so it lands at 4 rather than 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 gives a concrete use case – resolving DN-valued attributes such as a user's `manager` or a group's `managedBy` into full records – which tells an agent exactly which situation selects this tool. It does not state exclusions or explicitly name `search_ldap`/`get_user` as alternatives, so it is clear context without routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_computerGet ComputerARead-only
Get a single AD computer by sAMAccountName, cn or dNSHostName (exact match).
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | ||
| identifier | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already tells the agent this is a safe read operation. The description adds useful behavior: lookup is exact-match only, not a fuzzy search. It does not mention error behavior, missing-object behavior, or domain scoping, but with annotations covering safety this is a moderate rather than severe gap.
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 definition is a single compact sentence with no filler. The key lookup semantics and accepted identifier formats are front-loaded.
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?
This is a simple read tool with an output schema, so return values need not be explained. Still, the optional domain parameter is undocumented in both schema and description, and there is no guidance on exact-match failure or domain selection.
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 parameter meaning. It does clarify the required identifier parameter by listing sAMAccountName, cn, and dNSHostName and noting exact match, which is genuinely useful. However, it completely ignores the optional domain parameter, leaving half the parameters 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?
The description states a specific verb and resource: retrieve a single AD computer. It also specifies the supported attributes and exact-match semantics, which distinguishes this single-object getter from sibling find_computers or broader search tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The wording strongly implies use when looking up one exact computer, and the contrast with find_computers is inferable from 'single' and 'exact match'. However, it never explicitly says when to prefer this over find_computers or what to do if no exact match exists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_dnGet DnARead-only
Resolve a sAMAccountName (or DN) to a distinguished name (DN).
Returns the value unchanged if it already looks like a DN, otherwise looks
it up. Returns None if not found. Handy before get_by_dn or
get_ou_contents.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| entry | Yes | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already covers the safety profile, so the description's job is to add resolution semantics — and it does: it is idempotent ('Returns the value unchanged if it already looks like a DN') and fails soft ('Returns None if not found'). These are non-obvious behaviors the annotation does not convey. It doesn't explain whether the lookup is exact-match or a search under base/domain, which is the main remaining gap.
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 short sentences, front-loaded with the core action, followed by edge-case behavior, then routing advice. Every sentence 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?
An output schema exists, so return-value documentation is not required, and the description correctly notes the None case. However, for an LDAP tool where 'base' and 'domain' determine which naming context is searched, omitting both leaves the agent without enough to call it confidently in multi-domain setups.
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 meaning for the three parameters. It clarifies 'entry' meaningfully (sAMAccountName or DN), but 'base' and 'domain' are never mentioned, leaving two parameters with no semantic information anywhere.
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: 'Resolve a sAMAccountName (or DN) to a distinguished name (DN).' It also distinguishes itself from the sibling get_by_dn by positioning itself as the pre-step that produces a DN. An agent can tell exactly what this returns 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?
It gives explicit downstream usage ('Handy before get_by_dn or get_ou_contents'), which tells the agent when to reach for it relative to named siblings. It does not state when not to use it, nor how it relates to search_ldap or the find_* tools, so it falls short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_domain_infoGet Domain InfoBRead-only
Read the domain object: security-relevant settings and metadata (audit).
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description's 'Read' is consistent with readOnlyHint=true and adds that the payload is security-relevant settings plus metadata. Beyond that it conveys no behavioral detail such as whether omitting the domain falls back to the connected domain, or any access requirements. An output schema exists, so return-shape disclosure is not required.
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?
One short, front-loaded sentence with no filler; the verb and resource come first. It is efficient, though so terse that it borders on under-specification rather than optimal denseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema and readOnly annotation cover return shape and safety, and the description conveys the tool's scope. The unresolved piece is the domain parameter's default behavior, which an agent needs in order 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?
The single parameter 'domain' has a null default and 0% schema description coverage, so the description is the only place semantics could be supplied — yet it says nothing about what value to pass or that omitting it targets the current/default domain. This is a clear documentation gap for the sole parameter.
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 ('Read the domain object') and adds content hints ('security-relevant settings and metadata'), so an agent knows this returns domain-level configuration, not users or OUs. It does not explicitly differentiate from nearby siblings like get_password_policy or list_domain_controllers, leaving the agent to infer the broader scope.
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 '(audit)' implies an audit/compliance use case, which is a weak but real contextual cue. There is no statement of when to prefer this over get_password_policy, list_trusts, or list_domain_controllers, and no prerequisites are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_gpoGet GpoARead-only
Get a single Group Policy Object by its cn (GUID) or displayName.
The GUID may be given with or without braces. Returns None if not found.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | ||
| identifier | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true, and the description adds useful behavior beyond that: GUIDs may be braced or unbraced and a missing object returns None. It does not cover domain-resolution behavior or permission requirements, but the extra lookup details are meaningful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core action, followed by precise identifier details and the not-found behavior. No wasted language.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description notes the not-found result. The main remaining completeness gap is the unexplained domain parameter and lack of sibling routing guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description does compensate for the required identifier parameter by explaining that it accepts cn/GUID or displayName and that braces are optional. However, it completely omits the optional domain parameter, leaving half the parameter surface 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?
States a specific verb and resource ('Get a single Group Policy Object') and names the exact lookup keys, which clearly differentiates it from list_gpos and broad search tools. The scope of one object is explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used when you already have a GPO cn/GUID or displayName, but it never states when to prefer a broad search or list_gpos instead. Usage is inferable rather than explicitly guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_groupGet GroupARead-only
Get a single AD group by sAMAccountName or cn (exact match).
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | ||
| identifier | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true and an output schema already cover safety and return shape, so the description's main added value is the 'exact match' constraint, which tells the agent no wildcards or partial matching are accepted. It says nothing about not-found behavior, cn ambiguity, or what the domain parameter changes.
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 with no filler; the key constraint (exact match) is attached directly to the identifier explanation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only lookup with an output schema, the description covers the core input semantics adequately. The unexplained domain parameter and absent not-found/ambiguity behavior keep it from being complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate; it does add real meaning for 'identifier' (sAMAccountName or cn, exact match). However, the optional 'domain' parameter is entirely undocumented in both schema and description, leaving a significant gap.
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 ('Get a single AD group') and the 'single' qualifier implicitly contrasts with list-style siblings like find_groups. It never names a sibling explicitly, so an agent must infer the get-vs-find split itself.
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 'exact match' note implies this is for precise lookups rather than fuzzy searching, which hints at when to prefer find_groups. There is no explicit when-to-use/when-not or named alternative such as get_by_dn.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_ouGet OuARead-only
Get a single AD organizational unit by its ou name or full DN (exact).
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | ||
| identifier | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already declares the safety profile, so the description only needs to add context. It usefully discloses that matching is exact rather than fuzzy, but says nothing about behavior when the identifier does not resolve (error vs empty result).
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?
One sentence, front-loaded with the verb and resource, with the input contract appended. No wasted words, though the parenthetical qualifier reads slightly awkwardly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation. The remaining gaps are the undocumented `domain` parameter and not-found behavior, both minor for a simple single-object read.
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 burden. It clarifies that the required `identifier` accepts either a bare OU name or a full DN and that matching is exact, which is genuinely valuable, but the second parameter `domain` is never mentioned.
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 ('Get a single AD organizational unit') and constrains scope to one object, which distinguishes it from list-style siblings like find_ous. It does not explicitly name those siblings, so it falls 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?
The '(exact)' qualifier implies this is a lookup rather than a search, hinting that find_ous is the alternative for partial matching, but the description never states when to prefer one over the other. No prerequisites or exclusion conditions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_ou_contentsGet Ou ContentsBRead-only
List the objects contained under an OU (given its DN).
Optionally restrict to a single object_class (e.g. user, group, computer,
organizationalUnit). Returns an empty list if the OU DN does not exist.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| ou_dn | Yes | ||
| domain | No | ||
| object_class | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already establishes that this is a safe read operation. The description adds useful behavioral context by stating that results are restricted by OU DN and that an empty list is returned if the OU DN does not exist. It does not explain the limit behavior, domain scoping, pagination, or permission requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short sentences with no waste. It front-loads the primary action, then adds the optional filter and the empty-result edge case in a logical order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema and read-only annotations, so the description need not explain return values or safety. It still leaves domain and limit semantics unaddressed, which matters for a four-parameter LDAP listing tool. The core behavior is covered, but the definition is not complete enough to fully guide invocation in multi-domain contexts.
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 parameter meaning. It explains ou_dn as the OU DN and gives examples for object_class, but it leaves limit and domain entirely undocumented. With half the parameters unexplained in both schema and description, the compensation is insufficient.
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: list objects contained under an OU given its DN. It clearly distinguishes itself from get_ou by focusing on contents rather than the OU object itself, though it does not explicitly name sibling tools or explain when to choose this over search_ldap or get_by_dn.
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 by explaining that callers can optionally restrict results to a single object_class such as user, group, computer, or organizationalUnit. However, it gives no explicit when-to-use guidance, no exclusions, and no comparison to alternatives like find_ous, get_by_dn, or search_ldap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_password_policyGet Password PolicyBRead-only
Read the default domain password policy (maxPwdAge, minPwdLength, ...).
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already declares the safety profile, so the description's remaining burden is light. It adds the scope 'default domain' and example attributes but says nothing about what happens when the policy is unreadable, which domain is used, or any auth requirements.
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 with no filler; the trailing ellipsis is slightly loose but signals that additional attributes are returned. Efficient for a simple read tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation here, and annotations cover safety. The remaining gap is the optional domain parameter's default/current-domain semantics, which is unaddressed and is the main thing an agent could get wrong.
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 'domain' parameter is never mentioned in the description. Critically, it is optional with a null default, and the description does not explain that omitting it reads the current/default domain — exactly the kind of meaning the bare schema cannot 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?
Specific verb + resource: 'Read the default domain password policy', with sample attributes (maxPwdAge, minPwdLength) that make the return content concrete. The word 'default' implicitly separates it from list_fine_grained_password_policies and get_password_policy_violations, though neither is named.
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 reads the baseline domain policy rather than violations or FGPPs, but the description never states when to use this instead of those siblings, nor any prerequisites such as connectivity or permissions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_password_policy_violationsGet Password Policy ViolationsARead-only
Find users whose password violates the domain policy (audit).
Flags enabled users whose password has expired (older than the domain
maxPwdAge) and, when include_never_set is True, users who must set a
password at next logon (pwdLastSet=0). Accounts whose password never
expires are excluded. Returns an empty list if the domain has no maximum
password age.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| domain | No | ||
| include_never_set | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true; the description adds genuine behavioral context: never-expiring accounts are excluded and an empty list is returned when the domain has no maxPwdAge. It does not mention pagination or how 'limit' truncates results, which matters for an audit scan.
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 core purpose, then conditional behavior. Tight and mostly free of filler; the parenthetical '(audit)' is the only near-redundant token.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return shape needn't be described, and the description covers the key inclusion/exclusion rules and the empty-result edge case. The unaddressed 'limit' parameter is the notable remaining gap for a potentially large result set.
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 parameter meaning. It explains include_never_set well and implies domain via maxPwdAge, but 'limit' (default 100) is never mentioned, leaving truncation behavior undocumented in both schema and description.
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: find users whose password violates the domain policy, with an audit framing. It also defines the semantics of the violation precisely (expired vs pwdLastSet=0). It does not, however, name the sibling it differs from (expired_accounts, find_must_change_password, never_expires_password), which overlap heavily with this scope.
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 by the conditional on include_never_set, but there is no explicit 'use this instead of X' guidance despite several near-duplicate siblings. An agent must infer routing from tool names alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_privileged_groupsGet Privileged GroupsARead-only
Report on well-known privileged groups (Domain Admins, ...) with counts.
Each entry includes the group's attributes plus member_count. Set
with_members=True to include a members list (use nested=True to
expand nested membership).
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | ||
| nested | No | ||
| with_members | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 behavioral context beyond that: it documents the returned entry shape, states that member_count is always present, and warns that members only appear with with_members=True and that nested expansion requires nested=True. Not disclosed: cost/performance of nested traversal or any 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?
Three short sentences, front-loaded with the resource and immediately followed by output shape and the flags that change it. The '(Domain Admins, ...)' ellipsis is slightly hand-wavy but costs almost nothing.
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 an output schema present, the description needn't document return values, yet it helpfully summarizes the entry structure. The read-only nature is covered by annotations. The one remaining hole is the meaning of the `domain` parameter, which an agent would have to guess.
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 burden. It does this well for with_members and nested, explaining exactly what each adds to the output. The `domain` parameter, defaulting to null, is not explained at all — it is unclear whether null means the current/connected domain or an error condition.
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?
Specific verb and resource: 'Report on well-known privileged groups (Domain Admins, ...) with counts'. An agent can tell this is a curated report over a fixed set of privileged groups rather than a general group search. However, it never names the sibling tools (find_groups, get_group, group_members) it overlaps with, so the 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 only implied: the tool is for enumerating well-known privileged groups with membership counts. There is no explicit statement of when to prefer it over find_groups/get_group, nor any precondition or scope caveat (e.g. current domain vs. supplied domain).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_userGet UserARead-only
Get a single AD user by sAMAccountName, UPN, mail or cn (exact match).
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | ||
| identifier | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already declares the safety profile, so the description only adds that matching is exact and lists the attribute types accepted. It says nothing about behavior when no user matches (null vs error) or how the domain parameter affects resolution.
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 with the identifier formats immediately after the purpose. Every clause earns its place 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?
An output schema exists, so return values need not be explained, and readOnlyHint covers safety. The remaining deficit is the undocumented 'domain' parameter and the absence of any not-found behavior, which matters for an exact-match lookup 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 coverage is 0%, so the description carries real weight and does add value for 'identifier' by naming sAMAccountName, UPN, mail and cn as accepted forms. The 'domain' parameter is left entirely undocumented in both schema and description, leaving a meaningful gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('Get a single AD user') and enumerates the accepted identifier types, which distinguishes it from the bulk sibling find_users. It does not explicitly name the sibling it differs from, but 'single' plus 'exact match' makes the scope 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?
'exact match' implies this is for precise lookups rather than pattern searches, which implicitly routes the agent away from find_users. However, it never states when to prefer this over find_users or get_by_dn, nor any prerequisites for the identifier formats.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
group_membersGroup MembersBRead-only
List members of a group. Set nested=True for recursive membership.
| Name | Required | Description | Default |
|---|---|---|---|
| group | Yes | ||
| limit | No | ||
| domain | No | ||
| nested | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint already declares this a safe read, so the description only needs to add context beyond that. It discloses the recursive-expansion behavior for nested=True, but says nothing about pagination via limit (default 1000), domain scoping, or result truncation, which matter for large groups.
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 sentences, front-loaded with the core action and followed by the one non-obvious parameter tip. No filler, though the extreme brevity leaves gaps that a slightly longer description could close.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation. However, with 0% schema coverage and no annotations beyond readOnlyHint, the definition omits how to scope by domain, what limit does, and whether nested results are flattened.
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% across 4 parameters, so the description must compensate and largely does not: only 'nested' is explained. 'group', 'limit' (default 1000) and 'domain' (nullable) receive no meaning, format, or scoping guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'List members of a group.' An agent can distinguish it from nearby siblings like get_group (group metadata) or user_groups (reverse direction), though it never names those siblings 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?
Usage is only implied by the tool name; there is no statement of when to prefer it over user_groups or is_member, and no prerequisites. The one guidance sentence ('Set nested=True for recursive membership') is helpful but narrow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
healthHealthBRead-only
Server health check: reports server name, mcpAD/msad version and AD connectivity.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already declares the safety profile, so the description doesn't need to restate it. It does add useful context by naming what is probed (server name, version, AD connectivity), which hints the call touches the domain controller and could fail or be slow, but gives no detail on failure behavior or timing.
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 with no filler. It is efficient, though it is short enough that it could have spent a few more words on the domain parameter without becoming bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and readOnlyHint covers safety, so the description needn't explain returns. However, the unexplained 'domain' parameter and the absence of any disambiguation from test_connection/get_domain_info leave real gaps for a diagnostic tool in a crowded sibling set.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one optional parameter, 'domain', with 0% schema description coverage, and the description never mentions it. An agent cannot tell from either source what supplying a domain does versus leaving it null.
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 ('Server health check: reports server name, mcpAD/msad version and AD connectivity'), which is clearly a diagnostic read. It doesn't differentiate itself from near-siblings like test_connection or get_domain_info, which an agent could plausibly confuse it with.
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 explicit statement of when to use this tool versus test_connection or get_domain_info, both of which overlap in scope (connectivity checking, domain metadata). Usage is only weakly implied by 'health check'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
is_disabledIs DisabledBRead-only
Return True if the account is disabled, None if the user is not found.
| Name | Required | Description | Default |
|---|---|---|---|
| user | Yes | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 does add real behavioral value by specifying the None result when the user is not found, which is a non-obvious edge case. It stays silent on authentication/domain resolution behavior, which matters for a directory lookup.
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 with zero padding. The return-value contract and the not-found case are stated first, which is exactly what an agent needs before calling.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema covers the value contract, and the not-found case is disclosed. Still missing: how the domain parameter is resolved, and what distinguishes this from is_locked or disabled_users — gaps that matter in a 40+ sibling toolset.
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 for both parameters. It implicitly maps to the user parameter, but the domain parameter (nullable, default null) is never mentioned, leaving the agent to guess whether null means the connected domain.
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-like check and resource: returns True if the account is disabled. An agent can tell it is a single-account predicate, distinct from the list-oriented disabled_users sibling. However, it never names the closer alternative is_locked, so differentiation is only partially achieved.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use or when-not-to-use guidance. The sibling set contains obvious near-duplicates (disabled_users, is_locked, never_expiring_accounts), yet the description makes no attempt to route between them; usage must be inferred from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
is_lockedIs LockedBRead-only
Return True if the account is locked, None if the user is not found.
| Name | Required | Description | Default |
|---|---|---|---|
| user | Yes | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already establishes that this is a safe read operation. The description adds useful return behavior (True if locked, None if the user is not found), but it omits what happens when the account is not locked and does not mention permissions or search scope.
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 with no filler. It directly states the tool's behavior and return outcomes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only lookup with an output schema, the description is adequate on the return side. However, it leaves the `domain` parameter unexplained and does not fully specify the non-locked return value, so it is not complete enough to remove all ambiguity.
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 for undocumented parameters, but it only implicitly references `user` and says nothing about `domain`. The optional `domain` parameter is especially unclear given its null 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?
The description states a specific check (account lock status) and even gives two return outcomes, so the tool's core purpose is clear. It does not distinguish itself from siblings such as `is_disabled` or `locked_users`, which keeps it below 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 alternatives like `is_disabled` or `locked_users`. The intended use is only implied by the name and the return semantics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
is_memberIs MemberBRead-only
Return True if the user is a (nested) member of the group.
| Name | Required | Description | Default |
|---|---|---|---|
| user | Yes | ||
| group | Yes | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already establishes that this is a safe read operation. The description adds useful behavioral detail by stating that nested membership is considered, not just direct membership. However, it does not discuss edge cases such as nonexistent users/groups or domain-scoped lookup behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no wasted words. It states the return condition and the key nested-membership qualifier immediately. Brevity is appropriate for a simple boolean-check tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and annotations cover read-only safety, so the description need not explain the return value format. However, the optional domain parameter is undocumented everywhere, and the description gives no sibling-routing guidance for group_members versus user_groups. For a simple tool this is adequate but not complete.
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 for undocumented parameters. It implicitly identifies the user and group inputs but adds no meaning beyond their names, and it completely omits the optional domain parameter. With three parameters and no schema descriptions, this leaves a meaningful semantic gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: it returns True if a user is a member of a group. It also adds the important qualifier '(nested)', which distinguishes this membership test from simply listing direct memberships. The boolean-return purpose is clear enough to separate it from siblings like group_members and user_groups.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool instead of group_members, user_groups, or get_group. It implies a membership check but does not state alternatives, prerequisites, or whether it should be used for direct versus nested membership queries. The agent must infer usage from the name and one-sentence description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kerberos_preauth_not_requiredKerberos Preauth Not RequiredARead-only
Risk: list users not requiring Kerberos pre-authentication.
These accounts are vulnerable to offline (AS-REP roasting) password
guessing. Pass base (a DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe read. The description adds genuine domain context beyond the annotation: these accounts are vulnerable to offline AS-REP roasting, which tells the agent how to interpret and prioritize results. No return format or record-count behavior mentioned, but an output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: risk framing first, then the one actionable parameter tip. No boilerplate, and the highest-value information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values needn't be explained, and the risk framing covers intent. But for a 3-parameter tool at 0% schema coverage, missing guidance on `limit` truncation and on what happens when `base` is omitted (whole domain?) leaves a real operational 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 must carry all three parameters. It only explains `base` (a DN) and says nothing about `limit` (silently defaults to 100, implying truncation) or `domain` (presumably for multi-domain selection). Two of three parameters remain opaque.
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 users not requiring Kerberos pre-authentication." The attribute is distinctive enough that an agent won't confuse it with password_not_required or never_expires_password, but the description never names those near-neighbours to draw the boundary 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?
"Pass `base` (a DN) to scope to an OU" gives one usage instruction, and the AS-REP roasting note implies the use case is a security audit. There is no explicit when-not guidance or routing to alternatives such as search_ldap for custom filters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_domain_controllersList Domain ControllersBRead-only
List the domain controllers (computer accounts flagged as DCs).
Matches the SERVER_TRUST_ACCOUNT userAccountControl flag. Returns the
usual computer attributes for each DC.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already declares this is a safe read, so the bar is lower; the description still adds value by disclosing the underlying flag filter and the fact that results carry standard computer attributes. It says nothing about result volume, default 100-limit behavior, or what happens when a domain is not specified.
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 short sentences, front-loaded with the definition and immediately followed by the exact filter. Nothing is wasted or repetitive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be spelled out and the 'usual computer attributes' note is sufficient there. But with two undocumented parameters and no usage routing, the definition is only minimally complete for an agent 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% for both parameters, so the description carries the full burden and fails: neither 'limit' nor 'domain' is mentioned. In particular, the meaning of 'domain' (target a different domain vs. default to the connected one) is left entirely unexplained.
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 the domain controllers') and pins down the exact predicate used ('computer accounts flagged as DCs', SERVER_TRUST_ACCOUNT userAccountControl). That predicate is what separates it from the generic find_computers/get_computer siblings, though those siblings are never named.
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 usage is implied by the resource name – enumerate DCs – but there is no explicit when-to-use or when-not guidance, and no routing advice against find_computers, search_ldap, or get_computer, which an agent could easily confuse with this.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_empty_groupsList Empty GroupsARead-only
List groups with no direct members (hygiene/audit).
Matches groups whose member attribute is unset. Pass base (a DN) to
scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 relevant semantics annotations cannot: 'no direct members' plus 'matches groups whose member attribute is unset', telling the agent this is a literal attribute check rather than computed nested-membership emptiness.
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 short sentences, front-loaded with the purpose, then the matching rule, then the one parameter hint. 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?
An output schema exists so return shape need not be explained, and the emptiness rule is clear. But for a 3-parameter tool with zero schema coverage, the absence of any mention of `domain` and of how `limit` truncates results leaves real gaps for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden, yet it explains only `base` (a DN, scoping to an OU). `limit` (default 100, pagination behavior) and `domain` (presumably domain/DC selection) are left completely undocumented in both schema and description.
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 groups with no direct members') and adds the 'member attribute is unset' matching rule, which pins down what 'empty' means. It does not explicitly contrast itself with the sibling find_empty_ous, so the sibling differentiation is implied by resource rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The '(hygiene/audit)' tag hints at the use case and 'Pass base (a DN) to scope to an OU' gives a concrete usage pattern. There is no explicit when-not guidance or naming of alternatives such as find_groups with a filter.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_fine_grained_password_policiesList Fine Grained Password PoliciesARead-only
List fine-grained password policies (PSOs) (audit).
Reads msDS-PasswordSettings objects under
CN=Password Settings Container,CN=System,<base>. Reading them may require
extra directory rights; returns an empty list if the container is not
readable.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true already covering safety, the description adds real context: it names the LDAP source (msDS-PasswordSettings under CN=Password Settings Container), warns that extra directory rights may be required, and discloses the empty-list fallback when the container is unreadable. That fallback behavior is exactly the kind of thing an agent needs and cannot get 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?
Two short sentences, front-loaded with purpose, then the access caveat. Zero filler and nothing repeated from annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return shape needs no explanation, and the description covers the key failure mode (empty list on unreadable container). The main remaining gap is the undocumented 'domain' and 'limit' parameters, which matters for a multi-domain call.
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 neither parameter is mentioned in the description. The 'limit' pagination behavior and whether 'domain' selects the base DN for the container lookup are left entirely undefined, so an agent must guess at both.
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 ('List fine-grained password policies (PSOs)') and adds the underlying object type, which distinguishes it from the sibling get_password_policy. However, it never explicitly contrasts itself with that sibling, so the differentiation is implicit rather than spelled out.
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 '(audit)' tag and the read-only framing imply when the tool is useful, but there is no statement of when to prefer it over get_password_policy (default domain policy) or which domain to target. Usage is implied, not guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_fsmo_rolesList Fsmo RolesARead-only
Report the owner of each of the five FSMO roles (audit).
Returns one entry per role (schema_master, domain_naming_master,
pdc_emulator, rid_master, infrastructure_master) with the container
queried and the owning DSA DN (owner). The schema and domain-naming
masters live in the Configuration naming context, derived from the domain
base for a single-domain forest; pass config_base explicitly for a
multi-domain forest. Containers the service account cannot read are skipped.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | ||
| config_base | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint=true, it discloses real behavioral traits: how the Configuration NC is derived for a single-domain forest, the requirement to pass `config_base` explicitly for multi-domain forests, and that unreadable containers are silently skipped (a partial-result condition an agent must know about). It does not discuss permission requirements for the service account or failure/partial-failure signalling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose, then return shape, then the forest-scope caveat, then the skip behavior — a sensible ordering. Slightly verbose in the container/owner sentence, but each sentence adds 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?
With an output schema present, the description need not specify return values, yet it still names the fields, which helps. Combined with annotation coverage of the safety profile, the only notable gap is permission/authentication context and what the caller sees when containers are skipped.
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 and largely does: it explains that `config_base` overrides the derived Configuration naming context and when that is required. The `domain` parameter is only indirectly defined via 'derived from the domain base' — an agent must infer it is a domain base DN.
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 ('report the owner of each of the five FSMO roles') and enumerates the five roles returned, so an agent knows exactly what it gets. No sibling tool covers FSMO roles, so it is trivially distinguishable.
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 '(audit)' tag and the five-role enumeration imply an auditing/health-check use, and the description gives a conditional rule for passing `config_base` in multi-domain forests. It never explicitly states when to call this instead of adjacent tools such as get_domain_info or list_domain_controllers, so selection guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_gposList GposBRead-only
List Group Policy Objects (audit).
Reads groupPolicyContainer objects under CN=Policies,CN=System,<base>.
Each GPO's cn is its GUID and displayName the friendly name. Returns an
empty list if the Policies container cannot be read.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only safety profile, but the description adds real value: the LDAP path read (`groupPolicyContainer` under `CN=Policies,CN=System,<base>`), the meaning of `cn` (GUID) vs `displayName`, and the failure mode of returning an empty list when the container is unreadable. That is above-average disclosure for a simple read 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?
Three short sentences, front-loaded with purpose then implementation detail, with no filler. Slightly more LDAP internals than strictly necessary given an output schema exists, but each sentence is informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return shape needn't be explained, and the read-only nature is annotated. However, with two undocumented parameters at 0% schema coverage, the description leaves the agent guessing about `limit` behavior and domain scoping.
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 doesn't. The `<base>` reference hints that `domain` scopes which naming context is read, but `limit` (pagination/truncation semantics) is never mentioned and `domain`'s behavior when null 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 and resource ("List Group Policy Objects") with an audit framing, which is unambiguous. It does not explicitly distinguish itself from the sibling `get_gpo`, though the plural/list framing implies the difference.
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 versus `get_gpo` or any other GPO-adjacent sibling. The agent must infer from the tool name alone that this is the enumeration entry point.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sitesList SitesARead-only
List the Active Directory sites (audit).
Reads site objects from CN=Sites,CN=Configuration,<forest root>. The
Configuration naming context is derived from the domain base for a
single-domain forest; pass config_base explicitly for a multi-domain
forest. Returns an empty list if the container cannot be read.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| domain | No | ||
| config_base | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a safe read (readOnlyHint=true), so the bar is lower, and the description still adds real context: the underlying DN path, how the Configuration naming context is derived, and the failure mode 'returns an empty list if the container cannot be read'. That empty-result-on-failure behavior is genuinely useful and not in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first line, with supporting detail about the LDAP path and edge cases following. Every sentence carries information; there is minor redundancy between the forest-root path and the config_base note, but nothing extraneous.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and the description still flags the empty-list case. For a read-only, zero-required-parameter listing tool this is close to sufficient; the notable remaining gap is the unpaginated-sounding limit parameter and whether the listing is recursive.
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 schema alone leaves all three parameters opaque. The description compensates for config_base (pass explicitly for multi-domain forests) and implies the role of domain in deriving the config base, but says nothing about limit or its default of 100, leaving a third of the parameters undocumented anywhere.
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: 'List the Active Directory sites (audit)'. It also names the exact LDAP container read, which makes the object type unambiguous. It does not explicitly contrast with look-alike siblings such as list_trusts or list_domain_controllers, but the resource is distinct enough to route correctly.
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 '(audit)' tag hints at an auditing context, and the description states the one real branching rule, 'pass config_base explicitly for a multi-domain forest'. There is no guidance on when to choose this over search_ldap or get_dn for site objects, and no prerequisites are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_trustsList TrustsARead-only
List the domain's trust relationships (audit).
Reads trustedDomain objects under CN=System,<base>: trust partner,
direction, type and attributes. Returns an empty list if the container
cannot be read.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already covers the safety profile, and the description adds real context beyond it: the exact LDAP container read, the attributes surfaced (partner, direction, type), and the failure mode (empty list when the container is unreadable). It does not mention permissions needed to read CN=System, which would complete the picture.
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 paragraphs, zero filler, with the core purpose front-loaded and the implementation detail (container path, empty-list fallback) following. Every sentence adds 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?
The output schema means return shape need not be described, and the failure behavior is stated. However, for a 2-parameter tool with no schema descriptions, leaving `limit` and `domain` semantics unaddressed leaves the definition incomplete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries full burden, yet neither parameter is explained. `limit` (default 100) is never mentioned, so the agent cannot know it controls truncation of results, and `domain` is only obliquely referenced by "the domain's" with no statement of what happens when it is null.
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 the domain's trust relationships") and goes further by naming the underlying `trustedDomain` objects under `CN=System,<base>` plus the fields returned. It is naturally distinct from siblings since no other tool covers trusts, though it never acknowledges that `search_ldap` could also surface these objects.
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 "(audit)" implies the use case, but there is no explicit when-to-use, no prerequisites, and no steering away from the generic `search_ldap` sibling. Usage is inferable but left to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
locked_usersLocked UsersARead-only
List locked-out user accounts (lockoutTime >= 1).
Audit counterpart of is_locked: returns every locked account instead of
checking a single user. Pass base (a DN) to scope to an OU, or
extra_filter to AND an extra raw LDAP clause (must be pre-escaped).
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No | ||
| extra_filter | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only, and the description adds useful behavior beyond that: the exact lockout criterion, that it returns every locked account, and that `extra_filter` is ANDed as a raw LDAP clause requiring pre-escaping. It omits any discussion of limit/pagination behavior, which keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded: the core purpose is in the first sentence, followed immediately by sibling differentiation and the most important parameter behavior. Every sentence contributes directly to correct invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and annotations cover safety, the description is nearly complete for a read-only listing tool. It covers the complex filter semantics and the key sibling relationship, but does not explain `limit` or `domain`, which are potentially important when auditing large directories.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description must carry parameter meaning. It meaningfully explains `base` as a DN scoping an OU and `extra_filter` as a pre-escaped raw LDAP AND clause, but leaves `limit` and `domain` completely undocumented despite both being present 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?
The description states a specific verb and resource ("List locked-out user accounts") and even gives the concrete LDAP criterion ("lockoutTime >= 1"). It explicitly distinguishes itself from the sibling `is_locked`, making the intended scope 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?
It clearly contrasts this audit-style listing with the single-user check provided by `is_locked`, and explains how to narrow results using `base` or `extra_filter`. It does not mention exclusions or when one scoping option is preferable, but the primary selection guidance is present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
never_expires_passwordNever Expires PasswordARead-only
List users whose password never expires (userAccountControl flag 65536).
A common security-audit check. Pass base (a DN) to scope to an OU, or
extra_filter to AND an extra raw LDAP clause (must be pre-escaped).
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No | ||
| extra_filter | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only, so the safety profile is clear. The description adds useful behavioral context: the exact flag being audited and the requirement that extra_filter be pre-escaped, which is important for correct invocation.
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 paragraphs with no wasted text. The core purpose is front-loaded, followed by immediately useful audit context and parameter guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description gives enough to call the tool correctly for the most important filtering parameters, and an output schema exists for return values. Still, with 0% schema description coverage, the omission of limit and domain semantics is a meaningful completeness 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 coverage is 0%, so the description must carry parameter meaning. It explains base as a DN for OU scoping and extra_filter as an ANDed raw LDAP clause, but it leaves limit and domain 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?
States a specific verb and resource: listing users whose password never expires, with the exact userAccountControl flag. It is clear on its own, though it does not explicitly differentiate itself from the sibling never_expiring_accounts.
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?
Frames the tool as a common security-audit check and explains how to scope with base or extra_filter. However, it does not explicitly say when to choose this over sibling audit tools such as never_expiring_accounts or password_not_required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
never_expiring_accountsNever Expiring AccountsARead-only
List users whose ACCOUNT (not password) never expires.
Matches accountExpires set to the "never" sentinel values (0 or
9223372036854775807). Distinct from never_expires_password, which checks
the password-never-expires UAC flag instead. Pass base (a DN) to scope
to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint already tells the agent this is a safe read, and the description adds real behavioral context beyond that: the filter is on `accountExpires` with sentinel values 0 and 9223372036854775807, which is non-obvious LDAP semantics. It doesn't mention pagination or the default result cap, but the output schema covers returns.
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 short sentences, front-loaded with the core predicate before the sibling disambiguation and the parameter hint. No filler, and the parenthetical '(not password)' prevents the most likely confusion immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema and readOnlyHint remove the need to explain return shape or safety, and the filtering semantics are well covered. However, with zero schema description coverage, the unmentioned `limit` and `domain` parameters leave real gaps for a tool that no required params are needed to call but that may behave unexpectedly at scale or across domains.
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 parameter meaning. It documents `base` as a DN and its scoping role, but says nothing about `limit` (default 100) or `domain` (multi-domain targeting), leaving two of three parameters opaque to an agent that can't read descriptions 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 (list users whose account never expires) and disambiguates against the near-identical sibling by naming it: 'Distinct from never_expires_password, which checks the password-never-expires UAC flag instead.' It even gives the exact underlying attribute and sentinel values, so an agent knows precisely what the tool 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?
Explicitly contrasts with the closest alternative (never_expires_password) and explains the mechanism difference, plus notes that `base` scopes to an OU. It's clear when to pick this over the sibling, though it doesn't state exclusions like 'don't use for password-expiry questions' or mention interactions with the other expired/inactive-user tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
not_delegatedNot DelegatedARead-only
Risk: list accounts flagged "sensitive and cannot be delegated".
Worth auditing when a sensitive privilege was granted without also
excluding the account from delegation (or vice versa). Pass base (a DN)
to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 genuine value by framing the output as a *risk* finding and explaining the misconfiguration pattern being detected. It does not address pagination behavior or how the flag manifests in results, but the output schema presumably covers 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?
The 'Risk:' prefix front-loads the tool's category, then three short sentences deliver purpose, audit trigger, and the key parameter hint. Nothing is redundant and nothing important is buried.
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 an output schema present and readOnlyHint set, the description needn't explain return values or safety. It covers the risk semantics and OU scoping well; the only shortfall is the unaddressed `limit` and `domain` parameters.
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 it only documents `base` (a DN scoping to an OU) in a way that genuinely adds meaning. `limit` and `domain` are left entirely unexplained in both schema and description, leaving a real gap for a 3-parameter tool.
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 names the specific resource (accounts flagged 'sensitive and cannot be delegated') and the verb (list), which resolves the ambiguity of the terse name `not_delegated`. It is clearly distinct from every sibling (audit_admin_accounts, find_admin_count_accounts, get_privileged_groups), though it does not explicitly name an alternative it must be distinguished from.
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 an explicit audit trigger: use this when a sensitive privilege was granted without also excluding the account from delegation, or vice versa. It also states the scoping mechanism via `base`. It stops short of stating when not to use it or which sibling to prefer in overlapping cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
password_not_requiredPassword Not RequiredARead-only
Risk: list users with the PASSWD_NOTREQD UAC flag (account may have no password).
These accounts may have no password at all, letting anyone authenticate as
them and set their own. Pass base (a DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe read, so the description's job is to add context beyond that. It does explain the security implication (anyone could authenticate as such accounts and set their own password), which is genuinely useful context for reporting. It is silent on limit/pagination behavior and on how `domain` is resolved, so the behavioral picture is incomplete.
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?
Short and front-loaded, with the risk statement first and the parameter hint last. There is mild redundancy between "(account may have no password)" in the first sentence and "may have no password at all" in the second, which 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?
An output schema exists and annotations cover the read-only safety profile, so those burdens are lifted. The gap is the unspecified `limit`/`domain` semantics and the absence of any note on result size or default scope (100 rows, default domain) that an agent needs to call it confidently.
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 for three parameters, but it only explains `base` (a DN used to scope to an OU). `limit` and `domain` are left entirely undocumented in both the schema and the description, leaving two of three parameters opaque.
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 users with the PASSWD_NOTREQD UAC flag") and names the underlying AD attribute, which implicitly distinguishes it from sibling flag-based tools like never_expires_password and kerberos_preauth_not_required. An agent can identify the exact account population 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?
Framing it as "Risk:" implies a security-audit use case, and the base parameter guidance ("Pass `base` (a DN) to scope to an OU") gives an actionable usage note. However, it never states when to prefer this over generic `find_users` with a filter, nor any exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_ldapSearch LdapARead-only
Run a raw LDAP search with a custom filter (read-only, power-user escape hatch).
Use this when the typed tools (find_users, find_groups, ...) don't cover
a query. The search_filter is passed to LDAP verbatim, so it must be a
valid, already-escaped RFC 4515 filter, e.g.
(&(objectClass=user)(title=Manager)) or
(&(objectClass=group)(!(member=*))) for empty groups.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | DN to search under (defaults to the domain base). | |
| limit | No | max entries to return (default 100; 0 = no limit). | |
| domain | No | ||
| attributes | No | attributes to return (defaults to all attributes). | |
| search_filter | Yes | a raw LDAP filter (used as-is; escape any user input). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already conveys the safety profile, and the description reinforces it with 'read-only'. It adds genuinely useful behavioral context: the filter is passed verbatim, so malformed filters fail rather than being normalized. However, it does not disclose error behavior on invalid filters, result-volume/pagination implications, or that limit=0 means unbounded.
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 escape-hatch framing and the typed-tool alternative are front-loaded in the first two sentences; the examples in the third earn their place by showing two distinct non-obvious query shapes. 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?
An output schema exists, so return values need not be explained, and the filter semantics are well covered. Gaps are the undocumented `domain` parameter and no note on behavior when the filter matches a very large result set.
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 80%, so most params are already documented. The description nonetheless adds real meaning for the critical parameter by specifying RFC 4515 validity, pre-escaping responsibility, and two concrete filter examples. It does not cover the `domain` parameter, which is undocumented in both schema and description.
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 ('run a raw LDAP search with a custom filter') and immediately frames it as a power-user escape hatch relative to the typed sibling tools. An agent can distinguish it from find_users/find_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?
Explicitly names the condition for use ('when the typed tools (`find_users`, `find_groups`, ...) don't cover a query') and names those alternatives directly. The implicit inverse — use the typed tools for covered queries — is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
summarize_computer_osSummarize Computer OsARead-only
Summarize computer accounts grouped by operating system (audit/report).
Returns {operatingSystem, count} rows sorted by descending count;
computers without an operatingSystem are grouped under (unknown). Pass
base (a DN) to scope to an OU.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | ||
| limit | No | ||
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, covering the safety profile. The description adds valuable behavioral details: return format with {operatingSystem, count}, sorting by descending count, handling of missing OS as '(unknown)', and the optional 'base' parameter for scoping. It could still mention limit behavior or authentication requirements, but the added context is substantial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with purpose followed by return and parameter details. Every sentence adds value with no redundancy or 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?
Given a read-only tool with three parameters and an output schema, the description sufficiently covers return structure and the key scoping parameter. The omission of 'limit' and 'domain' semantics is a gap, but with defaults and an output schema present, the definition is largely complete for calling the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage and three parameters, the description must compensate. It explains only 'base' (a DN for OU scoping), leaving 'limit' and 'domain' completely undocumented in both schema and description. This partial coverage is insufficient for confident invocation of those parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Summarize') and resource ('computer accounts grouped by operating system'), clearly indicating an aggregation rather than a listing. It does not explicitly name a sibling tool for differentiation, but the grouping concept distinguishes it from simple find/get tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical '(audit/report)' hints at a use case, and the instruction to pass 'base' to scope to an OU provides some contextual guidance. However, it does not state when to use this tool versus alternatives like find_computers or find_stale_computers, nor does it mention exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
test_connectionTest ConnectionARead-only
Test connectivity and bind to the AD server without raising.
Returns a status dict with ok, target, auth and error. Use this to
verify the configuration and reachability before running other tools.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only behavior, and the description adds useful context beyond that: the call does not raise on failure and returns a status dict with `ok`, `target`, `auth`, and `error`. It does not discuss credential or permission requirements, but it discloses the key failure-mode behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tight sentences, front-loads the purpose, then gives return-shape and usage guidance. Every sentence adds useful information without repetition.
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 low-complexity connection test with an output schema and read-only annotation, the description covers the main behavior and return values. The undocumented `domain` parameter leaves a real invocation gap, so it is adequate but incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single `domain` parameter has 0% schema description coverage and is not mentioned in the description. The agent cannot tell whether `null` means use default configuration, what domain should be supplied, or how the parameter affects binding.
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: it tests connectivity and binds to the AD server, distinguishing it as a pre-flight verification tool. It does not explicitly contrast with the similar `health` sibling, so it falls 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 explicitly says to use this before running other tools to verify configuration and reachability, giving clear usage context. It does not state when not to use it or route the agent to the similar `health` tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
user_groupsUser GroupsBRead-only
List the groups a user belongs to (nested/recursive by default).
| Name | Required | Description | Default |
|---|---|---|---|
| user | Yes | ||
| limit | No | ||
| domain | No | ||
| nested | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already establishes this is a safe read, lowering the bar. The description adds that traversal is nested/recursive by default, which clarifies result scope, but it restates the schema default and says nothing about truncation under limit or what 'domain' changes.
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 with no filler, and the recursive-by-default caveat is attached directly to the verb. Brevity is appropriate; the shortfall is coverage, not verbosity.
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 an output schema present, return values need no explanation, but four parameters at 0% schema coverage and only a readOnlyHint annotation leave real gaps. An agent cannot tell whether 'user' takes a DN or sAMAccountName, what domain scoping does, or whether limit silently truncates recursive results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for 4 parameters. The description only touches 'user' and the nested default; 'limit' (default 1000) and 'domain' (nullable, default null) are wholly unexplained in both schema and description, leaving an agent guessing how to scope a multi-domain lookup.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: list the groups a given user belongs to. The direction (user → groups) is clear enough to distinguish it from the reverse sibling group_members, though no sibling is named 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?
Usage is only implied by the description; there is no explicit guidance on when to prefer this over group_members or is_member, and no mention of prerequisites such as needing a DN vs. a username for the required 'user' parameter.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoamiWhoamiARead-only
Report the identity the connection is bound as.
Uses the RFC 4532 "Who Am I?" extended operation: the directory server
reports the identity it actually authenticated, working with Kerberos/
SASL-GSSAPI as well as simple user/password bind. Returns
{"authzid": ...}.
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint=true annotation matches the description's read-only framing. Beyond annotations, it discloses the underlying RFC 4532 'Who Am I?' extended operation and that it behaves correctly across SASL-GSSAPI and simple binds — real behavioral context an agent couldn't get from the annotation alone.
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 core purpose is front-loaded in the first sentence and the follow-up is short and substantive. The inline `{"authzid": ...}` return shape is slightly redundant given an output schema exists, but it costs only a clause.
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?
Return values are covered by the output schema, so the description needn't expand there, and the protocol-level behavior is well explained. The unexplained optional 'domain' parameter is the notable remaining hole in an otherwise adequate definition for a one-parameter diagnostic tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'domain' has 0% schema description coverage, and the description never mentions it at all — no indication of what a domain value means here, whether it is a NetBIOS name, FQDN, or an LDAP base, or why it is optional. With low coverage the description was required to compensate and does 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 and resource: 'Report the identity the connection is bound as.' That is unambiguous and clearly distinct from neighboring tools like get_domain_info, test_connection, or is_member, none of which report the bound auth identity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when the tool is applicable by noting it works with Kerberos/SASL-GSSAPI and simple user/password bind, but it never states when to prefer this over siblings (e.g., test_connection or get_domain_info) or any preconditions/exclusions. Usage is inferable, not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
54 tool updates
v0.1.0- First observed
audit_admin_accounts - First observed
disabled_users - First observed
expired_accounts - First observed
find_admin_count_accounts - First observed
find_computers - First observed
find_contacts - First observed
find_distribution_groups - First observed
find_empty_ous - First observed
find_groups - First observed
find_inactive_users - First observed
find_must_change_password - First observed
find_ous - First observed
find_recently_created - First observed
find_recently_modified - First observed
find_security_groups - First observed
find_service_accounts - First observed
find_stale_computers - First observed
find_users - First observed
find_users_without_email - First observed
get_by_dn - First observed
get_computer - First observed
get_dn - First observed
get_domain_info - First observed
get_gpo - First observed
get_group - First observed
get_ou - First observed
get_ou_contents - First observed
get_password_policy - First observed
get_password_policy_violations - First observed
get_privileged_groups - First observed
get_user - First observed
group_members - First observed
health - First observed
is_disabled - First observed
is_locked - First observed
is_member - First observed
kerberos_preauth_not_required - First observed
list_domain_controllers - First observed
list_empty_groups - First observed
list_fine_grained_password_policies - First observed
list_fsmo_roles - First observed
list_gpos - First observed
list_sites - First observed
list_trusts - First observed
locked_users - First observed
never_expires_password - First observed
never_expiring_accounts - First observed
not_delegated - First observed
password_not_required - First observed
search_ldap - First observed
summarize_computer_os - First observed
test_connection - First observed
user_groups - First observed
whoami
TDQS
Scored across 54 tools
Most tools target a distinct object class plus action, and adjacent tools (find_users vs get_user vs get_by_dn, find_inactive_users vs find_stale_computers, is_disabled vs disabled_users) are explicitly cross-referenced in descriptions. The main soft spot is audit_admin_accounts, which is essentially get_privileged_groups(with_members=True, nested=True) wrapped in another tool, and search_ldap overlaps with the entire typed surface as an escape hatch.
The dominant pattern is verb_noun (find_users, get_group, list_gpos, get_ou_contents), but a large audit subset abandons verbs entirely for bare-noun or predicate phrasing: disabled_users, locked_users, password_not_required, not_delegated, never_expiring_accounts, group_members, user_groups. Predicate-named tools like password_not_required function as list queries, which reads oddly next to list_gpos. Still parseable, but three conventions coexist.
54 tools is far beyond a comfortable set; dozens are narrow single-purpose audit queries (kerberos_preauth_not_required, never_expires_password, find_users_without_email) that could collapse into a parameterized audit or search_ldap filter. The breadth reflects a genuinely large domain (users, groups, computers, OUs, GPOs, trusts, sites, FSMO, password policies), but the surface is too heavy for reliable tool selection.
Read-side coverage is excellent: nearly every AD object class and audit scenario has a dedicated query, plus search_ldap as a fallback. However, the surface is entirely read-only, so an agent that finds a stale or risky account has no path to disable, unlock, reset a password, or modify group membership, which is a notable dead end for an AD server.
Maintenance
Related MCP Connectors
Read-only AgentiScript concept search, catalog, authenticity, license, and approved asset discovery.
Read-only search of the Agent Connectors MCP directory.
Provides read access to your GKE and Kubernetes resources.
Read-only checks for DIDs, credentials, MCP servers, A2A cards and agent delegation.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables managing Active Directory users, groups, and computers using natural language, with support for queries and updates.58MIT
- AlicenseBqualityDmaintenanceProvides read-only access to corporate LDAP directories, enabling AI assistants to search for people, navigate organizational hierarchies, and export contact information.125MIT
- FlicenseNot gradedqualityCmaintenanceProvides read-only tools for monitoring and investigating Active Directory Domain Services, including users, groups, OUs, computers, GPOs, and domain metadata via LDAPS.-
- FlicenseNot gradedqualityCmaintenanceRead-only MCP server for Microsoft Entra ID (Azure AD) that enables querying user sign-in logs, group memberships, and assigned Microsoft 365 licenses via Microsoft Graph API. Provides security and audit visibility without any write operations.-