Skip to main content
Glama

Your AI agent transferred the funds, wrote the file, called the tool. Later, someone who does not trust you asks you to prove exactly what it did and why: a regulator, an auditor, a customer after an incident. Your own logs will not settle it, because you could have edited them.

Quick start

pip install vaara                            # Python: CLI, MCP proxy, server
brew tap vaaraio/tap && brew install vaara   # macOS: CLI + menu-bar app (built from source)
npm install @vaara/client                    # TypeScript client for the HTTP API
import vaara

@vaara.govern
def transfer_funds(to: str, amount: float) -> str:
    ...

That is the whole thing. Every call to a governed function is risk-scored and decided against your policy before the body runs. An allowed call runs, and the decision, the call, and the outcome land in a hash-chained, tamper-evident record anyone can verify offline, with a signed receipt beside it. Sign the whole trail at export (vaara trail export) for third-party proof. Records persist to ~/.vaara/trail/audit.db by default, so evidence survives restarts. Python 3.10+. The base install carries three runtime dependencies, cryptography, rfc8785 and cbor2, which sign and canonicalise the receipts.

Both deny and escalate raise vaara.Blocked, since an escalation means a human has not answered yet. On a fresh install the example above runs. The default operating point is balanced, which allows below 0.55 and denies above 0.85, and a first call to transfer_funds scores 0.275 with a conformal interval of [0.085, 0.465]. Vaara decides on the interval's upper bound, and with no outcome history that interval is wide, so a riskier call escalates before its point estimate reaches the threshold. Feeding real outcomes back through report_outcome narrows it. The other presets are listed by vaara mode list. To watch decisions without acting on them, start with @vaara.govern(shadow=True).

vaara.io/verify.html is the receipt explorer, in English and Finnish. A static page and one script, no build step and no dependencies. Paste in a receipt and it recomputes the DSSE pre-authentication encoding, takes its digest, and checks the Ed25519 signature with WebCrypto. The receipt never leaves the tab, nothing uploads, and the page works with the network off, so verification is not a service and Vaara is not a party to it. Save the page with its script and it keeps working.

It also states what a passing check does not establish: that the key belongs to the party you expect, that the signed statement is true, that decided_at means anything without an external time authority, or that one receipt is a whole history.

The explorer on the same page reads the public transparency log straight from your browser. Look a trail head up by digest, or paste a public key to see everything published under it. No account and no sign-in, because the key is the identity. Publishing to that log is opt-in and off by default (vaara trail publish-head), so an absence there means nothing was published rather than nothing happened.

vaara.io/conformance.html is the results page. It carries every suite and its verdict, and every party other than the maintainer who ran the checkers and reported what they found in public. Rows are chained, each holding the digest of the row before it, so removing or reordering one breaks every digest after it and the break is visible to anyone. The maintainer cannot take a row down either. A run that disagrees with ours is a row too, with the reason stated, and there is no blacklist.

The aggregate runner grades every suite at once, and grades another implementation's vectors the same way:

git clone https://github.com/vaaraio/vaara && cd vaara
pip install cryptography rfc8785                                     # enough for 50 of the 52 suites; the two that skip name their extra
python scripts/conformance_runner.py                                 # grade the reference corpus
python scripts/conformance_runner.py --vectors-dir ./your_vectors    # grade your own

It prints a prefilled link at the end of every run, so asking for a row takes one click. The named, versioned rule set, what a pass does and does not establish, and the full suite list are in docs/conformance-profile.md.

The decorator drives the same engine you can call directly when you want the decision object in hand.

from vaara.pipeline import InterceptionPipeline

pipeline = InterceptionPipeline()
result = pipeline.intercept(
    agent_id="agent-007",
    tool_name="fs.write_file",
    parameters={"path": "/etc/service.yaml", "content": "..."},
    agent_confidence=0.8,
)
if result.allowed:
    pipeline.report_outcome(result.action_id, outcome_severity=0.0)
else:
    print(result.reason)

