Free regulatory advisory in any MCP client, and five instrumentation paths from a one-line connection to full production capture. Every audit report states which path produced its evidence.
Regulatory guidance citing fourteen regulatory instruments across the six frameworks Truveil scores, in Claude, ChatGPT, or any MCP-compatible client. Know what the law requires before you instrument.
MCP connector, Node SDK, Python SDK, HTTP API, or the n8n community node. Every path feeds the same tamper-evident AI agent audit trail.
Before you instrument anything, Truveil answers the question every agent builder has: what does the law actually require of my agent, and where is my design exposed? The Advisory tools are free.
Six frameworks are scored, which means graded against:
Singapore's framework is two instruments, and Truveil names both: the Model AI Governance Framework for Generative AI and the Model AI Governance Framework for Agentic AI.
Fourteen regulatory instruments are cited, which means quoted with provisions: those seven, plus:
NYC Local Law 144 and DCWP's rules bind only where an automated tool screens candidates or employees for a New York City job.
One of the six frameworks scored. Included in every tier.
Three tools, available the moment you connect:
Describe the agent you are building and get build-specific guidance: which obligations attach, which oversight pattern fits, what your audit trail needs to capture.
Ask about a specific provision and get the authoritative text with Truveil's plain-language reading alongside it.
A structured overview of AI governance for any jurisdiction Truveil covers, useful before you enter a new market.
Connect the Truveil MCP to Claude, ChatGPT, or any MCP-compatible client with your per-user API key sent as the x-client-secret header. Advisory works anywhere MCP reaches, including as an external tool inside an n8n agent node.
When you have Truveil's advisory MCP connected to your client, the LLM does not always know when to route to Truveil versus answer from its own training. The phrase "Use Truveil" is the explicit routing instruction.
You can also call Truveil's advisory in normal chat without the explicit phrase. The LLM will route to Truveil when the question is regulatory in nature, but the "Use Truveil" phrase explicitly triggers the routing. Worth using when you want primary-source citations rather than the LLM's training-data answer.
Example promptUse Truveil to advise on the following build: We're an insurance startup launching a claims-triage AI in 2027. The system reviews motor, home, and travel insurance claims with photos and prior claim history. Auto-settles approvals under £5,000. Expanding to EU and UAE within 18 months. What regulatory obligations apply, and which should we resolve first?
Advisory tells you what accountability requires. The five paths below are how your agent proves it.
Request accessConnect Truveil as an MCP tool to Claude, ChatGPT, or any MCP-compatible client. One connection, no code. Your conversational agent's decisions, disclosures, and human checkpoints are captured through natural tool use, and a full audit report is one request away.
Setup: add https://mcp.truveil.app/mcp to your client as a custom connector. If your client supports connector sign-in, it opens a Truveil sign-in page and no key is needed. If it asks for a header instead, send your per-user API key, from Connect agent in your dashboard, as the x-client-secret header. Either route needs a Truveil account.
MCP clients cache tool lists. After Truveil ships updates, refresh your connector to reload the current tools.
The audit MCP exposes eight instrumentation tools through the standard MCP protocol. Same Schema-v2 evidence model. Same regulatory grounding. Same audit reports.
Register your agent at session start. Same parameters as the SDK.
Log every state change. Same parameters as the SDK.
Log every reasoning step. Same parameters as the SDK.
Record a checkpoint request before a decision in the consequential allowlist; returns an approval_id. Parameters: decision_type and context (required); run_id, project and agent_id (optional). Pass project, or the agent_id of an agent registered to your account; with neither, the request is refused.
Generic approval gate. Same parameters as the SDK.
Retrieve your agent's registration and recent run history. Use for self-awareness when adapting strategy based on prior audit results.
Retrieve recent log entries. Use to verify what has been recorded, debug missing events, or reconstruct prior runs.
Ask whether a run's audit record is complete enough to be graded, without scoring it. Read-only, leaves no record, never returns a grade: it names the signals still lacking structured evidence and exactly what clears each grading-floor condition in force. Call it near the end of a run, not after every log write.
A single dependency-free file you vendor into your codebase. No package manager, no supply chain, no transitive risk. Version 0.2.0 carries the capture contract: register the agent once, open a run handle, and each named method writes the typed row the engine scores. A decision's reasoning, confidence and human review travel on the decision itself. Every call states its own risk level: the SDK never rates your agent's actions for you.
JavaScriptconst Truveil = require('./truveil');
const truveil = new Truveil(
'https://api.truveil.app',
'your-truveil-api-key',
'My Agent'
);
await truveil.registerAgent({
agent_category: 1,
intended_purpose: 'Screens job applications and recommends candidates for interview',
owner_email: 'talent-ops@example.com',
risk_assessment_ref: 'DPIA-HR-7',
risk_assessment_date: '2026-09-01', // when that assessment was completed
retention_policy_ref: 'RET-HR-2Y',
});
const run = truveil.run();
run.oversightMode('human_in_loop', 'LOW');
run.disclosure('This screening is AI-generated decision support.', 'LOW');
run.provenance([{ source: 'ats', fetched_at: new Date().toISOString(), version: '3' }], 'LOW');
run.freshness(true, 'LOW');
run.validation('ats', true, 'LOW');
run.biasCheck({ selection_rate_ratio: 0.91 }, 'MEDIUM');
for (const item of pipeline) {
run.decision(item.id, {
outcome: item.verdict,
reasoning: item.reason,
confidence: item.score / 100,
human_checkpoint: Boolean(item.reviewer), // true only once a person has decided
approver: item.reviewer,
risk: 'HIGH',
});
run.sources(item.sources, 'LOW', { confidence: item.score / 100 });
}
run.groundedness(0.9, 'LOW');
run.overrideAvailable('recruiter console', 'LOW');
run.killSwitch(true, 'LOW');
run.reversible(true, 'LOW');
run.versioned('screener-1.2', 'LOW');
run.appealChannel('appeals@example.com', 'LOW');
run.correctionWorkflow('hr-corrections', 'LOW');
// Near the end of the run: is this record complete enough to be graded?
// Read-only, writes nothing, never returns a grade.
const check = await run.readiness();
console.log(check.summary); // and each condition still in force names what clears it
require('./truveil') resolves to it.
Fire-and-forget by design: a logging failure never blocks your agent. Per-subject decision records, stage completions that record what happened rather than what was about to happen, and named methods for the signals your agent genuinely has, each writing the typed row the engine reads. A standalone explanation, confidence or human-checkpoint call earns credit only when it names the decision it describes, so put those on the decision. The SDK never infers or manufactures evidence; it makes truthful capture effortless.
The identical 0.2.0 capture contract, ported method for method, with a parity test holding both SDKs to the same engine-read fields. If your agent is Python, nothing is lost in translation. The same vendored-file framing applies: one readable file, no package manager, no supply chain.
Pythonfrom truveil_sdk import TruveilSDK
sdk = TruveilSDK(
'https://api.truveil.app',
'your-truveil-api-key',
'My Agent',
)
sdk.register_agent(
agent_category=1,
intended_purpose='Screens job applications and recommends candidates for interview',
owner_email='talent-ops@example.com',
risk_assessment_ref='DPIA-HR-7',
risk_assessment_date='2026-09-01', # when that assessment was completed
retention_policy_ref='RET-HR-2Y',
)
run = sdk.run()
run.oversight_mode('human_in_loop', risk='LOW')
run.disclosure('This screening is AI-generated decision support.', risk='LOW')
run.provenance([{'source': 'ats', 'fetched_at': '2026-09-16T10:00:00Z', 'version': '3'}], risk='LOW')
run.freshness(True, risk='LOW')
run.validation('ats', True, risk='LOW')
run.bias_check({'selection_rate_ratio': 0.91}, risk='MEDIUM')
for item in pipeline:
run.decision(
item.id,
outcome=item.verdict,
reasoning=item.reason,
confidence=item.score / 100,
human_checkpoint=bool(item.reviewer), # True only once a person has decided
approver=item.reviewer,
risk='HIGH',
)
run.sources(item.sources, risk='LOW', confidence=item.score / 100)
run.groundedness(0.9, risk='LOW')
run.override_available('recruiter console', risk='LOW')
run.kill_switch(True, risk='LOW')
run.reversible(True, risk='LOW')
run.versioned('screener-1.2', risk='LOW')
run.appeal_channel('appeals@example.com', risk='LOW')
run.correction_workflow('hr-corrections', risk='LOW')
# Near the end of the run: is this record complete enough to be graded?
# Read-only, writes nothing, never returns a grade.
check = run.readiness()
print(check['summary']) # and each condition still in force names what clears it
from truveil_sdk import TruveilSDK resolves to it.
Everything the SDKs do is available directly over HTTPS. Authenticate every request with your per-user API key as the x-client-secret header, and log from any language or runtime. The Advisory REST API under /v1/advisory is the one exception on this host: it takes the same key as an Authorization: Bearer token, as shown in Custom GPT setup below.
Terminalcurl -X POST https://api.truveil.app/log \
-H "Content-Type: application/json" \
-H "x-client-secret: your-truveil-api-key" \
-d '{
"project": "My Agent",
"agent": "My Agent",
"run_id": "run_20260712_a1b2c3",
"step": 4,
"action": "decision: applicant-1042",
"detail": "REJECT | income verification failed on two sources",
"event_type": "synthesis",
"confidence": 0.82
}'
Send project on every call: it is the key a report is assembled under, and a row without one belongs to no project and can never be scored. step and event_type are what make a row legible to the engine — step is the only evidence of the order the run ran in, and two fields are read only on a typed row, so the sources you cite count on an output or synthesis event and your data provenance counts on an ingestion one. risk is the opposite case and is deliberately absent above: omit it unless you have actually assessed a level, because the row then records that you did not say, rather than a level Truveil picked for you.
When the run is nearly done, one read-only GET says whether its record is complete enough to be graded — it writes nothing, leaves no record, and never returns a grade. Each grading-floor condition still in force names exactly what clears it. Ask at the end of the run, not after every log write.
Terminalcurl "https://api.truveil.app/run/readiness?project=My%20Agent&run_id=run_20260712_a1b2c3" \ -H "x-client-secret: your-truveil-api-key"
The SDKs are thin, readable wrappers over this surface. If you want to see exactly what they send, read the file; it is one file.
n8n integrates through the dedicated community node, n8n-nodes-truveil, built in n8n's native node format. Install the node, create a Truveil API credential with your per-user API key (sent as x-client-secret), and add Truveil steps to any workflow. The node has six operations: Register Agent, Log Action, Log Decision, Request Approval, Request Consequential Decision, and Check Run Readiness — a read-only step for the end of the workflow (node version 0.3.0 or later) that says whether the run's record is complete enough to be graded, and names exactly what clears each floor condition still in force. It writes nothing and never returns a grade.
One placement decides whether the run can be scored at all: put a Log Action with Event Type ingestion straight after the node that reads your data. Provenance is credited only on an ingestion-typed event, so a run without one evidences nothing in Data Trust, and the audit withholds a grade rather than describe three dimensions as four. The node counts the step ordering for you and types everything else sensibly; this is the one call it cannot make on your behalf, because whether a step read external data is not something n8n can see from outside. Requires the node at version 0.2.0 or later.
In n8n: Settings, Community Nodes, Install, then enter n8n-nodes-truveil.
This is a purpose-built node, not an MCP attachment. Your credential is stored in n8n's credential vault and sent as a header, never in a URL.
Whichever path you choose, the outcome is the same: events land in the live feed within seconds, newest first, already graded for risk.
Truveil reports carry an instrumentation coverage line: which integration path produced the evidence, how many events were actually logged, and what that path structurally cannot observe. Steps reconstructed from sparse evidence are visibly marked as inferred, distinct from steps backed by logged events.
An MCP-instrumented report and an SDK-instrumented report are both honest about their coverage. That difference is printed on the page, not hidden in a methodology PDF. If you want a stronger evidence base, the report itself shows you exactly which integration upgrade earns it.
Provenance also weighs who authored each piece of evidence. Harness-recorded capture earns full standing, while an agent's own attestations about human oversight are capped, whatever they claim. So when someone asks who authorised an action, the answer is a field in the record with its authorship stated, not a recollection.
No accountability vendor discloses instrumentation provenance. We think an audit that will not tell you how it knows is not an audit.
Truveil's Custom GPT exposes the same advisory tools as the MCP via ChatGPT's OpenAPI Action surface. For ChatGPT users who prefer not to install MCP directly.
The Truveil Custom GPT is a pre-built GPT installed from the GPT Store. The advisory schema is already configured. Setup takes one click.
Building your own GPT action instead? The schema below is generated from the live Advisory REST API’s own validator, so every field, every required marker, every enum and the error shape are what the server actually enforces — paste it and the action works without editing. It accepts your API key only as a Bearer token (Authorization: Bearer). The MCP connector, the HTTP logging API, and the n8n node are documented on this page with the x-client-secret header instead. Note the enums are lowercase and case-sensitive: eu is accepted where EU is refused.
{
"openapi": "3.1.0",
"info": {
"title": "Truveil Advisory",
"version": "1.2.0",
"description": "Regulatory and build advisory grounded in primary regulatory text. Read-only: nothing here writes an audit log. Every enum below is lowercase and case-sensitive."
},
"servers": [{ "url": "https://api.truveil.app" }],
"security": [{ "BearerAuth": [] }],
"components": {
"securitySchemes": {
"BearerAuth": {
"type": "http",
"scheme": "bearer",
"description": "Your Truveil API key as a Bearer token"
}
},
"schemas": {
"Error": {
"type": "object",
"required": ["error"],
"properties": {
"error": {
"type": "string",
"description": "Machine-readable code: invalid_input, missing_bearer_token, invalid_token, rate_limited or internal_error."
},
"details": {
"type": "string",
"description": "On invalid_input only. Names the field and what was expected, for example: query: Invalid input: expected string, received undefined"
}
}
}
},
"responses": {
"BadRequest": {
"description": "invalid_input. A required field is missing, or a value falls outside a closed enum. The enums are lowercase; 'EU' is rejected where 'eu' is accepted.",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
},
"Unauthorized": {
"description": "missing_bearer_token when the Authorization header is absent or empty; invalid_token when the key does not resolve to an account.",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
},
"RateLimited": {
"description": "rate_limited. 60 requests per minute per account. Carries a Retry-After header and retry_after_seconds in the body.",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
},
"ServerError": {
"description": "internal_error. No detail is returned by design.",
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
}
}
},
"paths": {
"/v1/advisory/start": {
"post": {
"operationId": "routeIntent",
"summary": "Route an ambiguous request to the right advisory operation",
"description": "Call this when the user says something like 'use Truveil' without saying what for. It classifies the intent and names the operation to call next.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["user_intent"],
"properties": {
"user_intent": {
"type": "string",
"description": "The user's request in their own words. Pass through their exact phrasing if possible."
}
}
}
}
}
},
"responses": {
"200": {
"description": "The routing decision. result is the text to show the user; intent is the classification; recommended_tool names the next operation, or is null when the request is still ambiguous.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"result": { "type": "string" },
"intent": { "type": "string" },
"recommended_tool": { "type": ["string", "null"] },
"build_count": { "type": "integer" },
"remaining": { "type": "integer" }
}
}
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"429": { "$ref": "#/components/responses/RateLimited" },
"500": { "$ref": "#/components/responses/ServerError" }
}
}
},
"/v1/advisory/consult-regulation": {
"post": {
"operationId": "consultRegulation",
"summary": "Answer a regulatory question from primary text",
"description": "Use this for a question about what a regulation requires. The answer cites the instrument and subsection it came from.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["query"],
"properties": {
"query": {
"type": "string",
"description": "The user's regulatory question, in their own words."
},
"jurisdiction": {
"type": "string",
"enum": ["eu", "us", "india", "uae", "difc", "adgm", "singapore", "iso", "multi", "auto"],
"description": "Optional jurisdiction filter. Lowercase and case-sensitive: 'EU' is rejected, 'eu' is accepted. Use 'auto' to detect from the query. 'uae' covers UAE PDPL, DIFC DPL, DIFC Regulation 10 and ADGM DPR together; 'difc' and 'adgm' narrow to those regimes. Omit the field entirely rather than sending an empty string."
}
}
}
}
}
},
"responses": {
"200": {
"description": "The answer and its provenance. result is the text to show the user; the remaining fields name the instrument it was drawn from.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"result": { "type": "string" },
"jurisdiction": { "type": "string" },
"framework": { "type": "string" },
"subsection_id": { "type": "string" },
"subsection_title": { "type": "string" },
"citation": { "type": "string" },
"primary_source": { "type": "string" },
"stakes": { "type": "string" }
}
}
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"429": { "$ref": "#/components/responses/RateLimited" },
"500": { "$ref": "#/components/responses/ServerError" }
}
}
},
"/v1/advisory/consult-build": {
"post": {
"operationId": "consultBuild",
"summary": "Assess what a described AI build has to comply with",
"description": "Use this when the user describes something they are building. Returns an executive summary plus numbered deep-dive options; call it again with expand set to one of those option ids for the detail.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["build_description"],
"properties": {
"build_description": {
"type": "string",
"description": "Description of what the user is building: what it does, who it serves, what data it processes, what decisions it makes."
},
"jurisdictions": {
"type": "array",
"items": {
"type": "string",
"enum": ["eu", "us", "india", "uae", "singapore", "iso"]
},
"description": "Jurisdictions where the AI will operate. Lowercase and case-sensitive. Note this list is narrower than the one consultRegulation accepts: no difc, adgm, multi or auto. If not specified, they are inferred from the build description."
},
"specific_concerns": {
"type": "array",
"items": { "type": "string" },
"description": "Optional free-text compliance concerns the user wants addressed, for example: data minimization, human oversight, bias."
},
"expand": {
"type": "string",
"description": "Optional deep-dive path. Omit it for the executive summary plus numbered options. Set it to one of: provider_determination, jurisdiction_specific_compliance:eu (or :us, :india, :uae, :singapore), architectural_risk_analysis:PATTERN_ID, cross_jurisdictional_strategy, full_obligations_list, primary_sources_and_citations."
}
}
}
}
}
},
"responses": {
"200": {
"description": "The assessment. result is the text to show the user; deep_dive_options are the ids to pass back as expand; recommended_option names the one to offer first.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"result": { "type": "string" },
"paywall": { "type": "boolean" },
"consult_build_count": { "type": "integer" },
"summary": { "type": "object" },
"deep_dive_options": { "type": "array", "items": { "type": "object" } },
"recommended_option": { "type": ["object", "null"] },
"expand_response": { "type": ["object", "string", "null"] },
"jurisdictions": { "type": "array", "items": { "type": "string" } },
"stakes": { "type": "string" }
}
}
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"429": { "$ref": "#/components/responses/RateLimited" },
"500": { "$ref": "#/components/responses/ServerError" }
}
}
},
"/v1/advisory/jurisdiction-brief": {
"post": {
"operationId": "getJurisdictionBrief",
"summary": "Brief one jurisdiction or framework",
"description": "Use this when the user asks what applies in a place, rather than asking a specific question. jurisdiction is REQUIRED here, unlike on consultRegulation where it is a filter.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["jurisdiction"],
"properties": {
"jurisdiction": {
"type": "string",
"enum": ["eu", "us", "india", "uae", "singapore", "iso"],
"description": "Jurisdiction or framework to brief. Lowercase and case-sensitive: sending 'EU' returns 400 with the accepted values listed. This list is narrower than consultRegulation's: no difc, adgm, multi or auto."
},
"focus": {
"type": "string",
"enum": ["overview", "high_risk", "data_protection", "penalties", "effective_dates"],
"description": "Optional focus area within the brief. Lowercase and case-sensitive, like every enum here. Omit for the whole brief."
}
}
}
}
}
},
"responses": {
"200": {
"description": "The brief. result is the text to show the user; framework_ids names the instruments it covers.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"result": { "type": "string" },
"jurisdiction": { "type": "string" },
"focus": { "type": "string" },
"framework_ids": { "type": "array", "items": { "type": "string" } },
"framework_count": { "type": "integer" }
}
}
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"429": { "$ref": "#/components/responses/RateLimited" },
"500": { "$ref": "#/components/responses/ServerError" }
}
}
}
}
}
Coming to the public GPT Store soon. Until then, direct install link sent after Truveil signup.
Audit logs are hash-chained and tamper-evident. Verification replays the chain and halts at the first entry it cannot account for, naming that entry — a modification surfaces there or at the entry that follows it. Recorded erasures are bridged, so a lawful deletion reads as an erasure on record, not as tampering. Each account's chain head is countersigned by an independent RFC 3161 timestamping authority, re-anchored whenever the chain grows, so the record's integrity does not rest on Truveil's word.
Native bias screening on logged decision sets for high-consequence categories. Today, the engine scores whether your own bias testing is logged; this brings the analysis in-house.
Scoring thresholds adapt to the agent's declared category, with the category source shown on every report for regulator defensibility.
Findings cite primary regulatory text with jurisdiction-aware, two-layer citations across all six frameworks scored, including ISO/IEC 42001 readiness mapping. Readiness mapping is preparation, not certification.
Advisory is free in any MCP client. When your agent needs to prove itself, five instrumentation paths run from a one-line connection to full production capture.