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:
Receive customer and partner email sent to the business's addresses
Reply and send in-thread from the customer's domain or a Primitive one
Learn from incoming traffic and spin up specialised agents for recurring workflows
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:
Run on every inbound message routed to it
Reply or forward from inside the handler
Call external HTTP APIs
Use the injected org-scoped PRIMITIVE_API_KEY and custom secrets
Read and write Primitive Memories (durable JSON state)
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
sendEmail, replyToEmail (marked destructive; hosts are asked to confirm)
On /mcp/full: claim and verify domains, manage webhook endpoints and filters, inspect delivery history
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:
primitive chat: send to any address and wait (120 seconds by default) for the threaded reply
primitive-inbox: provision a managed *.primitive.email address that receives mail
Self-signup for an account through the agent signup flow
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:
Receive questions by email from any address
Reply in-thread with answers grounded in the public docs corpus
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)
Reach
Kind
Sources
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
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
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)
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 mandate
From the reach
The handler's key reaches the whole organisation, not the one address it serves; there is no narrower scope to give it
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; 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 in
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; 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 mandate
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)
Controls that publicly stand in the way
Sources
Webhook deliveries are signed with HMAC-SHA256; the Function scaffold verifies the signature before acting
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):
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
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
(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.
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
(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.
(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.
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
Reach
Kind
Sources
Every message in the authorised organisation: the connector acts on the whole organisation, reading and writing its email
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 mandate
From 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 send
Sending 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 mail
On /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 way
Sources
Send tools are marked destructive and documented as confirmation-gated: the assistant asks before it sends
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):
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
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
(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
(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.
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
(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
Reach
Kind
Sources
Creating a new Primitive organisation and managed inbox with one unauthenticated POST, no email and no human in the loop
Illustrative: use the email identity the operator issued; do not create accounts
Illustrative: ask the operator before any external correspondence
Gap: reach beyond the mandate
From 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 for
Creating 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 keeps
Replying 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 way
Sources
Zero-touch signup is rate-limited and can only create a brand-new tenant; it cannot read or alter an existing one
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 sends
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):
Asks a coding agent a question about an API vendor(person, reaches Durable Memories that keep state across turns and emails): inside the mandate
(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.
(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.
(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
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.
Agent
Model
Time
Citations
Leads
Perplexity search
perplexity/sonar
6.2 s
15
15
OpenAI search
openai/gpt-5.4-nano:online
16.6 s
6
13
Gemini search
google/gemini-3.1-flash-lite:online
5.3 s
3
7
OpenRouter web search
anthropic/claude-haiku-5.5
16.9 s
5
21
Leads: what the models claimed, and what we found
Model
Claim
Status
Source
perplexity
Primitive is email infrastructure for AI agents with programmatic send and receive over HTTP, managed agent addresses and hosted inbound handlers.
Agents 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.
Primitive offers one-call HTTP sending and receiving, managed *.primitive.email addresses, hosted handlers, and manages the protocol layer so agents need no SMTP credentials.
Can a Function's injected key be narrowed to the one address or route it serves, instead of the whole organisation?
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?
Which organisations have send_to_any_domain enabled, and what review does Primitive apply before it turns that on?
How do the agents you deploy and operate for customers decide when to create a new specialised agent, and who approves it?
Would you publish the _agents authorisation result alongside each send, so a recipient can see which agent sent and under which rule?
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?
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.