Skip to main content
Glama
msoukhomlinov

iit-mcp-hudu

iit-mcp-hudu

MCP server for Hudu IT documentation, built on the node-hudu SDK.

Tool surface

20 tools by default: hudu_list_operations, hudu_describe_operation, hudu_read, hudu_fetch_many, twelve core reads, and four bounded list reads. Setting HUDU_READ_ONLY=false adds hudu_write and hudu_delete (22 tools). Each dispatcher uses a separate SDK client in its matching mode, with names, annotations and operation enums from the SDK's curated metadata. SDK enforcement rejects cross-effect calls before requests. The old hudu_invoke, hudu_catalog and hudu_describe names are removed; consumers must resync their tool catalog.

The four list tools each wrap exactly ONE fixed registry operation (companies.list / articles.list / assets.listAcrossCompanies / asset_layouts.list), take exactly one page and accept no operation selector or nested invocation, so an ungated Reader can page companies, articles, assets or asset layouts without using a registry dispatcher and without exposing the write surface. The first three take page / page_size (capped at 100); hudu_list_asset_layouts takes page only, because /asset_layouts ignores page_size — a caller bound would truncate a vendor page and skip rows as page advanced, so the tool returns the vendor page whole and page N is always the vendor's Nth page. For the searchable resources (companies / articles / assets) a resource excluded by HUDU_SEARCH_RESOURCES is refused by the list tool too, before any request; asset_layouts is not searchable (the SDK declares no vendor text filter for it), so hudu_list_asset_layouts follows the same reachability as the existing ungated hudu_get_asset_layout tool.

These tools run on node-hudu 0.13.2; the SDK behaviour (0.12.0) section below covers the behaviours that shape them: redirect refusal, the closed input contract, the error envelope, and the client opt-ins. Numeric ids must be positive integers on every tool; anything else is refused before a request is made.

hudu_fetch_many (node-hudu 0.12.0) fetches up to 20 single records across mixed resources in one call: each item is exactly { resource, id, fields? } — one of the 22 bare-id resources, a numeric vendor id, and an optional client-side field projection. A shape violation is refused at the schema layer before any request, and failure is per-item: a miss or a vendor fault lands on its own row as a typed error while the rest of the batch is served. The deployment's secret-read policy applies to the batch's items exactly as to a single read, so a credential item is refused pre-request under the default HUDU_SECRET_READS=deny; HUDU_READ_ONLY keeps the tool — it is a read. The same batch stays reachable through hudu_read with operation operations.fetchMany, gated the same way.

Related MCP server: Hudu MCP Server

Transports

Transport

For

Caller auth

Hudu credential

stdio

Claude Code, Claude Desktop, VS Code

none — the process boundary is the trust boundary

HUDU_API_KEY + HUDU_BASE_URL env

http

Remote MCP clients

none — private, unpublished network

per request: X-Hudu-Api-Key + X-Hudu-Base-Url headers, or the optional HUDU_API_KEY + HUDU_BASE_URL defaults

Local use (stdio)

Needs Node 24+, a Hudu API key and your Hudu origin. stdio is the default transport, so no MCP_TRANSPORT is needed. Mutation tools stay off unless you set HUDU_READ_ONLY=false.

From npm (recommended):

claude mcp add hudu \
  --env HUDU_API_KEY=your-key --env HUDU_BASE_URL=https://your.hudu.host \
  -- npx -y iit-mcp-hudu

or in .mcp.json / Claude Desktop config:

{
  "mcpServers": {
    "hudu": {
      "command": "npx",
      "args": ["-y", "iit-mcp-hudu"],
      "env": { "HUDU_API_KEY": "your-key", "HUDU_BASE_URL": "https://your.hudu.host" }
    }
  }
}

npx fetches the package on first run and caches it; use iit-mcp-hudu@<version> to pin one.

From a clone (for development): see Development. Point your client at node /absolute/path/to/iit-mcp-hudu/dist/main.js after npm run build.

Loading credential values (read this before a live session)

A Hudu credential whose bytes reach this server mangled costs a real authentication failure against your Hudu account, and repeated ones risk an account lock. Two rules keep that from happening.

Load an env file the way the file documents — shell sourcing, not a generic dotenv parse.

set -a; . ./.env; set +a      # the .env.example recipe, for a file of single-quoted values

.env.example writes its example values in single quotes, which is the normal .env style. A shell consumes those quotes when the file is sourced, so the value the process sees is exactly the secret. A quote-preserving dotenv parser (dotenv-style KEY=VALUE splitting that keeps the quotes) does not: it hands '…' to the server, quotes included, and the vendor rejects it. The trap is sharpest when the secret itself contains $ — HUDU_API_KEY='a$b' becomes a$b when sourced and 'a$b' (with quotes) when naively parsed, and both look correct in the file.

The client-config and --env paths shown under Local use pass values verbatim and never parse a file, so they are already safe — this rule is for anyone loading a .env.

Run doctor before the first live call. It answers "did my credential load intact?" from the environment alone, with zero Hudu requests:

npx -y iit-mcp-hudu doctor     # or: node dist/main.js doctor

It prints, per credential field, the value's length, its two-character prefix2 and a shapeOk flag with the anomaly names when it is not; plus the origin that will actually be dialed. It exits non-zero when the credential would be refused, so a runbook step can gate on it:

node dist/main.js doctor && <start the live session>

The contract: a green doctor makes any later 401 vendor-side. With doctor clean, a 401 means Hudu refused a well-shaped credential — a rotated, revoked, or role-restricted key — and the fix is at the vendor, not in the load recipe. Do not re-dial to test it: a 401 at the auth gate is the signal to stop and check, because repeated failures risk locking the account. Conversely, a 401 whose envelope names a shape anomaly (credentialShape: "anomalous") points back at the load.

The server enforces the shape itself, so a bad load cannot reach the wire even if doctor is skipped: a malformed HUDU_API_KEY fails boot; a malformed X-Hudu-Api-Key header is refused before any client is built, with the typed CREDENTIAL_MALFORMED envelope (value-free, and retryable: false). Neither path dials. Since node-hudu 0.13.2 the SDK enforces credential shape itself too — refusing a contaminated value at client construction and attaching a value-free shape diagnostic to a refused credential — and this server consumes that diagnostic directly on a 401; the server's own gate stays as the boundary guard, a superset of the SDK's checks.

The server inspects shape only — length, a two-character prefix, and anomaly names. A credential value is never logged, never echoed in an error, and never returned by /doctor. The anomalies that fail a value are: preserved surrounding quotes (single or double), an embedded quote, a carriage return, a newline, an embedded control character (any non-printable ASCII byte besides those), edge whitespace, and a NUL byte.

Configuration

Copy .env.example. Every variable is validated at boot; the process exits non-zero on an invalid config rather than failing at the first tool call.

Under http the caller normally supplies both per request: its own Hudu API key in X-Hudu-Api-Key and the origin that key belongs to in X-Hudu-Base-Url (an absolute http/https origin, no path — validated by the SDK when the scoped client is built). A client can scope the key per user or per agent to match how the connection is configured, so a caller can read exactly what its own Hudu role permits and no more. There is no shared token: the listener is unauthenticated and must stay on a private, unpublished network.

Both may instead be set as defaults. HUDU_BASE_URL and HUDU_API_KEY are required under stdio and optional under http, where a request's headers win and the defaults fill in whatever it omits. Setting HUDU_API_KEY under http means every request without its own key runs as that key, so set it only when that is intended: with no shared token, the private network is the only gate on who can use it. It is only ever presented to the default HUDU_BASE_URL: a request that names some other origin and brings no key of its own gets no credential and fails closed, so a caller cannot aim the server's key at a host it controls. (A blank value, as a copied .env.example leaves it, is treated as unset.) Each (origin, credential) pair gets its own scoped client (its own search index) cached by the pair's hash and capped, so one caller's indexed article bodies can never answer another's search.

HUDU_ALLOWED_BASE_HOSTS (http only; required unless HUDU_ALLOW_ANY_BASE_HOST=true) restricts which origins a caller may name in X-Hudu-Base-Url: a comma-separated list of exact hostnames or *.example.com subdomain suffixes (no scheme, port or path; write an internationalised name in punycode). When it is unset and HUDU_BASE_URL is set, only that default origin is accepted. When both are unset, any caller-named origin would be accepted, so anyone who can reach the listener could make the server send requests (carrying their key) to hosts of their choosing; the server refuses to boot in that case unless HUDU_ALLOW_ANY_BASE_HOST=true opts in, for a listener only trusted callers can reach. The check is on the hostname string: it does not resolve DNS or block private addresses, so do not list a name you do not control. A request naming a host outside the effective policy fails closed on every tool call without dialing it. Only the hostname is checked for an explicit list: an allowed host is accepted on any port and over http. The default HUDU_BASE_URL is never checked against an explicit list.

