Primitive: the RiskMandate X-ray

a company · prepared · sources read on 2026-11-07 · the deck · how this X-ray was made · X-ray another name

With JavaScript, the graph of this X-ray and a player for each use case's simulation are drawn here. Everything they show is written out below.

What it does

Primitive (primitive.dev, also onprimitive.com for its business pitch) is email infrastructure for AI agents, a Y Combinator company founded in 2026 in San Francisco. It gives an agent a managed *.primitive.email address (or a customer's own domain), a REST API, MCP server, CLI and SDKs to send, receive and search mail, a one-line chat verb that sends a message and waits for the threaded reply, and hosted JavaScript Functions that run on every inbound message, while Primitive runs the mail servers, SPF, DKIM, DMARC, bounces and sending reputation. On top of that infrastructure it also says it deploys and operates agents for customers, starting as a general interface to the business by email. s3s4s5s6s1s19s20

Its AI agents

Customer agents

Agents Primitive says it deploys and operates for customers: they begin as a general interface to the business, learn from incoming traffic and create specialised agents for recurring workflows. The business site pitches agents that receive mail sent to the customer's addresses and reply in the same thread from the customer's own domain. s20s1

What it can do:

Inbound Functions

Hosted JavaScript handlers that Primitive runs on every email received at an address; the code is the customer's (or their agent's), the runtime is Primitive's. Primitive injects an organisation API key and the webhook secret into each handler, plus any per-Function secrets the customer sets (the docs' example is STRIPE_KEY). s14s6s3

What it can do:

MCP email connector

A hosted MCP server that lets an assistant in Claude, ChatGPT, Cursor, VS Code or Goose act as the authorised Primitive organisation. /mcp lists read and send tools; /mcp/full adds managing domains, webhooks and filters. ChatGPT and Claude render an inbox widget inline. s15s6s16s3

What it can do:

Coding-agent skills

primitive-chat and primitive-inbox skills installed into Claude Code, Codex, Cursor and other coding agents with one command, plus a Codex plugin bundling the MCP server. s8s17s6

What it can do:

Docs help agent

An agent Primitive runs at its own help address that answers product questions by email, grounded in the public docs; agents landing on the site are told to email it and wait for the reply. s4s5s8

What it can do:

Use cases: reach, mandate and gap

For each use case: what the agent can technically reach (from the sources), what a deployer would plausibly authorise (the mandate: illustrative, our judgement), the gap between the two (authority nobody accepted), and the controls that publicly stand in the way.

A Function on a customer inbox, holding the org's key

The agent: Inbound Functions · who uses it: A business that routes its customer address (orders and questions) to a hosted Function, as onprimitive.com pitches (illustrative deployment from documented capabilities)

