Skip to main content
Glama
AIR MCP Server

AIR MCP Server

by VericyIO

AIR MCP Server

npm version License: MIT

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, …)

npx @thalus-ai/mcp-air, with or without a key

Streamable HTTP

Claude Directory / remote MCP clients

Hosted at https://mcp.air.thalus.ai/mcp with OAuth

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.5.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.5.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.5.0

Remote 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.mjs

Two variables carry this deployment's identity, and both default to production:

Variable

What it sets

AIR_API_URL

The upstream API and the protected-resource metadata origin advertised in the 401

MCP_OAUTH_RESOURCE

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

air_create_account

Collects name, email, organization, code and terms — in a form or a dialog

air_submit_feedback

Sends feedback to Thalus — you are asked for a reply address when you have no account

air_signup_send_code, air_signup_verify_code

The form's own callbacks; hidden from the model

air_sign_out

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:

  1. Ask the assistant to create an AIR account. It calls air_create_account.

  2. Type your name, work email and organization. You type them — the model supplies nothing, and what you type does not enter its context.

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

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

AIR_API_KEY

Set in your MCP client config. Wins over anything on disk.

2

~/.air/credentials.json

Written by air_create_account. Override with AIR_CREDENTIALS_PATH.

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)

assessmentRunner

List domains/projects, start assessments, read reports on existing artifacts

assessments:read/write, projects:read, domains:read

fullPipeline

Upload documents, search, domain portfolio, create projects

Above plus projects:write, search:read, portfolio:read, domains:write

Capability

Minimum preset

air_list_domains, air_start_assessment, air_get_assessment_report

assessmentRunner

air_upload_document_*, air_run_assessment_from_file

fullPipeline

air_search, air_get_domain_portfolio, air_create_project

fullPipeline

air_record_project_decision

fullPipeline

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

.cursor/mcp.json or ~/.cursor/mcp.json

Restart after changes

Claude Code

.mcp.json or ~/.claude.json

Or: claude mcp add --env AIR_API_KEY=… --transport stdio air -- npx -y @thalus-ai/mcp-air@1.5.0 — docs

Claude Desktop

See platform paths below

Quit and reopen the app

VS Code

.vscode/mcp.json or user config via MCP: Open User Configuration

Use Copilot Agent mode; root key is servers

Windsurf

~/.codeium/windsurf/mcp_config.json

Same mcpServers JSON as Cursor

Other

Your client's MCP docs

Same command, args, and AIR_API_KEY

Claude Desktop paths

Platform

Path

macOS

~/Library/Application Support/Claude/claude_desktop_config.json

Windows

%APPDATA%\Claude\claude_desktop_config.json

Logs (macOS): ~/Library/Logs/Claude/mcp*.log

Full walkthrough: air.thalus.ai/docs/mcp-air-setup

Capabilities

Tools (45 stdio / 42 remote)

Category

Tools

Discovery

air_list_domains, air_get_domain, air_list_projects, air_get_project, air_create_project, air_search

Documents

air_list_documents, air_get_document_download_url, air_list_artifacts, air_get_artifact_text, air_upload_document_init, air_upload_document_complete, air_upload_document

Assessments

air_list_assessments, air_get_assessment, air_get_assessment_report, air_get_assessment_summary, air_list_open_facts, air_ask_open_facts, air_submit_fact_answers, air_get_assessment_stages, air_get_assessment_input_artifacts, air_create_assessment_draft, air_start_assessment, air_retry_assessment

Scan prep

air_list_project_fact_answers, air_ask_screening_questions, air_save_prepared_answers, air_get_rules_notice, air_postpone_rules_notice, air_recheck_tier

Decisions

air_list_project_decisions, air_record_project_decision

Portfolio

air_get_domain_portfolio

Composites

air_wait_for_document_extraction, air_wait_for_assessment, air_run_assessment_from_file†, air_run_full_assessment_pipeline†

Account

