Ultron as consumer
Every Ultron agent that mentions, researches, or transacts with another company should fetch that company's BCP manifest first. Bi-directional adoption is the property that makes BCP useful from day one - Ultron is both the largest publisher and the largest consumer of manifests in our own product.
Why Ultron reads manifests
The consumer side closes the loop.
Publishing manifests is half the story. If no one reads them, they decay into the same fate as agents.txt - published in marketing copy, ignored in practice. Ultron reads every manifest it can find, automatically. Three places matter:
| Where Ultron reads a manifest | What it unlocks |
|---|---|
| User mentions a domain in chat | The agent looks up the manifest, learns the company's MCP endpoint, treats the company as a first-class actor for the rest of the conversation. |
| A lead enrichment touches a domain | Identity block fills in legalName, jurisdiction, LEI without an extra Apollo / Crunchbase call. Free signal. |
| A scheduled agent or background mission targets a company | The mission planner reads the target's manifest to pick the right endpoint per step (catalog query vs lead submit vs booking). |
The bcp_lookup chat tool
A native chat v2 tool that wraps the resolution algorithm.
Implicit invocation
The chat-v2 system prompt instructs the model to callbcp_lookup the first time a new domain enters the conversation, before invoking any other tool that touches that domain. The result is cached for the conversation lifetime; subsequent mentions reuse the cache.
Resolution algorithm
What runs when bcp_lookup is called.
- 01NormaliseReduce the input to an apex domain.
https://www.acme.com/products→acme.com. - 02Race apex vs wwwHTTPS GET against
https://acme.com/.well-known/business.jsonandhttps://www.acme.com/.well-known/business.jsonin parallel with a 5s budget. First 2xx wins. - 03Fall back to registryIf both 404 or time out, call
https://bcp.51ultron.com/lookup?domain=acme.com. Returns either the Ultron-hosted manifest URL or 404. - 04Validate schemaParse JSON-LD. Reject if @type does not include BusinessCard or identity.domain does not match the resolved host.
- 05Verify signature (if present)Run the verification flow from the
/docs/bcp/signingpage. Compute the trust level (L0-L3). - 06Cache and returnStore with the source URL, hash, and trust level. Return a structured response to the model.
Verification level
The four levels and what each unlocks.
| Level | Means | What Ultron will do with it |
|---|---|---|
| L0 - Advisory | No signature, or signature fails. Manifest content not authenticated. | Use identity for display. Show endpoints in UI but warn before submitting. Never auto-act on write scopes. |
| L1 - Identified | Signed, signing key in identity.publicKey, no DNS binding. | Same as L0 for write actions. Use identity for narrative grounding. |
| L2 - DNS-pinned | Signed, signing key matches _bcp.<domain> TXT. | Auto-act on read scopes. Surface confirmation prompts before write scopes. Default tier for SMB customers. |
| L3 - vLEI-bound | Signed by a vLEI role credential, chained to GLEIF. | Auto-act on configured write scopes within rate limits. Acceptable counterparty for AP2 mandates. |
Caching strategy
Honour the publisher's cache headers, with a floor.
- Default TTL
- Honour
Cache-Control: max-age. Floor at 60 seconds, cap at 24 hours. - Stale-while-revalidate
- If the manifest is stale, return cached, refresh in background.
- ETag revalidation
- On expiry, conditional GET with
If-None-Match. 304 skips parse + verify. - Conversation cache
- Per chat session, cache for the entire session regardless of TTL. Single domain mention triggers one fetch only.
- Tenant cache
- Cross-conversation cache keyed by
(tenant_id, domain). Postgres-backed. Avoids redundant fetches inside one workspace. - Global cache
- None. Each tenant fetches independently. Privacy reason: who is asking about whom should not be cross-tenant observable.
Acting on a manifest
From a verified manifest to a tool call.
- 01Pick the right MCP serverIf the model needs a write scope, filter
mcpServersby scope match. If multiple servers match, prefer the one with the strongest auth (oauth2 > bearer > apikey > none). - 02ConnectIf oauth2, run the connect-once flow (per workspace, per counterparty domain). Cache the access token. If bearer, prompt the user for the token once. If none, connect anonymously.
- 03Issue the tool callStandard MCP tool invocation. The manifest's scope claim should match what the server actually exposes, but always re-check by querying the server's tool list before calling.
- 04Record the actionEvery call against a BCP-resolved server is written to
bcp_call_logwith the manifest hash, the scope used, and the response code. Used for billing, abuse detection, and audit. - 05Handle policy violationsIf the server rejects the call as out-of-scope, surface the diff between the manifest's claim and the server's actual behaviour. This is a publisher bug; flag it for the customer.
Error handling
What Ultron does when a manifest is missing, broken, or hostile.
| Error | Behaviour |
|---|---|
| No manifest published | Treat the domain as opaque. Use traditional research tools (web search, scrape) instead. No BCP-driven actions. |
| Manifest unreachable (DNS, timeout, 5xx) | One retry with backoff. Then fall back as if no manifest published. Log for the operator dashboard. |
| Manifest is malformed JSON | Reject, log, surface to publisher via support@ if the workspace has Ultron-issued contact. |
| Signature does not verify | Downgrade to L0. Continue to use identity block for narrative but never auto-act. |
| Manifest claims a domain that does not match the host | Reject outright. This is a strong impersonation signal. |
| Manifest is much larger than 256 KiB | Reject. Treat as malformed. |
| bcp:expires in the past | One re-fetch (the cache may be stale). If still expired, downgrade to L1 maximum. |
| Signing key revoked (vLEI witness mesh) | Reject manifest. Surface a security event. Do not auto-act. |
Safety considerations
What an attacker could do, and how the protocol pushes back.
policy.allowActionsmay list scopes the publisher does not actually honour. The MCP server pointed at may rate-limit or reject. The incident webhook may never fire. Always treat the manifest as a hint, never as enforcement.| Attack | Defense in BCP |
|---|---|
| Impersonation: attacker hosts manifest claiming to be acme.com | Signature must verify against acme.com's DNS-pinned key. Without that, only L0 (advisory) trust. |
| Phishing: attacker registers acme.co (typo) and publishes legit-looking manifest | Trust level is per-domain. The user must approve cross-counterparty actions. Ultron surfaces the resolved domain in confirmation prompts. |
| Replay: serve an old manifest where allowActions was broader | bcp:expires + signedAt freshness check. Stale manifests cannot authorise write scopes. |
| Confused deputy: A's manifest tricks Ultron into acting against B | Manifests are scoped to the domain they live on. Cross-domain actions require the target domain's manifest, fetched separately. |
| Resource exhaustion: huge manifest, infinite-redirect loop | Size cap 256 KiB. Redirect cap 3. Timeout 5s. Hard limits, no negotiation. |
| Sensitive data leak: manifest reveals private endpoints | Publisher's responsibility. Ultron only generates manifest fields from data the customer marked as public on /company-demo. |