AISOURCEOFTRUTH.COM
AGENTS · MCP · OAUTH · ONE-CALL VERIFY

Verify before you transact, with no browser

An agent can find out who made an artifact, check the signature and the log proof, and refuse to act on anything that fails, in one call. It can register itself, publish signed records, bind the identity it already carries, and anchor its own audit chain. Everything here is the public API; the MCP server is a thin layer over it.

THREE WAYS IN · PICK THE ONE THAT MATCHES WHO IS ASKING

Get access

Reading and verifying need no account and no token. You need access only to publish, to receive webhooks, or to act for an organization.

A PERSON, IN A BROWSER

Sign in and use the console

Switching on

  1. Sign in with PromptReports. One login covers every PromptReports product. Sign-in is not switched on yet. Until it is, the console takes a token made the third way.
  2. Create a publisher. Your browser makes the signing key; the registry never sees the private key.
  3. Make a client for each agent, with only the scopes it needs. Copy its secret once.
OPEN THE CONSOLE
AN MCP CLIENT

Connect Claude, ChatGPT or any MCP client

Planned

  1. Add https://aisourceoftruth.com/mcp as a connector. Reads work at once, with no sign-in.
  2. Sign-in for people from an MCP client is coming. Until then, give the client a token from a client you made in the console.
  3. You will choose the publisher and the scopes on an approval screen, then approve.
SEE THE MCP SERVER
AN AGENT, NO PERSON PRESENT

Register over the API

Live

  1. Make a key pair and register a publisher: POST /v1/publishers, signed by that key.
  2. Mint a 60 minute token with client_credentials at /oauth/token, asking only for the scopes you need.
  3. PromptReports ID agent tokens, DPoP-bound, are accepted here once they are switched on.
SEE THE STEPS

Scopes: ask only for what the agent does

SCOPELETS THE AGENTPROMPTREPORTS ID SCOPE
read:feedRead with higher limitsaisot:read, aisot:read:feed
subscribe:eventsFollow the event streamaisot:read, aisot:subscribe:events
publish:provenanceAppend provenance, incident, evidence and errata recordsaisot:write, aisot:publish:provenance
publish:verificationAppend verification records (reviewed publishers only)aisot:publish:verification
manage:webhooksList, add, pause, resume, retire and rotate webhooksaisot:manage
manage:clientsCreate, rotate and revoke this publisher's clientsaisot:manage
manage:billingRead the plan and change itaisot:manage
manage:keysRotate, revoke and recover signing keys (each change still needs a key signature)aisot:manage

Clients made before the manage scopes existed keep every scope their tier had. A new client gets only the scopes you give it.

curl -s -X POST https://aisourceoftruth.com/oauth/token -H 'content-type: application/json' -d '{"grant_type":"client_credentials","client_id":"<id>","client_secret":"<secret>","scope":"publish:provenance"}'
curl -s https://aisourceoftruth.com/.well-known/oauth-protected-resource/mcp
37
MCP TOOLS
1,000
DIGESTS PER VERIFY CALL
4
IDENTITY KINDS
THE MCP SERVER

37 tools, one per API call

Streamable HTTP at https://aisourceoftruth.com/mcp, protocol 2025-11-25. Reads are anonymous. Writes take a Tier-2 token on the request and a signature by your key, the same as the REST API.

{
  "mcpServers": {
    "aisourceoftruth": {
      "url": "https://aisourceoftruth.com/mcp"
    }
  }
}

Tools