With no usable key (none in the header and no HUDU_API_KEY default) a request is still let through: initialize and tools/list never reach Hudu, and a client's catalog sync needs them. Such a request resolves to a credential-less client that throws before any Hudu request is built, so every tool call fails closed rather than borrowing an identity. A request that has a key but no origin (no header and no HUDU_BASE_URL default) is let through the same way and fails closed on every tool call, with the error naming the missing header. A credential header sent twice (which Node would otherwise join with ", ") is treated as absent for the same reason.

HUDU_READ_ONLY=true is the default and omits both mutation tools entirely, regardless of write policy. To enable mutations, explicitly set it to false and configure HUDU_WRITE_POLICY: deny rejects all mutations, allow_list permits only the canonical keys in HUDU_WRITE_ALLOW, and all permits the SDK's mutation surface. An empty or invalid allow-list fails startup. The SDK clients receive the same allow-list plus reads needed by helper dependencies; client mode and effect dispatch remain independent restrictions. Writes default to dry-run previews; execution requires dry_run:false, and destructive operations additionally require exact confirm. A confirmation string is not human consent. Discovery reports deployment-policy refusals as unreachable.

HUDU_WRITE_POLICY stays a deployment-wide decision, not a per-caller one. Per-caller credentials make each caller's Hudu role an external authority too, but that authority is not ours to trust and cannot be allowed to widen this server's surface: the server-side policy is the floor, deny by default, and it holds even when a caller presents a key whose Hudu role could write. The same applies to HUDU_SECRET_READS and HUDU_SEARCH_RESOURCES — all three narrow what this server will ever offer, independent of what any one caller's key might otherwise permit.

HUDU_SECRET_READS governs the other thing no write policy covers: reads that return a plaintext credential. asset_passwords.get returns password and otp_secret as an ordinary read, and the curated tools hudu_find_asset_passwords_by_slug and hudu_get_password_folder reach the same records. It is deny by default and refuses every operation on the asset_passwords and password_folders resources — through hudu_read and through those two tools alike, before any request is issued — so a deployment cannot hand a secret to a model by omission. The batch read operations.fetchMany (reachable through hudu_read) is refused the same way, per item: its operation key is not itself a credential read, so each item's resource is checked before any request, and a mixed batch is refused whole rather than partially dialed. The cross-resource resolve operations.resolveAny (also reachable through hudu_read) is gated the same way: under deny an explicitly named credential resource is refused, and an omitted resource list resolves to the permitted set, which excludes the credential resources from the fan-out. It is scoped to the whole resource rather than to the expand flag, because asset_passwords.get returns the secret without expand. It is independent of HUDU_WRITE_POLICY: all does not imply open secrets, and allow does not open writes. hudu_search is unaffected — it already redacts hits on those two resources. Refusals are POLICY_DENIED and appear as unreachable rows in hudu_list_operations.

All SDK clients keep default redaction enabled, including when HUDU_SECRET_READS=allow. That flag permits credential-resource operations; it never enables plaintext results. The SDK masks credential fields and confidential or unclassified custom fields as [REDACTED]. Untyped fields may therefore be masked even when an external layout calls them public. Under deny, both company-context paths additionally project password rows to the summary field allow-list, dropping free-text descriptions and unknown future fields. No extra layout lookups are needed. The common result boundary also uses the SDK redactor with otp_seed, recovery_code, and recovery_codes as additional secret keys, preserving protections absent from the SDK's default key list.

Result text is a JSON envelope labelled untrusted_data; its fixed instruction marks both text and structuredContent as data, never instructions or authorization to invoke tools.

HUDU_SEARCH_RESOURCES is the read-edge counterpart: it narrows which resources the cross-resource reads — hudu_search and hudu_resolve_any, plus the same operations reached through hudu_read — may offer and query, because a Hudu API key inherits its user's role and may read fewer than the SDK's eight searchable resources. Unset means the full set; set it to what the credential can read so the schema never advertises a guaranteed-empty read. A per-resource read failure, and an auth failure thrown by the resolve fan-out, are reported as unavailable — never with Hudu's own authorization message, which is a fact about the calling credential, not the caller's query.

Under http each caller's search scope starts cold, so hudu_search defaults to tier:"auto" rather than "index": it answers from Hudu search immediately and builds the body index in the background, so a caller's later search is body-aware without the first one awaiting a corpus-wide walk (some clients enforce a 60s call timeout). Under stdio the one long-lived index stays warm and the default is "index". Pass tier:"index" explicitly for a complete first answer.

Three 0.12.0 preset knobs are env-tunable, each defaulting to the adopted behaviour. HUDU_CACHE_PRESET (on | off) toggles the read-through cache: the default on selects the SDK's recommended per-entity TTL preset, and off disables it, so repeated reads re-dial Hudu instead of being served from the cache. HUDU_COOLDOWN (on | off) is the 429 cooldown gate: off means a 429 retries per the agent profile instead of arming a local deadline whose refusals answer with notSent: true. HUDU_TIMEOUT_MS (positive integer milliseconds) is the whole-call deadline, default 30000; it is always sent to the SDK explicitly, so it stays above the profile's 20 s. blockPrivateHosts deliberately gets no override: it is the literal-IP SSRF floor for caller-named origins — a security property, not a deployment preference.

SDK behaviour (0.12.0)

Three SDK behaviours changed in the 0.12.0 line and shape a deployment:

  • Redirects are refused, not followed. Every Hudu request is sent with redirect: 'manual'; a 3xx answer (any except 304) is a REDIRECT_BLOCKED error carrying the location, and the SDK never follows it. If a reverse proxy in front of the Hudu origin answers 301/302 (scheme upgrade, trailing slash, host rename), dial the final origin instead — the fix is topology, not config.

  • Reads have a closed input contract. hudu_read now refuses unknown input fields at the schema layer with a typed CONFIG_ERROR naming the accepted fields, before any request; hudu_describe_operation serves the same contract as input_contract. The batch read operations.fetchMany (up to 20 single records across mixed resources in one call) is part of the hudu_read surface; this server also registers the dedicated hudu_fetch_many tool from the 0.12.0 CORE profile, with the secret-read policy applied to the batch's items on both paths.

  • Error envelopes carry the status in a field. The error message is the vendor's short detail (or a fixed default), never the status or the dialed host; those travel in their own fields, and a long upstream body is still replaced by the response shape, not served. The envelope also carries the SDK's category, retryable, operation, suggestedAction, fieldErrors and details where the error has them, notSent on a locally issued 429 cooldown refusal, and location on a REDIRECT_BLOCKED refusal; the status field is httpStatus. A 401/403-class credential refusal collapses to the fixed UNAUTHORIZED envelope on every tool — the vendor's own message never crosses the boundary, and the credential-shaped keys are redacted out of the payload the same way as the success path. Two honest corners: details may carry the SDK's own 256-char vendor body snippet, labelled untrusted like the rest of the envelope, and the location of a REDIRECT_BLOCKED refusal is the vendor's own target, served so the deployment can report or verify it.

Every client the server builds — the parent, the fail-closed placeholders and each (origin, credential) scope — opts into four 0.12.0 behaviours:

  • profile: 'agent': the conservative agent preset for every option this server leaves unset (1 retry, 240/min rate limit, concurrency 3, bounded resolution scans). The rate-limit bucket is per client, i.e. per scope. The preset stays a deployment-wide constant with no env override; the one deadline it would otherwise govern is pinned explicitly instead (HUDU_TIMEOUT_MS, below), and the 429 now arms the cooldown gate instead of retrying blindly.

  • cache: 'recommended' — env-toggled as HUDU_CACHE_PRESET (default on): the per-entity read-through TTL preset (1 h structural / 5 min mutable / 1 min base). Caches are per client, so per scope. A write through the write or delete client does not clear the read client's cache (separate instances), so a read after a mutation is TTL-bounded stale, never unbounded. off disables the read-through cache: repeated reads re-dial Hudu.

  • blockPrivateHosts on the per-scope clients: the literal-IP SSRF floor for CALLER-named origins, fail-closed at client construction. It complements the HUDU_ALLOWED_BASE_HOSTS hostname matcher (which alone can express wildcard suffixes) and holds even in bring-your-own-origin mode, where that matcher is wide. The operator's own base — the HUDU_BASE_URL under stdio, the default origin under http — is trusted at the process / env boundary and is never floor-checked, so an on-prem install whose Hudu sits on a literal private IP is unaffected by the upgrade. Deliberately no env override: it is a security property, not a deployment preference.

  • cooldown: { enabled: true } — env-tunable as HUDU_COOLDOWN (default on): the 429 cooldown gate; a call refused locally by the gate answers with notSent: true in the error envelope, so a model does not read a local refusal as a vendor rejection of a sent call. off retries a 429 per the profile instead of arming a local deadline.