Every call gets a risk score and an allow / block / escalate decision against your policy, then the call, the decision, and the real outcome are written to the audit trail. report_outcome closes the loop: the scorer reweights based on which signals actually predicted the outcome. Every release carries SLSA v1 build provenance as a GitHub artifact attestation (SLSA Build Level 2), and the PyPI wheel is the same file, so gh attestation verify vaara-<version>-py3-none-any.whl --repo vaaraio/vaara checks either download. Optional ML classifier: pip install 'vaara[ml]'.

Writing a trail is the easy half. The half that matters is letting someone who does not trust you check it, with no key, no access, and none of your code. Every Vaara record is content-addressed and fail-closed on authenticity, and ships with public conformance vectors plus a standalone checker that imports no Vaara code, so an independent party reproduces every verdict offline.

vaara verify-bundle evidence-bundle.json

ok only when a signature is actually established, not merely present in a log. The same property drives the standards work behind the Vaara Receipt Internet-Draft: evidence that holds up for someone who runs none of your software. The full verifier set, the trust model for each verb, and where trust comes from in each case are in docs/verifying-evidence.md.

To check that claim yourself, without installing Vaara, run the standalone checker against the published vectors. Its only dependencies are cryptography and rfc8785:

git clone https://github.com/vaaraio/vaara
cd vaara
pip install cryptography rfc8785        # the checker's only dependencies
python tests/vectors/external_evidence_v0/_check_independent.py

It re-derives every verdict from the receipt bytes and the public key alone. The output shows the property the trail is built for: a receipt dropped from inside a declared boundary is a provable gap from the held set, with no issuer access and no external witness.

For the whole loop in one runnable file, produce a signed record, verify it yourself, then watch a single forged byte get caught, see examples/prove-it-yourself/. The logs-versus-evidence argument behind it is in docs/logs-vs-evidence.md.

vaara compliance report --db audit.db --format json against a real trail produces an article-level evidence record an auditor reads directly. Articles with no recorded events return evidence_insufficient, not a rubber stamp.

{
  "system_name": "Acme HR Assistant",
  "overall_status": "evidence_insufficient",
  "trail_integrity": {"size": 105, "chain_intact": true},
  "articles": [
    {"article": "Article 12(1)", "title": "Record-Keeping (Logging)",
     "status": "evidence_sufficient", "strength": "strong", "evidence_count": 105},
    {"article": "Article 15(1)", "title": "Accuracy, Robustness and Cybersecurity",
     "status": "evidence_insufficient", "strength": "absent", "evidence_count": 0}
  ]
}

Each verdict carries the threshold-versus-observed snapshot, the rationale, and the underlying records, so a reviewer traces status back to a concrete event. The same data renders as a Notified-Body PDF, a static HTML dashboard, or a Sigstore-signed handoff envelope. See docs/COMPLIANCE.md.

  • Gate every tool call you route through it against your own policy: allow, block, or escalate. Coverage is whatever you wrap; each adapter documents the surface it sees, and the Claude Code plugin states its four explicitly.

  • A tamper-evident trail an outside party verifies without trusting your stack, with the chain head anchorable to an external RFC 3161 / eIDAS timestamp so its existence is provable against a clock you do not control.

  • Article-level EU AI Act evidence, honest about the gaps instead of papering over them.

  • Governance of the model call itself, not only the tools around it: a hardware-rooted inference receipt that a second, different local model cross-checks. This is the sovereign inference harness, new in v1.0.

  • Enforcement, not only a record (v1.1.0): a credential broker mints a signed, short-lived credential bound to the attestation digest and scoped to one tool, its argument commitment, and tenant, with typed capability scopes that bound what a call may do. A gateway in front of a protected tool refuses any call without a valid, attestation-bound grant, so a bypass stops being silent. Off by default.

  • Gap-evident completeness (v1.4.0): each authorization receipt can carry a signed per-boundary sequence and running count, so a dropped receipt inside a declared boundary is a provable gap from the held receipts alone, with no issuer access and no external witness (vaara verify-contiguity). Off by default.

  • Independent re-mint (v1.14.0): a second generator in each public vector set reproduces the signed carrier byte-exact from the declared canonicalization alone, with no Vaara import. A verifier that has never run Vaara software reproduces the same bytes.