air_create_account‡, air_signup_send_code‡§, air_signup_verify_code‡§, air_sign_out

Support

air_submit_feedback‡, air_request_credits, air_get_credit_balance

air_ask_open_facts — Ask the open EU AI Act questions as a short form: a checklist of what the system does, then details for what was ticked. Saves each page and re-checks the tier.

air_ask_screening_questions — Ask the same checklist before a scan; hold the answers and save them with air_save_prepared_answers once the scan starts.

air_recheck_tier — Re-check a scan's tier under the current AIR rules, with no new scan and no credit.

air_upload_document — Upload a text document, such as the scan summary, to a project in one call: start the upload, send the content, finish it, and wait until AIR has read it.

† 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 (air_run_assessment_from_file)

air_upload_document_init → PUT → air_upload_document_complete

MCP Tasks (air_run_full_assessment_pipeline)

air_start_assessment → air_wait_for_assessment → air_get_assessment_summary

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

air_get_assessment_summary

Overview, quality, EU AI Act tier, per-section counts, saved choices, and what changed since the previous scan

air_get_assessment_report (no section)

The whole report, or a section index if it doesn't fit

air_get_assessment_report + section

That one slice

air_get_assessment_report + section + offset / limit

A page of a list section, with totalItems and nextOffset

air://assessments/{pid}/report resource

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

air://assessments/{assessmentPid}/report

Completed assessment report JSON

air://assessments/{assessmentPid}/stages

Stage execution log

air://projects/{projectPid}/assessments

Assessments for a project

App resource (1)

URI

Description

ui://air/signup-form.html

The in-chat signup form, served as text/html;profile=mcp-app

Prompts (3)

Name

Purpose

run-assessment-workflow

End-to-end assessment workflow guidance

review-assessment-report

Structured report review

explore-portfolio

Domain portfolio exploration

Typical workflow

  1. No account yet? air_create_account (remote transport) — see Starting without an account

  2. air_list_domains → obtain domainPid

  3. air_list_projects → obtain projectPid (or air_create_project with fullPipeline)

  4. Upload evidence: air_run_assessment_from_file (stdio), or air_upload_document_init → PUT → air_upload_document_complete → air_wait_for_document_extraction

  5. air_start_assessment with artifactPids from air_list_artifacts

  6. air_wait_for_assessment

  7. air_get_assessment_report or read the air://assessments/{id}/report resource

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 test

Documentation