TOOLWHAT IT DOES
resolve_recordResolve an immutable record by digest.
search_recordsSearch records by text, publisher, or profile.
get_lineageGet an asset's lineage (up- and downstream).
get_keysThe publisher signing-key directory.
verify_signatureIndependently re-verify a record's signature against its registered key (crypto in-tool).
get_rootThe current log root + daily roots.
get_inclusion_proofRFC 6962 inclusion proof for a record against the latest signed checkpoint (one every few seconds while records arrive), or the checkpoint or daily root with tree_size. Carries the signed checkpoint note. A record no signed checkpoint covers yet has no proof: the answer says pending: true, proof: null, a reason and checkpoint_eta. That is not a failure. Checkpoints are signed every few seconds while records arrive; call again after checkpoint_eta to get the proof.
get_consistency_proofRFC 6962 consistency proof between two published checkpoints or daily roots (from and to are tree sizes; to defaults to the latest signed checkpoint). Same answer as GET /v1/proofs/consistency. It shows the log did not fork or roll back between them. No token needed.
get_checkpointThe latest C2SP signed checkpoint, exactly as GET /checkpoint serves it: signed by the log key, then every witness cosignature stored for it. Also lists the signer names and the quorum status (independent cosigners against the /log/policy quorum). No token needed.
get_witnessWho checks this log (GET /witness as JSON): the log key and any rotation, the registry keys, each witness with whether it is independent and its last co-signed size, and our own witness for other logs. No token needed.
get_certificateA record's certificate (GET /r/{digest}/certificate as JSON): signer, time, log position, proof, timestamps, and what the record proves and does not prove. No token needed.
export_bundleAn offline evidence bundle (aisot-export-v1, same as POST /v1/export) for up to 100 digests: signed bytes, signatures, keys, errata, inclusion proofs, roots, checkpoints and timestamp tokens. Save it as bundle.json and check it with node verify.mjs bundle.json (the verifier is at /v1/export/verify.mjs). No token needed.
get_eventsThe append-only event feed.
verify_batchVerify up to 1000 digests in one call (verify-before-transact). A record no signed checkpoint covers yet has no proof: the answer says pending: true, proof: null, a reason and checkpoint_eta. That is not a failure. Checkpoints are signed every few seconds while records arrive; call again after checkpoint_eta to get the proof.
get_pricingRegistry prices: what is free, publisher plans, add-ons, and how an agent pays. No token needed.
get_billingYour plan, usage this month, credit balance, monthly cap and receipts. Needs a Tier-2 Bearer token on the MCP request.
choose_planSwitch plan (free, pro, business), paid from prepaid credits within the owner's monthly cap. Answers with a 402 price sheet when credits or the cap fall short. Where plans are bought at the PromptReports portal, a new paid plan answers 409 with portal_url for a person to pay at. Needs a Tier-2 Bearer token.
register_clientCreate a client (RFC 7591). Returns client_id and client_secret for a Tier-1 read token. No token needed.
get_tokenMint a Bearer token with the client_credentials grant. Use the credentials from register_client or register_publisher.
register_publisherBecome a publisher. Generate an ES256 (P-256) or Ed25519 key yourself, build the JSON body { id, name, public_jwk, domain? }, sign those exact bytes with the private key, and pass body + signature. Returns Tier-2 client credentials. Never send a private key.
get_meYour publisher account: keys, quota, webhooks. Needs a Tier-2 Bearer token on the MCP request.
get_accountingYour org's audit events (one per agent action) and usage events (one per action the registry carried out), linked to the record, family statement and receipt each touched. Needs a PromptReports ID agent token on the MCP request.
get_launchA launch's claims and whether each claim's evidence verifies, exactly like GET /launches/{publisher}/{launch_id} as JSON (RepoOps LDG-2269). Record each claim first with publish_record as a signed launch_claim record (schema /spec/schemas/launch_claim.schema.json): the claim by hash, the launch block, and its evidence (ContextFile launch_proof, RepoOps release trace digest, PromptCompute approval id and receipt). A claim reads verified only when all three verify in this log; the answer names what is missing, and carries the badge URL and embed snippet for the blog post. No token needed.
verify_packetVerify a whole trust packet (RepoOps LDG-2272), exactly like POST /v1/verify/packet: pass the packet object, or url to fetch it. Checks the packet signature against the issuer's key in this registry's key directory, that the issuer is a member of the org, and per item: in this log, of the org, logged within the period, not sealed or corrected since. Each item reads verified, corrected (with the correction), sealed, not_found, out_of_period, wrong_org or unchecked; result is verified only when every item verified. An org-private item is confirmed only for a packet its org signed, and its content is never shown. Stores nothing. No token needed.
get_transparency_proofThe proof that a record is in a public Rekor v2 log (RepoOps LDG-2285), exactly like GET /v1/transparency/proof/{digest}: the record's inclusion proof in the first registry checkpoint anchored to Rekor v2 after it, that log-signed checkpoint, the Rekor entry with its inclusion proof and Rekor's signed checkpoint, and the RFC 3161 timestamp token over that checkpoint (LDG-2236), plus this registry's check of every step and how many of the two outside witnesses check against the quorum of 2. status is switching_on until the operator turns anchoring on, and pending until the next anchor covers the record. No token needed.
verify_transparencyCheck a transparency proof from anywhere (RepoOps LDG-2285), exactly like POST /v1/verify/transparency, against the keys this registry publishes at GET /v1/transparency: the record is in the checkpoint, the checkpoint is signed by the log key, the Rekor v2 entry names that exact checkpoint and is signed by the anchor key, Rekor's signed checkpoint includes the entry, and the RFC 3161 timestamp token names that checkpoint and chains to the pinned TSA root (LDG-2236). Reports the witness count against the quorum of 2. Stores nothing. No token needed.
verify_investor_updateVerify every figure of an investor update (RepoOps LDG-2278), exactly like POST /v1/verify/investor-update: pass the update object, or url to fetch it. Checks the signature against the issuer's key here and the issuer's membership of the org, then per figure: each record or family statement it names is in this log, of the org, logged from the start of the figure's period to the update's issue time, not sealed or corrected since; the value matches when a source record's asset is the figure digest or the named research scorecard as of its date gives the same number. approved is true only when the PromptCompute approval receipt is a record here, of the org, whose asset is the update's content digest. Each figure links to its records. Stores nothing. No token needed.
get_scorecardA publisher's graded research scorecard as the log stood at the end of as_of (YYYY-MM-DD, UTC; default today), exactly like GET /p/{publisher}/scorecard as JSON (RepoOps LDG-2277): every research_call record, its grade (research_grade) if one was logged by then, the hit rate and calibration (Brier score and bins) once at least 5 calls are graded, open and overdue calls counted apart, regrades and errata as they stood that day. A call the registry logged after it resolved is flagged and never counted. Record a call first with publish_record as a signed research_call (schema /spec/schemas/research_call.schema.json), then its outcome as a research_grade. No token needed.
publish_recordPublish a signed record (Tier-2 token + signature required, exactly like POST /v1/records).
register_statementRegister a SCITT signed statement (a COSE_Sign1, base64), exactly like SCRAPI POST /entries: Tier-2 token on the MCP request, kid = your publisher key id, CWT claims iss and sub, and a hash envelope (RFC 9995) or hashes-only JSON agent receipt payload. Returns the entry id, the receipt (base64 COSE) when a checkpoint covers it, or pending with the URL to poll.
lookupLook up records by content hash (sha256), C2PA manifest digest or urn:c2pa label (c2pa_manifest), claim instance id, or a C2PA soft binding (soft_binding_alg + value, base64), exactly like GET /lookup. Returns every match oldest first with publisher and signature status, and basis "value supplied by caller": the registry runs no watermark or fingerprint detection and never says whether content is AI-generated. No token needed.
get_receiptThe SCITT COSE receipt (RFC 9942, RFC9162_SHA256 inclusion proof signed by the log key) for a registered statement, as base64, exactly like SCRAPI GET /entries/{entry_id}. The keys are at /.well-known/scitt-keys. No token needed.
get_stateThe world model state receipt of one entity as of a signed checkpoint, exactly like GET /v1/model/state/{type}/{key}: state, facts, reasons (stable codes), relied_on, events_relied_on and receipt_sha256. Entity types: record, asset, publisher, key, model, judge, source, license, agent, agent-version, mandate, erratum, seal, log, lesson, repo. No token needed.
assessBefore you act on a record: rely, check or do_not_rely, from fixed rules, never a score, exactly like GET /v1/model/assess/{digest} (or ?asset= for an asset's latest record). Gives every reason as a stable code, the terms owed for the sources it cites, the proof (checkpoint, state receipt, the POST /v1/export body), and an explain block: each rule's result (signature, key_state, seal, errata, agent_status, terms) with the record digests and events it read, and the checkpoint's witness cosignature count. explain is outside the hashed receipt fields. Plan and payment never change it. No token needed.
get_impactWhat depends on a key (and since a time), an agent version, or an erratum, as of a signed checkpoint, exactly like GET /v1/model/impact. Give exactly one of key, agent_version, erratum. No token needed.
get_model_changesThe world model state change feed, exactly like GET /v1/model/changes: changes after cursor in order, each with entity, field, from, to, cause and time. Keep next_cursor and call again. No token needed.
get_model_diffOne entity's diff between two as_of points, exactly like GET /v1/model/diff: its state at each point, the links added and closed, the change events between them, and the RFC 6962 consistency proof from the from tree size to the to tree size (empty when both points share one tree size), as receipt type aisot-model-diff-v1. from must not be later than to. No token needed.
PROMPTREPORTS ID AGENT TOKEN

Sign an agent in with PromptReports ID

Across the products Planned state from family.json. Here Switching on.

This registry does not accept the token yet. Until it does, register with OAuth below.

REGISTER WITH OAUTH

No human in the loop

  1. Register a client (RFC 7591), no human in the loop
    curl -X POST https://aisourceoftruth.com/oauth/register -H 'content-type: application/json' -d '{"client_name":"my-agent"}'
  2. Mint a Bearer token with client_credentials
    curl -X POST https://aisourceoftruth.com/oauth/token -H 'content-type: application/json' -d '{"grant_type":"client_credentials","client_id":"<id>","client_secret":"<secret>"}'
  3. To publish, register a publisher with a key you generated; the registry never sees the private key
    POST https://aisourceoftruth.com/v1/publishers (or the MCP tool register_publisher), signed by the key in the body
ONE CALL TO VERIFY

Up to 1,000 digests per call. Each result carries the signature status, the inclusion proof (or pending), the cosignature quorum, the errata count and the judge version.

curl -X POST https://aisourceoftruth.com/v1/verify-batch -H 'content-type: application/json' -d '{"digests":["<64-hex record digest>"]}'
BIND YOUR AGENT'S IDENTITY
kindsweb-bot-auth, mcp-namespace, a2a-agent-card, wimse (claimed, not verified)
  1. Publish an identity record (POST /v1/records, profile identity) naming the kind and the subject, signed by your publisher key.
  2. Run its check with POST /v1/identity-bindings/verify { digest }, signed the same way. A passed check appends a public identity.verified event.
  3. End a binding with a later identity record that names it in revokes. The old binding stays in history.

A binding says this publisher proved control of that identity on that date. It is not an endorsement. Publishers can also add, check and end bindings in the console.

ANCHOR YOUR AGENT'S AUDIT CHAIN

A checkpoint record, signed by your key

{
  "profile": "checkpoint",
  "artifact": {
    "digest": "<root_hash>"
  },
  "checkpoint": {
    "log_id": "my-agent/audit",
    "tree_size": 48211,
    "root_hash": "<root_hash>",
    "algorithm": "sha256-chain",
    "period_end": "<ISO time>"
  },
  "created_at": "<ISO time>"
}
  • Post the head of your agent's own hash chain on a timer. Once a head is on this log, a rewrite below it shows.
  • A smaller tree_size than your last checkpoint for that log_id is refused as a rollback; the same tree_size with a different root is refused as a fork.
  • Checkpoint records never count against a quota.
SDKS
LANGUAGEINSTALLHELPERSSOURCE
JavaScript@aisourceoftruth/sdk: not on npm yet; call the HTTP API directly (POST https://aisourceoftruth.com/v1/records, https://aisourceoftruth.com/openapi.json)verifyBatch, publishCheckpoint, publishIdentity, verifyBindingpackages/sdk
Pythonpip install aisot (PyPI has 0.1.0 (publish, verify, verify_batch); the publish gate, publish_checkpoint, build_identity and anchor_chain come with 0.2.0, not released yet)verify_batch, publish_checkpoint, build_identitypackages/python
CLIaisot: not on npm yet; use the HTTP API or the Python packageaisot init, aisot publish, aisot verifypackages/cli

Discovery: /.well-known/agent.json, /openapi.json, /llms.txt, /for-assistants.

$ curl -H 'Accept: application/json' https://aisourceoftruth.com/agents # this page is a rendering of the API. Reproduce it as data.