Native adapters route the major Python agent frameworks through the same pipeline, each via the framework's own hook, emitting identical audit events:

Framework

Entry point

LangChain

VaaraCallbackHandler, vaara_wrap_tool

CrewAI

VaaraCrewGovernance

OpenAI Agents SDK

VaaraToolGuardrail, vaara_wrap_function

MCP server

vaara.integrations.mcp_server

To put Vaara in front of an MCP server, run it as a proxy. Every tools/call routes through the pipeline before reaching the upstream; allowed calls forward transparently, blocked calls return an MCP error.

vaara-mcp-proxy \
  --upstream npx --upstream-arg -y --upstream-arg @sap/mdk-mcp-server \
  --db ./mcp_audit.db --shadow

Start with --shadow: every call is classified, scored, and recorded, nothing is blocked. After a few days, vaara trail shadow-report --db ./mcp_audit.db shows what enforcement would have done; then drop the flag and enforce, starting from a ready-made perimeter for common MCP servers in examples/policies/mcp-starters/. Point your MCP client (Claude Code, Cursor, any host) at the proxy instead of the upstream. There is also an HTTP API (pip install 'vaara[server]', vaara serve) and a first-party TypeScript client on npm (@vaara/client) for non-Python agents. Framework details, the cloud and OSS guardrail adapters (Bedrock, Azure, GCP, NeMo, Guardrails AI, LLM Guard, Rebuff), and the multi-tenant proxy are in docs/adapters.md.

A policy is code, so it belongs in the pull request that changes it. The action validates the policy, runs its cases, and fails the build on a policy that does not parse, a failing case, or a trail whose chain or signature does not hold.

- uses: vaaraio/vaara@v2
  with:
    policy: policies/production.yaml
    cases: policies/production.cases.yaml

Point trail at a signed zip to verify one a job produced. Without a pubkey that checks the trail is internally intact; pass a key you obtained separately to bind the signer too, and the run says which of the two it did. Inputs, outputs and pinning are in docs/github-action.md.

This checks artifacts. Gating the agent is the runtime's job, at the moment of the tool call.

Each risk score blends five expert signals and keeps adapting as outcomes come back, and it carries a confidence interval with a coverage guarantee that holds regardless of the input distribution. On a held-out adversarial corpus the classifier reaches 85.6% recall (95% Wilson [83.4, 87.6]) at a 5.1% false-positive rate, and 0.0% FPR on benign calls under live injection pressure. The hot-path rule scorer adds 140 µs mean per call on commodity CPU; the ML classifier is opt-in (vaara[ml]) and off that path. make bench reproduces the classifier figures below against the bundles that ship in the repo; it needs pip install 'vaara[ml]' and downloads the embedding model on first run.

  • 25,556-entry adversarial corpus (250 hand-curated + 25,306 LLM-generated). The v0.40 split assigns 24,619 of them leak-free by (category, generation batch) cell: 15,114 train, 2,921 val, 2,980 test, 3,604 holdout.

  • Classifier v11 (254 hand-features + 384-dim MiniLM embeddings) at threshold 0.8800 on held-out TEST n=1,827: recall 85.6% [83.4, 87.6] at FPR 5.1% [3.8, 6.9]. Recall is up 0.9 points on v9 and the false-positive rate is up 1.0. That trade is deliberate and the rest of this section is why.

  • Cross-model held-out recall 86.3% over n=5,600, against attacks written by Qwen2.5-72B, a model absent from TRAIN. v9 reads 67.4% on the same set. The previous published figure here was 66.8% [64.9, 68.7], measured on v8 against the v0.37 surface; v9 reproducing it within a point on a different attacker family and freshly generated data is the reason that number survived two releases unchanged. This is still the honest worst case, and the in-distribution number above is the easier denominator.

  • On four attack categories that the corpus had barely covered until v0.40, measured on 5,600 entries generated after v11's operating point was fixed: recall 63.1% to 87.0% and false positives 6.6% to 2.5% against v9. Credential exfiltration alone moves 45.9% to 80.3% at 10.0% to 3.9% FPR. Full record in bench/V11-CANDIDATE.md, including the earlier candidate that was rejected and why.

  • BIPIA-pressure FPR on benign tool calls 0.0% [0.0, 0.5]: none of 704 calls flagged across four agent backends (Claude Haiku 4.5, Llama-3.1-8B, Mistral-7B, Qwen-2.5-7B). v9 flags 2.7% of the same calls and v8 35.7%. scripts/eval_bipia_entries.py reproduces all three.

  • Multi-attacker PAIR robustness, measured on v0.31 and not re-run on v11: 0/25 successes per attacker across Qwen2.5-32B, Qwen2.5-72B, Llama-3.3-70B on identical seeds, Wilson upper 13.3% (bench/vaara-bench-v0.31.md).

  • Distribution-free conformal coverage on the score; MWU regret bound O(sqrt(T log N)).

  • Chain of custody: corpus, split, training commit, and bundle SHAs locked and printed by every script.