Security

  • The MCP process runs with your OS user privileges. Tools such as air_run_assessment_from_file can read any local path your user can access.

  • Pin the package version in production (@thalus-ai/mcp-air@1.5.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 env or envFile in 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.

Maintainer notes (build, publish, constants sync): see AGENTS.md.

Available Tools

45 tools
air_ask_open_factsAsk open EU AI Act questionsA
Destructive

Ask the person the open EU AI Act questions one at a time. Each dialog shows the full question, then Yes, No and Not sure, or the labelled options. Saves each answer and re-checks the tier, until no question is open or every open one is "Not sure". proposedAnswers may only cover facts marked suggestFromCode, which the code can show; never suggest what the system is used for or whom it affects. Pass back notSureFactPaths from the last call as skipFactPaths. Answers are kept on the project for later scans. Requires assessments:write.

Inputs: assessmentPid (required), skipFactPaths, proposedAnswers.

air_ask_screening_questionsAsk the EU AI Act checklist before a scanA
Read-only

Before a scan, ask the person each EU AI Act screening question in its own dialog, with the full question and Yes, No and Not sure, or the labelled options. Facts the project already holds an answer for are left out. Returns the answers to hold: after air_start_assessment, send them with air_save_prepared_answers. It saves nothing itself. Requires projects:read.

Inputs: projectPid (required).

air_create_accountCreate an AIR accountA
Destructive

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.

Inputs: no named parameters.

air_create_assessment_draftCreate assessment draftA
Destructive

Create an assessment draft without starting the pipeline. Requires assessments:write.

Inputs: name (required), projectPid (required), artifactPids (required).

air_create_projectCreate projectA
Destructive

Create a project in a domain. Requires domains:write (fullPipeline preset). Returns project pid and slug.

Inputs: name (required), slug (required), domainPid (required), description.

air_get_artifact_textGet artifact textB
Read-only

Get extracted plain text for an artifact. Requires projects:read.

Inputs: projectPid (required), artifactPid (required).

air_get_assessmentGet assessmentB
Read-only

Get assessment detail including status and workflowRunId. Requires assessments:read.

Inputs: assessmentPid (required).

air_get_assessment_input_artifactsGet assessment input artifactsB
Read-only

List artifacts used as inputs when the assessment report was generated. Requires assessments:read.

Inputs: assessmentPid (required).

air_get_assessment_reportGet assessment reportA
Read-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.

Inputs: assessmentPid (required), limit, offset, section.

air_get_assessment_stagesGet assessment stagesA
Read-only

List per-stage checkpoint logs for an assessment run. Requires assessments:read.

Inputs: assessmentPid (required).

air_get_assessment_summaryGet assessment summaryA
Read-only

Fetch a slim assessment report summary without the full risk/evidence payload: overview, quality, the EU AI Act tier (value, name, description, and final: true when no open question can change it) with the names of the matched criteria, section counts, the saved project choices (projectDecisions, each with posture and, when it came back, cameBackBecause), and changesSincePrevious — each checklist item that closed, is still open, is new, was newly judged, came back, or could not be judged since the previous completed scan, plus inputs: the documents added, removed, or changed in content (a re-upload of the same text is unchanged). Read those labels as given; do not work out the match yourself. Prefer this over air_get_assessment_report for triage. topRisks lists the first few risk-register items in short form; fetch the riskRegister section of air_get_assessment_report for the full list. Requires assessments:read.

Inputs: assessmentPid (required).

air_get_credit_balanceGet credit balanceA
Read-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.

Inputs: no named parameters.

air_get_document_download_urlGet document download URLA
Read-only

Get a presigned download URL for an uploaded document source. Requires projects:read.

Inputs: sourcePid (required), projectPid (required).

air_get_domainGet domainA
Read-only

Resolve a domain by pid from air_list_domains results, or by orgSlug + domainSlug via slug lookup.

Inputs: orgSlug, domainPid, domainSlug.

air_get_domain_portfolioGet domain portfolioB
Read-only

Domain-level portfolio dashboard. Requires portfolio:read (fullPipeline preset). Domain-scoped API keys only work for their bound domain.

Inputs: orgSlug (required), domainSlug (required).

air_get_projectGet projectA
Read-only

Resolve a project by pid from air_list_projects, or by orgSlug + domainSlug + projectSlug.

Inputs: orgSlug, domainSlug, projectPid, projectSlug.

air_get_rules_noticeCheck if the AIR rules have moved onC
Read-only

due is true when the latest completed scan used older AIR EU AI Act rules and nobody has said later to the current ones. lastCompleted.tier is the stored tier and lastCompleted.tierUnderCurrentRules is what the same facts give now. postponed says when someone said later to the current rules. Do not decide the version yourself. Requires projects:read.

Inputs: projectPid (required).

air_list_artifactsList artifactsB
Read-only

List document-derived artifacts for a project. Use artifact pids in air_start_assessment. Requires projects:read.

Inputs: projectPid (required), includeArchived.

air_list_assessmentsList assessmentsB
Read-only

List assessment summaries for a project. Requires assessments:read.

Inputs: projectPid (required).

air_list_documentsList documentsA
Read-only

List document sources for a project. Poll until status is connected before starting an assessment. Requires projects:read.

Inputs: projectPid (required), includeArchived.

air_list_domainsList domainsA
Read-only

List domains visible to the API key. For domain-scoped service account keys, returns the single bound domain. Requires domains:read scope.

Inputs: no named parameters.

air_list_open_factsList open EU AI Act factsA
Read-only

List the open EU AI Act questions for an assessment: only facts whose answer can still change the tier and that are worth asking now, checklist facts first. screeningGroups are the checklist lines that still hold an open fact. Each item has question (ask it as written), help (one line on why it matters) and, for list facts, options (show the labels, send the values). Boolean facts take true, false, or null for "Not sure"; list facts take option values, or [] for none. answerConflicts are earlier answers that this scan read differently, with the scan's excerpts. Never show factPath, description or a raw null to the person. Prefer air_ask_open_facts when the client can show forms. Requires assessments:read.

Inputs: assessmentPid (required).

air_list_project_decisionsList saved project choicesA
Read-only

List saved choices for a project, each judged against assessmentPid. posture: stands (quiet; the topic is raised on the same documents and seriousness the person decided on), conflicts (show the saved sentence and ask again; cameBackBecause says why: new_evidence = the scan cites text that was not in the documents they decided on, more_serious = the topic moved up, for example from the watchlist to a risk, review_due = six months have passed), settled (the accepted gap is no longer open). Requires projects:read.

Inputs: projectPid (required), assessmentPid (required).

air_list_project_fact_answersList saved project fact answersC
Read-only

Active answers already saved on the project. factPath is for the tool call. Do not show factPath to the person. Requires projects:read.

Inputs: projectPid (required).

air_list_projectsList projectsA
Read-only

List projects in a domain (paginated). Requires domains:read and projects:read. Use domainPid from air_list_domains.

Inputs: domainPid (required), page, search, pageSize.

air_postpone_rules_noticeKeep the result on older AIR rules for nowC
Destructive

The person said later to the current AIR rules. Records who and when. The notice returns when the rules move past this version. Refused when nothing is due. Requires projects:write.

Inputs: projectPid (required).

air_recheck_tierRe-check the tier under the current AIR rulesA
Destructive

Re-check a scan's EU AI Act tier under the current AIR rules from the facts it already holds. Reads no documents and spends no credit. Returns previousTier, the new tier, and the questions that can still change it. Requires assessments:write.

Inputs: assessmentPid (required).

air_record_project_decisionSave a project choiceA
Destructive

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 while it is raised on the same documents and seriousness, and bring it back when the scan cites new text, the topic grows more serious, or six months have passed. 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. Pass the assessmentPid the person decided on; the choice remembers that scan's documents. 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.

Inputs: choice (required), reason (required), themeId (required), projectPid (required), +2 more.

air_request_creditsRequest more creditsA
Destructive

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.

Inputs: reason (required), credits (required).

air_retry_assessmentRetry assessmentA
Destructive

Retry a failed assessment from the last completed stage. Requires assessments:write and consumes credits.

Inputs: assessmentPid (required).

air_run_assessment_from_fileRun assessment from local fileA
Destructive

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.

Inputs: filePath (required), projectPid (required), name, contentType.

air_run_full_assessment_pipelineRun full assessment pipelineB
Destructive

Start assessment on existing artifacts, wait for completion, return report summary. Consumes credits. Returns an MCP Task handle immediately; poll tasks/get until completed.

Inputs: name (required), projectPid (required), artifactPids (required), waitTimeoutMs.

air_save_prepared_answersSave answers before the scan has factsA
Destructive

Save the checklist answers right after air_start_assessment. They are kept on the project and applied when the scan reads its facts; a scan that reads a different value from the documents raises it as a conflict. Refused once the scan has read its facts. It does not recompute the tier. Requires assessments:write.

Inputs: answers (required), assessmentPid (required).

air_sign_outSign out of AIR on this machineA
Destructive

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.

Inputs: no named parameters.

air_signup_send_codeSignup: send verification codeA
Destructive

Signup form step one: send the verification code. Submitted by the form itself, not by the assistant.

Inputs: name (required), email (required), orgName (required).

air_signup_verify_codeSignup: verify codeA
Destructive

Signup form step two: verify the code and create the account. Submitted by the form itself, not by the assistant.

Inputs: otp (required), acceptTerms (required), termsVersion (required), continuationToken (required).

air_start_assessmentStart assessmentA
Destructive

Start a risk assessment on a project. Consumes org credits and dispatches the risk pipeline. Requires assessments:write. Returns assessmentPid and reportUrl. Give the person the reportUrl link when the scan starts.

Inputs: name (required), projectPid (required), artifactPids (required).

air_submit_fact_answersSubmit EU AI Act fact answersA
Destructive

Submit answers for open EU AI Act facts and re-derive the tier on this assessment, with no new scan. Pass factPath + value + a short justification in the person's words. An array fact accepts only its allowedValues; any other word is refused with 422 naming the allowed values. Answers are kept on the project, so later scans start from them; null ("I don't know") clears a kept answer. Answering a conflicted fact replaces the kept answer. Requires assessments:write.

Inputs: answers (required), assessmentPid (required).

air_submit_feedbackSend feedback to ThalusB
Destructive

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.

Inputs: message (required), category (required).

air_upload_documentUpload a text documentA
Destructive

Upload a text document, such as the scan summary, to a project in one call: start the upload, send the content, finish it, and wait until AIR has read it. Returns the source and its status. For binary files, use air_upload_document_init and the related tools. Requires projects:write.

Inputs: content (required), fileName (required), projectPid (required), contentType.

air_upload_document_completeComplete document uploadA
Destructive

Finalize a presigned upload after the PUT to uploadUrl succeeded. Dispatches the document extraction workflow. Requires projects:write.

Inputs: s3Key (required), filename (required), projectPid (required), contentType (required).

air_upload_document_initInitialize document uploadA
Destructive

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.

Inputs: filename (required), projectPid (required), contentType (required).

air_wait_for_assessmentWait for assessmentA
Read-only

Wait until an assessment is completed, failed, or reportAvailable, or until its step differs from lastStageLabel, up to timeoutMs. Uses exponential backoff. A new step returns ready:false with stageLabel ("Step 4 of 12: Checking each risk theme"), the line to show the person, and reportUrl. Call again with lastStageLabel set to the line you showed. Returns ready:false with the last observed status if the wait budget runs out — call again to keep waiting. Requires assessments:read.

Inputs: assessmentPid (required), timeoutMs, lastStageLabel.

air_wait_for_document_extractionWait for document extractionA
Read-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.

Inputs: sourcePid (required), projectPid (required), timeoutMs.

Tool Schema Changelog

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

    TDQS

    B3.4/5.0

    Scored across 45 tools

    Disambiguation3/5

    Several tools overlap significantly, especially around starting assessments (air_start_assessment, air_run_full_assessment_pipeline, air_run_assessment_from_file) and answering facts (air_ask_open_facts, air_submit_fact_answers, air_save_prepared_answers). Descriptions are detailed and provide some differentiation, but an agent could easily misselect among these similarly purposed tools.

    Naming Consistency5/5

    All tool names follow a consistent air_verb_noun or air_verb pattern in snake_case. There is no mixing of camelCase or inconsistent verb styles; the prefix and structure are predictable throughout.

    Tool Count2/5

    45 tools is excessive for the apparent scope, with multiple redundant entry points for the same core workflows (assessment initiation, fact answering, uploads). The server would benefit from consolidation to reduce cognitive load and misselection risk.

    Completeness4/5

    Core lifecycle for risk assessment is well covered: project creation, document upload and extraction, assessment start and reporting, fact answering, decisions, credits, and account flows. Minor gaps exist such as no project update/delete or document deletion, but agents can work around them.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      B
      maintenance
      Enables 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.
      5
      3
      Apache 2.0
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables authorized compliance verification and security auditing through natural language, bridging AI assistants with industry-standard security tools for enterprise audits.
      24
      -
    • A
      license
      B
      quality
      B
      maintenance
      Enables 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.
      26
      790 npm
      3
      MIT