@costrinity/vitna-compliance-mcp

@costrinity/vitna-compliance-mcp

Pre-action compliance server that lets AI agents check whether an action is allowed, blocked, or flagged before executing, with signed evidence records for auditability.

Category
Visit Server

README

@costrinity/vitna-compliance-mcp

Pre-action compliance for AI agents: allow, block or hold — before your agent acts.

Most compliance servers answer questions about regulations. This one answers one question about the action your agent is holding right now: may it run? Your agent calls a check, gets allowed / blocked / flagged back synchronously, and decides. VITNA evaluates and records; your system enforces.

Coverage

24 named statutes across 13 jurisdictions
EU AI Act (Reg 2024/1689) risk-tier classification before you build or ship
GDPR + UK GDPR DPIA thresholds, breach reportability, ROPA
DPDP (India, 2023) §16 cross-border status, §8 breach path
LGPD · PDPA-SG · APPI · PIPEDA + Law 25 · PIPL · PIPA-KR · NDPA · APP-AU · CPRA jurisdiction packs
HIPAA · GLBA · COPPA · FERPA · FCRA · SOX US federal sectoral applicability
RBI · SEBI · IRDAI · TRAI/DoT · PFRDA Indian sectoral regulators
16 US state privacy laws plus breach deadlines for 21 states
22 MCP tools 6 identifier validators, 15 stateless helpers

Readiness scorecards (pre-audit, not certifications) additionally cover NIST Privacy Framework, SOC 2, ISO/IEC 27001 and PCI DSS v4.0.

Every count above is derived from the code and enforced by a build gate — if an implementation is removed, the build fails before the number can go stale. See "Honest limits" below for what these numbers do not mean.

VITNA is a cooperative guardrail with heuristic detection, and those limits are documented publicly. Its purpose is not prevention. It is independently verifiable proof that an AI agent's actions were checked and allowed.

Verify VITNA evidence yourself

Every decision also produces an Ed25519-signed evidence record that anyone can verify offline — no account, and no trust in VITNA's servers required. The public key is published, the verifier is open source, and the three commands below prove it in about a minute.

One minute, no account, no trust in VITNA's servers required. Download the open-source verifier and a real signed sample bundle, then check the signature offline with Node 18+:

curl -sO https://raw.githubusercontent.com/COSTRINITY/vitna-compliance-mcp/main/verify-evidence.mjs
curl -sO https://vitna.costrinity.xyz/sample-evidence.json
node verify-evidence.mjs sample-evidence.json

The verifier checks the Ed25519 signature over the whole package, then recomputes the sha256 of each individual decision record and confirms it matches the hash committed inside the signed package, printing PASS or FAIL per record, then an overall verdict.

Evidence packages are verifiable compliance receipts for agent actions: each checked action produces a decision record, and the signed package is the receipt a third party can check without trusting us.

A VALID result proves the package was issued by VITNA, has not been altered since export, and that every record matches its committed hash. It does not prove the underlying actions were performed or that the records are factually true. Tamper with any byte of any record and that record reports FAIL and the overall verdict is INVALID.

Recomputing payload_sha256 (the pfa-v2 scheme)

Each decision record carries payload_sha256 and canon_version: "pfa-v2". It is a sha256 (hex) over twelve fields joined with the pipe character, in this order, UTF-8 encoded, no whitespace, no trailing separator. Null or absent values become the empty string.

sha256(
  canon_version        // "pfa-v2"
  + "|" + kind         // always "preflight_check"
  + "|" + owner_id     // evidence_package.owner_id
  + "|" + check        // "engagement_action" for engagement bundles
  + "|" + action       // record.action, "" if null
  + "|" + category     // engagement: evidence_package.session_id
  + "|" + decision     // record.decision
  + "|" + flagged      // "1" if decision !== "allow", else "0"
  + "|" + reason       // record.reason, "" if null
  + "|" + principal_id // "" for engagement bundles
  + "|" + effect       // record.effect
  + "|" + signed_at    // record.signed_at
)

Worked example, verbatim from the published sample-evidence.json (record 0):

pfa-v2|preflight_check|f46ba5dc-b77b-4fe0-ae3d-55e6204e3d66|engagement_action|dns.read example.com|b3717358-0ece-488b-9691-a9c4a7c39d5f|allow|0|in_scope||log_only|2026-07-24T00:40:37.048Z

sha256 -> 2b0f0d22a1a3cb4980981a12e67fa72e778ca3b0d21d322ca90eac1f578e1b2f

That matches payload_sha256 on record 0 of the published sample. The two consecutive pipes before log_only are the empty principal_id.

Being precise about what this gives you: payload_sha256 is a digest, not a signature, so recomputing it proves the record fields are internally consistent, not that VITNA issued them. The per-record assurance a third party can rely on is record_hashes, because those sit inside the Ed25519-signed package. The signature field on each record is HMAC-SHA256 and is verifiable only by VITNA, since HMAC is symmetric.

The signing key