Method and per-cell breakdown: docs/architecture.md and bench/.

  • vaara.receipt/v1 is the canonical parent spec for the signed receipt format: hash-chained, canonicalized with JCS (RFC 8785), verifiable offline from a public key. The x402 settlement binding and an eIDAS qualified-timestamp profile are downstream profiles that pin to it rather than competing formats. Receipts can carry a self-hosted RFC 3161 timestamp that Vaara mints offline.

  • SEP-2828 signed execution records, carried forward as the IETF Internet-Draft draft-sirkkavaara-vaara-receipt. A second independent implementation has reproduced the SEP-2828 conformance vectors from a clean checkout with no shared code. Published corpora with independent checkers cover the fallback binding path (tests/vectors/fallback_projection_v0/) and CrewAI governance decisions (tests/vectors/governance_decision_v0/).

  • OVERT 1.0 (overt.is): Vaara is the Arbiter and emits Protocol Profile 1.0 Base Envelopes (canonical CBOR, Ed25519) alongside every record when attestation is on.

  • Post-quantum: an optional parallel ML-DSA-65 / FIPS 204 signature over the same preimage, so a stripped post-quantum signature is a detectable downgrade rather than a silent loss.

  • Root-agnostic evidence: the same Article 12 record is provable with or without a hardware TEE and re-expressible in IETF RATS EAR claims (AR4SI vector), whether rooted in a TPM 2.0 host, an AMD SEV-SNP confidential VM, or no TEE at all.

  • Sovereign inference harness (v1.0): a local model behind a signing proxy that emits a hardware-rooted inference receipt a second local model cross-checks. Developed privately, published here under AGPL-3.0.

Details and the offline checkers for each: docs/standards.md.

The public surface is fixed: the signed envelope (vaara.receipt/v1), capability constraints, the credential grant and gateway, and the @vaara.govern entry point. No new primitives are planned. New behavior ships as profiles that pin to vaara.receipt/v1, not as new core types, and no new format bindings will be added (the last was v1.13.0). From here the work is hardening and subtraction within this surface, so anyone building on it has a stable target.

Path

Contents

docs/verifying-evidence.md

Every verifier and its trust model

docs/logs-vs-evidence.md

Logs vs evidence: proving what an agent did, and what the AI Act actually requires

docs/prove-what-an-ai-agent-did.md

The four properties a provable record of agent actions needs

docs/eu-ai-act-article-12.md

Article 12 record-keeping: what it requires, what it does not, what to demand from tooling

docs/tamper-evident-audit-trail.md

How the trail works, its honest limits, and what it costs

docs/vaara-vs-observability-vs-grc.md

Vaara vs Datadog/Splunk vs Vanta/Drata: three different questions

docs/dogfood/

Our marketing runs under this gate; the signed trail and key to verify it

docs/capabilities.md

Everything Vaara does, by area, each entry naming its code

docs/library.md