The whole-call deadline is HUDU_TIMEOUT_MS (positive integer milliseconds, default 30000): it is always passed to the SDK explicitly, so it stays above the agent profile's 20 s regardless of preset — the preset's 20 s would shorten a cold tier:'index' body-index walk that the 0.9.2 deployment tolerated at the SDK's 30 s, and a cold-scope search must not start timing out because of an upgrade.

These are deployment-wide, not per-caller: HUDU_CACHE_PRESET, HUDU_COOLDOWN and HUDU_TIMEOUT_MS are env-tunable with the defaults above, while profile and blockPrivateHosts stay constants.

Development

git clone https://github.com/msoukhomlinov/iit-mcp-hudu.git
cd iit-mcp-hudu
npm install
npm run build
npm test
npm run dev

CI (.github/workflows/ci.yml) runs typecheck, lint and test on every push and pull request.

node-hudu is pinned to 0.13.2. The catalog hash test detects metadata drift; upgrades require review of the client authority, operation enums and redaction regressions. Docker uses npm ci.

Deployment

Dockerfile builds a non-root runtime image. The healthcheck is liveness-only and deliberately does not call Hudu — otherwise an upstream outage would cycle the container, turning a partial failure into a total one.

GET /doctor (same trust model as /healthz: unauthenticated, answered before the MCP handler, zero Hudu requests) serves the same zero-wire credential-shape report the doctor subcommand prints, so a deployment can check its loaded credential without a vendor dial.

The deployment definition is docker-compose.yml: its own Compose project, joining an existing app_net external network (create it with docker network create app_net, or rename it in the file). The listener is not published to the host, so put a TLS-terminating reverse proxy in front of it, or share the network with the client that calls it. Copy .env.example to .env and fill it in, then deploy from a clean git checkout with:

scripts/deploy.sh

The script tags the build with the git short SHA of HEAD (iit-mcp-hudu-iit-mcp-hudu:<sha>) — never :latest — so the running container is always tied to a commit.

Rolling back

A rebuild cannot touch a previous tag, so it stays resolvable in the local image store. Roll back from the same checkout — and only from it:

docker image inspect iit-mcp-hudu-iit-mcp-hudu:<previous-sha> >/dev/null  # must exist locally
HUDU_IMAGE_TAG=<previous-sha> docker compose up -d --no-build --pull never

--no-build and --pull never are not optional: the service declares both image and build, so without them Compose would fall back to pulling — or building the current source under the old tag — if the image is missing, a rollback that deploys the new code instead. The compose file also pins pull_policy: never as the backstop for any invocation, and the docker image inspect line makes a pruned or absent image fail loudly before anything is started.

The image that was running before the first tagged deploy was :latest (unpinned); until a newer pinned tag exists it remains the rollback target via the same two commands with latest.

Release checklist

  • Server identity (name / version reported in initialize) is hardcoded in src/tools/server.ts, because rootDir: "src" forbids importing package.json from across the repo root. Bump it there as well as in package.json.

  • BUILT_AGAINST_PLAN_HASH in src/tools.ts pins the SDK catalogue this server was built against. If its test fails after an SDK upgrade, re-read the catalogue and re-check the 19 registered tools, then move the constant. Never move it to make CI green — that is the one thing it exists to stop.

Available Tools

20 tools
hudu_describe_operationDescribe One OperationA
Read-only

Return the full input schema, effect, flags, dry-run support, error vocabulary, related operations and preferredWhen guidance for ONE operation, so a capability can be called correctly without carrying every schema in context. Use it after hudu_list_operations named the operation and before hudu_read/hudu_write/hudu_delete. Takes the canonical operation key exactly as the catalog prints it (for example "companies.update") — never a tool name, and there is no fuzzy matching: an unknown key is a CONFIG_ERROR naming the nearest catalog keys.

ParametersJSON Schema
NameRequiredDescriptionDefault
operationYesCanonical operation key exactly as hudu_list_operations prints it, e.g. "companies.update". Never a tool name; there is no fuzzy match.

Output Schema

ParametersJSON Schema
NameRequiredDescription
opYes

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already establish readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description still adds real behavior beyond that: no fuzzy matching, and an unknown key yields a CONFIG_ERROR naming the nearest catalog keys. It is only mildly incomplete on return shape, which the output schema covers.

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

Conciseness4/5

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

Front-loads what the tool returns and then the routing, with no filler sentence. The long em-dash aside about key format is dense but each clause carries distinct information, so it is appropriately sized rather than wasteful.

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

Completeness4/5

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

With an output schema present, the description need not enumerate return values, and it covers the remaining gaps: when to call it, key format, and error behavior. Nothing an agent needs to invoke it correctly is missing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds semantics the schema does not carry: the CONFIG_ERROR failure mode for unknown keys and the explicit 'never a tool name' prohibition. It does partly repeat the schema's own property description, keeping it short of a 5.

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

Purpose5/5

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

States a specific verb (Return) and a precisely enumerated resource (input schema, effect, flags, dry-run support, error vocabulary, related operations, preferredWhen) scoped to ONE operation, and explicitly contrasts itself with hudu_list_operations and hudu_read/write/delete. An agent can identify it 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.

Usage Guidelines5/5

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

Gives explicit sequencing: 'Use it after hudu_list_operations named the operation and before hudu_read/hudu_write/hudu_delete.' Both the predecessor and the successors are named, which is exactly the routing an agent needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_fetch_manyFetch Many Records (Batch Read)A
Read-only

Fetch up to 20 single records across MIXED resources in ONE call — the batch form of the single-record reads (it collapses N sequential hudu_read calls into one). items is a CLOSED array of 1-20 entries; each entry is EXACTLY { resource, id, fields? } — no other keys. resource is one of the 22 bare-id resources; assets (company-scoped get) and the download resources (photos, public_photos, uploads, exports, s3_exports) are NOT fetchMany-shaped (no derived field set) and are refused pre-request with a pointer at the resource's own read operations. id is a NUMERIC non-negative vendor id — a string identifier is resolveAny territory, refused pre-request. fields (optional, 1 or more) is a CLIENT-SIDE projection of exact vendor field names, checked pre-request against the resource's derived field set. Duplicate { resource, id } items are INDEPENDENT requests (each issues its own GET and row; no dedup). Items are fetched sequentially through each resource's own get (no in-SDK fan-out); partial failure is PER-ITEM — one failed item never aborts the rest. ALL items are validated before any request (a violation is a CONFIG_ERROR naming every problem, ZERO wire). Read-only: it can issue no write; no dry run applies to reads.

ParametersJSON Schema
NameRequiredDescriptionDefault
itemsYes1-20 items, each exactly { resource, id, fields? }.

Output Schema

ParametersJSON Schema
NameRequiredDescription
okYesItems that fetched a record.
failedYesItems that failed (a miss or a vendor fault) — the typed error is on the item row.
resultsYesOne outcome per input item, in input order: { resource, id, found, value, error? }.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnlyHint and openWorldHint, so safety is covered, yet the description adds substantial non-obvious behavior: validation of ALL items before any wire request (CONFIG_ERROR naming every problem, zero I/O), per-item partial failure that never aborts the batch, sequential fetching with no fan-out, and no dedup for duplicate {resource,id} pairs. This is exactly the extra context the lower bar for annotated tools rewards.

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

Conciseness4/5

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

Purpose and the batch-vs-single framing are front-loaded in the first clause, and every sentence carries actionable content (validation order, failure isolation, restrictions). It is dense and heavy on ALL-CAPS emphasis, which slightly hurts scanability, but nothing is redundant.

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

Completeness5/5

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

For a batch read tool with an output schema present and fully-covered parameters, the description covers what the schema and annotations cannot: pre-request validation semantics, per-item failure isolation, resource exclusions, and read-only scope. Nothing an agent needs to invoke it correctly is missing.

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

Parameters4/5

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

Schema coverage is 100% and already carries the 1-20 bounds, the 22-value resource enum, and the integer id constraint, so structure is not the description's job. The description still adds real semantics the schema cannot express — that `fields` is a client-side projection of exact vendor field names validated pre-request against the resource's derived field set, and that ids must be numeric non-negative vendor ids — which materially reduces mis-calls.

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

Purpose5/5

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

States a precise verb and resource — batch fetch of up to 20 single records across mixed resources — and explicitly positions it against siblings by calling itself 'the batch form of the single-record reads' that collapses N sequential hudu_read calls. An agent can distinguish it from hudu_read 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.

Usage Guidelines5/5

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

Explicitly names when to use it (consolidating many single-record reads) and when not to: assets, photos, public_photos, uploads, exports and s3_exports are refused pre-request with a pointer at those resources' own read operations, and string identifiers are routed to resolveAny. Both alternatives and exclusions are spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_find_asset_passwords_by_slugFind Asset Passwords By SlugA
Read-only