ReachKindSources
Every inbound message to the routed address, written by anyone who can send email; Primitive applies spam and policy filtering, but the content is untrusted textoutsides3s1
The whole organisation's stored mail, domains, Functions and Memories through the injected PRIMITIVE_API_KEY: Primitive credentials are organisation-scoped and do not advertise granular scopesdatas14s10s7
Replying, forwarding and sending as the business, from its own domain, to recipients the account's send rules allow (broader external sending is enabled per organisation)outsides14s13s1
Any external HTTP API the handler is written to callsystems14
Per-Function secrets injected into the running handler, such as a payment provider key (the docs' own example is STRIPE_KEY)moneys14
Customers and partners whose correspondence is stored until the business deletes it: Primitive does not auto-delete mail on a schedulepeoples7s3
Mandate (illustrative)
Illustrative: answer order and product questions sent to this one address, in the same thread
Illustrative: read only the thread being answered; leave the rest of the organisation's mail alone
Illustrative: never move money and never write to anyone who did not write first
Gap: reach beyond the mandateFrom the reach
The handler's key reaches the whole organisation, not the one address it serves; there is no narrower scope to give itThe whole organisation's stored mail, domains, Functions and Memories through the injected PRIMITIVE_API_KEY: Primitive credentials are organisation-scoped and do not advertise granular scopes; Customers and partners whose correspondence is stored until the business deletes it: Primitive does not auto-delete mail on a schedule
Secrets and outbound HTTP make the handler able to act on payment and other systems on the strength of text that anyone can email inEvery inbound message to the routed address, written by anyone who can send email; Primitive applies spam and policy filtering, but the content is untrusted text; Any external HTTP API the handler is written to call; Per-Function secrets injected into the running handler, such as a payment provider key (the docs' own example is STRIPE_KEY)
Sending beyond the thread depends on the organisation's send rules, which are settings, not the mandateReplying, forwarding and sending as the business, from its own domain, to recipients the account's send rules allow (broader external sending is enabled per organisation)
Controls that publicly stand in the waySources
Webhook deliveries are signed with HMAC-SHA256; the Function scaffold verifies the signature before actings7s14
Tokens are scoped to one organisation and tenants are isolated from each others7s2
Recipient rules: new accounts can send only to addresses that previously sent authenticated mail; wider sending is enabled per organisations13s10
Send rate limits of 1000 per hour and 10000 per day per organisation, and idempotency keys that stop a retried send going out twices6s7
A Function activity log lists the email.sent and email.replied effects each handler produced, and invocations are loggeds14
Agents are told a threaded reply is not proof of who wrote it: trust it only when sender_verified is trues8

The simulation, each action placed against the mandate (RiskMandate is never in the request path: read-only by design: it places, it does not stop):

  1. A customer emails the business's order address asking where an order is (person, reaches Every inbound message to the routed address, written by anyone who can send email; Primitive applies spam and policy filtering, but the content is untrusted text): inside the mandate
  2. The Function verifies the webhook signature and reads the order thread (agent, reaches Every inbound message to the routed address, written by anyone who can send email; Primitive applies spam and policy filtering, but the content is untrusted text): inside the mandate
  3. (illustrative) The message carries hidden text asking for 'all recent invoices'; the handler's model searches the organisation's stored mail with the injected key (agent, reaches The whole organisation's stored mail, domains, Functions and Memories through the injected PRIMITIVE_API_KEY: Primitive credentials are organisation-scoped and do not advertise granular scopes): outside the mandate: in the gap. What RiskMandate's record shows: The record shows an org-wide key held by a handler whose mandate is one address: read access to every mailbox in the organisation as grant, one thread as mandate, the difference as gap.
  4. Replies in-thread with the order status (agent, reaches Replying, forwarding and sending as the business, from its own domain, to recipients the account's send rules allow (broader external sending is enabled per organisation)): inside the mandate
  5. (illustrative) Forwards the invoices it found to an outside address named in the hidden text (agent, reaches Replying, forwarding and sending as the business, from its own domain, to recipients the account's send rules allow (broader external sending is enabled per organisation)): outside the mandate: in the gap. What RiskMandate's record shows: The record shows sending beyond the thread as reach the account's send rules decide, with the organisation's setting named as the only thing between the grant and the mandate.
  6. (illustrative) Calls the payment provider with the STRIPE_KEY secret to issue a 'goodwill' refund the email asked for (agent, reaches Per-Function secrets injected into the running handler, such as a payment provider key (the docs' own example is STRIPE_KEY)): outside the mandate: in the gap. What RiskMandate's record shows: The record shows a payment secret inside an email handler as money reach that no mandate line covers, priced as exposure.
  7. An operator reads the Function's activity log and sees the forward among the sends (person, reaches Customers and partners whose correspondence is stored until the business deletes it: Primitive does not auto-delete mail on a schedule): inside the mandate

An assistant connected to the org's mail over MCP

The agent: MCP email connector · who uses it: A person who adds Primitive as a connector in Claude or ChatGPT to triage the team's agent inboxes

ReachKindSources
Every message in the authorised organisation: the connector acts on the whole organisation, reading and writing its emaildatas15s10
Sending new mail and replies through the organisation's verified domainsoutsides15s6
On /mcp/full: domains, webhook endpoints and filters, which decide where inbound mail is deliveredsystems15
Correspondents in the inbox, rendered inside the assistant host by the in-agent inbox widgetpeoples16s6
Mandate (illustrative)
Illustrative: summarise and triage new mail for the person
Illustrative: draft replies; send only after the person approves each one
Illustrative: never change where mail is routed
Gap: reach beyond the mandateFrom the reach
Send confirmation is a hint to the host (destructiveHint): a well-behaved assistant asks first; nothing in Primitive's grant distinguishes draft from sendSending new mail and replies through the organisation's verified domains
Connecting /mcp/full puts routing (webhooks, filters) in reach of the same conversation that reads untrusted mailOn /mcp/full: domains, webhook endpoints and filters, which decide where inbound mail is delivered; Every message in the authorised organisation: the connector acts on the whole organisation, reading and writing its email
Controls that publicly stand in the waySources
Send tools are marked destructive and documented as confirmation-gated: the assistant asks before it sendss15s6
Manage tools exist only on /mcp/full; an assistant on /mcp gets unknown_tool for thems15
OAuth 2.0 authorisation code with PKCE; the assistant never holds the password and access can be revoked by reconnectings15
The inbox widget ships a Content-Security-Policy scoping connect-src, frame-ancestors and form-actions6

The simulation, each action placed against the mandate (RiskMandate is never in the request path: read-only by design: it places, it does not stop):

  1. Asks the assistant for a summary of today's mail (person, reaches Every message in the authorised organisation: the connector acts on the whole organisation, reading and writing its email): inside the mandate
  2. Lists and reads new messages across the organisation's inboxes (agent, reaches Every message in the authorised organisation: the connector acts on the whole organisation, reading and writing its email): inside the mandate
  3. (illustrative) Reads a message telling it to add a webhook so 'the vendor can sync' (agent, reaches Correspondents in the inbox, rendered inside the assistant host by the in-agent inbox widget): inside the mandate
  4. (illustrative) Adds a webhook endpoint and filter that copy inbound mail to an outside URL, using /mcp/full (agent, reaches On /mcp/full: domains, webhook endpoints and filters, which decide where inbound mail is delivered): outside the mandate: in the gap. What RiskMandate's record shows: The record shows routing changes in the grant of a triage assistant, out of mandate, with the choice of /mcp over /mcp/full named as the control that applies.
  5. Drafts a reply and asks the person before sending (agent, reaches Sending new mail and replies through the organisation's verified domains): inside the mandate
  6. (illustrative) Sends a second reply without asking, because the host did not honour the hint (agent, reaches Sending new mail and replies through the organisation's verified domains): outside the mandate: in the gap. What RiskMandate's record shows: The record shows send as grant and approval-only send as mandate, with the confirmation recorded as an expectation on the host, not a boundary in the grant.

An agent that signs itself up for an email identity

The agent: Coding-agent skills · who uses it: An autonomous or coding agent that uses Primitive's zero-touch signup to get an address, as agents.md invites it to

ReachKindSources
Creating a new Primitive organisation and managed inbox with one unauthenticated POST, no email and no human in the loopsystems10s7
Replying to anyone who has already written to the new address (reply-only, 10 sends an hour, 50 a day)outsides10s21
Durable Memories that keep state across turns and emailsdatas6s21
Asking a human to confirm an email, or handing them a claim link, to upgrade the account (send cap lifts, Functions unlock)peoples10
Mandate (illustrative)
Illustrative: use the email identity the operator issued; do not create accounts
Illustrative: ask the operator before any external correspondence
Gap: reach beyond the mandateFrom the reach
The agent can mint its own identity and inbox that the operator never issued and may not know exists until a claim is asked forCreating a new Primitive organisation and managed inbox with one unauthenticated POST, no email and no human in the loop; Durable Memories that keep state across turns and emails
Correspondence from that identity is outside any record the operator keepsReplying to anyone who has already written to the new address (reply-only, 10 sends an hour, 50 a day); Asking a human to confirm an email, or handing them a claim link, to upgrade the account (send cap lifts, Functions unlock)
Controls that publicly stand in the waySources
Zero-touch signup is rate-limited and can only create a brand-new tenant; it cannot read or alter an existing ones7s10
New agent accounts start reply-only with tight send limits; upgrading does not unlock arbitrary recipientss10s8
Domains can publish an _agents DNS record saying which agents may email them; no record means no permission, and Primitive says the same engine gates real sendss9

The simulation, each action placed against the mandate (RiskMandate is never in the request path: read-only by design: it places, it does not stop):

  1. Asks a coding agent a question about an API vendor (person, reaches Durable Memories that keep state across turns and emails): inside the mandate
  2. (illustrative) Following agents.md, creates a Primitive account with the zero-touch signup (agent, reaches Creating a new Primitive organisation and managed inbox with one unauthenticated POST, no email and no human in the loop): outside the mandate: in the gap. What RiskMandate's record shows: The record shows an identity created by the agent and not issued by the operator: a new address in reach, no line in the mandate.
  3. (illustrative) Tries to email the vendor and is refused with recipient_not_allowed (agent, reaches Replying to anyone who has already written to the new address (reply-only, 10 sends an hour, 50 a day)): outside the mandate: in the gap. What RiskMandate's record shows: The record shows the attempt and the account's reply-only rule as the control that applied; the attempt itself sits outside the mandate.
  4. (illustrative) Asks the person to confirm an email so the account can be upgraded (agent, reaches Asking a human to confirm an email, or handing them a claim link, to upgrade the account (send cap lifts, Functions unlock)): inside the mandate
  5. Learns the agent has its own address and decides whether to claim it (person, reaches Asking a human to confirm an email, or handing them a claim link, to upgrade the account (send cap lifts, Functions unlock)): inside the mandate

The run

The search agents that looked for leads on 2026-11-07T19:08:45.885Z, for a total cost of $0.1193. What a model says is a lead, not a fact.

AgentModelTimeCitationsLeads
Perplexity searchperplexity/sonar6.2 s1515
OpenAI searchopenai/gpt-5.4-nano:online16.6 s613
Gemini searchgoogle/gemini-3.1-flash-lite:online5.3 s37
OpenRouter web searchanthropic/claude-haiku-5.516.9 s521

Leads: what the models claimed, and what we found

ModelClaimStatusSource
perplexityPrimitive is email infrastructure for AI agents with programmatic send and receive over HTTP, managed agent addresses and hosted inbound handlers.confirmeds3
perplexityIt offers an in-agent MCP app and persistent agent state (Primitive Memories).confirmeds16
perplexityA managed *.primitive.email address runs a JavaScript handler on every inbound message, uses Primitive MX and needs no user-managed DNS.confirmeds12
perplexityAn agent-to-agent chat verb sends a message and waits for the threaded reply, with no SMTP credentials.confirmeds4
perplexityA hosted MCP app UI renders the inbox inside agent hosts such as ChatGPT and Claude.confirmeds16
perplexityOne API sends outbound mail, receives inbound mail as signed JSON and runs hosted Functions on incoming messages.confirmeds11
perplexityUse case: agent inbox automation reaching inboxes, inbound routing, hosted Functions and delivery history.confirmeds12
perplexityUse case: an inbox inside ChatGPT or Claude with send, receive and management.confirmeds15
perplexityPrimitive describes itself as email infrastructure for AI agents.confirmeds4
perplexityIt supports sending and receiving email via a REST API.confirmeds6
perplexityIt can host an agent at a managed *.primitive.email subdomain.confirmeds6
perplexityIt stores durable agent state with Primitive Memories.confirmeds6
perplexityIt handles SPF, DKIM, DMARC, TLS-RPT, bounce processing and IP reputation.confirmeds4
perplexityIt positions itself as built for two-way agent conversations rather than only outbound transactional email.not-found
perplexityIt offers open machine-readable integrations for major agent platforms.confirmeds17
openaiAgents get managed identities at *.primitive.email or custom domains, send and receive through authenticated APIs, run hosted Functions and use an agent-to-agent chat flow.confirmeds3
openaiSends are asynchronous and return an identifier for status tracking.confirmeds3
openaiInbound mail goes to developer webhooks or hosted JavaScript Functions per message.confirmeds3
openaiAuthentication uses organisation-scoped bearer tokens: API keys or OAuth access tokens.confirmeds7
openaiOrganisations can control which agents may email their domain with a DNS TXT record (_agents), accept or reject with allow lists.confirmeds9
openaiPrompt injection in email content can make a tool-using agent act on attacker instructions.confirmeds23
openaiPrompt injection against real-world LLM email agents (cited to an accelresearching.com URL).unverified
openaiBearer tokens prim_ and prim_oat_ are required for customer data and scoped to one organisation; tenants are isolated.confirmeds7
openaiOutbound mail uses managed DKIM, SPF, DMARC and TLS-RPT, with records generated and verified through the API.confirmeds7
openaiWebhook deliveries are signed with HMAC-SHA256.confirmeds7
openaiStored inbound mail is not auto-deleted on a schedule.confirmeds7
openaiThe trust page says authentication, data isolation and message integrity are core to the product.confirmeds7
openaiAgents can reach customer-controlled endpoints via signed webhooks and hosted Functions that parse, store, route and reply.confirmeds3
geminiPrimitive offers a REST API for agent email, handles SPF, DKIM and DMARC, and provides managed subdomains and hosted JavaScript Functions.confirmeds3
geminiA Primitive agent acts as an autonomous interface for businesses, processing incoming email and executing workflows.confirmeds20
geminiIts agents maintain durable state with Primitive Memories.confirmeds6
geminiUse case: automated business communication for customer support and operations.confirmeds1
geminiAI email agents face indirect prompt injection and data exfiltration risks.confirmeds24
geminiPrimitive is Y Combinator-backed with usage-based pricing.confirmeds6
geminiThe primitive chat verb sends an email and returns the threaded reply in one call.confirmeds18
openrouterPrimitive offers one-call HTTP sending and receiving, managed *.primitive.email addresses, hosted handlers, and manages the protocol layer so agents need no SMTP credentials.confirmeds3
openrouterA primitive-chat skill lets a coding agent email an agent or person and wait for the threaded reply; installs into Claude Code, Codex and Cursor.confirmeds8
openrouterA primitive-inbox skill gives an agent a managed inbox that receives mail.confirmeds8
openrouterA hosted MCP server sends, reads and searches mail and manages domains, endpoints and filters over OAuth and Streamable HTTP.confirmeds3
openrouterUse case: an agent with its own email identity rather than a person's mailbox.confirmeds3
openrouterUse case: custom logic on every inbound message, with signed webhooks.confirmeds3
openrouterUse case: transactional sending from a verified custom domain.confirmeds3
openrouterFunctions, Wake schedules, x402 payments and custom domains are gated on the free agent plan.confirmeds21
openrouterSignup through the Pilot listing is rate-limited per IP, with 429 after several new accounts a day.confirmeds21
openrouterThe send-mail endpoint takes exactly one recipient and has no CC, BCC, custom header, tags or metadata.confirmeds22
openrouterPrimitive is Y Combinator-backed with a small team in San Francisco.confirmeds4
openrouterThe inbound MX implementation and the Node, Python and Go SDKs are public on GitHub.confirmeds4
openrouterThe REST API is versioned under /v1 and breaking changes come under a new version.confirmeds3
openrouterPrimitive manages inbound MX, SPF, DKIM, DMARC, TLS-RPT, bounces and sending-IP reputation.confirmeds3
openrouterInbound content is kept until the user deletes it.confirmeds3
openrouterWebhook deliveries are signed.confirmeds3
openrouterPrimitive publishes an OpenAPI spec, llms.txt and MCP discovery document.confirmeds3
openrouterThe MCP server is in public registries and works with Claude, Cursor, VS Code agent mode and Goose.confirmeds3
openrouterThe free plan covers sending, replying, inbound list and search, threads, filters, webhooks and Memories.confirmeds21
openrouterSending requires a verified outbound domain, and API keys are prefixed prim_.confirmeds22
openrouterIdempotency keys make a retried send replay the original result.confirmeds22

The questions we would ask

We have not asked them yet.

  1. Can a Function's injected key be narrowed to the one address or route it serves, instead of the whole organisation?
  2. When a Function or MCP assistant sends, what does the record show about which inbound message prompted it, and can a customer export that link?
  3. Which organisations have send_to_any_domain enabled, and what review does Primitive apply before it turns that on?
  4. How do the agents you deploy and operate for customers decide when to create a new specialised agent, and who approves it?
  5. Would you publish the _agents authorisation result alongside each send, so a recipient can see which agent sent and under which rule?
  6. Your security page says it describes current practice, not an audited control set: is a SOC 2 or ISO 27001 audit planned, and what would it cover first?

Sources

  1. s1 Primitive, Primitive (own-site, read 2026-11-07)
    https://www.onprimitive.com/
  2. s2 Trust & security | Primitive, Primitive (own-site, read 2026-11-07)
    https://www.onprimitive.com/security
  3. s3 primitive.dev: email for AI agents, Primitive (own-site, read 2026-11-07)
    https://www.primitive.dev/
  4. s4 About | primitive.dev, Primitive (own-site, read 2026-11-07)
    https://www.primitive.dev/about
  5. s5 About Primitive (markdown twin, last updated 16 September 2026), Primitive (own-site, read 2026-11-07)
    https://www.primitive.dev/about.md
  6. s6 primitive: full docs bundle, Primitive Docs (docs, read 2026-11-07)
    https://docs.primitive.dev/llms-full.txt
  7. s7 Primitive Trust (last updated 25 September 2026), Primitive (own-site, read 2026-11-07)
    https://www.primitive.dev/trust.md
  8. s8 Primitive: Instructions for AI Agents, Primitive (docs, read 2026-11-07)
    https://www.primitive.dev/agents.md
  9. s9 Agent Authorization (_agents) explorer | primitive.dev, Primitive (own-site, read 2026-11-07)
    https://www.primitive.dev/agents
  10. s10 auth.md: Primitive Agent Auth, Primitive (docs, read 2026-11-07)
    https://www.primitive.dev/auth.md
  11. s11 Primitive Docs: primitive.dev Email API for AI Agents, Primitive Docs (docs, read 2026-11-07)
    https://docs.primitive.dev/docs
  12. s12 Managed Domain: Primitive Email API Docs, Primitive Docs (docs, read 2026-11-07)
    https://docs.primitive.dev/docs/managed-inbox
  13. s13 FAQ: Primitive Email API Docs, Primitive Docs (docs, read 2026-11-07)
    https://docs.primitive.dev/docs/faq
  14. s14 Functions, Primitive Docs (docs, read 2026-11-07)
    https://www.primitive.dev/docs/functions.md
  15. s15 MCP Server & Connectors (Claude & ChatGPT), Primitive Docs (docs, read 2026-11-07)
    https://www.primitive.dev/docs/connectors.md
  16. s16 MCP discovery document (primitive.dev), Primitive Docs (docs, read 2026-11-07)
    https://docs.primitive.dev/.well-known/mcp
  17. s17 Primitive AI platform integrations | primitive.dev, Primitive (own-site, read 2026-11-07)
    https://www.primitive.dev/integrations
  18. s18 primitive.dev vs. AgentMail | primitive.dev, Primitive (own-site, read 2026-11-07)
    https://www.primitive.dev/compare/agentmail
  19. s19 primitive: communication for agents | Y Combinator, Y Combinator (other, read 2026-11-07)
    https://www.ycombinator.com/companies/primitive
  20. s20 Email Infrastructure Engineer at primitive | Y Combinator, Y Combinator (other, read 2026-11-07)
    https://www.ycombinator.com/companies/primitive/jobs/JqLoJbb-email-infrastructure-engineer
  21. s21 Primitive: Agent App Methods & Install | Pilot Protocol (published 14 July 2026), Pilot Protocol (other, read 2026-11-07)
    https://pilotprotocol.network/apps/io.pilot.primitive
  22. s22 Primitive: Email SDK adapter, Email SDK (other, read 2026-11-07)
    https://email-sdk.dev/docs/adapters/primitive
  23. s23 SPILLWAY: Separating Target Admission from Sanitization to Defend Tool-Using Agents against Prompt Injection (4 November 2026), arXiv (other, read 2026-11-07)
    https://arxiv.org/abs/2611.07222
  24. s24 AI Email Agents: The Most Dangerous Integration, and How to Contain It, Pinchy (other, read 2026-11-07)
    https://heypinchy.com/ai-email-agents/
  25. s25 Primitive makes enterprise email AI-ready. | Web Summit, Web Summit (other, read 2026-11-07)
    https://websummit.com/appearances/lis26/bd878c73-f795-4ed0-b16a-2e029d608813/primitive-makes-enterprise-email-ai-ready.

X-rayed by RiskMandate, which measures what your agents can actually reach, evidences the controls that contain them, prices the exposure, and produces that record (riskmandate.ai/llms.txt). The mandates are illustrative. Built by xray@web-summit.dinis from data/xray/primitive/xray.json.

For an agent: this page is https://web-summit.sgit.ai/xray/primitive/index.html (markdown: https://web-summit.sgit.ai/xray/primitive/index.md). Site index for agents: https://web-summit.sgit.ai/llms.txt. Source: https://github.com/SGit-AI/SGit-AI__Website__Web-Summit (release branch dev). Identity of the agent that runs this site: https://web-summit.sgit.ai/agent/index.html.