KYB developer guide
Early access. Security controls are in place. Tool names, input fields, and documentation may change as we incorporate feedback.
This guide shows the shortest working path for business verification: connect an MCP client, find the correct business, verify it, and retrieve the report. Start with sandbox data. Move to live verification only after the flow works end to end.
Before you start
- An MCP client that supports streamable HTTP.
- A business name and country, or a known registration number.
- Start in sandbox so you can test the full flow without billing.
The flow
- Connect. Add
https://mcp.trulioo.com/mcpto your MCP client and complete OAuth. - Find the business. Search by name, or look up the registration rules for the country.
- Confirm the candidate. If search returns more than one business, ask the user to choose before you verify.
- Verify. Call
kyb_verifywith the selected registration identifier. - Handle the result. Follow
next_actionwhen the result is not terminal. Save the transaction ID. - Retrieve the report. Call
kyb_get_reportafter verification completes.
Tools used in this guide
| Search for a business | kyb_search · Tools → |
| Look up registration details | kyb_registration_lookup · Tools → |
| Verify a business | kyb_verify · Tools → |
| Retrieve a completed report | kyb_get_report · Tools → |
Zero to verified
Early access. Security controls are in place. Tool names, input fields, and documentation may change as we incorporate feedback.
One MCP connection gives any agent KYC, KYB, account analytics, and Know Your Agent - the signed identity an agent carries so anyone can prove who is behind it. There is no key to copy-paste - your client enrols itself over OAuth. Here is the whole path.
- Connect the MCP server. Point any MCP client at the hosted endpoint - it discovers the authorization server and registers itself, so there is no key to copy-paste. Client setup →
- Call a verification tool. Run
kyc_verifyorkyb_verifyagainst synthetic test entities and branch on the typed result. Tools → - Give your agent an identity. Verify the organization behind the agent, then mint a signed, scoped attestation with
kya_issue_mandate. Know Your Agent → - Let anyone verify it. Publish the attestation in your A2A card; any party checks it against the issuer JWKS - no key needed. Verify agents →
I want to…
| Verify a person | kyc_verify · Tools → |
| Verify a business | kyb_verify · Tools → |
| View business transaction trends | analytics_query - business profile - Analytics → |
| Review recent business transactions | analytics_list_transactions - business profile - Analytics → |
| See what account analytics can answer | analytics_account_overview - business profile - Analytics → |
| Screen a name on its own | aml_screen - per-account · Tools → |
| Capture a document or a selfie | docv_create_session - per-account · Tools → |
| Prove who is behind an agent | Know Your Agent → |
| Verify another agent's profile (DAP) | kya_verify_agent · Verify agents → |
| Connect an MCP client | Client setup → |
| Authenticate with OAuth | Authentication → |
| Have an agent set this up for me | Let your agent introduce you → |
| Read the docs as an agent | index.md · llms.txt |
Let your agent guide your KYB setup
Paste this into your coding agent. It will check the current connection before asking you to configure anything, then guide one sandbox business verification from discovery through report retrieval.
Paste this to your agent
agent-guide.md is a focused operating guide for this early access workflow. It covers connection checks, OAuth, business search, optional candidate confirmation, verification, non-terminal results, and report retrieval.
It checks before it acts. The guide first looks for an existing Trulioo connection and confirms the session mode. It starts verification only after the developer confirms the correct business.
The MCP endpoint
One hosted endpoint, spoken over MCP streamable HTTP. Any MCP-compatible client or agent framework connects to the same URL - one integration for your whole fleet.
Endpoint
One endpoint, two connection modes. Use the client-managed OAuth consent
flow for sandbox testing. For a live integration, exchange your Trulioo
client_id and client_secret for an MCP access token before
connecting to the same endpoint.
Try synthetic data without signing in
Use https://mcp.trulioo.com/mock/mcp for anonymous protocol testing.
In a connection tester, enter that URL and leave Auth Header empty.
This endpoint returns synthetic data and has a limited feature set.
Call trulioo_health, confirm mode: sandbox, then
read trulioo_capabilities before choosing a workflow.
/mcp remains the authenticated endpoint for installed plugins.
Choose Sandbox during OAuth to evaluate it without Trulioo API credentials.
The host root is a documentation page, not an MCP transport.
The existing /sandbox/mcp alias still requires OAuth and does
not bypass authentication or select a mode.
Connection troubleshooting
| Result | Next step |
|---|---|
401 on /mcp | Complete OAuth or renew the MCP access token. No Trulioo API credentials are required for OAuth Sandbox. For anonymous testing, use /mock/mcp with an empty Auth Header. |
| HTML or a redirect instead of MCP | Use the full transport URL ending in /mcp or /mock/mcp, not the host root. |
| Callback registration rejected | Use HTTPS or a loopback HTTP callback. Clients with private URI schemes, including Cursor, need the local bridge shown in Client setup. |
| A tool is missing | Read trulioo_capabilities and discover its family with trulioo_find_tools. Availability depends on the connection and enabled features. |
| Protocol error after connecting | Let an MCP SDK manage protocol negotiation and session headers. Raw HTTP clients must follow the negotiated revision; responses may be Server-Sent Events. |
| Rate limited | Honor the returned retry guidance and use bounded retries. Contact Trulioo before increasing production traffic. |
Keep bearer tokens and Trulioo API secrets out of prompts, screenshots, logs, and committed configuration. An MCP access token is distinct from your Trulioo API client secret; use the approved bootstrap below for autonomous live integrations.
For hosted actions that require review, tool approval in the client alone is insufficient. The server requires an actor-bound session and the reviewed Trust Workspace flow. Mock and shared sandbox credentials cannot authorize those actions.
Authentication
/mcp requires an access token. Start with the sandbox
connection to validate your KYB workflow. When your account is approved for live use,
bootstrap a live token with your Trulioo client credentials.
Sandbox connection
Claude Code, Cursor, Codex, and ChatGPT connect through OAuth 2.1 + PKCE. Clients with private URI callbacks, including Cursor, need a local bridge with a supported callback. OAuth-capable clients manage the flow:
- Add
https://mcp.trulioo.com/mcpto the client. - The client discovers Trulioo authorization and opens the consent flow.
- Choose sandbox.
- The client initializes the MCP session and loads the tools available to that connection.
Let the client manage sandbox OAuth. Do not copy sandbox tokens, register a client by hand, or hardcode authorization endpoints.
Start in sandbox
Sandbox uses the same endpoint and tool schemas as live access. It is unbilled and intended for testing the
full integration before you work with production data. Sandbox results include a test_mode
marker so your application can identify them.
Live integration with client credentials
For an approved live account, store the Trulioo client_id and
client_secret in your secret manager or environment. Send them only to the
token bootstrap endpoint over TLS.
Request an MCP access token
Response
The bootstrap validates the credentials with Trulioo, holds the upstream credential
server-side, and returns a short-lived MCP access token. Store the returned
access_token in TOKEN; the Raw JSON-RPC client setup below shows
the complete initialization sequence.
- Never send
client_secretto/mcp, place it in a URL, or log it. - The bootstrap does not return a refresh token. Re-run the bootstrap when the MCP
access token expires or the server returns
401. 401 invalid_clientmeans the credentials were malformed or rejected. Retry only after checking the credential configuration.- If Trulioo authentication is temporarily unavailable, retry the bootstrap with bounded backoff.
Usage limits
Usage limits apply and may change during early access. If a result includes
retry_after_seconds, wait for that interval before retrying. Contact Trulioo before a
production-scale rollout so limits can be reviewed for your use case.
Client setup
Pick your client and point it at the hosted endpoint. Use its OAuth flow for sandbox. For live use, the client must support sending the bearer token returned by the client-credentials bootstrap.
Add the endpoint
After adding the server, open Claude Code, run /mcp, and authenticate
Trulioo. Choose Sandbox in the browser, then call trulioo_health
to confirm the mode. For a project-scoped server, approve the project's MCP
configuration when prompted.
Clients that use an mcpServers block
Use this in clients that accept a remote server URL and support OAuth.
Claude Desktop uses its custom-connector interface. Cursor's native
cursor:// callback is not accepted by Trulioo's client registration;
use a local mcp-remote bridge with a loopback callback:
VS Code - .vscode/mcp.json
Run MCP: List Servers, start Trulioo, complete OAuth, and
choose Sandbox. For anonymous synthetic testing, replace the URL with
https://mcp.trulioo.com/mock/mcp; no OAuth login is required.
OpenAI Codex CLI - add by URL
Choose Sandbox in the browser. The CLI and IDE extension share the MCP configuration. Registering a ChatGPT workspace connector is a separate setup step.
ChatGPT (Developer mode) - add the server by URL
Leave OAuth client ID and secret blank when the client supports automatic discovery.
Complete OAuth and choose Sandbox. Workspace policy controls whether a custom connector
can be added, shared, or enabled; installing a CLI plugin does not register a ChatGPT
workspace connection. Verify trulioo_health in the connected client.
Discover the tools an agent can call
This is a real MCP session, not a REST API: initialize first, keep the
mcp-session-id the server hands back, and send it on every later call. A bare
tools/list is refused with 422 Unexpected message, expect initialize request
even when your token is perfectly good. An MCP client does all of this for you - you only need the
sequence below if you are speaking the protocol by hand.
Responses come back as Server-Sent Events, so parse data: lines rather than expecting one
JSON body - that is what -N and the text/event-stream accept header are for.
Without the bearer token the first call returns 401 plus a WWW-Authenticate
header pointing at the authorization server. How to get a token →
OpenAI Responses API
Include this entry in your request's tools array to try synthetic
sandbox without a Trulioo token:
The API does not run an interactive OAuth login. For the protected
/mcp endpoint, obtain a token through
Authentication and provide it in the tool's
authorization field on every request. Handle MCP approval requests
in your application. OpenAI API authentication and billing are separate from
Trulioo's synthetic sandbox.
Account analytics
Three read tools answer questions about the authenticated customer's own KYB
activity: analytics_account_overview (packages, a 90-day headline, and the
state of the account copy), analytics_query (aggregate transaction volume
for trends, charts, dashboards, and reports), and
analytics_list_transactions (individual transactions, newest first).
Account scope is derived server-side from the Trulioo credential. No tool accepts an
account id, SQL, a relation name, or an arbitrary filter.
analytics_query supports transaction_volume; day, week
(ISO, starting Monday), or month grain; a window of at most 90 days that starts no
earlier than 90 days before today (UTC); optional grouping by country,
data_source, or product; and a result limit from 1 to 100
(default 100). Grain defaults to day for windows up to 31 days and to week beyond that,
and every period is the ISO date its bucket starts.
summary.total covers the full requested range even when the bounded series
is truncated; the summary reports available and returned series-row counts plus
series_truncated.
analytics_list_transactions defaults to the last 7 days and 25 rows per
page (limit 1 to 100). Filter by country, data_source,
product, or transaction_id, and pass
page.next_cursor back as cursor, with the same filters, to
continue.
First use. Where the account store is configured, the first
analytics call registers a 90-day copy of the account's transactions. Until the
requested window is copied a result reports status: "preparing" with
sync.progress and a first_use notice, and
summary, chart, and the overview headline are
null. A copy unused for 30 days is deleted; the next call rebuilds it and says so with
a rebuilding_after_eviction notice.
Example: query the authenticated account
Availability. Analytics is published on the business MCP profile.
Sandbox sessions return deterministic synthetic results, ready immediately, for
evaluation; test sessions are refused; live sessions need a deployment with an
analytics source. On progressive discovery the analytics tools are deferred rather
than resident: find them with trulioo_find_tools using
family: "analytics", inspect them with trulioo_tool_schema,
then call them through trulioo_invoke_tool. If discovery does not return
a tool, the connected account or deployment does not expose it.
Going live does not change the MCP URL. It changes how the bearer token is obtained:
use the approved account's client_id and client_secret at
/oauth/token.
Authentication →
KYB tools reference
Tools reference
The KYB surface is a typed sequence: discover the business,
resolve ambiguity, verify it, poll when needed, and fetch the report.
tools/list remains the authority for the tools available to your account.
Every capability is a typed, discoverable MCP tool - schema-enforced inputs,
structured results agents branch on, and no raw passthrough - a tool that is not on your connection is not
reachable by another route. A default progressive connection exposes 57 addressable entries: 18 resident
tools and 39 deferred product capabilities. The product contract is 55 tools because two resident entries are
progressive-only routing tools. Per-account families change the enabled set. The exact
resident set is what tools/list returns for
your connection, so discover it rather than hardcoding this list.
Example: call a tool over JSON-RPC
Both headers are required: $TOKEN from
Authentication, and $SID from the
initialize handshake - see Raw JSON-RPC under Client
setup.
KYB workflow and responses
Identity & business verification
| Step | Tool | Use it when | Response and next step |
|---|---|---|---|
| 1 | kyb_search |
You have a business name but not a confirmed registration identifier. | Returns: search_summary with candidate_count, decision, and selection. Confirm a candidate before verification, then verify it with selection.ref plus its candidate_id; do not use the top-level RecordStatus to decide whether matches were found. |
| As needed | kyb_registration_lookup |
You need the registration types or jurisdiction details accepted for a country. | Returns: supported registration-number types or jurisdictions of incorporation. Use them to format the search or verification input. |
| As needed | (no extra call) | Search returns multiple businesses and the user must choose the correct one. | Returns: the choice is in the search result. search_summary.selection lists every candidate once with an id, selection.discriminators names the fields that actually separate them, and search_summary.clarification carries a ready-made closed question. Verify with selection.ref plus the chosen candidate_id. |
| 2 | kyb_verify |
You have confirmed the business and are ready to start verification. | Returns: transaction_id, record_id, status, is_terminal, and next_action. Branch on status; follow next_action when the result is not terminal. |
| While running | kyb_get_partial_result |
The verification is still running and you need the latest available state. | Returns: the latest available verification fields plus is_terminal and next_action. Continue polling only while the result is not terminal. |
| 3 | kyb_get_report |
The verification is complete and you need the final report. | Returns: a structured report, or a PDF descriptor with record_id, report_available, content_type, and resource_uri. Store the report reference with the transaction. |
| Reference | transaction_lookup |
You need to retrieve a previous verification from its transaction identifier. | Returns: the matching record and identity context for a TransactionID or TransactionRecordID. Use the resolved record for status or report retrieval. |
| Tool | Does |
|---|---|
kyc_verify | Verify a person across 195+ countries; returns match / review / nomatch + next-action hints. |
kyc_get_status / kyc_get_record | Poll an async verification, then fetch the completed record. |
kyb_verify | Verify a business, with UBO discovery and due-diligence sequencing. |
kyb_search / kyb_get_report | Find a business, then retrieve its full report. |
kyb_registration_lookup | Registration numbers + jurisdictions of incorporation (routes by the args you pass). |
kyb_get_partial_result | Fetch partial results for a long-running KYB job. |
transaction_lookup | Look up a past KYC/KYB verification by the transactionId you already hold - resolves a TransactionID or TransactionRecordID to the record + identity. |
Per-account families
Off unless your account is entitled to them, each enabled on its own. They are real and supported;
they are simply absent from tools/list until your deployment has them. Ask Trulioo for the
families you need rather than coding around them, and read the result from tools/list -
getting one family does not get you the rest.
| Tool | Does |
|---|---|
aml_screen | Standalone sanctions and PEP screening for a name you are not verifying. |
docv_create_session | Start a document + liveness capture session. Returns a session_url the person opens; images and biometric data never cross the MCP stream. |
docv_get_result | Read the outcome of a capture session. Returns a Task to a tasks-capable client; otherwise poll. |
docv_cancel_session | Cancel a capture session the person abandoned. |
docv_create_mobile_handoff | Hand a desktop session off to the person's phone for the camera step. |
age_check | Age assurance from a known date of birth. Its sibling age_estimate_biometric is declared but returns NotImplemented until biometric estimation ships - do not build against it. |
monitoring_enroll | Put a verified subject under ongoing monitoring. |
monitoring_get_alert | Read an alert monitoring raised. |
monitoring_refresh | Re-run the checks behind an enrollment now. |
monitoring_cancel | End an enrollment. |
monitoring_get_enrollment | Read an enrollment's current state. |
Alpha tier - internal and alpha customers only. A single switch,
TRULIOO_EXPERIMENTAL=true, turns on four families at once - ownership graph, deep
research, document verification and standalone AML screening - taking the fully enabled union from
55 tools to 63 tools. A per-family variable still wins in both directions, so TRULIOO_ENABLE_DOCV=false
beside it holds document verification back. Age assurance and ongoing monitoring are not in
the tier; they stay individually entitled. It does not reach the host-rendering surfaces
(TRULIOO_ENABLE_EXPERIENCES, TRULIOO_ENABLE_MCP_APPS), which a client negotiates
rather than an account entitles. On a hosted connection this is an operator-set deployment variable,
not something a client can ask for. Post-KYB work starts through
kyb_run_follow_up; poll Deep Research with kyb_get_research or a streamed
ownership walk with ubo_get_graph. Direct starts are not exposed.
tools/list and config_discover_account are the authority on what your
connection has. Do not hardcode the list above, and do not synthesize a tool name that is not on it -
there is no raw passthrough, so a tool that is absent is not reachable by another route.
Know Your Agent
| Tool | Does |
|---|---|
kya_admission_challenge | Mint a short-lived, single-use enterprise admission challenge for one privileged target tool. The returned token is bound to the authenticated tenant, session, target tool, and policy version. |
kya_possession_challenge | Mint the single-use nonce a keyed card's possession proof must carry. Call this first - kya_issue_mandate rejects a proof without a fresh nonce. On a software key this proof is also what earns AAL2; tier alone does not. |
kya_issue_mandate | One call: verify the organization → register the agent → sign a scoped attestation → anchor it. Returns the attestation JWS + the A2A extension block. |
kya_verify_agent | Verify another agent's card; optionally check a requested_action against its signed scope (the scoped handshake). |
kya_lookup | Public lookup of an agent's standing by DAP handle or fingerprint. depth selects the tier: lookup (free, is it verified and who is it) or verify (paid, adds advisory signals). |
kya_list_agents | List a bounded, tenant-scoped page of the authenticated account's agents for selection and Digital Agent Profile inspection. Internal account joins, keys, and recovery authority are excluded. |
kya_get_insights | Read complete account agent-inventory counts by status, lifecycle and issuance environment. Retrieval time is supplied; snapshot freshness is unknown. Historical activity, verification rates, plugin release health and runtime assurance are unavailable. |
kya_get_agent_metrics | Read recorded lifetime lookup counts, a 30-day UTC daily series and a bounded recent feed for one current agent owned by the authenticated standalone connector's account. The source event read limit is 500; all agent interactions and billing usage are unavailable. Shared hosted reads remain unavailable until caller-to-account binding is validated. |
kya_get_agent_domain | Read the account-bound domain and current proof state for one selected Digital Agent Profile. |
kya_start_agent_domain_challenge | Create the exact DNS challenge required to bind the selected agent's domain. The account and agent authority are derived from the connector and opaque Agent-ID. |
kya_verify_agent_domain | Check the DNS challenge and mark the selected agent domain verified when the expected proof is present. |
kya_card_fingerprint | Compute a card's fingerprint before you register it - answers “will this build keep my Digital Agent Profile?”. Costs nothing and spends no issuance - pure arithmetic over the card you supply - but it needs your account key like the rest of the keyed surface: it is a build-time developer utility, not a relying-party read. It names which fields are identity-bearing (name, the first interface URL, code_digest, and the agent_key thumbprint - so rotating your key re-mints too) and which are free to change. Returns no trust verdict. |
kya_verify_web_bot_auth | Verify a Web Bot Auth (RFC 9421) signed HTTP request and resolve it to the agent behind it. Note a bare, replayable signature is AAL1 even at tier 2. |
kya_verify_protocol | Verify a rail-specific envelope (UCP / AP2 / ACP / x402). A2A cards use kya_verify_agent. |
kya_supersede_agent | Rotate an agent's key or reissue its profile, superseding the prior credential so verifiers follow the replacement. |
kya_retire_agent | Revoke standing for a retired or compromised agent. A verifier resolving its lookup sees the credential is no longer good. |
kya_verify_mandate | Verify a mandate credential a counterparty presented to you - signature, issuer, validity window, and with freshness: central_fresh its revocation status. Reach for this rather than kya_get_mandate whenever somebody hands you a credential: reading a mandate by an id lifted out of an unverified document trusts the document to describe itself. Pass amount to also learn whether the sum you are about to authorize sits inside the ceiling the credential declares - advisory only, and it never changes valid. An amount_advisory.within of null means unanswerable, never a pass. |
kya_get_mandate | Read a mandate you issued: status, validity window, and the signed scope - allowed actions, merchants, and the spend cap. A max_amount of null means uncapped, never a cap of zero. |
kya_record_spend | Record a settled spend against a mandate, which is what makes a day/total ceiling answerable at all. Your settlement_id is the de-duplication key: replaying it with the same amount returns recorded: false and counts once, while the same id with a different amount is refused 409 rather than silently overwritten. Recording is not enforcement - it moves no money and blocks nothing. |
kya_mandate_spend | Read a mandate's spend ledger: the running totals per currency, the declared ceiling, and the headroom left. A remaining of null is not zero - it means there is no headroom to speak of, either uncapped or a per-transaction cap, which limits each purchase rather than depleting. |
kya_revoke_mandate | Revoke one mandate, with a reason recorded for the audit trail. The capability rails fail closed on the next verify; the A2A discovery tier is OfflineOk by design, so it lags until the credential expires. |
kya_revocations | List the mandates already revoked, with the status-list index each one occupies - the bulk read behind a verifier's own cache. |
kya_transparency_sth | Fetch the signed tree head: tree size, root hash, and the issuer's signature over both. The anchor every inclusion proof hangs from. Public - no account needed. |
kya_inclusion_proof | Prove a leaf sits under a signed root (RFC 6962). Public - no account needed. Verify the returned audit path with verify_inclusion_hashed, not verify_inclusion: the served leaf_hash is already hashed, and hashing it twice reports a sound log as broken. |
kya_status_list | Fetch the signed status list as its compact JWS (application/statuslist+jwt) - the revocation bitstring a verifier checks offline. Public. Re-signed per request with a fresh validFrom, so do not cache or diff it by byte hash. |
kya_rails | What each rail demands before you build for it: expected_typ, tier, freshness, binding, signing alg, schema URL, and the issuer JWKS to resolve keys from. Public. |
kya_assess_readiness | Measure the public agent-facing documents a host publishes and return evidence-backed reason codes and residuals. It reports no score or grade and requires account credentials. |
kya_verify_client | Verify a Client ID Metadata Document before admitting an OAuth client: fetch the https URL that is its client_id under MCP 2026-07-28, validate it against draft-ietf-oauth-client-id-metadata-document-00, and get back the document's origin, its redirect_uris, whether it publishes a key (jwks_uri + private_key_jwt) or is a public client, and any KYA operator claim it carries. Runs the same SSRF-hardened fetch the authorization server runs, so the verdict predicts admission. Two tier fields, deliberately: record_trust_tier is a statement about the URL, request_trust_tier_ceiling is the most a request carrying that client_id could reach - binding the first to a request is the mistake this shape exists to prevent. The carried attestation is never verified here (attestation_verified is always false); the issuer is the source of truth, so follow up with kya_lookup on the fingerprint. |
kya_list_artifact_candidates | List a bounded page of this account's unpublished Agentic Releases so a host can present an opaque selection UI without accepting an account id from the caller. |
kya_list_publisher_bindings | List this account's publisher namespace bindings and whether each remains active and publishable before release registration. |
kya_register_artifact | Register a complete Plugin package as an immutable Agentic Release candidate. The server verifies publisher binding and computes package and distribution digests without publishing it. |
kya_publish_artifact | Publish a registered Agentic Release candidate using an audited, optimistic-concurrency transition. |
kya_revoke_artifact | Permanently revoke a compromised Agentic Release. This audited transition is destructive and irreversible. |
Discovery, meta & workflow prompts
| Tool | Does |
|---|---|
trulioo_tool_schema | Read a tool's full input schema and complete authored guidance (up to 8 at a time). The tool list carries a one-line description to keep a client's cold start small; this is where the operational detail lives - required fields per country, which flag actually starts an ownership walk, which result fields are advisory rather than evidence. |
trulioo_find_tools / trulioo_invoke_tool | Progressive discovery, advertised only when TRULIOO_TOOL_DISCOVERY=progressive. The server then lists an 18-tool resident core (~2.8k tokens instead of ~8.0k) and keeps 29 product capabilities reachable: trulioo_find_tools searches the manifest by keyword or family, trulioo_invoke_tool calls a tool that is not listed. Dispatch passes the same profile, family, rate-limit, circuit-breaker and KYA gates as a direct call, cannot widen a profile or re-enable a disabled family, and refuses destructive verbs - those stay advertised so your client always sees their approval hints. |
Sandbox scenarios (sandbox credentials only)
Seed the outcome you want to test before you call a verify tool, instead of hunting for a fixture that happens to produce it. A scenario is a small JSON body you post once and then reference by id; it steers the simulated rail only, so these tools refuse on any connection whose data axis is not synthetic - a seeded outcome must never stand in for a real verification.
| Tool | Does |
|---|---|
sandbox_seed_scenario | Register one scenario and get back its scenario_id (scn_ prefix). Idempotent by content: the same body returns the same id, and any change to a steering field returns a new one. Bodies are capped at 16 KiB, 50 scenarios per caller, and expire 15 minutes after they are seeded. |
sandbox_list_scenarios | List the scenarios this caller has seeded and still holds, with the published caps so an automation suite can size itself rather than discover a limit by failing. |
sandbox_reset_scenarios | Drop every scenario this caller seeded and report how many went. Scoped to the caller, so one test run cannot clear another's state - call it between suites to start from a known-empty plane. |
config_discover_account, config_describe_context, and
config_list_test_entities tell an agent what its account can do and which safe test
subjects it can use before it starts a KYB flow. trulioo_health and
webhook_journal cover liveness and async callbacks. The
kyb_due_diligence_workflow prompt sequences search, disambiguation, verification, and
screening; prompts/list is the authority on the set your connection offers.
trulioo_capabilities and trulioo_getting_started let an agent self-orient.
config_discover_account, config_describe_context, and
config_list_test_entities tell an agent what its account can do and which safe test
subjects it can use before it asks a user for anything. trulioo_health and
webhook_journal cover liveness and async callbacks. Guided workflow
prompts (kyc_onboarding_workflow, kyb_due_diligence_workflow) sequence the
multi-step flows; prompts/list is the authority on the set your connection offers.
trulioo_capabilities and trulioo_getting_started let an
agent self-orient. There is no raw passthrough: every upstream call goes through a typed tool, so a
tool that is not on your connection is not reachable by another route.
Protocol capabilities (negotiated per connection)
The revision is negotiated at initialize: the floor is 2025-06-18 and the
newest draft the server supports is 2026-07-28. Features land only for a client that
asked for the revision carrying them - everything else degrades to the floor behavior, so read the
negotiated value back from trulioo_capabilities rather than assuming one. Two optional
extensions a capable client can opt into:
Handle the result
| Result | What your code should do |
|---|---|
is_terminal:false | Do not treat the verification as complete. Follow next_action and poll within a bounded retry budget. |
status: match | Continue the approved business onboarding flow and store the transaction ID. |
status: review | Pause automation and route the result to a human reviewer. |
status: nomatch | Stop the onboarding path and present the returned next action. |
- Tasks (
io.modelcontextprotocol/tasks) -kyb_verifyreturns a task handle you poll withtasks/getwhen your client declares the capability; otherwise it returns the samenext_actionlong-poll. Task state is per-instance today, so a not-foundtasks/getmeans fall back to the poll. - Tasks (
io.modelcontextprotocol/tasks) - the long-running tools (kyc_verify,kyb_verify) return a task handle you poll withtasks/getwhen your client declares the capability; otherwise they return the samenext_actionlong-poll. Task state is per-instance today, so a not-foundtasks/getmeans fall back to the poll. - MCP Apps / SEP-1865 (
io.modelcontextprotocol/ui) -render_app_verdictreturns a host-renderedui://verdict card (sandboxed iframe,text/html;profile=mcp-app) with a text fallback for non-Apps clients. Enabled per account (TRULIOO_ENABLE_MCP_APPS).
Result contracts
Tools return structured results an agent can branch on directly - not prose to parse.
kyb_verify (terminal shape)
kyc_verify (shape)
- Errors are results, not exceptions. A failed upstream comes back as a typed result the agent can reason about, not a thrown error that ends the run.
- Circuit breaker per upstream. Each verification surface has its own breaker, so one degraded provider does not take down the others.
- Async is explicit.
is_terminal:falsetells the agent to poll rather than assume completion. A long-running operation returns a continuation to poll; exhausting an approved poll budget requires review rather than an unbounded loop.
Give an agent an identity
Any agent can claim any name. Know Your Agent proves the real organization behind an agent and issues a signed, scoped, revocable credential - the Digital Agent Profile (DAP) - that anyone can verify. It rides in the agent's A2A card, so trust travels with the agent.
- Verify the organization. KYC/KYB + sanctions on the accountable owner behind the agent.
- Register the agent. The agent presents its own Ed25519 key; that key is the identity anchor. A build fingerprint binds the credential to this exact agent.
- Sign a scoped mandate.
kya_issue_mandatemints a short-lived, least-privilege attestation for named scopes (e.g.purchase), signed byidentity.trulioo.com. - Publish it. The attestation attaches to your A2A card under
capabilities.extensions[](urihttps://identity.trulioo.com/a2a/kya/v1) and is anchored in a tamper-evident log.
The KYA extension on an A2A agent card
Scopes are signed, but enforced by the relying party. Trulioo signs and audits the allowed scopes; the party accepting the agent is what actually enforces them. The attestation is a verifiable claim of trust, not an authorization grant on its own.
Why agent trust has layers
"Verified" is not one thing. A DAP asserts a stack of independent facts, and a relying party checks the layers its risk calls for. Knowing the layers tells you exactly what a profile does - and does not - prove.
- Identity anchor. The agent holds its own key. Everything else binds to that key, so the profile is about this agent, not a name it typed.
- Integrity & provenance. A build fingerprint binds the credential to the exact code. Change the code and the fingerprint changes - forcing re-attestation.
- Authenticity of use. A possession proof shows the party presenting the card actually controls the anchor key - not a copied card.
- Origin & accountability. KYC/KYB ties the agent to a real, sanctions-screened organization, and every issuance is anchored in a tamper-evident log.
This matters to your company directly: it is what lets you (or your customers) accept an agent's action with a known, accountable party behind it - and decline or step up when a layer is missing. The full trust model →
Verify an agent (DAP)
Verification is the critical path: a system deciding whether to trust an inbound agent confirms its Digital Agent Profile and attestation before acting. Verify through MCP; the issuer also publishes the two keyless, public primitives so any party can check a profile with no account.
Try it live
Drive the mint-then-verify lifecycle end to end. This simulation runs entirely in your browser - no network calls. Mint on the left; verify the same agent on the right.
1 - Issue a credential
Verify org → register agent → sign mandate → anchor in the log.
- The lifecycle trace streams here - one signed step at a time.
2 - Verify an agent
Against the issuer, not the card. The agent from step 1 lands here.
🔒 Run step 1 first - the agent you mint arrives here to verify.
In an agent (recommended)
Call kya_verify_agent with the agent's card - it validates the signature, fingerprint,
expiry and sanctions, and returns the Verified-by-Trulioo record. Add a requested_action to
check it against the signed scope in the same step. This is the integration path; the KYA verification
logic lives behind MCP, not a public write API.
Verify over MCP
$TOKEN comes from Authentication and
$SID from the initialize handshake. If you only need to check a profile
and not run a verification, the public keyless lookup below needs neither.
Public, keyless lookup (for any verifier)
The issuer publishes two public primitives at https://identity.trulioo.com so a relying
party that isn't running an MCP client can still confirm a profile without an account:
GET /kya/attestation/{dap}- look up an agent's current standing by its Digital Agent Profile (the "anyone can check" path).GET /.well-known/jwks.json- the issuer's signing keys (rotation-aware) to verify an attestation JWS yourself.
What a verifier checks: the JWS signature against the pinned issuer key by
kid (the algorithm is pinned from the resolved key, never read from the token
header - blocks alg:none and alg-confusion); the fingerprint against the
agent's own key + card; the exp (short-lived, re-attested on change);
verified; assurance.trust_tier against your own minimum; and the signed
allowed_scopes. Scopes are signed and auditable but enforced by you, the
relying party.
There is no signed sanctions boolean. Signing a standing
sanctions_clear would assert a check that may not have run, on a payment-adjacent
credential. Screening is an optional provenanced claim carried only when it actually ran, and
a hit or review suspends the credential's standing through its status_reference.
Check standing, not a boolean.
The DAP wire schema (ats-v2)
A Digital Agent Profile is a conformant SD-JWT-VC (typ: dc+sd-jwt) carrying a
vct of https://identity.trulioo.com/vct/agent-profile.1. A passport core is
inline - a KYB-verified operator and a composite assurance grade - while the
identity, mandate, status and behavior objects are referenced and dereferenced independently.
This is the exact record the KYA card flips to; the full JSON Schema is
ats-v2-dap.schema.json (governed by ADR-P-022).
DAP 2.0 presentation (public-discovery profile)
Disclosure integrity. assurance (incl. trust_tier) is always
inline; operator (at tier ≥ 2) and screening.result (when present) are
not holder-omittable - a holder cannot strip a signed sanctions hit or claim tier ≥ 2 while
hiding the operator. Only operator.registration_id, screening.watchlists, and
(pairwise profile only) agent_id/build_id are selectively disclosable.
Two profiles. Public discovery reveals agent_id/build_id
inline (shown above). Pairwise withholds them via SD-JWT selective disclosure and substitutes a
per-relying-party sub alias, so a profile isn't linkable across verifiers. The variant is
chosen by the agent's exposure mode - never a caller flag - so an agent can't be tricked into
over-disclosing.
How the DAP projects onto each rail
One DAP, issued once, is projected into each protocol's native shape - KYA proves who is accountable; the rail carries and authenticates the transaction. The mapping below is what actually travels on each rail and which DAP claim the verifier reads.
| Rail | Where the DAP travels | What the verifier reads |
|---|---|---|
| Google A2A Live |
Inline in the Agent Card under capabilities.extensions[], uri identity.trulioo.com/a2a/kya/v1, as a compact JWS in params.attestation. |
The attestation JWS against the issuer JWKS, then operator + assurance.trust_tier from the verified DAP. |
| Google AP2 Live |
The DAP is the credential - a conformant SD-JWT-VC AP2 already speaks (typ: dc+sd-jwt), presented as the mandate. |
iss = identity.trulioo.com, the cnf holder-key proof, and the inline operator/assurance core. |
| Google + Shopify UCP Live |
Referenced from the merchant profile the business publishes with its signing keys. | operator.kyb = verified and assurance.trust_tier - is this a real, screened business? |
| OpenAI + Stripe ACP Live |
Checked out-of-band before the delegated Stripe token is honored, via kya_verify_agent(card). |
The signed capabilities scope (e.g. checkout) and operator - is this agent allowed to make this purchase? |
| Visa TAP Preview |
TAP signs the request (RFC 9421, Ed25519) with the agent key; the DAP is resolved from that key. | The cnf.jkt thumbprint maps the signing key to a DAP, then operator - the accountable org behind the key. |
| Mastercard Agent Pay Preview |
The Agentic Token binds to the DAP's durable agent_id + verified operator. |
agent_id and operator - the tokenized card is bound to a real, verified organization. |
| Cloudflare Web Bot Auth Live |
Signed edge requests (RFC 9421) carry Signature-Agent; the DAP sits beneath the signing key. |
cnf key match + operator/assurance - replaces a spoofable User-Agent with a verified org. |
| Coinbase x402 Live |
The wallet signs the on-chain payment; the DAP rides the bridged A2A card alongside it. | The DAP attestation - the wallet moves value, the DAP proves the accountable org behind the agent. |
| Skyfire Live |
Skyfire's identity token references the DAP as its regulated assurance source. | assurance.trust_tier (e.g. trulioo:tier-2) - the KYC/KYB depth the token anchors to. |
Across every rail the DAP's role is the same - prove the accountable organization and its signed scope; the rail enforces and settles. No proprietary token, no lock-in: it's a conformant SD-JWT-VC anyone can verify against the issuer JWKS.
Drop-in "Verified" badge
Prefer not to build the UI? Embed the same <trulioo-verified> element Trulioo runs on
its own surfaces. It runs the live attestation lookup itself, stays hidden until the agent verifies, and
opens the full Digital Agent Profile on click - Organization, Issuer, DAP, verified-as-of, sanctions,
attestations, scopes, and a link into the transparency log. One framework-agnostic custom element; no build
step. It's live in the hero of the sibling Know Your Agent page.
Embed it
Orchestration patterns
The tools are typed and composable, so an agent chains them mid-task and branches on each result. The examples below show how to combine the raw tools.
Pattern 1 - Verify a person before a high-risk action
The agent checks identity mid-conversation and branches on the typed status.
Ships as /trulioo-mcp:kyc-onboarding.
KYB due diligence - discover, verify, screen
Pattern 2 - Onboard a business, then screen it
Find the business, confirm the correct candidate, verify it, and branch on the typed result.
Pattern 3 - Give the agent its own identity (KYA)
Once the org behind the agent is verified, mint the agent's DAP so every downstream call is attributable.
Keep the business identity continuous. Carry the selected registration identifier from search into verification, store the returned transaction ID, and use that transaction as the anchor for report retrieval.
Enterprise agent teams. A fleet shares one MCP connection and one identity layer - every agent inherits the same verification tools, and each carries its own DAP, so downstream systems know which agent (and which accountable org) took an action. One integration, governed centrally.
Security & honest limits
- Schema-enforced inputs. Every tool validates its arguments (
additionalProperties: false), so malformed or injected calls are rejected before reaching an upstream. - Prompt-injection resistance. Tools act only on their typed arguments; free-text in a document or field is data, never an instruction to the server.
- Algorithm pinning. Attestation verification pins the algorithm from the resolved key (EdDSA / ES256 only) -
alg:noneand alg-confusion attacks are rejected. - Honest limits. A DAP proves identity, integrity, scope and accountability - it does not authorize a payment or guarantee behavior. Scope enforcement is the relying party's; certified biometric liveness has a defined boundary. We surface dependencies we do not own.
- Governed surface. The verification agents and skills behind these tools are eval-gated and release-controlled - the same discipline you would apply to a compliance-critical dependency.
FAQ
Should I search before calling kyb_verify?
Search when you do not already have an authoritative registration identifier. If search returns
multiple candidates, choose one from search_summary.selection before verification.
What should I do when search returns several businesses?
Do not guess. search_summary.selection lists every candidate once with an
id, and search_summary.clarification carries a ready-made closed
question when the rows split on one field. Confirm the correct business, then call
kyb_verify with selection.ref plus that candidate_id.
How do I continue after KYB completes?
Use the transaction ID to retrieve and store the completed report.
Does an agent need its own key for KYA?
Yes. The agent's own key is the identity anchor; the profile binds to it. Trulioo does not mint the agent's key for it.
Does the attestation authorize a payment?
No. It is a signed, verifiable claim of identity and scope. Whether to accept an action is the relying party's decision; scope is enforced there.
How does someone verify an agent without a key?
The issuer publishes its signing keys at /.well-known/jwks.json; verification is a public signature check against those keys.