Find one password record by its URL slug. Preferred over a full asset passwords scan for a slug lookup. Returns one record: a compact AssetPasswordSummary (passwordable_id, passwordable_type, description, … dropped); expand: true returns the full AssetPassword. Bounded: limit default 25, max 100; the client scan stops at 500 records / 4 pages (RESOLUTION_TRUNCATED, never a partial answer). Do not use it to enumerate or to page: it returns at most one exact match (call hudu_search or hudu_get_asset_password for that). Sensitive: returns credential-shaped fields; the SDK masks them in results by default and always in diagnostics.

ParametersJSON Schema
NameRequiredDescriptionDefault
optsNo
slugYesExact slug of the asset password.

Output Schema

ParametersJSON Schema
NameRequiredDescription
foundYes
recordYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations cover only readOnlyHint/openWorldHint, but the description discloses real behavior: a hard bounded scan (limit default 25, max 100, client stop at 500 records / 4 pages) that yields RESOLUTION_TRUNCATED rather than a partial answer, plus the fact that credential-shaped fields are returned and masked by the SDK in results and diagnostics. This is context an agent cannot derive from 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.

Conciseness4/5

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

Front-loaded with purpose and the preferred-use statement, then limits, then exclusions, then sensitivity. Dense and information-rich with almost no filler, though the parenthetical field list ('passwordable_id, passwordable_type, description, … dropped') reads as clipped and slightly obscures the point.

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

Completeness5/5

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

An output schema exists so return values need no exhaustive treatment, yet the description still flags the masked-credential behavior, the truncation sentinel, and the scan caps. Given the nested opts object and the sensitivity of the data, nothing an agent needs to call this safely is missing.

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

Parameters4/5

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

Schema coverage is 50% and the schema already documents both slug and opts.expand. The description adds real meaning on top: expand: true returns the full AssetPassword while the default returns a compact AssetPasswordSummary with fields dropped, and it clarifies the scan bound applies rather than the caller-supplied limit being a page size.

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

Purpose5/5

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

States a specific verb (find) and a tightly scoped resource (one password record by URL slug), and explicitly positions itself against a full asset passwords scan and against the sibling tools hudu_search / hudu_get_asset_password. An agent can distinguish it from neighbors without reading any schema.

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

Usage Guidelines5/5

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

Names the preferred case ('Preferred over a full asset passwords scan for a slug lookup') and the exclusions ('Do not use it to enumerate or to page... call hudu_search or hudu_get_asset_password for that'). When-to-use, when-not-to-use and the alternative are all explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_find_websites_by_slugFind Websites By SlugA
Read-only

Find one website by its URL slug. Preferred over a full websites scan for a slug lookup. Returns one record: a compact WebsiteSummary (code, message, keyword, … dropped); expand: true returns the full Website. Bounded: limit default 25, max 100; the client scan stops at 500 records / 4 pages (RESOLUTION_TRUNCATED, never a partial answer). Do not use it to enumerate or to page: it returns at most one exact match (call hudu_search or hudu_get_website for that).

ParametersJSON Schema
NameRequiredDescriptionDefault
optsNo
slugYesExact slug of the website.

Output Schema

ParametersJSON Schema
NameRequiredDescription
foundYes
recordYes

TDQS

A4.8/5.0
Behavior5/5

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

With readOnlyHint/openWorldHint already declaring the safety profile, the description still adds substantial behavioral context: return shape (compact WebsiteSummary vs full Website on expand), bounding (limit default 25 / max 100), truncation semantics (client scan stops at 500 records / 4 pages, RESOLUTION_TRUNCATED, 'never a partial answer'). This is well beyond what the annotations convey.

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

Conciseness4/5

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

Front-loaded with the core purpose, then routing guidance, then bounding constraints. Sentences are dense but every one carries signal; the parenthetical '(code, message, keyword, … dropped)' and some punctuation-heavy clauses add minor friction but no real waste.

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

Completeness5/5

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

For a bounded singleton lookup with an output schema available, the description covers return cardinality, return shape variants, truncation behavior, and sibling routing. Given the output schema already documents return values, nothing an agent needs to call this correctly is missing.

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

Parameters4/5

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

Schema coverage is 50%, and the description adds meaning to 'expand' by contrasting the compact WebsiteSummary return with the full Website. The slug parameter's exact-match semantics largely duplicate the schema text, and the nested 'opts' object is not fully elaborated, so it stops short of fully compensating for the coverage gap.

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

Purpose5/5

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

States a specific verb and resource with scope: 'Find one website by its URL slug.' It immediately implies the singleton lookup nature ('one website'), distinguishing it from the bulk siblings. An agent can tell what it returns and at what cardinality 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.

Usage Guidelines5/5

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

Explicitly positions itself against alternatives: 'Preferred over a full websites scan for a slug lookup' and then names the exclusions 'Do not use it to enumerate or to page... call hudu_search or hudu_get_website for that.' Both when-to-use and when-not-to-use with named fallbacks are present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_get_api_infoGet Api InfoA
Read-only

Return the API information document. Prefer api_info.get; this exists so every resource satisfies the same floor. Bounded: limit default 25, max 100; the client scan stops at 500 records / 4 pages (RESOLUTION_TRUNCATED, never a partial answer). Not for text discovery: call hudu_search.

ParametersJSON Schema
NameRequiredDescriptionDefault
optsNo
identifierNoOptional identifier; omit it for the tenant-wide api info.

Output Schema

ParametersJSON Schema
NameRequiredDescription
foundYes
recordYes

TDQS

A4.1/5.0
Behavior5/5

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

With readOnlyHint/openWorldHint already covering safety, the description adds substantive behavioral detail beyond the annotations: default limit 25, max 100, a hard client scan ceiling of 500 records / 4 pages, and explicit semantics that truncation surfaces as RESOLUTION_TRUNCATED rather than a partial answer. This is meaningful operational disclosure.

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

Conciseness4/5

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

Front-loaded with the core action and tightly written across three sentences with no filler. Some phrasing ('satisfies the same floor') is internal jargon an agent may not parse, but the structure is efficient.

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

Completeness4/5

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

An output schema exists, so return values need not be explained, and the description covers bounding, truncation, and routing. For a read-only, no-required-param tool this is largely sufficient, though the unresolved 'limit' and 'api_info.get' references leave minor ambiguity.

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

Parameters3/5

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

Schema coverage is 50%, so the schema documents 'identifier' and 'opts.expand' reasonably well. The description adds bounding info but references a 'limit' parameter that does not appear in the visible schema, and says nothing about what 'expand' or the identifier forms do — so it neither clarifies the real params nor cleanly compensates for the coverage gap.

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

Purpose4/5

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

States a clear verb+resource: 'Return the API information document.' It further differentiates from the sibling hudu_search ('Not for text discovery'). However, the reference to 'api_info.get' as the preferred route is ambiguous since no such sibling is listed, slightly muddying what the tool's unique role is.

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

Usage Guidelines4/5

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

Gives an explicit exclusion ('Not for text discovery: call hudu_search') and names an alternative ('Prefer api_info.get'), which is exactly the when/when-not guidance an agent needs. The alternative is not in the sibling set, though, so the routing advice is only partially actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_get_article_contextGet Article ContextA
Read-only

Fetch an article with its company and folder context. Preferred over three separate calls when an agent starts from an article. Returns ArticleContext. Bounded: every sub-list uses limit (default 25, max 100) — no sub-fetch walks the account. Not for paging: call hudu_search. Context depends on the resources available to this deployment; a refused credential answers UNAUTHORIZED (401, "Bad credentials") like every other tool, and any other failure keeps its real code — never partial results.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesNumeric article id (hudu_get_article_context takes the id; use hudu_search or hudu_read / hudu_write / hudu_delete with articles.resolve to find it).
optsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
contextYes

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the readOnlyHint/openWorldHint annotations, the description discloses bounding behavior (every sub-list uses limit, default 25, max 100; no sub-fetch walks the account), the error contract (401 UNAUTHORIZED 'Bad credentials' for refused credentials, real codes otherwise), and the all-or-nothing guarantee ('never partial results'). These are exactly the operational traits annotations cannot convey.

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

Conciseness4/5

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

Tight, front-loaded, and every clause carries information (scope, preference, bounds, error behavior, exclusions). It is dense to the point of a slightly run-on error-semantics sentence, but there is no filler.

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

Completeness4/5

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

For a nested-context tool with an output schema, the description covers scope, bounds, failure modes, and alternatives adequately; the output schema handles return values. The one gap is the referenced 'limit' that has no corresponding schema field, which could confuse an agent about how to control sub-list size.

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

Parameters4/5

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

Schema coverage is only 50%, so the description must compensate, and it does add the per-sublist limit semantics (default 25, max 100) that appear nowhere in the schema. However, this 'limit' is not exposed in the input schema at all, leaving it ambiguous whether/how an agent can set it, which caps the score below 5.

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

Purpose5/5

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