The capabilities with no command of their own, reached from Python, each with a block that runs

docs/architecture.md

Scoring, conformal coverage, time anchor, formal properties

SPEC.md

The canonical vaara.receipt/v1 receipt format spec

docs/standards.md

SEP-2828, SEP-2787, OVERT, the sovereign inference harness

docs/adapters.md

Framework and cloud/OSS guardrail adapters, multi-tenant proxy

docs/COMPLIANCE.md

EU AI Act and DORA article mapping, eval numbers

docs/multi-replica-deployment.md

Scaling past one proxy process: per-replica chains, rotation, archive index

docs/kubernetes-rancher.md

Running the proxy on Kubernetes with Rancher: chart, storage, enforcement, network isolation

docs/supported-platforms.md

Python, container and Kubernetes versions Vaara supports, and which have been verified

CHANGELOG.md

Version-by-version evolution

docs/PRIOR_ART.md

When each concept first shipped, plus adjacent work

Vaara helps deployers assemble evidence for their own conformity work. It does not certify compliance or constitute legal advice. Deployers own their obligations under the EU AI Act and other applicable law.

Commercial license and paid pilots available: see vaara.io or contact hello@vaara.io. Licensing terms are in LICENSING.md, and the commercial licence is described in COMMERCIAL.md.

Related MCP server: Dvarapala

Acknowledgements

Red Hat is a trademark of Red Hat, LLC, registered in the United States and other countries.

Citation

If you build on Vaara or its receipt format, cite the repository (see CITATION.cff) and the specification it implements:

Henri Sirkkavaara. The Vaara Receipt: A Recomputable Receipt Format for Decisions About Agent Actions. IETF Internet-Draft draft-sirkkavaara-vaara-receipt.

Every tagged release is archived by Zenodo and minted a DOI. Cite 10.5281/zenodo.22027975 for the software as a whole, which always resolves to the newest version, or the version DOI printed on a specific release for the exact bytes you ran.

License

Copyright © 2026 Henri Sirkkavaara. Licensed under AGPL-3.0-or-later. See LICENSE.

Available Tools

4 tools
vaara_checkA

Check the risk level of an action BEFORE executing it. Returns a risk assessment with point estimate, conformal interval, and recommended decision (allow/deny/escalate). Does NOT record to the audit trail — use vaara_intercept for that.

ParametersJSON Schema
NameRequiredDescriptionDefault
agent_idNoIdentifier for the agent requesting the actionmcp-agent
tool_nameYesThe tool/action to check (e.g., 'tx.transfer', 'data.delete')
confidenceNoAgent's self-assessed confidence in the action (0.0-1.0)
parametersNoAction parameters (optional, for context)

TDQS

A4.4/5.0
Behavior4/5

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

No annotations exist, so the description carries the full burden, and it does disclose the important non-side-effect: it does not write to the audit trail. It also describes the return payload (point estimate, conformal interval, allow/deny/escalate decision). It does not mention auth requirements, latency, or whether the check itself is logged anywhere, leaving a modest gap.

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

Conciseness5/5

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

Three short sentences, front-loaded with the primary purpose, then the return shape, then the sibling disambiguation. No filler or repetition; every sentence earns its place.

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

Completeness4/5

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

There is no output schema, but the description compensates by enumerating the return values. Purpose, return shape, and the critical non-recording behavior are covered for a non-mutating check tool; minor gaps like auth or latency expectations remain.

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

Parameters3/5

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

Schema description coverage is 100%, so all four parameters (agent_id, tool_name, confidence, parameters) are already documented in the schema. The description adds no parameter-level meaning beyond what the schema provides, so the baseline of 3 applies.

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

Purpose5/5

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

States a specific verb (Check) and resource (risk level of an action), with a clear scope qualifier ('BEFORE executing it'). It explicitly distinguishes itself from the closest sibling by naming vaara_intercept as the tool that records to the audit trail.

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

Usage Guidelines5/5

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

Gives the when ('BEFORE executing it'), the when-not ('Does NOT record to the audit trail'), and the alternative ('use vaara_intercept for that'). This is an explicit routing rule an agent can act on without inference.

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

