KYA-BRASIL
This MCP server lets you check who answers for an AI agent (a Brazilian company via e-CNPJ, or a person via e-CPF), what it's allowed to do, and verify its credential — online at the issuer or fully offline.
Verify an agent's credential (
kya_verify, free): returns the principal (CNPJ + legal name, or an anonymous person), the mandate, live status (active/suspended/revoked/expired) and history — bycredential_idor agent key (evm,web-bot-auth,erc8004).Verify with a signed receipt (
kya_verify_paid, $0.01): same as above without the free daily limit, plus a signed receipt.Check an action against the mandate (
kya_check_action, $0.01): a signed allow/deny verdict listing every rule evaluated (action, per-operation/per-day ceilings, currency, counterparty, payment instrument) — usable as evidence.Track revocations (
kya_revocations, free): credentials revoked since a date, so cached credentials can be dropped.Get a signing link (
kya_sign_link, free): after registration, the link for the e-CNPJ/e-CPF holder to review and sign with their certificate.Offline mandate checks (
kya_check_mandate,kya_validate_mandate, free): evaluate an action against a mandate, or validate/normalize a mandate before registering — nothing leaves the machine.Offline credential check (
kya_verify_credential_offline): validates the issuer's Ed25519 signature and expiry (can't see later revocations).Offline delegation check (
kya_verify_delegation): verifies a sub-agent's delegation chain — signatures, depth, lifetime, mandate containment — and whether every level allows the action.Learn the system (
kya_about, free): what KYA Brasil is, how agents get credentials, where the spec and issuer keys live.
Supports agents whose identity is rooted in Ethereum. Agent keys can be evm (EIP-191) or erc8004, i.e. an ERC-8004 agent whose on-chain Ethereum wallet signs requests. The verification middleware resolves the agent's on-chain identity (agent id / wallet) and binds it to the company's or person's ICP-Brasil-backed mandate.
Mandates can bind payment instruments to the credential, including Visa network card tokens / PARs stored only as hashes, so per-action checks confirm that a payment action uses an instrument explicitly authorized in the mandate.
KYA Brasil