States a specific verb and resource ('Fetch an article with its company and folder context') and names the return type (ArticleContext). It explicitly distinguishes itself from sibling patterns by declaring itself preferred over 'three separate calls' and routing paging to hudu_search, so an agent can place it among hudu_list_articles / hudu_get_company_context without opening schemas.

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

Usage Guidelines5/5

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

Gives an explicit when: 'when an agent starts from an article,' plus an explicit when-not: 'Not for paging: call hudu_search,' and names the alternative it replaces (three separate calls). This is prescriptive routing rather than implied context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_get_asset_contextGet Asset ContextA
Read-only

Fetch an asset with the context an agent needs about it. Preferred over four separate calls when an agent starts from an asset. Returns AssetContext. Bounded: every sub-list uses limit (default 25, max 100) — no sub-fetch walks the account. Not for paging: call hudu_search. Context depends on the resources available to this deployment; a refused credential answers UNAUTHORIZED (401, "Bad credentials") like every other tool, and any other failure keeps its real code — never partial results.

ParametersJSON Schema
NameRequiredDescriptionDefault
optsNo
identifierYesId, name, slug, primary serial or { id, companyId }.

Output Schema

ParametersJSON Schema
NameRequiredDescription
contextYes

TDQS

A4.6/5.0
Behavior5/5

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

Goes well beyond the readOnlyHint/openWorldHint annotations: it discloses the bounding contract (every sub-list uses limit, no sub-fetch walks the account), the error semantics (refused credential -> UNAUTHORIZED 401 with a specific message; other failures keep their real code) and the no-partial-results guarantee. This is exactly the kind of trait an agent cannot recover from structured fields.

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

Conciseness4/5

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

Front-loaded with purpose, then routing, then the bound and error contract, with each sentence carrying distinct information. The final sentence is information-dense but every clause (401, other codes, no partial results) earns its place; 'Returns AssetContext' is the one mild redundancy given an output schema exists.

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

Completeness5/5

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

For a composite read tool with a rich nested identifier schema, an output schema, and annotations, the description covers everything an agent still needs: scope of the fan-out, the limit bound, routing vs. hudu_search, and failure semantics. Return-value documentation is correctly delegated to the output schema.

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

Parameters3/5

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

Schema coverage is 50%, and the description's parameter content (limit default 25, max 100) largely restates what the schema and its 'CONFIG_ERROR' note already say. It adds no guidance on what the identifier forms resolve to or what 'expand' changes, so it neither compensates for the coverage gap nor exceeds the schema.

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

Purpose5/5

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

Specific verb+resource ('Fetch an asset with the context an agent needs') and it explicitly frames itself against a known alternative ('Preferred over four separate calls when an agent starts from an asset'). It also names the exact sibling it is not ('Not for paging: call hudu_search'), so an agent can distinguish it from get_company_context/get_article_context 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.

Usage Guidelines5/5

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

Gives an explicit triggering condition ('when an agent starts from an asset'), an explicit exclusion ('Not for paging: call hudu_search'), and states the alternative it replaces (four separate calls). Nothing about when/when-not is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_get_asset_layoutGet Asset LayoutA
Read-only

Resolve an asset layout from an id, name or slug. Use when the identifier is a layout name or slug; asset_layouts.get is cheaper for a known id. Returns one record: a compact AssetLayoutSummary (icon_color, sidebar_folder_id, include_passwords, … dropped); expand: true returns the full AssetLayout. Bounded: limit default 25, max 100; the client scan stops at 500 records / 4 pages (RESOLUTION_TRUNCATED, never a partial answer). Not for text discovery: call hudu_search.

ParametersJSON Schema
NameRequiredDescriptionDefault
optsNo
identifierYesId, exact name/slug, or an identifier object.

Output Schema

ParametersJSON Schema
NameRequiredDescription
foundYes
recordYes

TDQS

A4.5/5.0
Behavior5/5

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

With annotations already covering safety (readOnlyHint) and open-world scope, the description still adds substantial behavioral context: compact vs. full return shape, expand semantics, and precise bounding behavior (limit default 25/max 100, scan capped at 500 records/4 pages, RESOLUTION_TRUNCATED rather than a partial answer).

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

Conciseness4/5

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

Front-loaded with purpose then usage then return/bounds/alternatives, and every clause carries information. It is dense and semicolon-heavy, running several concerns into one compound sentence, which slightly reduces readability.

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

Completeness5/5

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

For a read tool with an output schema and safety annotations, the definition covers everything an agent needs: resolution semantics, return shape, a documented truncation boundary, and routing to hudu_search. Nothing material is missing.

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

Parameters4/5

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

Schema coverage is 50%, but the description compensates by explaining the identifier's role (resolution from name/slug vs. id) and what opts.expand true/false yields. It enriches the sparse schema (opts carries no description) without fully documenting every identifier-object key (domain, external_id) beyond what the schema shows.

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

Purpose4/5

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

States a specific verb+resource ("Resolve an asset layout") and enumerates accepted identifier forms (id, name, slug). It distinguishes itself from hudu_search ("not for text discovery") and from a cheaper direct-id path, though the latter ("asset_layouts.get") is an operation name rather than a listed sibling tool, slightly muddying differentiation.

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

Usage Guidelines5/5

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

Gives explicit when-to-use ("when the identifier is a layout name or slug") and when-not ("asset_layouts.get is cheaper for a known id"; "Not for text discovery: call hudu_search"). Both an alternative and the selecting condition are named, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_get_company_contextGet Company ContextA
Read-only

Fetch a company together with the bounded context an agent needs about it. Preferred over four separate list calls when an agent starts work on a company. Returns CompanyContext. Bounded: every sub-list uses limit (default 25, max 100) — no sub-fetch walks the account. Not for paging: call hudu_search. Context depends on the resources available to this deployment; a refused credential answers UNAUTHORIZED (401, "Bad credentials") like every other tool, and any other failure keeps its real code — never partial results.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesNumeric company id.
optsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
contextYes

TDQS

A4.6/5.0
Behavior5/5

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

Beyond the readOnlyHint/openWorldHint annotations, it discloses that every sub-list is bounded by limit (default 25, max 100), that no sub-fetch walks the account, that results are never partial, and that a refused credential answers UNAUTHORIZED 401 while other failures preserve their real code. This is rich behavioral context that the annotations do not carry.

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

Conciseness4/5

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

Dense but well-ordered: purpose, preference, bounding rule, exclusion, then error semantics. Each sentence carries weight, though the error-handling sentence is long and slightly digressive for a selection-oriented description.

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

Completeness5/5

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

An output schema exists, so return-value detail is unnecessary, and the description still covers bounds, failure semantics, and routing. For a nested-object tool with a 50%-documented schema, nothing an agent needs to invoke it correctly is missing.

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

Parameters3/5

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

Schema coverage is 50%. The description reiterates limit's default/max (already in the schema) and adds the useful nuance that the bound applies to every sub-list, but it never addresses the 'expand' option or the meaning of 'id' input. It only partially compensates for the coverage gap, so a baseline 3 is right.

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

Purpose5/5

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

States a specific verb (Fetch) and resource (a company plus its bounded context), and explicitly differentiates itself from siblings: 'Preferred over four separate list calls' and 'Not for paging: call hudu_search.' An agent can select it 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.

Usage Guidelines5/5

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

Gives explicit when-to-use ('when an agent starts work on a company'), when-not ('Not for paging'), and names the alternative ('call hudu_search'). Routing guidance is complete and unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_get_folderGet FolderA
Read-only

Resolve a folder from an id or name, optionally scoped to a company. Use when the identifier is a folder name; folders.get is cheaper for a known id. Returns one record: a compact FolderSummary (description, created_at, … dropped); expand: true returns the full Folder. Bounded: limit default 25, max 100; the client scan stops at 500 records / 4 pages (RESOLUTION_TRUNCATED, never a partial answer). Not for text discovery: call hudu_search.

ParametersJSON Schema
NameRequiredDescriptionDefault
optsNo
identifierYesId, exact name/slug, or an identifier object.

Output Schema

ParametersJSON Schema
NameRequiredDescription
foundYes
recordYes

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered; the description still adds substantive behavior: the compact FolderSummary vs full Folder under expand, and truncation semantics (scan stops at 500 records / 4 pages, RESOLUTION_TRUNCATED, never a partial answer). Minor gap: it cites 'limit default 25, max 100' but no limit parameter appears in the schema, which could mislead about how to bound the call.

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

Conciseness5/5

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

Four dense sentences, front-loaded with the core action and each subsequent clause carrying routing or behavioral information. No filler; the telegraphic style is intentional and readable.

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

Completeness5/5

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

Output schema exists, so return values need not be fully specified, yet the description still characterizes the response shape and expansion behavior. Combined with bounds, truncation reporting, and sibling routing, nothing an agent needs to call this correctly is missing.

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

Parameters4/5

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

Schema coverage is 50%, and the description compensates by explaining that identifier can be an id or a name and that expand:true upgrades the return from summaries to full records. This adds meaning beyond the schema for the two real parameters, though it does not clarify the slug/domain/external_id identifier branches the schema hints at.

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

Purpose5/5

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

States a specific verb+resource ('Resolve a folder') plus the accepted identifier forms and optional company scoping. It explicitly distinguishes itself from folders.get (known id) and hudu_search (text discovery), so an agent can route correctly 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.

Usage Guidelines5/5

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

Gives an explicit selection rule ('use when the identifier is a folder name'), names the cheaper alternative for a known id (folders.get), and states an exclusion ('not for text discovery: call hudu_search'). Both the positive and negative cases are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_get_groupGet GroupA
Read-only

Resolve a user group from an id, name or slug. Use when the identifier is a group name; groups.get is cheaper for a known id. Returns one record: a compact GroupSummary (url, created_at, members, … dropped); expand: true returns the full Group. Bounded: limit default 25, max 100; the client scan stops at 500 records / 4 pages (RESOLUTION_TRUNCATED, never a partial answer). Not for text discovery: call hudu_search.

ParametersJSON Schema
NameRequiredDescriptionDefault
optsNo
identifierYesId, exact name/slug, or an identifier object.

Output Schema

ParametersJSON Schema
NameRequiredDescription
foundYes
recordYes

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare read-only and open-world behavior, but the description adds important operational details: bounded scanning, limit defaults and caps, RESOLUTION_TRUNCATED, and the guarantee of never returning a partial answer. These are substantive behavioral traits beyond the structured annotations.

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

Conciseness5/5

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

The description is dense but front-loaded: resolution purpose first, routing guidance second, return and bound behavior third. Every sentence adds operational value, and there is no redundant restatement of the name or title.

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

Completeness5/5

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

Given the output schema exists, the description need not explain return values, but it still clarifies compact vs expanded results and truncation behavior. Combined with annotations and schema, an agent has enough context to invoke the tool correctly in the intended cases.

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

Parameters4/5

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

Schema description coverage is 50%, and the description adds useful meaning for identifier resolution (id, name, or slug) and expand: true returning the full Group. It also mentions a limit cap that is not present in the provided schema, which creates minor ambiguity, so it falls short of fully compensating for the coverage gap.

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

Purpose5/5

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

States a specific verb and resource: resolve a user group from an id, name, or slug. It distinguishes itself from siblings by naming groups.get for known ids and hudu_search for text discovery, so an agent can route correctly without opening schemas.

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

Usage Guidelines5/5

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

Explicitly says when to use it: when the identifier is a group name. It also names alternatives and exclusions: groups.get is cheaper for a known id, and it is not for text discovery — call hudu_search. This is complete routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_get_password_folderGet Password FolderA
Read-only

Resolve a password folder from an id or name, optionally scoped to a company. Use when the identifier is a folder name; password_folders.get is cheaper for a known id. Returns one record: a compact PasswordFolderSummary (description, allowed_groups, created_at, … dropped); expand: true returns the full PasswordFolder. Bounded: limit default 25, max 100; the client scan stops at 500 records / 4 pages (RESOLUTION_TRUNCATED, never a partial answer). Not for text discovery: call hudu_search. Sensitive: returns credential-shaped fields; the SDK masks them in results by default and always in diagnostics.

ParametersJSON Schema
NameRequiredDescriptionDefault
optsNo
identifierYesId, exact name/slug, or an identifier object.

Output Schema

ParametersJSON Schema
NameRequiredDescription
foundYes
recordYes

TDQS

A4.8/5.0
Behavior5/5

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

Goes well beyond the readOnlyHint/openWorldHint annotations: discloses pagination bounds (limit default 25, max 100), scan cutoff behavior (500 records/4 pages, RESOLUTION_TRUNCATED, 'never a partial answer'), and sensitivity (credential-shaped fields masked by default in results, always in diagnostics). This is exactly the behavioral context annotations don't carry.

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

Conciseness4/5

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

Front-loads the purpose, then when-to-use, return shape, bounds, exclusions and sensitivity in a tight sequence; every clause earns its place. It is dense and semicolon-heavy with some cryptic parentheticals (e.g., '… dropped'), which slightly hurts readability.

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

Completeness5/5

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

For a resolution tool with hidden bounds and sensitive fields, the description covers selection, truncation limits, masking, and expansion – despite an output schema existing, it still clarifies summary-vs-full behavior. Nothing an agent needs to call it correctly is missing.

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

Parameters4/5

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

Schema coverage is 50%, and the description compensates by clarifying identifier form usage (name vs id) and the expand toggle ('expand: true returns the full PasswordFolder'). However, 'optionally scoped to a company' is not reflected in any schema parameter, leaving a small ambiguity.

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

Purpose5/5

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

States a specific verb+resource ('Resolve a password folder from an id or name') and defines scope precisely. It explicitly contrasts itself with the sibling password_folders.get ('cheaper for a known id'), so an agent can route correctly. Purpose is unambiguous.

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

Usage Guidelines5/5

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

Gives explicit when-to-use conditions ('Use when the identifier is a folder name') and names the cheaper alternative for the id case. It also states an exclusion: 'Not for text discovery: call hudu_search.' This is textbook alternative-aware guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_list_articlesList ArticlesA
Read-only

List ONE bounded page of knowledge-base articles, backed by the fixed operation articles.list. Returns at most page_size rows plus whether more exist; it never pages through the tenant. This tool takes no operation argument and cannot be redirected to a write. Prefer hudu_search to find an article by text, and hudu_get_article_context to read one. This is the ungated path for the articles.list read; use it rather than the approval-gated hudu_read / hudu_write / hudu_delete.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoExact or partial article name.
pageNoPage number to fetch (1-based, default 1). This tool returns that one page and never follows it.
slugNoExact article slug.
draftNotrue for drafts, false for published articles.
searchNoFree-text search within articles.
page_sizeNoRows per page (1-100, default 25). The registry record caps a page at 100; a larger value is refused, never clamped.
company_idNoOnly articles belonging to this company id.
updated_atNoISO 8601; only articles updated at or after it.
enable_sharingNoOnly articles with sharing enabled/disabled.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
rowsYes
countYes
has_moreYes
page_sizeYes

TDQS

A4.6/5.0
Behavior5/5

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

Beyond the readOnlyHint annotation, it discloses that it returns at most page_size rows plus a has-more flag, never auto-pages the tenant, accepts no operation argument, and cannot be redirected to a write. It also flags the gated/ungated distinction relative to hudu_read/hudu_write/hudu_delete, which is real operational context.

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

Conciseness4/5

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

Front-loads the core behavior (bounded page, fixed operation) before routing advice, and each sentence carries actionable content. It is somewhat dense across five sentences, but nothing is pure filler.

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

Completeness5/5

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

With an output schema present and annotations covering the safety profile, the description only needs to cover scope, paging semantics, and routing – all of which it does. Nothing an agent needs to invoke it correctly is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so all 9 parameters are already documented in the schema. The description echoes page_size behavior ('returns at most page_size rows') but adds no syntax or format detail beyond the schema. Baseline 3 is appropriate.

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

Purpose5/5

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

States a specific verb (List) and resource (knowledge-base articles) with explicit scope: one bounded page backed by the fixed operation articles.list. It also names the siblings it is not (hudu_search, hudu_get_article_context), so an agent can distinguish it 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.

Usage Guidelines5/5

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

Gives explicit routing: prefer hudu_search for text lookup, hudu_get_article_context to read a single article, and use this tool rather than the approval-gated hudu_read/hudu_write/hudu_delete. Both when-to-use and when-to-use-something-else are stated plainly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_list_asset_layoutsList Asset LayoutsA
Read-only

List ONE bounded page of asset layouts, backed by the fixed operation asset_layouts.list. The vendor endpoint honours page but ignores page_size, so a page is the vendor’s own size and is returned whole; page N is always the vendor’s Nth page, so walking page never skips rows. has_more is conservative (true for any non-empty page); stop when a page comes back empty. This tool takes no operation argument and cannot be redirected to a write. Use the name or slug filter to find a layout; asset_layouts is not searchable, so hudu_search cannot return one. Prefer hudu_get_asset_layout to read one layout in full by name or slug. This is the ungated path for the asset_layouts.list read; use it rather than the approval-gated hudu_read / hudu_write / hudu_delete.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoExact or partial asset layout name.
pageNoPage number to fetch (1-based, default 1). This tool returns that one page and never follows it.
slugNoExact asset layout slug.
activeNotrue for active layouts, false for archived ones.
updated_atNoISO 8601; only layouts updated at or after it.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
rowsYes
countYes
has_moreYes
page_sizeYes

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only cover readOnlyHint and openWorldHint, but the description adds substantial non-obvious behavior: the vendor honours page but ignores page_size, page N is always the vendor's Nth page so walking never skips rows, has_more is conservative (true for any non-empty page), and you stop when a page comes back empty. It also confirms the tool takes no operation argument and cannot be redirected to a write, which the annotations do not state.

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