vaara_interceptA

Intercept an action with full risk scoring and audit trail. Classifies the action, scores risk with conformal prediction, decides allow/deny/escalate, and records everything in a tamper-evident audit trail. Returns the decision and action_id for later outcome reporting.

ParametersJSON Schema
NameRequiredDescriptionDefault
agent_idNoIdentifier for the agentmcp-agent
tool_nameYesThe tool/action to intercept
confidenceNoAgent's self-assessed confidence (0.0-1.0)
parametersNoAction parameters
session_idNoSession identifier for grouping related actions

TDQS

A3.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does reasonably well: it discloses the decision space (allow/deny/escalate), that scoring uses conformal prediction, and that a tamper-evident audit record is written. It stops short of saying whether the intercepted action is actually blocked or whether execution is the caller's responsibility, which is important for a mutation-adjacent gate.

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

Conciseness4/5

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

Three tight sentences, front-loaded with the core purpose before the sub-steps and the return note. Slight redundancy between 'risk scoring' in sentence one and 'scores risk with conformal prediction' in sentence two, but overall efficient.

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

Completeness4/5

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

Absent an output schema, the description usefully states what is returned (the decision and action_id). Given the multi-stage behavior and five parameters, the coverage is good, though the missing routing guidance relative to vaara_check leaves a genuine gap for an agent choosing between the two.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all five parameters, including agent_id, confidence, parameters, and session_id. The description adds no format, constraint, or example meaning beyond that, so the baseline 3 applies.

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

Purpose4/5

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

Names a specific verb ('Intercept') and resource ('an action') and enumerates the pipeline it runs (classify, score, decide, record). It is clear what the tool does, but it never distinguishes itself from the sibling vaara_check, which an agent could easily 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.

Usage Guidelines2/5

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

No when-to-use guidance is given: it never says when to prefer this over vaara_check, whether it must precede vaara_report_outcome, or what preconditions apply. The only hint of usage is the trailing mention of action_id 'for later outcome reporting', which implies sequencing but states nothing explicit.

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

vaara_report_outcomeA

Report what happened after an action was executed. This closes the feedback loop — the scorer learns from outcomes to improve future risk assessments. Provide the action_id from vaara_intercept and the observed severity.

ParametersJSON Schema
NameRequiredDescriptionDefault
action_idYesThe action_id returned by vaara_intercept
descriptionNoHuman-readable description of what happened
outcome_severityYesHow severe was the outcome? 0.0 = completely safe, 1.0 = catastrophic

TDQS

A3.6/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral burden. It does disclose a genuine non-obvious trait — that the reported outcome feeds a scorer that improves future risk assessments — but says nothing about auth requirements, whether reporting is mandatory or idempotent, or what happens on an unknown action_id.

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

Conciseness4/5

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

Short, front-loaded with the action, and the rationale sentence earns its place by explaining the feedback loop. The final instruction sentence is mildly redundant with the schema's parameter descriptions.

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

Completeness3/5

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

All three parameters are documented via the schema, but with no annotations and no output schema the description should ideally state what a successful report returns or what happens if the action_id is unknown. It covers the why but not the mechanics.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents action_id, outcome_severity (with its 0.0–1.0 scale) and description. The prose mostly restates the schema's own hints rather than adding format or edge-case guidance, so the baseline 3 applies.

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

Purpose4/5

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

States a specific verb and resource — reporting the observed outcome of an executed action — and ties itself to vaara_intercept as the source of the action_id. It does not explicitly differentiate itself from vaara_verify_receipt, so an agent must infer the boundary between 'report outcome' and 'verify receipt'.

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

Usage Guidelines4/5

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

The timing is explicit ('after an action was executed') and the data provenance is stated ('the action_id from vaara_intercept'), which gives clear context for when to call it. It stops short of naming when not to use it or contrasting it with vaara_verify_receipt/vaara_check.

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

vaara_verify_receiptA