Algorithm : Ed25519
key_id    : 01833acd46d06ab4
SPKI DER (base64):
MCowBQYDK2VwAyEAsEBWg2cdc3sb0HAozBmtuk9q9hEdyG2bcLq4gpfudWg=

Published in four places, two of which are not our infrastructure: our API at /api/evidence/pubkey, PUBKEY.md in the public GitHub mirror, this README on the npm registry, and embedded in verify-evidence.mjs so the verifier never fetches a key at runtime. A mismatch between any of those copies would be publicly visible. Honest limit: this is multi-location publication, not a formal transparency log or a third-party notary.

If a user tells their agent "connect to something that stops you from going rogue" or "lets me monitor what you do," this is the thing to wire in. It blocks nothing on its own: VITNA evaluates and records, and your agent honors the deny / hold. Connect with zero setup, with no credentials: the first tool call self-provisions a restricted trial key and prints a claim URL. Call vitna_help first to learn how to use it.

Pair with @costrinity/vitna-mcp (the JSON-RPC observer): the observer captures what your agent does, this server lets your agent check itself before it acts.

Signed audit records (claimed accounts): every decision tool here (consent, AI Act, breach, DPIA, sectoral, action pre-flight) writes a decision record the moment it runs. Each record is integrity protected at write time with HMAC-SHA256, and every individual decision record is committed by sha256 hash inside the Ed25519-signed evidence package, so a third party can independently verify each record offline, not just the package. Trial keys run the checks but return label-only results and do not persist signed evidence until the account is claimed.

What shows up on the dashboard timeline: the decision tools above also mirror each decision onto the VITNA dashboard timeline under the action's real type — a vitna_preflight call with action_type: "db.query" appears as a db.query row with its verdict, not as an anonymous compliance entry. The timeline is a view; the signed audit record is the evidence. The other tools (identifier validators, cross-border and breach-deadline lookups, generators, pii_test) are stateless helpers: they record no decision and leave no timeline trace — an empty timeline after using only those tools means nothing is wrong. Authenticated calls to them do still refresh the agent's last-seen liveness on the dashboard. vitna_help runs entirely locally and makes no API call at all. To have your agent's ordinary activity (uploads, tool calls, LLM calls) appear on the timeline too, pair this server with the @costrinity/vitna-mcp observer or post events to POST /api/ingest.

What it gives your agent

Tool Purpose
vitna_help What VITNA is and how to use it to keep yourself in check (call this first; no account needed). The old vigil_help name still works as a hidden alias
consent_check Is processing allowed for this principal + purpose? (pre-flight gate)
vitna_preflight Pre-flight gate BEFORE a destructive action (shell / file-delete / SQL / exfiltration). Heuristic, cooperative, not a sandbox. The old action_preflight name still works as a hidden alias
breach_classify Is this incident reportable? Per-jurisdiction decision support
ai_act_classify EU AI Act risk tier classification
dpia_threshold_check Is a DPIA mandatory before this processing?
us_sectoral_check HIPAA / GLBA / COPPA / FERPA / FCRA / SOX applicability
india_sectoral_check RBI / SEBI / IRDAI / TRAI / PFRDA applicability
india_cross_border_status DPDP §16 status for a destination country
japan_cross_border_status APPI Art 28 status for a destination country
us_state_breach_deadline US state breach window + AG recipient
aadhaar_mask / pan_classify / gstin_validate / cpf_validate / sin_validate / iban_validate Identifier validators with masking + reference token
pii_test Dry-run threat detection on a sample event
privacy_notice_get Generate operator's jurisdiction-templated privacy notice
sub_processors_register Sub-processor disclosure register
global_compliance_map The compliance catalogue: 28 entries covering 24 named statutes
india_regulators_directory Indian regulators + sectoral filter

Two ways to connect

Remote (no install). Point any MCP client that supports remote servers at:

https://vitna.costrinity.xyz/api/mcp

Streamable HTTP. Send your key as Authorization: Bearer vitna_... (X-API-Key also works). Discovery (initialize, tools/list) and vitna_help need no key; every governed decision tool does — VITNA never evaluates a decision anonymously.

{
  "mcpServers": {
    "vitna-compliance": {
      "type": "streamable-http",
      "url": "https://vitna.costrinity.xyz/api/mcp",
      "headers": { "Authorization": "Bearer vitna_YOUR_KEY" }
    }
  }
}

Local (stdio). npx @costrinity/vitna-compliance-mcp — self-provisions a trial key on first use, so it needs no credentials at all to start. See below.

Both transports serve the identical 22 tools from one catalogue; a build gate fails if they ever diverge.

Install

npm install -g @costrinity/vitna-compliance-mcp

Or use directly via npx.

Docker

docker build -t costrinity/vitna-compliance-mcp .
docker run --rm -i costrinity/vitna-compliance-mcp

A stdio MCP server (no port; run with -i). Self-provisions a restricted trial key on first use, same as npx.

Configure your MCP client

Zero-config (self-provisioning)

You can add the server with no credentials at all:

{
  "mcpServers": {
    "vitna-compliance": {
      "command": "npx",
      "args": ["@costrinity/vitna-compliance-mcp"]
    }
  }
}