Conciseness5/5

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

Front-loaded with the core purpose, then pagination mechanics, then filters, then the alternative, then the gating rationale. Despite its length, every sentence carries distinct information (no restatement of the name or title), so nothing reads as filler.

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

Completeness5/5

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

An output schema exists, so return-shape details are not needed here. For a zero-required-parameter list tool with sibling overlap, the description supplies the pagination contract, filter guidance, the alternative read tool, and the gating distinction — everything an agent needs to call it correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all five parameters, and the baseline is 3. The description reinforces page semantics (one page, never followed) but adds little beyond what the schema's own page description already provides, and says nothing extra about name/slug/active/updated_at beyond the schema.

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

Purpose5/5

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

States a specific verb and resource ('List ONE bounded page of asset layouts') and pins the backing operation (asset_layouts.list). It explicitly distinguishes itself from siblings by naming hudu_get_asset_layout, hudu_search, and the gated hudu_read/hudu_write/hudu_delete, so an agent can route 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.

Usage Guidelines5/5

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

Gives explicit when-to-use ('use the name or slug filter to find a layout'), when-to-use-something-else ('Prefer hudu_get_asset_layout to read one layout in full'), and the exclusion that asset_layouts is not searchable so hudu_search cannot return one. It also names the ungated path as the reason to prefer this over the approval-gated siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_list_assetsList AssetsA
Read-only

List ONE bounded page of assets across all companies, backed by the fixed operation assets.listAcrossCompanies. Returns at most page_size rows plus whether more exist; it never pages through the tenant. The operation is page-paginated by the vendor (page and page_size are sent upstream), so later pages are reachable by raising page. This tool takes no operation argument and cannot be redirected to a write. Filter by company_id, primary_serial, asset_layout_id or search. Prefer hudu_get_asset_context to read one asset in full, and hudu_search to find one by text. This is the ungated path for both assets.listAcrossCompanies and the company-scoped assets.list read (filter by company_id); use it rather than the approval-gated hudu_read / hudu_write / hudu_delete.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoExact asset id.
nameNoExact or partial asset name.
pageNoPage number to fetch (1-based, default 1). This tool returns that one page and never follows it.
slugNoExact asset slug.
searchNoFree-text search within assets.
archivedNotrue for archived assets, false for active ones.
page_sizeNoRows per page (1-100, default 25). The registry record caps a page at 100; a larger value is refused, never clamped.
company_idNoOnly assets belonging to this company id.
updated_atNoISO 8601; only assets updated at or after it.
primary_serialNoAsset primary serial.
asset_layout_idNoOnly assets using this asset layout id.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
rowsYes
countYes
has_moreYes
page_sizeYes

TDQS

A4.6/5.0
Behavior5/5

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

Annotations only declare readOnlyHint and openWorldHint; the description adds substantial non-obvious behavior: it returns exactly one page and never pages through the tenant, pagination is vendor-side with later pages reached by raising page, the tool takes no operation argument, and it cannot be redirected to a write. It also notes page_size above the cap is refused rather than clamped.

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

Conciseness4/5

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

Front-loaded with the scope and bounding constraint, and every sentence carries information about pagination, filters, or routing. It is somewhat dense and longer than strictly necessary, but there is little filler.

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

Completeness5/5

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

An output schema exists, so return values need not be explained beyond the note that it returns at most page_size rows plus a more-exists flag. Combined with full parameter documentation, annotations, and explicit sibling routing, nothing needed to call it correctly is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so all 11 parameters are already documented in the schema. The description restates the filter set (company_id, primary_serial, asset_layout_id, search) without adding format or syntax meaning beyond it, so the baseline 3 applies.

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

Purpose5/5

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

States a specific verb, resource, and scope: 'List ONE bounded page of assets across all companies'. It explicitly names the backing operation and distinguishes itself from siblings by naming hudu_get_asset_context and hudu_search as the tools for other needs.

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

Usage Guidelines5/5

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

Gives explicit routing: prefer hudu_get_asset_context to read one asset in full, hudu_search to find one by text, and use this ungated path rather than approval-gated hudu_read / hudu_write / hudu_delete. It also identifies the filter dimensions that select this tool (company_id, primary_serial, asset_layout_id, search).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_list_companiesList CompaniesA
Read-only

List ONE bounded page of companies, backed by the fixed operation companies.list. Returns at most page_size rows plus whether more exist; it never pages through the tenant. This tool takes no operation argument and cannot be redirected to a write. Prefer hudu_search or hudu_resolve_any to identify a single company, and hudu_get_company_context to read one. This is the ungated path for the companies.list read; use it rather than the approval-gated hudu_read / hudu_write / hudu_delete.

ParametersJSON Schema
NameRequiredDescriptionDefault
cityNoCompany city.
nameNoExact or partial company name.
pageNoPage number to fetch (1-based, default 1). This tool returns that one page and never follows it.
slugNoExact company slug.
stateNoCompany state.
searchNoFree-text search within companies.
websiteNoCompany website.
id_numberNoCompany id number.
page_sizeNoRows per page (1-100, default 25). The registry record caps a page at 100; a larger value is refused, never clamped.
updated_atNoISO 8601; only companies updated at or after it.
phone_numberNoCompany phone number.
id_in_integrationNoVendor-side integration id.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
rowsYes
countYes
has_moreYes
page_sizeYes

TDQS

A4.6/5.0
Behavior5/5

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

Annotations only declare readOnlyHint and openWorldHint, but the description adds real behavioral context: returns at most page_size rows plus a 'more exist' flag, never pages through the tenant, takes no operation argument, cannot be redirected to a write, and is the ungated path versus approval-gated siblings. That is a substantive complement to 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.

Conciseness4/5

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

Front-loaded with the scope and pagination constraint before the routing advice; every sentence carries routing or behavioral information. It is slightly redundant, restating the no-paging constraint that the page/page_size field descriptions also cover.

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

Completeness5/5

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

With an output schema present, return values need no elaboration, and the description still covers the mutation-non-redirectability, gating model, and sibling routing. An agent has everything needed to select and invoke this correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all 12 parameters with types, defaults, and bounds. The description reinforces the page/page_size semantics (one page, cap refusal) but adds no filter syntax or values beyond what the schema states, so the baseline 3 applies.

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

Purpose5/5

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

States a specific verb and resource with scope: 'List ONE bounded page of companies, backed by the fixed operation companies.list', and explicitly frames it as a single-page, non-paginating read. This lets an agent distinguish it from hudu_search, hudu_resolve_any, and hudu_get_company_context 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.

Usage Guidelines5/5

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

Names alternatives and the conditions that select them: 'Prefer hudu_search or hudu_resolve_any to identify a single company, and hudu_get_company_context to read one.' It also routes the agent away from the approval-gated hudu_read / hudu_write / hudu_delete, which is an explicit when-not.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_list_operationsDiscover Operations (Catalog)A
Read-only

List the operations the Hudu SDK implements, with the tool that exposes each one (when it has one), its effect, whether it needs a dry run or a confirmation flag, and the arguments it requires. The tool list on this server is a SUBSET: this is a curated core profile, and the catalog is how you discover a capability that has no tool of its own — find the row, call hudu_describe_operation for the exact schema, then hudu_read/hudu_write/hudu_delete. Rows with no "tool" are reachable only through hudu_read/hudu_write/hudu_delete. Rows with "reachable": false are deliberately not callable here and state why (an unbounded read, or a binary/download surface). Bounded: limit defaults to 40 and is hard-capped at 100, offset pages through the rest; the whole catalog is ~10k tokens, so ask for a filter or a page rather than dumping it.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoRows per page (1-100, default 40); the whole catalog is ~10k tokens, so page it.
effectNoOnly rows with this effect.
offsetNoRow offset, for paging.
resourceNoOnly rows of this registry resource (e.g. "assets").
unexposed_onlyNoOnly rows with NO tool of their own — the capabilities reachable only through hudu_read / hudu_write / hudu_delete.

Output Schema

ParametersJSON Schema
NameRequiredDescription
rowsYes
limitYes
offsetYes
matchedYes
has_moreYes
total_operationsYes
reachable_operationsYes
unexposed_operationsYes
unreachable_operationsYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only cover readOnlyHint and openWorldHint; the description adds substantial behavioral context: why certain rows are deliberately uncallable (unbounded reads, binary/download surfaces), the reachability rules, and the hard cap of 100 with a ~10k-token catalog cost. This is exactly the extra context annotations cannot express.

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

Conciseness4/5

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

Front-loads the purpose, then the workflow, then the edge cases and paging constraints; each sentence carries information. It is dense and slightly run-on, but no sentence is filler, so it stays efficient rather than padded.

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