Know-your-agent backed by ICP-Brasil. Most "KYA" tools prove that an agent holds a key and give it a score. KYA Brasil answers the question a supplier, a bank or a marketplace actually asks: who answers for this agent, and what is it allowed to do?
A Brazilian company signs with its e-CNPJ, or a person with their e-CPF, that an AI agent key acts on their behalf within a declared mandate (actions, amounts, currencies, counterparties, payment instruments, validity). The issuer validates the ICP-Brasil chain and the certificate's revocation (CRL), checks that the company is active at the Receita Federal, and re-checks every day. The result is an Ed25519-signed credential: verifiable offline, live status at a stable URL, revocable at once. Every per-action verdict is signed too.
Open source and self-contained. No closed service, no API key, no contract: Receita open data (BrasilAPI, CNPJ.ws, or your own source), each AC's public CRL, the ITI trust anchors in this repository.
Three ways to use it. The hosted service (HTTP and MCP, pay per call with x402), the library
@kya-brasil/coreinside your own systems, or your own issuer from this repository.Signing without friction. A1
.pfxin the browser, A3 token or card (PKCS#11 or any ICP-Brasil signer), cloud certificates through a provider interface; the agent prepares, a person signs.Privacy by design. Companies: no CPF or name of the certificate holder. Persons: no name, no CPF, only a keyed hash, deleted when the credential ends.
KYA Brasil answers who speaks for whom, not whether they are a good risk. Sanctions, debt and litigation are the verifier's call, with whatever screening it trusts.
Service |
|
MCP | remote (streamable HTTP) |
npm |
|
Payments | x402, USDC on Base, no signup. Free verification up to 50/day per IP. Errors are never charged. |
Spec | |
License | MIT |
Why this is different
Key-only KYA (DID, score, bonds) | Policy gateways | KYA Brasil | |
Who answers for the agent | nobody, a key | the agent's operator | a company (e-CNPJ) or a person (e-CPF), ICP-Brasil |
Link kept true | no | no | certificate revocation and company registration, at issuance and daily |
Mandate | no | operator policy | declared by whoever answers for the agent, shown to them when they sign |
Verdict per action | score | allow / deny | signed allow / deny with every check listed, usable as evidence |
Payment instruments | no | no | card tokens / PARs bound to the mandate, as hashes |
Whoever answers sees its agents | no | dashboard | inventory (and webhooks for companies), signed with their certificate |
Verifiable offline, open spec and code | rarely | no | yes |
Related MCP server: mcp-fiscal-brasil
For verifiers: you receive an action from someone else's agent
import { createKyaClient, verifyAttestation } from "@kya-brasil/agent-tools";
const kya = createKyaClient(); // add { privateKey } for paid calls
const v = await kya.verify(credentialId); // free: principal, mandate, live status
if (v.status !== "active") reject();
const verdict = await kya.allowed(credentialId, { // $0.01, signed
action: "order", amount: 4200, currency: "BRL", counterparty: "12345678000190"
});
if (!verdict.allowed) reject(verdict.reason);
await verifyAttestation(verdict); // the issuer's signature, checked locallyCheck that the key that signed the agent's request is
v.agent.id(orv.agent.walletfor ERC-8004).Check
principal.kindbefore readingprincipal.cnpj:"person"credentials carry no CNPJ and nothing personal.max_per_dayuses thespent_todayyou pass: the issuer does not record what agents do.Offline (issuer unreachable):
verifyCredentialOffline(credential)checks signature and expiry, withlive_status: "unknown".
Over MCP: kya_verify, kya_check_action, kya_verify_paid. Claude Desktop, Cursor and others: add the remote
server https://kya-br-agents.marcelfons.workers.dev/mcp, no auth, or run it locally with npx -y @kya-brasil/mcp
(packages/mcp: offline mandate and delegation checks included).
Sign in with KYA (one middleware)
The agent signs every request with its key (four KYA-* headers); your server verifies it and gets who the agent
is, who answers for it and its mandate. Hono, Express, Workers, Next, Bun, Deno.
import { createKyaAuth } from "@kya-brasil/agent-tools";
const auth = createKyaAuth();
app.use("/api/*", auth.hono()); // or auth.express(), auth.fetchHandler(handler)
app.post("/api/orders", (c) => {
const kya = c.get("kya"); // { credential_id, agent, principal, mandate, check(), allowed() }
if (!kya.check({ action: "order", amount: 4200, currency: "BRL" }).allowed) return c.json({ error: "outside the mandate" }, 403);
});Agent to agent, both sides verified: createKyaAgent(...).fetch(url) and signResponse. Profile in
docs/SPEC.md section 14.
Sub-agents: one certificate signature for the whole tree
When the mandate carries delegation: { max_depth, max_ttl_seconds }, the agent hands a narrower mandate to
another key with its own signature, no new e-CNPJ or e-CPF signature. The sub-agent signs its requests with its own
key and sends the chain; your middleware verifies it offline and check() / allowed() evaluate every mandate in it.
import { signDelegation, signRequest } from "@kya-brasil/agent-tools";
const chain = await signDelegation({ credential, key: agentKey, delegate: { kind: "web-bot-auth", id: subPublicKey },
mandate: { actions: ["quote"], max_per_operation: { amount: 500, currency: "BRL" } }, ttlSeconds: 600 });
const headers = await signRequest({ credentialId, key: subKey, delegation: chain, method: "GET", url });
// server side: c.get("kya").delegation → { depth, delegate, mandates, expires_at, chain }Short-lived (at most max_ttl_seconds, never past the credential), contained in the parent mandate, at most 3
levels; revoking the credential ends the whole tree. The issuer stores nothing. docs/SPEC.md section 17.
Give your agent a credential
Register (
POST /v1/agents, $0.25, or MCPkya_register): the agent key, the mandate, and either the company'scnpjorprincipal: "person". Returns a one-time challenge and asign_url.The agent signs the challenge with its key and sends
sign_url+&agent_signature=…(also from the freekya_sign_link) to whoever holds the certificate: the owner or the accountant, or the person themselves.A person signs with the certificate, in whichever way fits:
Certificate
Browser (
/sign)Terminal (
kya-sign)Code (
@kya-brasil/core)A1 file (
.pfx/.p12)sign in the page; the file never leaves the computer
kya-sign --pfx empresa.pfx --link "<url>"openPfx(bytes, password)A3 token or card
download the challenge, sign it in your usual signer, upload the
.p7skya-sign --pkcs11 <vendor library> --link "<url>"ecnpjSigner({ certificates, sign })Cloud (PSC)
"Certificado em nuvem" tab on an issuer with a provider configured
kya-sign --cloud ./my-psc.mjs --link "<url>"cloudSigner(session)Cloud certificates go through one interface,
CloudSignatureProvider; no PSC is implemented here because each has its own contract (template).Issued (
/prove, free): agent signature, ICP-Brasil chain, CRL, the CNPJ in the certificate (or the e-CPF), company ATIVA. Valid 90 days; renew for $0.10; revoke at once, free, signed with the same certificate.
The page shows exactly what is being authorized (agent, company or person, mandate) before anything is signed. An agent should not hold the certificate to sign for itself: that signature is the consent of whoever answers.
Agent keys: evm (EIP-191), web-bot-auth (Ed25519, RFC 9421) or erc8004 (an
ERC-8004 agent whose on-chain wallet signs). Mandate example:
{ "actions": ["quote", "order", "pay"],
"max_per_operation": { "amount": 5000, "currency": "BRL" }, "max_per_day": { "amount": 20000, "currency": "BRL" },
"currencies": ["BRL"], "counterparties": ["12345678000190", "*.beta.com.br"],
"payment_instruments": [{ "network": "visa", "ref_sha256": "9f2c…" }],
"valid_until": "2027-01-01T00:00:00Z" }Companies see every agent in their name and get signed lifecycle events at a webhook
(kya_company_agents, kya_company_webhook, signed with the e-CNPJ).
For people: an agent that acts for you
With principal: "person" the person signs with their e-CPF. The credential publishes nothing personal
(principal: { kind: "person", verified_by: "icp-brasil-e-cpf" }). The issuer keeps only an HMAC of the CPF with a
secret key, never the name or the CPF, and deletes it when the credential is revoked or expires.
A verifier that already has the person's CPF asks POST /v1/agents/{id}/principal-match ($0.01, signed): it learns
only whether it matches, plus a subject_ref of its own for that person, different for every verifier so services
cannot link the person across them. Three wrong answers stop its checks. The person sees every check in their
inventory (POST /v1/people/agents, signed with the e-CPF).
For payment networks, acquirers and issuers
The mandate can list the payment instruments the agent may use: the network and the SHA-256 of a reference the network already gives (token reference, PAR), never a card number. At authorization time, hash what you received and ask whether that instrument belongs to an agent authorized within its limits. The signed verdict records the instrument, the amount and the time: evidence for a later dispute (examples/evidence).
import { checkAction, hashPaymentRef } from "@kya-brasil/core";
const verdict = checkAction(credential.mandate, {
action: "buy", amount: 4200, currency: "BRL", payment_network: "visa", payment_ref_sha256: await hashPaymentRef(tokenRef)
});As a library: no hosted service in the path
@kya-brasil/core is the code the issuer runs, as pure functions: e-CNPJ and e-CPF signatures with the ICP-Brasil
chain, CRL revocation, agent signatures, mandate evaluation (payment instruments included), credential build,
signing and verification, holder-side signing (A1, tokens, cloud), and the person hashing. A bank, a network or a
platform can verify credentials from any issuer offline, or issue its own with its own keys, storage and audit.
Storage and network stay yours: see packages/core/README.md.
Tools and prices
Tool | HTTP | USDC |
|
| free, 50/day per IP |
|
| free |
|
| 0.01 |
|
| 0.01 |
|
| 0.01 |
|
| 0.10 |
|
| 0.25 |
Discovery: /docs (Swagger UI), /llms.txt, /openapi.json, /server.json, /.well-known/kya.json (signing keys,
active and retired), /.well-known/kya-mandate.schema.json, /.well-known/x402, /status, /terms, /sign.
Verifier for any signed document: POST /v1/verify.
What a credential looks like
{ "credential_id": "6d0b…", "version": 1,
"agent": { "kind": "evm", "id": "0x7099…" },
"principal": { "cnpj": "11222333000181", "cnpj_formatted": "11.222.333/0001-81", "legal_name": "ACME LTDA", "registration_status": "ATIVA" },
"authorized_by": { "method": "icp-brasil-e-cnpj", "certificate_sha256": "3b7a…", "certificate_subject": "CN=ACME LTDA:11222333000181, …", "issuer": "CN=AC …", "signed_at": "…" },
"mandate": { "…": "…" }, "kyb_snapshot": null,
"status": "active", "issued_at": "…", "expires_at": "…",
"verify_url": "https://kya-br-agents.marcelfons.workers.dev/v1/agents/6d0b…",
"attestation": { "algorithm": "ed25519", "key_id": "35bb864a2e87c8fd", "sha256": "…", "signed_at": "…", "signature": "…" } }A person's credential has "principal": { "kind": "person", "verified_by": "icp-brasil-e-cpf" } and
"authorized_by": { "method": "icp-brasil-e-cpf", … } without a subject. The signature covers the credential as
issued; suspension, revocation and expiry are reported live at verify_url and /v1/revocations.
registration_status is ATIVA, or UNVERIFIED / NOT_CHECKED when the Receita sources were down or the check is
off (issued anyway, with a warning: availability never depends on a third party).
Architecture
agent / verifier ──x402 or MCP──▶ kya-br-agents (Cloudflare Worker: Hono HTTP + MCP Durable Object)
│ D1: agents, challenges, events, webhooks, person checks, call log
│ KV: cache, limits, ICP-Brasil anchors, cloud signing state
│ cron 03:17 UTC: certificate CRLs, company registration, person data retention
├──HTTPS──▶ [CNPJ_API_URL] → BrasilAPI → CNPJ.ws (Receita open data, no key)
└──HTTPS──▶ each AC's CRL (from the certificate)Path | What |
| npm |
| npm |
| npm |
| The issuer: HTTP routes, MCP server, |
| Pulumi: KV, D1 + migrations, Worker, cron, secrets. |
| ICP-Brasil trust anchors (PEM) uploaded to KV by the CD. No anchors, no issuance. |
| Signed evidence JSONs, the cloud provider template. |
| Specification, test vectors, decisions, runbook, self-hosting. |
Run it
docker compose up --build # whole issuer in a container, http://localhost:8787
pnpm install && pnpm typecheck && pnpm test # development (CI also runs the A3 path on a SoftHSM2 token)
cd apps/worker && cp .dev.vars.example .dev.vars && pnpm devPush to main deploys dev and prod from the GitHub environments of the same name (PULUMI_ACCESS_TOKEN,
CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID, PAY_TO; optional INTERNAL_API_KEY, CDP_API_KEY_ID /
CDP_API_KEY_SECRET, CNPJ_API_URL, REGISTRATION_CHECK). The CD applies the D1 migrations, generates the
signing key and the person HMAC key once per stack, uploads the anchors, runs the smoke test and rolls back on
failure. docs/RUNBOOK.md, docs/SELF-HOSTING.md.
Code and service. The MIT license covers this code. The hosted issuer at kya-br-agents.marcelfons.workers.dev
is a service with its own terms, and the name KYA Brasil
identifies it; a fork is a different issuer with a different key, and verifiers choose which issuers they trust.
Contributing and security
Contributions are welcome, in Portuguese or English: CONTRIBUTING.md,
CODE_OF_CONDUCT.md, SECURITY.md (report vulnerabilities privately). Changes to
the format are changes to the spec first; /v1 fields are only added, never renamed or removed.
Available Tools
10 toolskya_aboutAbout KYA BrasilARead-onlyIdempotent
Free and offline. What KYA Brasil is, how an agent gets a credential, which tools to use as a verifier, and where the specification and the issuer's keys are.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover read-only, idempotent, and non-open-world behavior, so the safety profile is already handled. The description still adds real context beyond them: 'Free' (no cost/quota concern) and 'offline' (no network dependency), which are not derivable from readOnlyHint/idempotentHint and matter for an agent deciding whether it can call this in a constrained environment.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense sentence, front-loaded with the two most decision-relevant facts ('Free and offline'), then the content inventory. No filler, no restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, no-output-schema documentation tool, the description is nearly complete: it tells the agent what topics the payload covers and that access is free and offline. A brief note on the return format (structured JSON vs. prose/markdown) would close the remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the schema baseline of 4 applies. The description correctly adds no parameter discussion, which is appropriate here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description enumerates exactly what the tool delivers: what KYA Brasil is, how an agent obtains a credential, which sibling tools serve a verifier, and where the spec and issuer keys live. That content list distinguishes it from the verify/check/revocation siblings, which all perform operations rather than explain them. It lacks an explicit verb ('returns documentation about...'), but the scope is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Free and offline' plus the mention of 'which tools to use as a verifier' implies this is the onboarding/orientation entry point, but the description never states when to call it (e.g. 'call this first', 'use before choosing a verify tool'). Usage is inferable rather than explicit, and no exclusions or alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kya_check_actionSigned verdict for an action (paid)ARead-only
$0.01 (x402, USDC on Base; set KYA_PRIVATE_KEY). May this agent perform this action under its mandate, and is its credential active right now? The issuer answers with a signed verdict that lists every rule it evaluated, usable as evidence in a dispute. For a free, unsigned answer use kya_check_mandate on the mandate from kya_verify.
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | What the agent wants to do, lowercase (order, pay, quote, sign, ...). | |
| amount | No | Amount of this operation. | |
| currency | No | BRL, USDC, ... | |
| spent_today | No | What this agent already spent today, if you track it; needed for max_per_day (the issuer keeps no record of acts). | |
| counterparty | No | Your CNPJ, domain or wallet address (the other side of the operation). | |
| credential_id | Yes | The agent's credential_id (the agent sends it with its request, e.g. in the KYA-Credential header). | |
| payment_network | No | Payment network of this operation: visa, mastercard, elo, pix, ... | |
| payment_ref_sha256 | No | SHA-256 hex of the payment token reference or PAR used, never a card number. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say readOnlyHint and openWorldHint, but the description adds material behavior: the call costs $0.01 via x402/USDC on Base, requires KYA_PRIVATE_KEY to be set, and returns a signed verdict enumerating every evaluated rule that can be used as dispute evidence. None of that is recoverable from the annotations or schema, so the description carries real added value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, each doing distinct work: pricing/auth, the decision being made, then the fallback sibling. The only weakness is that the dense parenthetical '$0.01 (x402, USDC on Base; set KYA_PRIVATE_KEY)' puts implementation jargon ahead of the purpose statement, so the tool's job is not the very first thing read.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 8 parameters, no output schema and no destructive/denial semantics in the annotations, the description does the essential work: it explains the payment barrier, the credential prerequisite, and the shape of the returned verdict. It stops short of explaining failure/denial behavior or error responses, which would be useful for a paid, decision-returning call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and each parameter (action, amount, spent_today, counterparty, payment_ref_sha256, etc.) already has a clear schema description, including the note that spent_today is needed for max_per_day because the issuer keeps no record of acts. The prose references actions, mandates and credentials conceptually but adds no syntax, format or constraint detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise verb+resource: decide whether an agent may perform a given action under its mandate and whether its credential is currently active. It also distinguishes itself from the sibling kya_check_mandate by delivering a signed, evidentiary verdict rather than a free unsigned answer, so an agent can route between them without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit when-to-use rule ('For a free, unsigned answer use kya_check_mandate on the mandate from kya_verify'), which both names the alternative and states the condition that selects it. The paid nature of this tool is stated up front, which is the key selection criterion against its free sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kya_check_mandateCheck an action against a mandate (offline)ARead-onlyIdempotent
Free and offline. Evaluates an intended action against a KYA mandate (the credential's mandate from kya_verify, or one you are drafting) and lists every rule with its result: action, ceilings per operation and per day, currency, counterparty (with *.domain wildcards), payment instrument, validity window. Nothing is sent anywhere.
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | What the agent wants to do, lowercase (order, pay, quote, sign, ...). | |
| amount | No | Amount of this operation. | |
| mandate | Yes | A KYA mandate: actions, max_per_operation, max_per_day, currencies, counterparties, payment_instruments, valid_from, valid_until, delegation. | |
| currency | No | BRL, USDC, ... | |
| spent_today | No | What this agent already spent today, if you track it; needed for max_per_day (the issuer keeps no record of acts). | |
| counterparty | No | Your CNPJ, domain or wallet address (the other side of the operation). | |
| payment_network | No | Payment network of this operation: visa, mastercard, elo, pix, ... | |
| payment_ref_sha256 | No | SHA-256 hex of the payment token reference or PAR used, never a card number. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and openWorldHint=false, so the safety profile is covered. The description reinforces and enriches this: 'Nothing is sent anywhere' confirms the offline nature, 'Free' adds a cost dimension the annotations lack, and it discloses the shape of the result ('lists every rule with its result'), which the missing output schema does not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the most decision-relevant facts ('Free and offline'), then the mechanics. The rule enumeration is dense but earns its place by previewing what the caller receives in the absence of an output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only 8-parameter tool with nested mandate object and no output schema, the description does the essential work: it establishes offline/free behavior, the mandate source, and the returned per-rule breakdown. It could say more about failure/edge behavior when a rule fails, but nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage the baseline is 3, and the description adds real meaning beyond the schema by naming the mandate fields evaluated (ceilings per operation and per day, validity window) and by calling out the '*.domain wildcard' semantics for counterparty, which the schema's plain 'Your CNPJ, domain or wallet address' does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Evaluates an intended action against a KYA mandate') and enumerates the rules checked, so the agent knows exactly what the tool does. It hints at input provenance ('the credential's mandate from kya_verify, or one you are drafting') but does not explicitly differentiate itself from close siblings like kya_validate_mandate or kya_check_action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context of use is implied ('Free and offline', mandate from kya_verify or drafting) but there is no explicit when-to-use guidance or exclusion relative to alternatives such as kya_validate_mandate or kya_check_action. An agent must infer the choice from the one-line purpose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kya_revocationsList revoked credentialsARead-only
Free. Credentials the issuer revoked since a date (default: the last 30 days). For verifiers that cache credentials and want to drop revoked ones.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | ISO 8601 date-time; default 30 days ago. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds "Free" cost context and the default 30-day window, which is thin but useful; it says nothing about result volume, pagination, or ordering.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight fragments, front-loaded with cost, then purpose, then use case. No padding or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, single-parameter read-only list tool with annotations covering safety and an open-world hint, the description supplies purpose, default window, and audience. Nothing essential to correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the single `since` parameter is already documented with its ISO 8601 format and 30-day default. The description restates the default but adds no syntax or meaning beyond the schema, matching the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (list) and resource (revoked credentials) scoped by a date. It is naturally distinct from the sibling verify/mandate/sign tools, though it never explicitly names an alternative. Clear purpose with no sibling callout.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"For verifiers that cache credentials and want to drop revoked ones" clearly identifies the intended caller and scenario. It gives context without naming alternatives or exclusions, which fits the 4 bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kya_sign_linkSigning link for the certificate holderARead-only
Free. The link to send to whoever holds the e-CNPJ or e-CPF (owner, accountant, the person) so they see what is being authorized and sign in the browser. Use after a registration: give credential_id and challenge_id, and the agent's signature of the challenge so the holder only signs with the certificate.
| Name | Required | Description | Default |
|---|---|---|---|
| challenge_id | Yes | challenge.id from the registration or renewal. | |
| credential_id | Yes | The agent's credential_id (the agent sends it with its request, e.g. in the KYA-Credential header). | |
| agent_signature | No | The agent key's signature of challenge.text. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and openWorldHint=true, and the description is consistent with that. It adds context beyond the annotations: the operation is 'Free', the output is a link handed to a human who signs in the browser, and the agent pre-signs the challenge so the holder 'only signs with the certificate'. It does not cover link expiry or reuse, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the distinctive 'Free' marker and followed immediately by what the link is and who receives it. No filler, though the sentences are dense.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still conveys that the return is a shareable link, and it covers the safe-read annotation profile and the post-registration sequencing. It leaves the link's validity window and exact payload unspecified, so not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description earns a bump by explaining the workflow relationship between the three inputs: the agent supplies credential_id and challenge_id and its own signature of the challenge so the certificate holder's browser step is minimized.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies a specific artifact (a signing link) and its audience (the e-CNPJ/e-CPF holder, owner or accountant). It is readily distinguishable from the sibling verify/check/revocations tools, which audit rather than produce a signing link. It never names a sibling explicitly to route the agent, hence not a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states clear context: 'Use after a registration' and names the required inputs (credential_id, challenge_id). It does not name an alternative tool or a when-not-to-use condition, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kya_validate_mandateValidate a mandate (offline)ARead-onlyIdempotent
Free and offline. Checks a mandate against the KYA schema before registering an agent with it, and returns it normalized (actions deduplicated, counterparties and payment instruments normalized). Refuses card numbers and malformed fields with the reason.
| Name | Required | Description | Default |
|---|---|---|---|
| mandate | Yes | A KYA mandate: actions, max_per_operation, max_per_day, currencies, counterparties, payment_instruments, valid_from, valid_until, delegation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/closed-world, so the safety profile is covered. The description adds real behavioral context beyond that: it returns a normalized mandate (actions deduplicated, counterparties and payment instruments normalized) and rejects card numbers and malformed fields with a reason — useful for predicting success/failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the key constraint ('Free and offline'), then purpose and return/refusal behavior. No filler, though the normalization detail is packed densely into one clause.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so: it states the mandate is returned normalized and that errors include a reason. For a one-parameter, read-only validation tool this is largely sufficient, missing only what a failure reason looks like structurally.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single parameter, and schema description coverage is 100% — the schema itself enumerates the mandate fields (actions, max_per_operation, currencies, counterparties, etc.). The description adds no format or syntax detail 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.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('checks a mandate against the KYA schema') and adds scope detail: pre-registration validation plus normalization. It does not, however, differentiate itself from the similarly named sibling kya_check_mandate, so an agent could still hesitate between the two.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'before registering an agent with it' implies the workflow position (pre-registration gate), and 'free and offline' hints at a distinction from the online kya_verify family. But no explicit alternatives or exclusions are named, and the kya_check_mandate overlap is left unresolved.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kya_verifyVerify an agent's credentialARead-only
Free. Who answers for this AI agent? Looks up the agent's KYA Brasil credential at the issuer and returns the principal (a Brazilian company with CNPJ and name, or a person verified by e-CPF with nothing personal), the mandate, the live status (active, suspended, revoked, expired) and its history. Give credential_id, or the agent key to find its active credentials. Use it before trusting an order, payment or signature that comes from an agent.
| Name | Required | Description | Default |
|---|---|---|---|
| agent | No | Alternative to credential_id: the agent's key. | |
| credential_id | No | The agent's credential_id (the agent sends it with its request, e.g. in the KYA-Credential header). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds genuinely new context: it is free, it performs a live issuer lookup, and it enumerates return contents including the status lifecycle (active, suspended, revoked, expired) and history. It does not mention error/not-found behavior or rate limits, but for a read-only lookup that is a minor omission.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the key qualifier 'Free.' and packs return contents, input options and usage trigger into a tight block. The rhetorical opener 'Who answers for this AI agent?' adds a little flavor at slight cost to density, but nothing is truly wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly takes on the burden of describing return values (principal, mandate, status, history) and does so. Both optional parameters are fully documented in the schema, so the only real gap is behavior on missing/invalid credentials or no-match results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds real semantic value beyond the schema by clarifying the either/or relationship ('Give credential_id, or the agent key') and disclosing that supplying an agent key returns its active credentials (plural), which the schema does not state.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (looks up the agent's KYA Brasil credential at the issuer) and enumerates what comes back: principal, mandate, live status, history. It implicitly distinguishes itself from siblings like kya_verify_credential_offline (issuer lookup vs offline) and kya_verify_paid ('Free.'), but never names an alternative explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a clear triggering condition: 'Use it before trusting an order, payment or signature that comes from an agent.' That is strong positive guidance, but there are no exclusions or named alternatives telling the agent when to reach for a different verify-family sibling instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kya_verify_credential_offlineVerify a credential's signature (offline)ARead-only
Free. Checks a credential document you already hold: the issuer's Ed25519 signature (key from the issuer's /.well-known/kya.json, fetched once) and the expiry. It cannot see a revocation made after issuance (live_status is unknown); use kya_verify for the live status.
| Name | Required | Description | Default |
|---|---|---|---|
| credential | Yes | The full credential JSON, including its attestation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint/openWorldHint already covering the safety profile, the description adds the non-obvious behavior: the issuer key comes from /.well-known/kya.json and is 'fetched once', and a post-issuance revocation cannot be seen, leaving live_status unknown. That limitation disclosure is exactly the kind of context the name ('offline') would otherwise mislead on.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with the cost note ('Free.') and the scope front-loaded, followed by the limitation and the routing pointer. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter verification tool with no output schema and strong annotations, the description covers cost, scope, mechanics and the key limitation. It stops short of indicating the shape of the verification result (beyond hinting that live_status is a field), which leaves the return contract implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter and the schema describes it at 100% coverage ('the full credential JSON, including its attestation'), so the schema does the heavy lifting. The description adds the notion that the caller must already hold the document, but no syntax or shape detail beyond the schema — baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Checks a credential document you already hold') plus exactly which checks are performed: the issuer's Ed25519 signature and the expiry. It explicitly separates itself from the sibling kya_verify, so an agent can pick between them without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives the selecting condition for this tool (a credential document you already hold) and names the alternative with its trigger ('use kya_verify for the live status'). It also flags the revocation blind spot as a reason the alternative may be required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kya_verify_delegationVerify a sub-agent's delegation chain (offline)ARead-onlyIdempotent
Free and offline. A sub-agent acts under a delegation chain signed by the credential's agent (KYA-Delegation header). Checks every link (signatures, depth, lifetime, each mandate contained in the one above) against the credential, returns the key that must sign the sub-agent's requests, and, when an action is given, evaluates it on every level: allowed only if all of them allow it.
| Name | Required | Description | Default |
|---|---|---|---|
| chain | Yes | The KYA-Delegation header value (base64url), or the chain as a JSON array. | |
| action | No | What the agent wants to do, lowercase (order, pay, quote, sign, ...). | |
| amount | No | Amount of this operation. | |
| currency | No | BRL, USDC, ... | |
| credential | Yes | The credential (credential_id, agent, mandate, expires_at), e.g. the `credential` from kya_verify. | |
| spent_today | No | What this agent already spent today, if you track it; needed for max_per_day (the issuer keeps no record of acts). | |
| counterparty | No | Your CNPJ, domain or wallet address (the other side of the operation). | |
| payment_network | No | Payment network of this operation: visa, mastercard, elo, pix, ... | |
| payment_ref_sha256 | No | SHA-256 hex of the payment token reference or PAR used, never a card number. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and closed-world, so the bar is lower. The description adds real value beyond them: it is free/offline, describes the chain validation semantics, states the return (the key that must sign the sub-agent's requests), and explains that an action passes only if every level allows it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the key qualifier ('Free and offline') and is dense with no filler. The middle sentence is long and comma-heavy, but every clause carries distinct information about what is checked.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly explains the return value (the signing key) and the conditional action evaluation. For a read-only verification tool with 100% schema coverage, this covers what an agent needs, though it does not sketch the failure/return shape.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 9 parameters thoroughly. The description adds the action-evaluation-on-every-level semantic that helps interpret action/amount, but adds little about the other params, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: verifying a sub-agent's delegation chain, and enumerates what it checks (signatures, depth, lifetime, mandate containment). It is clearly distinguishable from credential-level siblings, though it never names an alternative tool directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Establishes the context ('a sub-agent acts under a delegation chain') and the conditional behavior when 'action' is given, but offers no explicit when-to-use versus siblings like kya_check_action or kya_verify_paid. Usage is implied rather than routed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kya_verify_paidVerify with a signed receipt (paid)ARead-only
$0.01 (x402, USDC on Base; set KYA_PRIVATE_KEY). Same answer as kya_verify, without the free daily limit, plus a signed receipt of the verification.
| Name | Required | Description | Default |
|---|---|---|---|
| credential_id | Yes | The agent's credential_id (the agent sends it with its request, e.g. in the KYA-Credential header). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint/openWorldHint annotations by disclosing price ($0.01), payment rail (x402, USDC on Base), the required environment credential (KYA_PRIVATE_KEY), the absence of the free daily limit, and the extra signed receipt in the response. These are exactly the cost, auth, and rate-limit facts an agent needs before invoking a paid endpoint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense sentence with the cost and payment prerequisites front-loaded and the differentiation from kya_verify second. No filler and nothing that fails to earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter verification tool it covers cost, prerequisite env var, rate-limit contrast, and the added return artifact (signed receipt), which substitutes for the missing output schema at a high level. It does not describe receipt format or payment-failure behavior, leaving a small gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single credential_id parameter, including format, pattern, and header context, so the schema already carries the semantics. The description adds no parameter detail beyond that, which is the baseline-3 case for a fully documented single param.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (verification via kya_verify_paid) and immediately differentiates from its closest sibling: 'Same answer as kya_verify, without the free daily limit, plus a signed receipt.' An agent can tell exactly what it gets versus the free variant without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'without the free daily limit' implies the selection condition (use when the free tier is exhausted or when a receipt is needed), and it explicitly names the alternative kya_verify. It stops short of an explicit 'use this when / not when' statement, so it is clear context rather than full routing guidance.
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.
10 tool updates
v0.1.0- First observed
kya_about - First observed
kya_check_action - First observed
kya_check_mandate - First observed
kya_revocations - First observed
kya_sign_link - First observed
kya_validate_mandate - First observed
kya_verify - First observed
kya_verify_credential_offline - First observed
kya_verify_delegation - First observed
kya_verify_paid
TDQS
Scored across 10 tools
Several tool pairs overlap heavily (kya_verify vs kya_verify_paid, kya_check_action vs kya_check_mandate, kya_validate_mandate vs kya_check_mandate), but the descriptions explicitly cross-reference each other and state when to use the free/offline vs live/paid variant, so boundaries are largely recoverable. An agent must read carefully to pick the right variant, which keeps this from a 5.
All tools share a consistent kya_ snake_case prefix followed by a verb_noun form (validate_mandate, check_action, verify_delegation). Minor deviations exist: kya_revocations and kya_about are noun-only with no verb, and the verify family uses inconsistent suffixes (verify, verify_paid, verify_credential_offline).
Ten tools is well within the ideal 3-15 range and each covers a distinct verification/validation concern for the KYA credential lifecycle. No tool feels gratuitous given the breadth of the domain.
The surface covers the full verifier lifecycle: pre-registration mandate validation, signing link, offline and live credential verification, action/mandate checks, revocation polling, delegation chains, and documentation. Only minor gaps, such as issuance itself being external, keep it short of perfect coverage.
Maintenance
Related MCP Connectors
KYA backed by a real company: e-CNPJ-signed agent mandates, revocation-checked, signed verdicts
Brazilian KYB beyond registry checks: CGU sanctions, forced labour, PGFN, IBAMA, signed risk score
KYB due diligence for agents: sanctions screening, EU VAT/VIES, LEI, IBAN in one verdict.
Brazilian company data, CNPJ/CPF validation and KYB risk score. Pay per call via x402 (USDC).
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceKYA (Know Your Agent) identity, trust scoring, and insurance protocol for autonomous AI agents. Issues verifiable credentials, computes real-time trust scores, and provides agent liability coverage on Base L2.MIT
- AlicenseBqualityCmaintenanceConnects AI agents to Brazilian tax compliance data (CNPJ, CPF, NFe, SPED, eSocial) and provides tools for due diligence, risk scoring, and tax regime comparison.44165 PyPI319MIT
- FlicenseAqualityDmaintenanceAgentic KYC/AML compliance server with tools for sanctions screening, identity verification, and risk assessment, where AI orchestrates discretionary checks within deterministic compliance guardrails.6-

KYA-OS MCP Serverofficial
FlicenseNot gradedqualityDmaintenanceA ready-to-deploy MCP server with in-process agent verification via KYA-OS Checkpoint, enabling secure tool access for verified agents.1-