AIR MCP Server
Connect AI assistants to AIR (AI Responsibly) to discover projects, upload evidence, run governed risk assessments, and retrieve structured reports.
Discover domains, projects, documents, artifacts, and assessments.
Create projects, search orgs/domains/projects, record decisions, and view domain portfolio dashboards.
Upload documents via presigned URLs and wait for extraction.
Start, retry, or draft risk assessments; consumes organization credits.
Poll long-running jobs with MCP Tasks wait tools; retrieve reports, stages, and input artifacts.
Run composite workflows from a local file or existing artifacts.
Create an AIR account in-chat, submit feedback, request/check credits, and sign out on stdio.
Access resources for reports/stages/project assessments and prompts for workflow guidance.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@AIR MCP ServerStart a risk assessment for project 'Photon' using the latest uploaded evidence."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
AIR MCP Server
Connect AI assistants to AIR (AI Responsibly) for governed risk assessments: discover projects, upload evidence, run assessments, and retrieve structured reports — from Cursor, Claude Code, Claude Desktop, VS Code, Windsurf, or any Model Context Protocol client.
This package ships two transports:
Transport | Who uses it | How |
stdio (default) | Local IDE agents (Cursor, Claude Code, VS Code, …) |
|
Streamable HTTP | Claude Directory / remote MCP clients | Hosted at |
Local assessment workloads still execute on Thalus cloud via the AIR Integrator API. For stdio you provide a domain-scoped API key, or let the server store one when you create an account in chat; remote Directory clients authorize through the AIR portal (OAuth). No local database, worker, or Docker stack is required for stdio.
No AIR account? Create one from inside the conversation on the local server or the hosted connector — see Starting without an account.
Overview
┌──────────────────────┐ stdio MCP ┌──────────────────┐ HTTPS ┌─────────────────┐
│ Your IDE / agent │ ◄────────────► │ @thalus-ai/ │ ────────► │ AIR Integrator │
│ (Cursor, Claude, │ │ mcp-air (local) │ │ API (cloud) │
│ VS Code, …) │ └──────────────────┘ └─────────────────┘
└──────────────────────┘Component | Role |
This server | Exposes MCP tools, resources, and prompts; translates agent requests to Integrator API calls |
AIR cloud | Document extraction, risk pipeline, billing, and report generation |
Your API key | Domain-scoped bearer token created in the AIR portal |
Related MCP server: Phantom MCP
Prerequisites
Node.js 20+
An AIR organization with active billing (assessments consume credits) — or create one from the conversation, see Starting without an account
A credential, from any of three sources — see Credentials. None is needed to start: with no credential the server boots in setup mode so you can create an account.
Quick start
1. Create an API key
In the AIR portal: open your domain → API Keys → create a key with the assessmentRunner or fullPipeline preset (see below).
2. Configure your MCP client
Add the server to whichever client you use. All clients run the same npx command; only the config file and JSON root key differ.
Most clients (Cursor, Claude Code, Claude Desktop, Windsurf) — mcpServers:
{
"mcpServers": {
"air": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@thalus-ai/mcp-air@1.3.0"],
"env": {
"AIR_API_KEY": "${env:AIR_API_KEY}"
}
}
}
}VS Code — servers in .vscode/mcp.json (docs):
{
"servers": {
"air": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@thalus-ai/mcp-air@1.3.0"],
"env": {
"AIR_API_KEY": "${env:AIR_API_KEY}"
}
}
}
}Set AIR_API_KEY in your shell, or use envFile where supported. See Client setup for file paths per IDE.
3. Verify
Ask your agent to run air_list_domains and air_list_projects. You should see successful tool calls in the MCP log.
MCP Inspector (optional):
AIR_API_KEY=your-key npx @modelcontextprotocol/inspector npx -y @thalus-ai/mcp-air@1.3.0Remote HTTP (operators)
Hosted endpoint: https://mcp.air.thalus.ai/mcp.
# After build
AIR_API_URL=https://api.air.thalus.ai \
MCP_OAUTH_RESOURCE=https://mcp.air.thalus.ai/mcp \
REDIS_URL=redis://127.0.0.1:6379 \
OAUTH_INTROSPECT_CLIENT_ID=your-resource-server-client-id \
OAUTH_INTROSPECT_CLIENT_SECRET=your-resource-server-client-secret \
MCP_HTTP_PORT=4104 \
node dist/build/http.mjsTwo variables carry this deployment's identity, and both default to production:
Variable | What it sets |
| The upstream API and the protected-resource metadata origin advertised in the |
| This server's own public URL, which access tokens must name as their audience |
Set both when running anywhere other than production. Left at their defaults, a staging or dev server sends clients to production for OAuth discovery and then rejects the tokens they come back with, because the audience never matches.
Deploy notes, Angie, and systemd units live in infra/.
Remote clients authorize with OAuth 2.0 against https://api.air.thalus.ai (authorization code + PKCE S256, dynamic client registration). Discovery starts from the 401 on /mcp, whose WWW-Authenticate header points at https://api.air.thalus.ai/.well-known/oauth-protected-resource. Access tokens must carry https://mcp.air.thalus.ai/mcp as their audience.
End-user setup: Remote MCP server (OAuth).
Starting without an account
Both transports support this. On stdio the server boots in setup mode with no credential; on the remote transport the connector can be added without a token. These tools need no credential:
Tool | What it does |
| Collects name, email, organization, code and terms — in a form or a dialog |
| Sends feedback to Thalus — you are asked for a reply address when you have no account |
| The form's own callbacks; hidden from the model |
| stdio only; clears the stored credential |
On the remote transport, everything else is protected. The first time the assistant calls a protected tool without a token, the server answers HTTP 401 with a WWW-Authenticate challenge, and the client shows its inline Connect card. You authorize in a popup, the client retries the same call automatically, and the conversation carries on — nothing is lost. This is lazy authentication; the alternative, refusing every request until you sign in first, is what made an agent-first signup impossible.
Creating an account in chat:
Ask the assistant to create an AIR account. It calls
air_create_account.Type your name, work email and organization. You type them — the model supplies nothing, and what you type does not enter its context.
Enter the code emailed to you, tick the terms box, and submit. The terms tick is read from the checkbox only; the model cannot set it, and the API refuses without it.
On the remote transport, press the sign-in button: it gives your browser a session, so the OAuth consent screen appears directly next time. On stdio there is nothing more to do — the key is already stored and the full tool set is available.
Your organization starts on the Free plan with one assessment credit per 30 days. Use air_get_credit_balance to see where you stand and air_request_credits to ask for more.
Neither feedback nor a credit request asks the assistant for an email address. Thalus replies to the organization owner, or to an address you type yourself in the confirmation dialog. Only the unauthenticated case needs one from you, because there is no account to reply to.
What your client supports
air_create_account uses the richest input your client offers:
Client capability | What happens |
MCP Apps (Claude Code, Claude, VS Code) | A form renders in the conversation. Fields never reach the model at all. |
Elicitation only | Two dialogs: details, then the code and the terms checkbox. |
Neither | The portal signup link, and it stops. It will not ask the model for your details. |
Credentials
The stdio server resolves a credential in this order, and starts either way:
Order | Source | Notes |
1 |
| Set in your MCP client config. Wins over anything on disk. |
2 |
| Written by |
3 | none → setup mode | Only the tools that work without an account are offered. |
The stored file holds a bearer key, so it is written with mode 0600 (owner read/write only) in a directory created 0700. The key is written straight to that file and never returned in a tool result, so it does not end up in your conversation transcript or your client's logs. Alongside it the file records the API URL, org slug, domain pid, domain slug and creation time, so the server can answer "which account is this?" without a network call.
A damaged or unreadable credential file is reported on stderr and treated as no credential, so the server still starts in setup mode; air_sign_out removes the file.
Setup mode
With no credential, the server offers five tools — air_create_account, air_submit_feedback, air_sign_out, and the signup form's two callbacks. Everything else is registered but disabled, so it is not offered and cannot be called.
The moment an account is created, the key is stored and the full surface is enabled, and the server emits tools/list_changed. No restart is needed — the client sees the tool list grow in place.
Signing out
air_sign_out deletes ~/.air/credentials.json and returns to setup mode. The account itself is untouched; you can sign back in with the same key or create another account.
Signing out forgets the key on this machine — it does not revoke it. The key keeps working anywhere else it is held. If the machine was lost, shared, or is no longer yours, revoke the key itself in the AIR portal: open your domain → API Keys, find the key for the MCP service account, and revoke it there.
If your key came from AIR_API_KEY, there is no file to delete and the tool says so rather than reporting a success: remove the variable from your client configuration and restart. If a stored file also exists, the result tells you that too, since that file would take over once the variable is gone.
Configuration
For stdio you can set AIR_API_KEY, or create an account in the conversation and let the server store one. The server connects to production AIR automatically.
API key scopes
Choose a portal preset when creating your key:
Preset | Use when | Scopes (summary) |
| List domains/projects, start assessments, read reports on existing artifacts |
|
| Upload documents, search, domain portfolio, create projects | Above plus |
Capability | Minimum preset |
|
|
|
|
|
|
|
|
Org-wide portfolio dashboards require a browser session in the portal and are not available via MCP.
Full scope reference: Authentication guide.
Client setup
Client | Config file | Notes |
Cursor |
| Restart after changes |
Claude Code |
| Or: |
Claude Desktop | See platform paths below | Quit and reopen the app |
VS Code |
| Use Copilot Agent mode; root key is |
Windsurf |
| Same |
Other | Your client's MCP docs | Same |
Claude Desktop paths
Platform | Path |
macOS |
|
Windows |
|
Logs (macOS): ~/Library/Logs/Claude/mcp*.log
Full walkthrough: air.thalus.ai/docs/mcp-air-setup
Capabilities
Tools (37 stdio / 34 remote)
Category | Tools |
Discovery |
|
Documents |
|
Assessments |
|
Decisions |
|
Portfolio |
|
Composites |
|
Account |
|
Support |
|
† stdio only ‡ needs no credential § form-only, hidden from the model ¶ stdio only — it exists where a credential file can
The stdio count is one higher than the remote count because air_sign_out manages the local credential file, and the hosted transport has none: there, OAuth is the credential.
air_wait_for_* block with exponential backoff until the resource is ready or timeoutMs elapses, then return ready: false with the last observed status — call again with the same pid to keep waiting. Pipeline tools (air_run_assessment_from_file, air_run_full_assessment_pipeline) use the MCP Tasks extension and return a task handle immediately, so they require a Tasks-capable client.
Surface differences: stdio vs remote
Local capability | Remote equivalent |
Read a local file ( |
|
MCP Tasks ( |
|
Uploads work the same on both surfaces, through the presigned pair. The client must be able to reach the storage host to perform the PUT.
Remote waits are capped at 240s per call (hosted clients abort a tool call at 300s); stdio keeps the longer 10 / 30 minute ceilings.
Uploading to the presigned URL
The presigned URL signs content-type and host only. Send the file bytes with the same contentType you passed to air_upload_document_init and nothing else:
curl -X PUT --upload-file ./model-card.pdf \
-H 'Content-Type: application/pdf' \
"$UPLOAD_URL"Do not add x-amz-* headers. AWS SDKs and aws s3 cp attach x-amz-checksum-crc32 and x-amz-sdk-checksum-algorithm by default; those are not part of the signature and the PUT fails with SignatureDoesNotMatch. With boto3, set AWS_REQUEST_CHECKSUM_CALCULATION=when_required, or use a plain HTTP client.
Reading a large report
A full report can run past what a single tool result can carry, so air_get_assessment_report degrades in steps rather than getting truncated:
Call | You get |
| Overview, quality, EU AI Act tier, per-section counts, saved choices, and what changed since the previous scan |
| The whole report, or a section index if it doesn't fit |
| That one slice |
| A page of a list section, with |
| The raw full report, unsliced |
The section index lists every section with its serialized size and item count, so a caller that overflows can pick deliberately instead of guessing. List sections page automatically: ask for riskRegister and you get as many entries as fit plus a nextOffset to resume from.
Resources (3 templates)
URI pattern | Description |
| Completed assessment report JSON |
| Stage execution log |
| Assessments for a project |
App resource (1)
URI | Description |
| The in-chat signup form, served as |
Prompts (3)
Name | Purpose |
| End-to-end assessment workflow guidance |
| Structured report review |
| Domain portfolio exploration |
Typical workflow
No account yet?
air_create_account(remote transport) — see Starting without an accountair_list_domains→ obtaindomainPidair_list_projects→ obtainprojectPid(orair_create_projectwith fullPipeline)Upload evidence:
air_run_assessment_from_file(stdio), orair_upload_document_init→ PUT →air_upload_document_complete→air_wait_for_document_extractionair_start_assessmentwithartifactPidsfromair_list_artifactsair_wait_for_assessmentair_get_assessment_reportor read theair://assessments/{id}/reportresource
See the Integration flow guide for the underlying HTTP API sequence.
Development
Contributors: see AGENTS.md for build, test, publish, and optional AIR_API_URL override.
git clone https://github.com/VericyIO/mcp-air.git
cd mcp-air && pnpm install && pnpm build
pnpm testDocumentation
Resource | URL |
MCP setup guide | |
Integrator API guides | |
API reference | |
Agent skills (optional) |
Security
The MCP process runs with your OS user privileges. Tools such as
air_run_assessment_from_filecan read any local path your user can access.Pin the package version in production (
@thalus-ai/mcp-air@1.3.0) rather than floating@latest.Use least-privilege API key scopes. Write tools (
air_start_assessment, uploads) consume organization credits.Never commit API keys. Use
envorenvFilein MCP client configuration.
Privacy
The AIR cloud (Thalus) processes the documents, project data, and account information you submit through this server in order to run assessments and generate reports. See the Privacy Policy for details on data collection, usage and storage, third-party sharing, and retention. Contact privacy@thalus.ai with privacy questions.
License
MIT — see LICENSE.
Related repositories
VericyIO/mcp-air — this server (source)
VericyIO/thalus-air-skills — optional agent skills for MCP workflows
Maintainer notes (build, publish, constants sync): see AGENTS.md.
Available Tools
37 toolsair_create_accountCreate an AIR accountADestructive
Open a form in this conversation to create an AIR account. The person types their own details and accepts the terms; the model supplies nothing. Needs no existing account.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the write/destructive/open-world profile, so the bar is lower; the description adds real context annotations cannot express — that a form is rendered in-conversation, the person supplies their own details, and the model contributes nothing. It does not say what happens after the form completes, which holds it back from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short clauses, front-loaded with the action, and every clause carries information the agent needs (mechanism, who supplies data, precondition). No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-param, no-output-schema tool the description is nearly sufficient. The one missing piece is the outcome — whether the tool blocks until the form is submitted, returns a pending handle, or completes synchronously — which matters for an agent orchestrating a conversation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4. The description reinforces this by stating 'the model supplies nothing,' confirming the agent should pass no arguments.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Open a form ... to create an AIR account') and clarifies the mechanism, which is what separates it from sibling create tools like air_create_project. An agent can immediately tell this is an interactive, human-driven flow rather than a data-submitting call.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Needs no existing account' supplies the key precondition for use, which is helpful. However, it gives no explicit alternatives despite the presence of air_signup_send_code and air_signup_verify_code siblings, leaving the agent to infer which account-creation path to pick.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_create_assessment_draftCreate assessment draftADestructive
Create an assessment draft without starting the pipeline. Requires assessments:write.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Display name for the assessment | |
| projectPid | Yes | ||
| artifactPids | Yes | Up to five artifact pids |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true and openWorldHint=true. The description adds two pieces of context the annotations do not carry: that no pipeline is triggered (draft-only side effect) and that assessments:write is required for authorization. It doesn't explain what a draft can subsequently be used for or why a create would be flagged destructive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the differentiating scope constraint ("without starting the pipeline") front-loaded ahead of the permission note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-required-param mutation tool with no output schema, the description covers the essential safety/scope signal and the permission needed, but says nothing about what the created draft returns (e.g. a draft or assessment id) or how the draft moves forward into a run, leaving the lifecycle incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 67%, and the description adds nothing about any of the three parameters (name, projectPid, artifactPids). The undocumented projectPid receives no explanation in either place, so the definition does not compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ("Create an assessment draft") and adds the key scope qualifier "without starting the pipeline," which implicitly separates it from air_start_assessment and air_run_assessment_from_file. It stops short of naming those siblings explicitly, so an agent still has to reason about which to pick.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Without starting the pipeline" hints at when to choose this over a full run, and the permission requirement is stated, but there is no explicit guidance on when a draft is preferable to starting or running an assessment, nor any prerequisites or follow-up steps.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_create_projectCreate projectADestructive
Create a project in a domain. Requires domains:write (fullPipeline preset). Returns project pid and slug.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Display name for the project | |
| slug | Yes | URL-safe slug (unique within the domain) | |
| domainPid | Yes | Domain pid from air_list_domains | |
| description | No | Optional project description |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true and openWorldHint=true, so the write semantics are covered structurally. The description adds two things annotations cannot: the required permission scope and the fact that the call returns a pid and slug. It doesn't cover rate limits or failure modes, but the added context is meaningful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, zero filler, front-loaded with the action and scope before the prerequisite and return value. Every sentence carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming the return values (pid and slug), and it discloses the auth scope needed for a write operation. It lacks any note on slug uniqueness conflicts or idempotency, which a create tool could usefully mention, but overall an agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters (name, slug, domainPid, description) are already documented with constraints and cross-references (air_list_domains). The description adds only the generic phrase "in a domain", so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Create a project in a domain") that clearly distinguishes it from read-oriented siblings like air_list_projects and air_get_project. It does not, however, explicitly name an alternative or contrast itself with them, so it stays at 4 rather than 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a prerequisite ("Requires domains:write (fullPipeline preset)") which is genuinely useful, but says nothing about when to use this tool versus siblings such as air_create_account or the assessment-creation tools. Usage is only implied by the verb.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_get_artifact_textGet artifact textBRead-only
Get extracted plain text for an artifact. Requires projects:read.
| Name | Required | Description | Default |
|---|---|---|---|
| projectPid | Yes | ||
| artifactPid | Yes | Artifact pid (artf_*) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds the authorization scope (projects:read) and implies the text must already be extracted, which is useful beyond the annotations, but it says nothing about size limits, truncation, or behavior when extraction has not completed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the action and scope, with zero filler. Nothing is wasted and the reading order is correct.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter read tool with no output schema, the essentials are mostly present, but the definition is thin: it doesn't clarify the relationship between projectPid and artifactPid, what 'extracted' implies about timing/dependencies, or what the returned text looks like.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 50%: artifactPid is documented as artf_* in the schema, but projectPid has no description anywhere. The description adds no parameter meaning at all, so it fails to compensate for the uncovered parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: retrieving the extracted plain text of an artifact. It is distinguishable from siblings like air_get_document_download_url (raw file) and air_list_artifacts (enumeration), though it never names those alternatives explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The statement 'Requires projects:read' gives a prerequisite, which implies the calling context, but there is no explicit when-to-use guidance or comparison against the download-URL sibling. Usage is only weakly implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_get_assessmentGet assessmentBRead-only
Get assessment detail including status and workflowRunId. Requires assessments:read.
| Name | Required | Description | Default |
|---|---|---|---|
| assessmentPid | Yes | Assessment pid (pasm_*) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered by structured data. The description adds a genuine behavioral fact beyond that - the required auth scope and the fact that it surfaces workflowRunId - but says nothing about error behavior for unknown pids or how status transitions appear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero filler, and the returned-field information is front-loaded before the permission note. Nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity single-parameter read tool with a complete schema this is close to adequate, and it hints at return contents despite no output schema. But in a sibling cluster of five or more assessment-getting tools, the description omits the disambiguation an agent most needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single parameter with 100% schema description coverage ('Assessment pid (pasm_*)'), so the schema fully documents it and the baseline is 3. The description adds no format, prefix, or lookup guidance beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get assessment detail') and names two concrete returned fields (status, workflowRunId). However, it does not differentiate itself from the many similarly named siblings such as air_get_assessment_summary, air_get_assessment_report, and air_get_assessment_stages, leaving the agent to guess which 'get assessment*' variant it needs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only guidance is a permission prerequisite ('Requires assessments:read'). There is no statement of when to use this tool over air_list_assessments, air_get_assessment_summary, or air_wait_for_assessment, and no exclusion guidance. Prerequisite alone is not usage routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_get_assessment_input_artifactsGet assessment input artifactsBRead-only
List artifacts used as inputs when the assessment report was generated. Requires assessments:read.
| Name | Required | Description | Default |
|---|---|---|---|
| assessmentPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safe-read profile is covered. The description adds one genuinely useful non-schema fact, the required 'assessments:read' scope, but says nothing about pagination, result ordering, or what happens when no report exists yet.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, the purpose front-loaded ahead of the permission note, with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with no output schema, the description covers what is returned and the auth requirement, but leaves the parameter undocumented and does not clarify how this differs from the sibling air_list_artifacts. Adequate but with visible gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one parameter (assessmentPid) with 0% schema description coverage, and the description never explains it, its format, or where to obtain it. With low coverage the description is expected to compensate, and it does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('List artifacts') and narrows it with a clear scope: artifacts used as inputs when the assessment report was generated, tied to a specific assessmentPid. It is distinguishable from the generic air_list_artifacts, though it never names that sibling to make the contrast explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'when the assessment report was generated' implies the usage context (after a report exists) and the required scope 'assessments:read' is stated. However there is no explicit when-to-use vs when-not guidance and no pointer to the related siblings (air_list_artifacts, air_get_assessment_report).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_get_assessment_reportGet assessment reportARead-only
Fetch the structured risk assessment report for a completed run. Omit section to get the whole report; if it is too large for one response you get a section index instead — each section with its size and item count — so you can pull the parts you need. Pass section for one slice, and offset/limit to page through a list section such as riskRegister or evidenceAppendix. Requires assessments:read.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max items to return when section is a list | |
| offset | No | First item to return when section is a list (default 0) | |
| section | No | Report section to return instead of the whole report | |
| assessmentPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already covering the read-only safety profile, the description adds substantial behavioral context: the section-index fallback when the report is too large, pagination semantics for list sections, and an explicit permission requirement ('Requires assessments:read'). This is disclosure beyond what the structured fields provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, front-loaded with the core action, then behavior, then parameters. Every sentence carries information, though the middle sentence is somewhat complex and could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing the section-index response structure and paging model, and it covers permissions. It is nearly complete; the missing piece is sibling differentiation against other assessment-retrieval tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 75%, and the description meaningfully augments it by explaining that section selects one slice, that offset/limit page through list sections, and naming examples (riskRegister, evidenceAppendix). It does not explain assessmentPid, though that is self-evident from its name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fetch the structured risk assessment report') with the scope qualifier 'for a completed run', which is meaningful. It does not explicitly distinguish itself from siblings like air_get_assessment_summary or air_get_assessment, leaving that inference to the agent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear parameter-level usage (omit section for the whole report, pass section for one slice, offset/limit to page), which is strong operational guidance. However, it never says when to use this tool over the summary/assessment siblings, so alternative selection is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_get_assessment_stagesGet assessment stagesARead-only
List per-stage checkpoint logs for an assessment run. Requires assessments:read.
| Name | Required | Description | Default |
|---|---|---|---|
| assessmentPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description usefully adds the required OAuth scope (assessments:read), which the annotations do not convey, but it says nothing about pagination, log volume, or ordering of the per-stage logs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the core purpose front-loaded and the permission requirement second; nothing is redundant or padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter read tool with no output schema, the description covers what the tool returns (per-stage checkpoint logs), the scope it applies to (an assessment run), and the authorization needed. Return shape need not be detailed since no output schema exists, but nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter assessmentPid has 0% schema description coverage, so the description carries the burden, and it only indirectly implies that this value identifies the assessment run. It adds no format, source, or example for obtaining the PID, so the low-coverage gap is not fully compensated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('per-stage checkpoint logs for an assessment run'), which is concrete and distinguishable in kind from siblings like air_get_assessment_report or air_get_assessment_summary. However, it never explicitly contrasts itself with those neighboring tools, so an agent must infer the boundary on its own.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a prerequisite ('Requires assessments:read') and a context ('for an assessment run'), implying when the tool applies. It does not, however, say when to prefer this over the sibling assessment-detail tools or note any conditions/exclusions, so usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_get_assessment_summaryGet assessment summaryARead-only
Fetch a slim assessment report summary without the full risk/evidence payload: overview, quality, EU AI Act tier, section counts, the saved project choices (projectDecisions), and changesSincePrevious — each checklist item that closed, is still open, is new, or came back since the previous completed scan, plus whether the input documents changed. Read those labels as given; do not work out the match yourself. Prefer this over air_get_assessment_report for triage. Requires assessments:read.
| Name | Required | Description | Default |
|---|---|---|---|
| assessmentPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, destructiveHint=false, openWorldHint), so the bar is lower. The description still adds real value: it discloses the auth scope needed, that the response is deliberately slim and omits risk/evidence payload, and that change labels are authoritative. It stops short of explaining pagination/limits, which for a summary call is minor.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the verb and resource, then the sibling-routing guidance, then the auth requirement. The middle enumeration is dense but every clause maps to a distinct return field; the 'read those labels as given' instruction earns its place as an interpretation guard.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully enumerates the returned fields and warns against recomputing the change match, and it covers the auth requirement and sibling routing. The only substantive gap is identification of assessmentPid.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter assessmentPid has 0% schema description coverage, and the description never explains what the identifier is, its format, or where to obtain it. With one undocumented parameter the description should compensate but does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Fetch') and resource ('slim assessment report summary'), explicitly scopes it against the full payload, and enumerates the payload contents (overview, quality, EU AI Act tier, section counts, projectDecisions, changesSincePrevious). An agent can distinguish it from air_get_assessment_report without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the alternative sibling and the selecting condition: 'Prefer this over air_get_assessment_report for triage.' It also states the prerequisite ('Requires assessments:read') and gives an operational rule for interpreting changesSincePrevious rather than recomputing it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_get_credit_balanceGet credit balanceARead-only
Assessment credits available to this organization, with the plan and the cost per assessment. Call it before a batch of assessments so the limit is predicted instead of hit.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint=true, destructiveHint=false, openWorldHint=true). The description adds behavioral value by disclosing the return payload — plan and per-assessment cost — which is meaningful since no output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: the first declares what is returned, the second front-loads the calling context. Zero waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless read tool with no output schema, the description adequately discloses what comes back and when to call it. A note on whether the balance is per-org global or scoped would make it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4; there is nothing parameter-wise for the description to clarify or compensate for.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (assessment credits for this organization) and enumerates the returned contents (plan and cost per assessment). An agent can distinguish it from sibling 'air_request_credits' immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly prescribes when to call it: before a batch of assessments, so the limit is predicted rather than hit. No alternative or exclusion is named (e.g. request_credits for topping up), so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_get_document_download_urlGet document download URLARead-only
Get a presigned download URL for an uploaded document source. Requires projects:read.
| Name | Required | Description | Default |
|---|---|---|---|
| sourcePid | Yes | Document source pid (psrc_*) | |
| projectPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds genuinely useful context beyond that: the call returns a presigned (temporary, time-limited) URL and requires the projects:read scope, which an agent needs to know before invoking. It stops short of stating URL expiry behaviour or error modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero filler; the purpose is front-loaded and the permission requirement follows. Nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining the return value, and 'presigned download URL' conveys both shape and temporary nature. Minor gaps remain around URL lifetime, but the essential contract for calling the tool correctly is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% — sourcePid is documented as a psrc_* identifier while projectPid has no description. The description supplies no parameter-level detail of its own, so the undocumented projectPid is left to inference. Baseline 3 is appropriate given the schema carries the partial burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource — 'Get a presigned download URL for an uploaded document source' — which is precise enough to distinguish it from read-oriented siblings like air_get_artifact_text and air_list_documents. It does not explicitly name an alternative tool, but the resource scope ('uploaded document source') does the routing work.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states a permission prerequisite ('Requires projects:read') but offers no guidance on when to choose this tool versus alternatives such as air_get_artifact_text or air_list_documents. Usage is implied by the resource name rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_get_domainGet domainARead-only
Resolve a domain by pid from air_list_domains results, or by orgSlug + domainSlug via slug lookup.
| Name | Required | Description | Default |
|---|---|---|---|
| orgSlug | No | Organization slug for lookup | |
| domainPid | No | Domain pid from air_list_domains | |
| domainSlug | No | Domain slug for lookup |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds the useful dependency that domainPid must come from a prior air_list_domains call, but says nothing about failure behavior when a domain is not found or any rate/scope limits. With annotations carrying the safety burden, this is adequate but thin.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with no filler, front-loaded with the action and followed by both resolution paths. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the burden of conveying the return, and it says only that a domain is 'resolved' without describing the returned shape or error case. It does adequately cover the input paths for a 3-parameter read tool, so it is minimally viable rather than deficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema: it establishes that domainPid is an alternative to the orgSlug+domainSlug pair and where the pid comes from. This disambiguates the three optional, non-required parameters that the schema lists without indicating they are mutually exclusive paths.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource ('Resolve a domain') and enumerates the two resolution paths (pid, or orgSlug+domainSlug). It names the sibling air_list_domains as the source of pids, which helps separate it from air_list_domains. It stops short of explicitly contrasting with other get_* siblings (air_get_project, air_get_assessment), so it is clear but not fully differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly describes the two invocation modes and where the pid value originates ('from air_list_domains results'), which is actionable routing guidance. It does not state when to prefer one path over the other or when not to use this tool at all, so no explicit exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_get_domain_portfolioGet domain portfolioBRead-only
Domain-level portfolio dashboard. Requires portfolio:read (fullPipeline preset). Domain-scoped API keys only work for their bound domain.
| Name | Required | Description | Default |
|---|---|---|---|
| orgSlug | Yes | ||
| domainSlug | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, non-destructive, openWorld), and the description adds genuinely new behavioral context: the required permission scope with its preset, and the fact that domain-scoped API keys only work for their bound domain. This is real auth/constraint disclosure beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the resource identity, no filler or repetition. The opening 'dashboard' framing is slightly label-like but the auth constraint follows immediately and earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description should describe what the portfolio call returns; 'dashboard' is too vague to tell an agent what metrics or entities come back. The permission and key-scoping notes are valuable, but the return-value gap keeps this only minimally complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for both required parameters, so the description carries the full burden. It only hints at domain scoping via the API-key note and never explains orgSlug, domainSlug, or their expected format, leaving the agent to guess at identifier conventions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description labels the resource ('Domain-level portfolio dashboard') but never states a concrete verb or what a 'portfolio' actually contains, so an agent cannot tell what data is retrieved. It does not differentiate this tool from nearby siblings such as air_get_domain or air_list_domains.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the prerequisite scope ('Requires portfolio:read (fullPipeline preset)') and an API-key constraint, which implies when the call can succeed. However, it gives no guidance on when to pick this tool over air_get_domain or the other domain-scoped readers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_get_projectGet projectARead-only
Resolve a project by pid from air_list_projects, or by orgSlug + domainSlug + projectSlug.
| Name | Required | Description | Default |
|---|---|---|---|
| orgSlug | No | ||
| domainSlug | No | ||
| projectPid | No | Project pid from air_list_projects | |
| projectSlug | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, destructiveHint=false, so safety is covered. The description adds the resolution semantics (alternative composite key), but says nothing about not-found/error behavior or return shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence, front-loaded with the primary resolution path and the alternative, with zero filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and 0 required parameters, the description supplies the key information an agent needs: where the pid comes from and the composite-key alternative. It stops short of stating requiredness rules, which is the main residual gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 25% (only projectPid documented), so the description must compensate. It does: it links pid to air_list_projects and explains that orgSlug + domainSlug + projectSlug form an alternate lookup path, giving meaning to three otherwise-bare parameters. It doesn't clarify whether the slug trio can be partially supplied.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (resolve) and resource (project), and distinguishes the two lookup modes. It names air_list_projects as the pid source, tying it to a sibling, though it doesn't contrast against other get_* siblings like air_get_domain.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the two ways to invoke it and implicitly the prerequisite (obtain pid via air_list_projects). No explicit when-not-use or ordering guidance beyond that, but the calling context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_list_artifactsList artifactsBRead-only
List document-derived artifacts for a project. Use artifact pids in air_start_assessment. Requires projects:read.
| Name | Required | Description | Default |
|---|---|---|---|
| projectPid | Yes | ||
| includeArchived | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds the required scope (projects:read), which annotations do not carry. It does not disclose whether archived artifacts are excluded by default, which the includeArchived parameter implies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the action, and every clause carries information (scope, downstream use, permission). No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and 0% parameter coverage, the description should carry more weight. It covers purpose, auth, and follow-up use, but leaves the archived/active default and parameter meanings unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for both parameters. 'For a project' loosely maps to projectPid, but includeArchived is never mentioned or explained, so the description does not compensate for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'List document-derived artifacts for a project.' This distinguishes it from air_list_documents and air_get_artifact_text, though it never explicitly contrasts with those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives the permission prerequisite ('Requires projects:read') and a downstream hint ('Use artifact pids in air_start_assessment'), which is real usage value. However, it offers no when-not guidance or explicit alternative among the many list/get siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_list_assessmentsList assessmentsBRead-only
List assessment summaries for a project. Requires assessments:read.
| Name | Required | Description | Default |
|---|---|---|---|
| projectPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds the auth scope requirement (assessments:read) and implies a lightweight payload via 'summaries', but says nothing about pagination, filtering, or result volume.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the core action and scope front-loaded. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description should carry more of the return-value burden; 'assessment summaries' hints at shape but omits pagination, ordering, or result limits. For a simple one-parameter read tool this is adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for the single projectPid parameter, but the description's phrase 'for a project' implies the parameter identifies the target project. It adds no format or naming details (e.g., PID vs. numeric ID) beyond that implication.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('List assessment summaries') and scopes it to a project, which is clear. However, it does not differentiate from close siblings like air_get_assessment_summary or air_get_assessment, so an agent must infer the distinction from names alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description names a required permission ('Requires assessments:read'), which is a useful prerequisite, but gives no guidance on when to choose this over air_get_assessment_summary, air_get_assessment, or air_get_assessment_report. Usage is only implied by the verb.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_list_documentsList documentsARead-only
List document sources for a project. Poll until status is connected before starting an assessment. Requires projects:read.
| Name | Required | Description | Default |
|---|---|---|---|
| projectPid | Yes | Project pid | |
| includeArchived | No | Include archived document sources |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=true, destructiveHint=false, openWorldHint=true), so the bar is lower. The description still adds the authorization requirement (projects:read) and the polling/status-contract behavior, which the annotations do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: what it lists, the timing/status precondition, and the permission requirement. Front-loaded with the action and scope.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a small read-only list tool with a fully documented two-parameter schema and covering annotations, this is nearly complete. Minor gap: no output/pagination hints, though no output schema exists to defer to.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for both parameters, so the schema fully documents projectPid and includeArchived. The description adds no syntax, format, or defaulting detail beyond that, making 3 the correct baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with scope ('List document sources for a project'), which an agent can distinguish from sibling list tools like air_list_projects, air_list_domains, and air_list_artifacts. It does not explicitly name the nearest alternatives, but the resource noun is specific enough to route correctly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives real operational guidance: poll until status is 'connected' before starting an assessment, and the required scope 'projects:read'. It tells the agent the pre-condition and timing, though it does not name an alternative tool for the same data if this one is unavailable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_list_domainsList domainsARead-only
List domains visible to the API key. For domain-scoped service account keys, returns the single bound domain. Requires domains:read scope.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, openWorld and non-destructive, so the safety profile is covered. The description adds real behavioral value beyond that: the auth scope requirement and the fact that domain-scoped keys collapse the result to a single bound domain. It doesn't mention pagination or ordering, which is a minor gap for a list endpoint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with what the tool returns before the qualifiers. Every sentence adds distinct information (scope, edge case, auth requirement) with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless read-only list with no output schema and no annotations gap, the description covers what is returned, under what key scoping, and what scope is required. Only return-shape/ordering details are absent, which is acceptable at this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4 per the rubric. There is no parameter syntax for the description to explain away, and the empty schema leaves nothing ambiguous.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('domains') and clarifies the scoping semantics: domains visible to the API key, with a special case for domain-scoped service account keys. This differentiates it from the singular air_get_domain sibling, though it never names that alternative explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description supplies a prerequisite ('Requires domains:read scope') and explains the domain-scoped-key edge case, which helps an agent anticipate behavior. However, it gives no guidance on when to prefer this over air_get_domain or air_get_domain_portfolio, so usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_list_open_factsList open EU AI Act factsARead-only
List the deduplicated open EU AI Act fact worklist for an assessment (each missing fact once, with criteria it unblocks). Requires assessments:read.
| Name | Required | Description | Default |
|---|---|---|---|
| assessmentPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds that results are deduplicated and each fact appears once with unblocked criteria, which is useful behavior. But it doesn't explain pagination, ordering, or what happens when all facts are answered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence that is front-loaded with the resource, followed by scope clarification and permission requirement. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, scope, return composition (deduplicated facts with criteria), and permission requirement. A tool with one simple parameter and no output schema is adequately described, though parameter semantics and usage relative to siblings could be stronger.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does nothing to explain the single parameter assessmentPid. An agent must infer that it identifies the assessment, but the format (UUID, PID string) and constraints are not clarified. With one undocumented required parameter, the description fails to compensate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (deduplicated open EU AI Act fact worklist for an assessment), and defines the scope precisely with 'each missing fact once, with criteria it unblocks'. Distinguishable from siblings like air_get_assessment_summary and air_list_assessments.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this is used to find what facts are still needed for an assessment, which gives some usage context. However, it does not explicitly state when to use this versus air_get_assessment or air_get_assessment_summary, nor does it mention prerequisites beyond the permission.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_list_project_decisionsList saved project choicesBRead-only
List saved choices for a project, each judged against assessmentPid. posture: stands (no later scan disagrees), conflicts (a later scan raised the topic again; show the saved sentence and ask again), settled (the accepted gap is no longer open). Requires projects:read.
| Name | Required | Description | Default |
|---|---|---|---|
| projectPid | Yes | ||
| assessmentPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds real value beyond that: an explicit auth requirement ('Requires projects:read') and a semantic key for the returned posture states (stands/conflicts/settled), including the prompt to re-ask on 'conflicts'. Missing pagination/result-shape notes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the operation, then the posture enumeration, then the auth caveat — a sensible order with no filler sentences. The posture clause is dense but each element earns its place by defining return states.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and partially does so by defining the three posture values. It omits the remaining fields returned per decision and any pagination behavior, so an agent can interpret states but not the full response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and both required parameters are undocumented in the schema, so the description must compensate fully. It maps roles loosely ('for a project' → projectPid, 'judged against assessmentPid' → assessmentPid), which helps, but does not explain PID format or how assessmentPid is chosen, leaving the agent to infer.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('saved choices for a project'), and the read counterpart is distinguishable from the write sibling air_record_project_decision. It does not explicitly name that sibling, but the read/write split is inferable. Clear enough to select correctly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use or when-not guidance, and no reference to the alternative air_record_project_decision or to other list tools. The 'ask again' note inside the conflicts definition hints at action but is about interpreting a result, not about when to call this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_list_projectsList projectsARead-only
List projects in a domain (paginated). Requires domains:read and projects:read. Use domainPid from air_list_domains.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1) | |
| search | No | Filter projects by name | |
| pageSize | No | Page size (default 20) | |
| domainPid | Yes | Domain pid |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds genuinely useful non-annotation context: the required scopes (domains:read, projects:read) and that results are paginated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the core action, then auth, then the dependency. Every clause earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with full schema coverage and annotations carrying the safety profile, the description is nearly complete. It notes pagination but says nothing about the shape of returned items, which is a minor gap given there is no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so page, pageSize, search, and domainPid are already documented in the schema. The description only adds the provenance hint for domainPid, which is already named; baseline 3 applies when the schema carries the semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('projects') with explicit scope ('in a domain'), which cleanly separates it from air_get_project (single project) and air_list_domains (domains). An agent can pick this without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear prerequisite/chaining guidance by telling the agent to obtain domainPid from air_list_domains, naming a sibling explicitly. It does not state when not to use it (e.g., vs air_search or air_get_project), so it falls short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_record_project_decisionSave a project choiceADestructive
Save a developer choice on the project, in the person's own words. Ask them first. Use not_applicable when the whole topic (themeId) does not apply to this system: later scans keep that topic and its gaps quiet until one raises the topic again. Use accept_gap when the topic applies but the person accepts one missing control (controlId required): the gap stays listed with the saved sentence beside it. The scan the choice is recorded on does not judge it; later scans do. A later choice for the same theme or control replaces the earlier one. Requires projects:write.
| Name | Required | Description | Default |
|---|---|---|---|
| choice | Yes | ||
| reason | Yes | ||
| themeId | Yes | ||
| controlId | No | ||
| projectPid | Yes | ||
| assessmentPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only flag readOnly=false and destructive=true; the description goes well beyond by disclosing consent requirement, the projects:write permission, the upsert/replacement semantics ('a later choice ... replaces the earlier one'), and the deferred-judgment behavior across scans. This is exactly the added context the lower annotation bar rewards.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action and consent requirement, then the two enum branches, then the replacement/permission caveats. Dense but every clause carries distinct meaning; a couple of long sentences could be split for readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-param mutation tool with no output schema, the description covers intent, mode selection, auth, consent, and lifecycle effects. It omits only return/response expectations and the identity of projectPid/assessmentPid, minor gaps given no output schema is declared.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage the description must carry the burden, and it does for most params: it defines both enum values of choice, ties themeId to the topic, and marks controlId as required only for accept_gap, while reason is implied by 'in the person's own words'. projectPid and assessmentPid are not explained, so it falls just short of complete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Save a developer choice on the project') and immediately scopes it as an upsert of a decision record, which clearly separates it from the read-only sibling air_list_project_decisions. An agent knows exactly what this tool does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes between the two enum modes: not_applicable when the whole topic does not apply, accept_gap when the topic applies but a missing control is accepted (with controlId required). It also names the precondition 'Ask them first' and the replacement rule for repeat choices, 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.
air_request_creditsRequest more creditsADestructive
Ask Thalus for more assessment credits. The person reviews the amount and the reason before the request is sent, and Thalus replies by email to the organization owner. To buy credits immediately instead, call air_get_credit_balance for the purchase link.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | ||
| credits | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond the annotations (readOnlyHint=false, destructiveHint=true, openWorldHint=true) by disclosing the human review step before submission and the email-reply-to-owner outcome, which tells the agent the request is asynchronous and not instantaneous. It does not explain why the tool is flagged destructive or any rate/submission limits, but the added process context is meaningful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: the purpose and the review/notification behavior come first, the alternative path last. No filler or restated title text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly explains the observable outcome (email reply to the organization owner) and the human-review gate, so the agent knows what happens after the call. The gap is the undocumented parameter bounds, not the behavioral picture.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for both required parameters, so the description must carry the load. It only alludes to 'the amount and the reason', which loosely maps to credits and reason but omits the 1–100 credit ceiling and the reason length constraint that the schema enforces silently.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Ask Thalus for more assessment credits') with scope, and explicitly differentiates from the sibling air_get_credit_balance for immediate purchases. An agent can distinguish this from the many air_list_*/air_get_* siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear routing rule: use air_get_credit_balance if you want to buy immediately rather than request. It stops short of stating prerequisites or when a request would be rejected, but the alternative path is named with its selecting condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_retry_assessmentRetry assessmentADestructive
Retry a failed assessment from the last completed stage. Requires assessments:write and consumes credits.
| Name | Required | Description | Default |
|---|---|---|---|
| assessmentPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly=false, destructive=true, openWorld=true), and the description adds genuinely new behavioral facts: the required assessments:write scope and that credits are consumed. The resumption-from-last-completed-stage behavior is also a useful disclosure, though it doesn't say what happens to prior partial results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler, with the core action front-loaded and the auth/cost constraints appended. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter mutation with annotations covering safety and no output schema, the description covers purpose, auth, and cost. It omits only minor details such as what the caller gets back or whether the retry is idempotent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry parameter meaning, and it says nothing about assessmentPid — not even that it identifies the failed assessment to resume. The parameter name is largely self-explanatory, which keeps this from being worse than a baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (retry), resource (assessment), and scope (resumes from the last completed stage), which distinguishes it from air_start_assessment and air_run_assessment_from_file. An agent can identify the operation without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The word 'failed' implicitly defines the selection condition — use this instead of starting fresh when a prior run failed. No explicit when-not guidance or named alternative is given, but the context is clear enough to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_run_assessment_from_fileRun assessment from local fileADestructive
Upload a local file, wait for extraction, start assessment on the new artifact. Consumes credits. Requires projects:write and assessments:write. Returns an MCP Task handle immediately. Reads filePath with your OS user permissions.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Assessment name (defaults to filename) | |
| filePath | Yes | Absolute or relative path to a local document file | |
| projectPid | Yes | ||
| contentType | No | MIME type (inferred from extension when omitted) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: discloses that credits are consumed, the two required OAuth scopes, that an MCP Task handle is returned immediately (async, not blocking), and that filePath is read under the caller's OS user permissions. The local-filesystem permission model and credit cost are exactly the kind of operational context an agent cannot get from readOnlyHint/destructiveHint alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, zero filler, and the operation sequence is front-loaded before cost/auth/return details. Every clause carries information an agent needs (credits, scopes, return shape, file access).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a multi-stage, no-output-schema tool, the description covers the key unknowns: it is a composite operation, it is asynchronous, and it returns a task handle. The one gap is that it does not name the sibling (air_wait_for_assessment / air_wait_for_document_extraction) an agent should call to collect the result of the returned handle.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 75%, so most parameters are documented structurally; baseline is 3. The description adds one genuinely new fact about filePath (it is read with the caller's OS permissions), but says nothing about projectPid, contentType, or name beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the exact three-step operation (upload local file, wait for extraction, start assessment) against a specific resource, so an agent knows precisely what happens. It is clear but does not explicitly distinguish itself from the sibling air_run_full_assessment_pipeline, which sounds like an overlapping convenience wrapper.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the opening sentence: use this when you have a local file and want an assessment created from it. Prerequisites (projects:write, assessments:write) are stated, but there are no exclusions and no explicit routing away from the manual air_upload_document_init/air_start_assessment flow or toward air_run_full_assessment_pipeline.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_run_full_assessment_pipelineRun full assessment pipelineBDestructive
Start assessment on existing artifacts, wait for completion, return report summary. Consumes credits. Returns an MCP Task handle immediately; poll tasks/get until completed.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| projectPid | Yes | ||
| artifactPids | Yes | ||
| waitTimeoutMs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so safety is partially covered. The description adds genuinely useful non-annotated behavior: credit consumption and the MCP Task handle/polling requirement. But it is internally contradictory, saying it 'wait[s] for completion, return[s] report summary' while also 'Returns an MCP Task handle immediately', which muddles whether the agent should expect a result or a handle.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, front-loaded sentences with no filler; the operational details (credits, task handle, polling) are compactly stated. The only defect is that the first and third sentences contradict each other rather than complementing, which is a content problem more than a verbosity one.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists and this is a credit-consuming, asynchronous, multi-parameter operation, so the description should do more work. It sketches the flow well but omits parameter semantics, credit magnitude, and what the 'report summary' contains, leaving the agent under-equipped to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% with 4 parameters (3 required), so the description carries the full burden and largely fails it. Only artifactPids is obliquely implied by 'existing artifacts'; projectPid, name, and waitTimeoutMs are completely unexplained, and the interaction between waitTimeoutMs and the claimed async handle is not addressed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (start/run assessment pipeline) with scope qualifier 'on existing artifacts', which implicitly separates it from the sibling air_run_assessment_from_file. However, it never explicitly names start_assessment, wait_for_assessment, or run_assessment_from_file, so the disambiguation is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives partial when-to-use context ('on existing artifacts') and a procedural note to poll tasks/get until completed. But it does not say when to prefer this over air_start_assessment + air_wait_for_assessment or air_run_assessment_from_file, which are the obvious alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_searchSearchARead-only
Full-text search across orgs, domains, and projects. Requires search:read scope (fullPipeline preset; not included in assessmentRunner).
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | Search query | |
| kind | No | Restrict to entity kind | |
| limit | No | Max results (default 20) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so safety is covered. The description adds meaningful authorization context beyond annotations: the required search:read scope and the preset conditions (fullPipeline included, assessmentRunner excluded). It stops short of describing return format or pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences, zero waste. The core capability is front-loaded and the scope prerequisite follows, making it easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only search tool whose safety profile is already carried by annotations and whose parameters are fully documented in the schema, the description covers purpose and authorization well. The only notable gap is that with no output schema it does not describe the shape of returned results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so q, kind (enum), and limit are already fully documented in the schema. The description adds no syntax or format detail beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (search) and resource scope (orgs, domains, projects) with the mechanism (full-text). It is clear what the tool does, though it does not explicitly name which siblings it supersedes, so an agent must infer the contrast with the entity-specific list/get tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a prerequisite (requires search:read scope via fullPipeline preset, not in assessmentRunner) but offers no explicit when-to-use or when-not-to-use guidance versus siblings like air_list_domains or air_get_project. Usage is only implied by 'full-text search.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_sign_outSign out of AIR on this machineADestructive
Remove the AIR credentials stored on this machine and return to setup mode. The account itself is untouched. A key supplied through AIR_API_KEY cannot be removed here — the result says where to remove it instead.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and readOnlyHint=false, so safety is covered. The description adds genuinely non-obvious behavior: the account is preserved, and an env-supplied AIR_API_KEY cannot be removed here with the result directing the caller to the right place. It doesn't state whether the removal is reversible or what happens on re-run.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with no waste; the core action is front-loaded and each remaining sentence carries a distinct caveat (account untouched, env-key exception).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless, local, destructive action with annotations covering the safety profile, the description supplies everything an agent needs: what is removed, what is preserved, and the one case where it won't work.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the schema-imposed baseline is 4. There is nothing parameter-related the description needs to compensate for.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Remove the AIR credentials') plus precise scope ('stored on this machine'), which distinguishes it from account-level operations such as air_create_account. An agent can immediately tell this is a local credential teardown, not an account deletion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context for use and explicitly bounds the effect ('The account itself is untouched'), and even routes the caller elsewhere for the AIR_API_KEY case. It does not name a sibling tool as an alternative, but the when-to-use condition is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_signup_send_codeSignup: send verification codeADestructive
Signup form step one: send the verification code. Submitted by the form itself, not by the assistant.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| Yes | |||
| orgName | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, openWorldHint=true, and readOnlyHint=false, so the side-effect profile is covered without the description. The description adds useful context that this is a UI-driven step-one trigger, but says nothing about email delivery, code expiry, rate limits, or whether prior codes are invalidated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the flow position and followed by the caller restriction. Every clause earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-required-param, no-output-schema tool, the description covers placement in the flow and the intended caller, which is the core need. It omits follow-on behavior (that air_signup_verify_code is step two), failure modes, and any return expectations, leaving a gap for an agent that ends up involved in signup.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so all three parameters (name, email, orgName) rely on their names alone, and the description contributes nothing about them. The names are largely self-explanatory for a signup form, which prevents a 1, but the description does no work to compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('send the verification code') and situates it as 'Signup form step one', which implicitly separates it from the sibling air_signup_verify_code. It stops short of naming that sibling outright, but the scope is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Submitted by the form itself, not by the assistant' is an explicit when-not-to-use instruction, which is unusually strong guidance. It does not, however, tell the agent what to use instead or what to do if it needs to drive signup programmatically.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_signup_verify_codeSignup: verify codeADestructive
Signup form step two: verify the code and create the account. Submitted by the form itself, not by the assistant.
| Name | Required | Description | Default |
|---|---|---|---|
| otp | Yes | ||
| acceptTerms | Yes | ||
| termsVersion | Yes | ||
| continuationToken | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true, openWorldHint=true, so the mutation and safety profile are covered structurally. The description is consistent with these and adds that the call creates an account and is form-driven, but says nothing about auth requirements, what happens on failure, or side effects on existing accounts. With annotations carrying the main burden, 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the purpose front-loaded and the audience constraint immediately after. No filler; every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Since the description tells the agent this tool is not for assistant use, the essential context (do not call it, it completes signup) is present, and no output schema is expected. However, the four undocumented required parameters and the absence of any note on failure/verification behavior leave real gaps if the tool is ever invoked.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and all four required parameters (otp, acceptTerms, termsVersion, continuationToken) are undocumented in the schema. The description only obliquely references 'the code' and the account-creation step, leaving continuationToken and the terms parameters entirely unexplained. It does not compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('verify the code and create the account') and explicitly frames itself as 'step two' of the signup flow, distinguishing it from air_signup_send_code (step one) and air_create_account. An agent can place it precisely in the flow without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a strong, explicit exclusion: 'Submitted by the form itself, not by the assistant.' This tells the agent it should not invoke the tool. It stops short of naming what the assistant should call instead, so it is clear context without a full alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_start_assessmentStart assessmentADestructive
Start a risk assessment on a project. Consumes org credits and dispatches the risk pipeline. Requires assessments:write. Returns assessmentPid.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Display name for the run | |
| projectPid | Yes | ||
| artifactPids | Yes | Artifact pids from air_list_artifacts (max 5) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the safety profile is covered. The description adds genuinely non-structured context: it consumes org credits, dispatches an asynchronous pipeline, and requires assessments:write. It could go further on irreversibility of the credit spend or failure semantics, but this is solid added value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, front-loaded sentences with no filler: action, side effects, permission, and return value. Every sentence carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a credit-consuming, asynchronous mutation with no output schema, the description covers the essentials: cost, required scope, and what is returned (assessmentPid), which is necessary since no output schema exists. It stops short of stating blocking/async behavior expectations or what happens on partial failure, which would have made it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 67% (name and artifactPids documented, projectPid bare), so the schema does most of the work. The description adds no parameter-level detail such as artifact-count limits or pid format, so it neither compensates for the gap nor adds meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: 'Start a risk assessment on a project', which clearly distinguishes it from read-side siblings like air_list_assessments and air_get_assessment. It does not, however, differentiate itself from closely related write siblings such as air_create_assessment_draft, air_retry_assessment, or air_run_assessment_from_file, which an agent could plausibly confuse it with.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description notes the required scope (assessments:write) but gives no guidance on when to use this versus air_create_assessment_draft, air_retry_assessment, air_run_assessment_from_file, or air_run_full_assessment_pipeline. With four sibling tools that all run or prepare assessments, the absence of routing guidance is a real gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_submit_fact_answersSubmit EU AI Act fact answersADestructive
Submit answers for open EU AI Act facts and re-derive the waterfall tier. Pass factPath + value (+ optional justification). Requires assessments:write.
| Name | Required | Description | Default |
|---|---|---|---|
| answers | Yes | ||
| assessmentPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false and openWorldHint=true, so the mutation profile is covered. The description usefully adds that the call re-derives the waterfall tier (the actual downstream effect) and that it requires the assessments:write permission, which the annotations do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, zero filler, with the core action and its side effect front-loaded. Every clause adds information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description would ideally state what the caller gets back (e.g. the new tier), but it only says a re-derivation happens. Combined with the undocumented required assessmentPid and 0% schema coverage, it is adequate but leaves real gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries full burden, yet it only mentions factPath, value and optional justification. The required top-level assessmentPid is never mentioned, evidenceChunkIds is omitted, and the polymorphic value type (boolean | string[] | null) is not explained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a concrete verb (Submit) and resource (answers for open EU AI Act facts) plus a consequence (re-derive the waterfall tier). It clearly reads as the write-side counterpart to the 'open facts' listing tools, though it never explicitly names a sibling to differentiate from.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Submit answers for open EU AI Act facts' implies the trigger condition (there are open facts awaiting answers), but no when-not guidance, prerequisites, or explicit alternative tool is given. Usage is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_submit_feedbackSend feedback to ThalusBDestructive
Send product feedback to Thalus. The person reviews the text before it is sent. A reply goes to the organization owner, or to an address the person gives. Works without an AIR account, where the person is asked for one.
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | ||
| category | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, destructiveHint=true and openWorldHint=true, so the safety profile is already covered. The description adds genuinely non-structured behavior: a human reviews the text before it is sent, and the reply is routed to the organization owner or a caller-supplied address. That said, the destructiveHint=true annotation is never explained or reconciled with what is effectively a submit-to-human operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action and no filler. Slightly awkward phrasing in the trailing clause ('where the person is asked for one'), but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with no output schema, the description adequately covers routing, the review step, and the account requirement, so the calling context is mostly complete. It falls short on the parameter side: with 0% schema coverage, the category options and message constraints should have been spelled out.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and there are two required parameters, so the description carries the full burden — yet it never mentions 'message' or 'category', the 4000-character limit, or the bug/idea/praise/other enum. An agent gets no help from the prose on what to pass.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Send product feedback to Thalus'), which is unambiguous and clearly distinct from every sibling tool (none of which deal with feedback). It does not explicitly name a sibling to differentiate against, but no sibling is confusable, so the omission is harmless.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The line 'Works without an AIR account, where the person is asked for one' gives real context on when this call is viable, which is useful for an agent operating in an unauthenticated flow. However, there is no guidance on when to prefer this over other routes or how to choose between categories, so usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_upload_document_completeComplete document uploadADestructive
Finalize a presigned upload after the PUT to uploadUrl succeeded. Dispatches the document extraction workflow. Requires projects:write.
| Name | Required | Description | Default |
|---|---|---|---|
| s3Key | Yes | Storage key from air_upload_document_init | |
| filename | Yes | ||
| projectPid | Yes | ||
| contentType | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (write, destructive, open-world), so the description adds the key behavioral facts: it is a terminal step that triggers asynchronous extraction, and it needs projects:write. It does not say what destruction means if called twice or on a bad key.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action and precondition, with no filler. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-param mutation with no output schema, the description covers the sequencing, the side effect (extraction dispatch), and the required scope. What's missing is the async handoff (wait_for_document_extraction) and the three undocumented params.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 25%, so only s3Key is partly explained (via the init link). filename, projectPid, and contentType are bare in both schema and description, and the description adds no format or constraint details. Baseline 3 is generous given the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Finalize) and resource (presigned upload), and links it to its lifecycle predecessor air_upload_document_init and the uploadUrl PUT. An agent can tell this is the step-2 counterpart to init without opening anything else.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The sequencing is explicit: finalize only after the PUT to uploadUrl succeeded, and it dispatches the extraction workflow. It does not name air_wait_for_document_extraction as the natural next step or state what to do if the PUT failed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_upload_document_initInitialize document uploadADestructive
Start a presigned upload: returns uploadUrl and s3Key. PUT the raw file bytes to uploadUrl with the same contentType you passed here and no other headers — the URL signs content-type and host only, so any x-amz-* header (notably the checksum headers AWS SDKs add by default) invalidates the signature. Then call air_upload_document_complete with the returned s3Key. Requires projects:write.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | Original filename including extension | |
| projectPid | Yes | ||
| contentType | Yes | MIME type, e.g. application/pdf |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations only covering safety hints, the description carries the real behavioral burden and does so: it warns that the URL signs content-type and host only, that any x-amz-* header (especially SDK checksum headers) invalidates the signature, and that the contentType must match. It also discloses the required projects:write scope. This is exactly the kind of non-obvious operational detail an agent cannot infer from schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly written sentences, front-loaded with the return values, followed by the critical header caveat and the next-step call. Every sentence carries actionable information with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although there is no output schema, the description names the return fields and the complete two-step upload flow, so an agent knows both what it gets back and what to do next. Nothing essential for a correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67% (projectPid is undocumented), so the description must compensate, and it does: it ties contentType to the signed PUT header, which is the semantically important constraint. It adds meaning beyond the schema, though projectPid's role remains unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource (start a presigned upload) and names the concrete artifacts it returns (uploadUrl and s3Key). It is clearly distinguishable from the sibling air_upload_document_complete, which it explicitly references as the follow-up step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear workflow context: upload first, then call air_upload_document_complete with the returned s3Key, and it names the required scope (projects:write). It does not, however, state when this tool should NOT be used or how it relates to any alternative upload path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_wait_for_assessmentWait for assessmentARead-only
Wait until an assessment is completed, failed, or reportAvailable, up to timeoutMs. Uses exponential backoff. Returns ready:false with the last observed status if the wait budget runs out — call again with the same assessmentPid to keep waiting. Requires assessments:read.
| Name | Required | Description | Default |
|---|---|---|---|
| timeoutMs | No | Default 1800000ms; max 1800000ms | |
| assessmentPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond annotations (which only cover readOnly/openWorld/non-destructive) by disclosing exponential backoff, the timeout budget concept, and the partial-result behavior (ready:false plus last observed status). It also names the required scope, assessments:read. It doesn't describe the ready:true payload, which matters since there is no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the wait condition, then implementation behavior, then the retry pattern. No filler sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the wait semantics, idempotent re-invocation, and auth scope, which is most of what an agent needs for a two-parameter async wait tool. Missing pieces are the shape of a successful return (no output schema exists) and its relationship to air_start_assessment / air_run_assessment_from_file in a longer workflow.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: timeoutMs already carries default/max in the schema and the description only restates it as the wait bound. For assessmentPid the description adds that reusing the same value continues the same wait, which is useful semantics, but gives no format or source for the PID. Roughly baseline-level.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (wait for assessment) and enumerates the terminal conditions it waits on: completed, failed, reportAvailable. It does not differentiate itself from the similarly named sibling air_wait_for_document_extraction, but an agent can still tell what resource this operates on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit follow-up guidance: if the budget runs out with ready:false, call again with the same assessmentPid to keep waiting. It doesn't state when to prefer this over polling air_get_assessment/air_list_assessments, so alternatives are left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
air_wait_for_document_extractionWait for document extractionARead-only
Wait until sourcePid reaches connected or error, up to timeoutMs. Uses exponential backoff. Returns ready:false with the last observed status if the wait budget runs out — call again with the same sourcePid to keep waiting. Requires projects:read.
| Name | Required | Description | Default |
|---|---|---|---|
| sourcePid | Yes | ||
| timeoutMs | No | Default 600000ms; max 600000ms | |
| projectPid | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/destructive/openWorld, and the description adds substantial extra behavior: exponential backoff, the ready:false return on budget exhaustion, the retry-preserving-same-sourcePid pattern, and the required projects:read scope. This is well beyond what structured fields convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loading the wait condition, then backoff, then timeout/retry, then the auth requirement. Every sentence adds distinct operational value with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a polling tool with no output schema, the description usefully sketches the timeout return shape and retry semantics, and annotations cover the safety profile. It stops short of describing the success return or the full set of statuses, and projectPid remains unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 33% (only timeoutMs documented), so the description must compensate. It explains sourcePid's role as the polled status target and restates the timeoutMs budget, but projectPid is left entirely undefined in both schema and description, leaving a material gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb (wait), resource (document extraction keyed by sourcePid), and terminal condition (connected or error). It does not differentiate itself from the analogous air_wait_for_assessment sibling, so it stays at 4 rather than 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context (wait up to timeoutMs) and explicit retry guidance ('call again with the same sourcePid to keep waiting'), plus a permission prerequisite ('Requires projects:read'). It omits when-not-to-use and any alternative sibling, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
15 tool updates
v1.0.2- Added
air_create_account - Changed
air_get_assessment_report3 fields changed- added
Input schema / properties / limitAdded value: +{ + "description": "Max items to return when section is a list", + "exclusiveMinimum": 0, + "type": "integer" +} - added
Input schema / properties / offsetAdded value: +{ + "description": "First item to return when section is a list (default 0)", + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / sectionAdded value: +{ + "description": "Report section to return instead of the whole report", + "enum": [ + "overview", + "quality", + "systemProfile", + "riskRegister", + "watchlist", + "clearedThemes", + "cannotEvaluateThemes", + "controlMatrix", + "overlays", + "controlEvidence", + "positions", + "lensViews", + "euAiActTier", + "euAiActFacts", + "projectDecisions", + "changesSincePrevious", + "evidenceAppendix", + "inputArtifacts" + ], + "type": "string" +}
- Added
air_get_assessment_summary - Added
air_get_credit_balance - Added
air_list_open_facts - Added
air_list_project_decisions - Added
air_record_project_decision - Added
air_request_credits - Added
air_sign_out - Added
air_signup_send_code - Added
air_signup_verify_code - Added
air_submit_fact_answers - Added
air_submit_feedback - Changed
air_wait_for_assessment2 fields changed- changed
Input schema / properties / timeoutMs / descriptionPrevious value: -"Default 1800000ms"New value: +"Default 1800000ms; max 1800000ms" - added
Input schema / properties / timeoutMs / maximumAdded value: +1800000
- Changed
air_wait_for_document_extraction2 fields changed- changed
Input schema / properties / timeoutMs / descriptionPrevious value: -"Default 600000ms"New value: +"Default 600000ms; max 600000ms" - added
Input schema / properties / timeoutMs / maximumAdded value: +600000
25 tool updates
v1.0.1- First observed
air_create_assessment_draft - First observed
air_create_project - First observed
air_get_artifact_text - First observed
air_get_assessment - First observed
air_get_assessment_input_artifacts - First observed
air_get_assessment_report - First observed
air_get_assessment_stages - First observed
air_get_document_download_url - First observed
air_get_domain - First observed
air_get_domain_portfolio - First observed
air_get_project - First observed
air_list_artifacts - First observed
air_list_assessments - First observed
air_list_documents - First observed
air_list_domains - First observed
air_list_projects - First observed
air_retry_assessment - First observed
air_run_assessment_from_file - First observed
air_run_full_assessment_pipeline - First observed
air_search - First observed
air_start_assessment - First observed
air_upload_document_complete - First observed
air_upload_document_init - First observed
air_wait_for_assessment - First observed
air_wait_for_document_extraction
TDQS
Scored across 37 tools
The tool set has many distinct operations, but several boundaries are blurry: air_get_assessment_report vs air_get_assessment_summary, air_start_assessment vs air_create_assessment_draft vs air_retry_assessment, and the high-level pipeline tools vs the individual start/wait/report tools. The detailed descriptions help, but an agent can still plausibly choose the wrong assessment or document tool for a given workflow.
All tools use a consistent air_ prefix and snake_case naming. The dominant pattern is verb_noun, with predictable sub-patterns for phased operations such as air_upload_document_init/complete and air_signup_send_code/verify_code.
At 37 tools, the set is well beyond the typical 3-15 range. The platform is broad, but there are many convenience and orchestration tools that overlap with lower-level tools, making the surface feel heavy rather than tightly scoped.
The server covers the core AIR assessment lifecycle well: domains, projects, document upload, artifacts, assessments, reports, facts, decisions, credits, and account/signup flows. Some lifecycle gaps remain, such as no update/delete for projects or documents and no assessment cancellation, but these are minor and workable for most agent workflows.
Maintenance
Related MCP Connectors
Governance maturity assessment, compliance gap analysis, and evidence-linked briefs for AI agents.
Connect your AI assistant to governed tender and RFP dossiers: sources, versions, decisions.
AI inventory and EU AI Act compliance. Find AI tools and use cases, check new AI uses before launch.
AI-native project and portfolio management platform for PMOs. OAuth + PAT.
Related MCP Servers
AlicenseAqualityBmaintenanceEnables AI agents to assess AWS environments against the AWS Security Reference Architecture (SRA) by providing tools to discover, describe, and run security checks across AWS services and accounts.53Apache 2.0- FlicenseNot gradedqualityDmaintenanceEnables authorized compliance verification and security auditing through natural language, bridging AI assistants with industry-standard security tools for enterprise audits.24-

AIReady MCP Serverofficial
AlicenseNot gradedqualityDmaintenanceEnables AI agents to assess AI-readiness and improve AI leverage through analysis tools, resources, and prompts for project scanning and remediation.12 npmMIT- AlicenseAqualityAmaintenanceEnables AI agents to interact with the SCF Controls Platform for security compliance, including browsing controls, tracking implementation, managing evidence, assessing risks, and monitoring vendors via natural language.2241,045 npm2MIT