Completeness5/5

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

An output schema exists, so return values need not be explained. Given that, the description covers everything an agent needs: what the catalog contains, how to act on a row, which rows are unreachable and why, and the paging/token budget.

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

Parameters4/5

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

Schema description coverage is 100%, so the schema already documents limit, offset, effect, resource, and unexposed_only, making 3 the baseline. The description goes further by explaining the operational rationale behind paging (hard-capped at 100, whole catalog ~10k tokens) and why to prefer a filter or a page over a full dump.

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

Purpose5/5

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

States a specific verb and resource ('List the operations the Hudu SDK implements') and immediately narrows the payload to the tool mapping, effect, dry-run/confirmation needs, and required arguments. It also positions itself against siblings by calling out that the tool list is a curated subset and that this catalog covers capabilities with no tool of their own.

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

Usage Guidelines5/5

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

Gives an explicit discovery workflow: find the row, call hudu_describe_operation for the exact schema, then hudu_read/hudu_write/hudu_delete. It names the conditions that select alternatives (rows with no 'tool' are reachable only via the generic verbs; 'reachable: false' rows are not callable) and even advises filtering/paging instead of dumping.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_readDispatch read operationA
Read-only

Execute only read operations by canonical registry key. input is a CLOSED per-operation contract (issues #70/#72): exactly the operation's declared fields - unknown fields are refused before any request (typed CONFIG_ERROR names the valid fields); the per-operation field table, types, vendor picklists and guidance notes are in the served input schema and in hudu_describe_operation (the same contract, zero wire cost). Runtime effect enforcement precedes SDK validation and HTTP. Reads have no dry run. Neither preview nor confirm is human consent: the host must enforce its own approval policy. Results mask credentials and asset custom fields by default.

ParametersJSON Schema
NameRequiredDescriptionDefault
inputNoThe operation arguments as one object; validated against the registry record before any request. The field contract is closed: an unknown top-level field is a typed CONFIG_ERROR naming the accepted fields, which hudu_describe_operation serves as input_contract.
operationYesCanonical operation key (see hudu_list_operations). Exact registry key, never a tool name.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes
operationYes
simulatedYes

TDQS

A3.8/5.0
Behavior5/5

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

Goes well beyond the annotations: closed-contract validation with a typed CONFIG_ERROR naming valid fields before any request, enforcement ordering (effect checks precede SDK validation and HTTP), no dry run for reads, preview/confirm explicitly not counting as human consent with the approval burden placed on the host, and default masking of credentials and asset custom fields. This is exactly the behavioral context annotations cannot carry.

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

Conciseness3/5

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

Front-loaded with the purpose, which is good, but the body is a dense multi-clause block that mixes issue references ('issues #70/#72') and repeated closed-contract statements that also live in the schema. Several clauses could be trimmed without losing agent-relevant information.

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

Completeness4/5

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

For a 90-plus-operation dispatcher with an output schema available, the description covers the contract source, validation/error behavior, masking defaults, and approval semantics. It omits only secondary concerns such as pagination or rate limits, which is acceptable given per-operation schemas and a defined output schema.

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

Parameters3/5

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

Schema description coverage is 100%, so both parameters are already documented, including the registry-key semantics of 'operation'. The description largely restates the closed-contract behavior already present in the input schema's description, adding only the enforcement-point detail, so baseline 3 is appropriate.

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

Purpose4/5

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

States a specific verb and resource: 'Execute only read operations by canonical registry key,' which tells an agent this is a generic dispatcher over a fixed operation enum rather than a domain-specific tool. It does not explicitly differentiate itself from siblings like hudu_search or hudu_resolve_any, so it stops short of a 5.

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

Usage Guidelines3/5

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

It points the agent at the served input schema and hudu_describe_operation as the zero-wire-cost way to obtain the per-operation field contract, which is useful routing. However, it never states when to pick this dispatcher over the concrete siblings (hudu_get_company_context, hudu_search, hudu_resolve_any), leaving the choice implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hudu_resolve_anyResolve AnyA
Read-only

Resolve an identifier against several resources and return the candidates that match. Preferred when the caller has an identifier but not the resource type; use the resource's own resolve when the type is known. Returns ResolutionCandidateHit rows for each resource that matched, with scanned/truncated counts; it does not throw RESOLUTION_AMBIGUOUS across resources. Bounded: limit defaults to 25 and is hard-capped at 100; a larger value throws CONFIG_ERROR and is never silently clamped. Do not use it when the resource type is known: call that resource's hudu_get_.

ParametersJSON Schema
NameRequiredDescriptionDefault
optsNo
identifierYesId, exact name/slug, or an identifier object; resolved against every requested resource.

Output Schema

ParametersJSON Schema
NameRequiredDescription
hitsYes
totalYes
scannedYes
truncatedYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so safety is covered. Beyond that the description adds genuinely non-obvious behavior: the return shape (ResolutionCandidateHit rows with scanned/truncated counts), that it deliberately does NOT throw RESOLUTION_AMBIGUOUS across resources, and the hard-cap error semantics (larger than 100 throws CONFIG_ERROR, never silently clamped). Only a richer description of ordering across resources is missing.

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

Conciseness4/5

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

Front-loaded with purpose and the routing rule, followed by return/error semantics. Efficient overall, though the limit-bound sentence partially duplicates text already present in the schema's limit description, which is a small redundancy.

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

Completeness5/5

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

For a nested-object, cross-resource resolver with an output schema, the description covers routing, return semantics, ambiguity behavior, and bound/error handling. Nothing an agent needs to call it correctly is missing, and return-value detail is appropriately delegated to the output schema.

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

Parameters3/5

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

Schema coverage is 50% and the schema already documents both params thoroughly, including the same limit cap/CONFIG_ERROR wording repeated in the description. The description restates the limit bound rather than adding new meaning, and never mentions the resources fan-out parameter at all, so it neither compensates nor extends the schema meaningfully.

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

Purpose5/5

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

States a specific verb (Resolve) and resource (an identifier against several resources) with the concrete outcome (return the candidates that match). It explicitly distinguishes itself from the per-resource resolve alternative, so an agent can tell it apart from siblings like hudu_search and the hudu_get_<singular> family 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.

Usage Guidelines5/5

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

Gives the positive condition (identifier known but resource type unknown), the negative condition (do not use when the resource type is known), and names the alternative to use instead ('call that resource's hudu_get_<singular>'). This is exactly the when/when-not/alternative triad.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 20 tool updatesv0.2.3
    • First observedhudu_describe_operation
    • First observedhudu_fetch_many
    • First observedhudu_find_asset_passwords_by_slug
    • First observedhudu_find_websites_by_slug
    • First observedhudu_get_api_info
    • First observedhudu_get_article_context
    • First observedhudu_get_asset_context
    • First observedhudu_get_asset_layout
    • First observedhudu_get_company_context
    • First observedhudu_get_folder
    • First observedhudu_get_group
    • First observedhudu_get_password_folder
    • First observedhudu_list_articles
    • First observedhudu_list_asset_layouts
    • First observedhudu_list_assets
    • First observedhudu_list_companies
    • First observedhudu_list_operations
    • First observedhudu_read
    • First observedhudu_resolve_any
    • First observedhudu_search

TDQS

A4.1/5.0

Scored across 20 tools

Disambiguation4/5

Most tools have distinct roles, but hudu_read overlaps with hudu_list_* and hudu_fetch_many for read access, and hudu_resolve_any overlaps with the resource-specific resolver tools. The descriptions give preferredWhen guidance, so an agent can usually recover the boundary, but the set is not perfectly crisp.

Naming Consistency4/5

All tools use the hudu_ prefix and snake_case, mostly following hudu_<verb>_<noun> (list_companies, get_asset_layout, find_websites_by_slug). A few generic or suffix forms (hudu_read, hudu_search, hudu_resolve_any, hudu_fetch_many) break the strict verb_noun pattern, but the convention remains readable and predictable.

Tool Count4/5

20 tools is on the heavy side, and several are convenience wrappers around hudu_read (context fetchers, list pages, resolvers). Given Hudu's breadth and the catalog/discovery layer, the count is defensible but slightly over-scoped for a curated MCP surface.

Completeness2/5

Read, search, resolve, context, list, and batch-fetch operations are well covered. However, hudu_write and hudu_delete are referenced throughout the descriptions but are absent from the tool list, leaving mutation and deletion workflows unreachable and creating a significant lifecycle gap for a CRUD-oriented Hudu API server.

Maintenance

ActivityMaintained
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables AI assistants to interact with Hudu IT documentation, providing tools for companies, assets, knowledge base articles, credentials, IPAM, racks, and more, with security gates for passwords and destructive operations.
    70
    13 npm
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    A Model Context Protocol server for querying and reading articles from a how-to documentation portal, with search and retrieval tools scoped to the token's user permissions.
    3
    2 npm
    Apache 2.0