Verify a signed decision receipt: its signature, and that the evidence it carries is the evidence it signed. For a receipt under this server's own key it also checks that the record it names is in this server's audit trail. Pass the receipt file's JSON as 'receipt'. The server's key is used unless 'public_key_pem' names another issuer's key; then the trail is not checked.

ParametersJSON Schema
NameRequiredDescriptionDefault
receiptYesThe receipt file's JSON: {"receipt": ..., "evidence": ...}
public_key_pemNoIssuer public key, PEM (optional; defaults to this server's key)

TDQS

A4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden, and it does disclose meaningful behavior: two distinct verification steps (signature, evidence binding) plus a conditional third check that depends on whose key is used, including the non-obvious consequence that the audit-trail check is skipped for foreign keys. The notable gap is that it never indicates what the result looks like (valid/invalid verdict, failure mode), and there is no output schema to cover that.

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

Conciseness4/5

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

Roughly four sentences, front-loaded with the purpose before the conditional details, and each sentence carries information. It is slightly more verbose than strictly needed — the 'Pass the receipt file's JSON as receipt' instruction largely duplicates the 100%-covered schema — but nothing is wasted or buried.

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

Completeness3/5

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

For a verification tool with a nested-object parameter and no output schema, the description covers the checks performed and the key-dependent branching but says nothing about the shape of the verdict or error results, which the agent must know to interpret a call. Moderate complexity is covered adequately for inputs, incompletely for outcomes.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning beyond the schema: it explains that 'receipt' takes the receipt file's JSON as-is, and it spells out the semantic consequence of supplying 'public_key_pem' (a foreign issuer's key disables the trail check) rather than merely restating the default.

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

Purpose5/5

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

The description names a specific verb and resource — verify a signed decision receipt — and enumerates exactly what is verified: the signature and the binding between the evidence and what was signed. That is clearly distinct from the sibling tools vaara_check, vaara_intercept, and vaara_report_outcome, none of which share this verify-a-receipt purpose.

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

Usage Guidelines3/5

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

Usage is implied rather than stated: an agent can infer this is the tool for validating a receipt it holds, and the description notes that passing another issuer's key skips the trail check. But there is no explicit when-to-use vs. when-to-use-something-else guidance relative to the sibling tools, and no statement of prerequisites beyond the conditional key behavior.

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

Tool Schema Changelog

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

  1. 4 tool updatesv2.14.0
    • First observedvaara_check
    • First observedvaara_intercept
    • First observedvaara_report_outcome
    • First observedvaara_verify_receipt

TDQS

A3.9/5.0

Scored across 4 tools

Disambiguation4/5

vaara_check and vaara_intercept overlap substantially—both classify, score risk with conformal prediction, and return allow/deny/escalate. The descriptions explicitly differentiate them (check = no audit recording; intercept = full audit trail), which resolves most confusion, but the boundary still requires careful reading.

Naming Consistency5/5

All four tools follow a strict 'vaara_' prefix plus clear verb_noun pattern (check, intercept, report_outcome, verify_receipt). The convention is predictable and readable throughout.

Tool Count4/5

Four tools is a tight, well-scoped set for a risk-scoring and governance service, and each has a distinct role in the decision lifecycle. Slightly thin but no tool feels redundant or filler.

Completeness4/5

The set covers scoring, interception with audit recording, outcome feedback, and receipt verification, forming a closed loop. A read/list tool for the audit trail itself is absent, a minor gap agents could work around via verify_receipt.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    A
    maintenance
    A governance proxy for AI tools — every MCP/agent tool call is policy-gated, secret-redacted, and written to a hash-chained, offline-verifiable audit trail.
    13
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides permission gates and tamper-evident audit logging for AI agent tool executions, with declarative policies, consent ladders, and hash-chained verification.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Tamper-evident audit trail for AI agent tool calls. Cryptographically signed, hash-chained records that prove what your agents did.
    3
    11 npm
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enforces policy controls for AI agents, including spend limits, action approvals, kill switch, scoped credentials, dry-run diffs, loop prevention, and auditable hash-chained logs.
    MIT