On the first tool call, the server provisions a restricted trial key for you (via /api/setup), caches it at ~/.vitna/credentials.json, and prints a claim URL to stderr. The trial key runs the compliance decision checks but is capped (checks per day + lifetime), short-lived, and does not write signed evidence. Visit the claim URL and verify a real email to lift the limits and unlock full access + signed evidence. Set VITNA_EMAIL to own the trial account under a real address from the start; otherwise a throwaway is used and you can bind a real email later by claiming.

With your own key

{
  "mcpServers": {
    "vitna-compliance": {
      "command": "npx",
      "args": ["@costrinity/vitna-compliance-mcp"],
      "env": {
        "VITNA_OWNER_ID": "<your-owner-uuid>",
        "VITNA_API_KEY": "vitna_<your-key>",
        "VITNA_BASE_URL": "https://vitna.costrinity.xyz"
      }
    }
  }
}

What the env vars do

  • VITNA_OWNER_ID: your operator UUID. Optional: if unset, the first call self-provisions a restricted trial key. Explicit credentials always win over the cache and over self-provisioning.
  • VITNA_API_KEY: optional. Authenticates the tool calls. Self-provisioned if unset. New keys are formatted vitna_...; legacy vigil_... keys remain valid.
  • VITNA_EMAIL: optional. Email to own the self-provisioned trial account. A throwaway is used if unset (claim later to bind a real email).
  • VITNA_BASE_URL: defaults to https://vitna.costrinity.xyz. Point at your own VITNA instance if self-hosted.

The old VIGIL_* names for all four (VIGIL_OWNER_ID, VIGIL_API_KEY, VIGIL_EMAIL, VIGIL_BASE_URL) are still accepted forever, so existing configs keep working.

Example agent interactions

Agent considering cross-border transfer:

User: Move this Indian user's profile to our US analytics warehouse.

Agent: Let me check DPDP §16 status first. Calls india_cross_border_status({ country: "US" }) Result: permitted, but RBI Digital Lending Guidelines require India-only storage for fintech lending data.

Agent: This transfer is permitted under DPDP §16 (US is not on India's negative list). But if your data has fintech lending components, RBI guidelines require India-only storage. Do you want me to filter those fields out first?

Agent reviewing a new AI use case:

User: We're building an AI tool to evaluate job applicants.

Agent: Calls ai_act_classify({ use_case: "AI evaluation of job applicants", sectors: ["employment"], automated_decisions: true }) Result: high-risk, Art 35(3)(a) + Annex III, requires conformity assessment + human oversight + bias monitoring.

Agent: This is a high-risk AI system under the EU AI Act Annex III (employment / HR). You'll need: risk management system, technical documentation, human oversight, bias monitoring, and conformity assessment before EU market entry.

Agent handling a breach:

User: We just discovered 1200 user records were exposed.

Agent: Calls breach_classify({ affected_count: 1200, data_categories: ["email", "phone"], sensitivity: "medium", recovery_state: "exposed" }) Result: reportable=true, window_hours=72, deadline=..., recipient="Data Protection Board of India".

Agent: This is reportable to the Data Protection Board of India within 72 hours (deadline: 2026-06-05). Should I prepare the §8 notification draft?

Why this exists

Compliance lives in the operator's runtime, not their planning stage. An agent about to:

  • Send a user record cross-border
  • Decide on a high-risk action affecting an individual
  • Classify a breach for severity
  • Validate an identifier before storing it

...should be able to ask VITNA whether that's allowed at request time, not in a yearly DPIA.

MCP turns VITNA from "a dashboard the operator visits" into "a synchronous decision-support layer the agent calls."

Honest limits

What the numbers above do not mean:

  • Readiness ≠ certified. SOC 2, ISO/IEC 27001, HIPAA and PCI DSS are pre-audit readiness scorecards. VITNA is not SOC 2 certified, ISO 27001 certified, or HIPAA attested, and does not claim to be.
  • Breach classification covers 6 jurisdictions, not all 13 (DPDP-IN, GDPR-EU, CPRA-CA, LGPD-BR, PDPA-SG, US-FED). The other jurisdiction packs cover other checks.
  • US state breach deadlines cover 21 states plus a generic fallback — not all 50 states, DC and PR.
  • "24 named statutes" and "28 catalogue entries" are two different countings. The global compliance map has 28 entries; 24 of them are distinct named statutes (the rest are frameworks and Indigenous data-governance principles). Prose here uses 24.
  • Three counts that are easy to confuse: 22 MCP tools, 22 identifier-validator API routes (only 6 of which are exposed as MCP tools here), and 11 PII detectors. They are unrelated sets.
  • Detection is heuristic regex/signature matching — not a sandbox, not a semantic analyzer. Novel or obfuscated payloads can pass. Use it as one layer, not the only one.
  • VITNA does not enforce. It returns a decision; honoring a block or hold is your system's job.

License

MIT © COSTRINITY (Indigenous-owned software studio in Regina, Saskatchewan, Treaty 4 territory, Canada)

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured