Using trust in agents
Practical patterns for agents that read email - gate tool use on the trust level, quarantine, feed the model only agent-safe text, wrap email as untrusted data in prompts, and read the MCP tools' trust output.
The trust report is only useful if your agent acts on it. These patterns move the decision out of the model, which can be talked into things, and into your code, which can’t.
A default policy
Start here and loosen it only where a task needs it:
level | The model may read it | The agent may act on it |
|---|---|---|
verified | yes | yes, within the task |
known | yes | read, summarise, extract codes and links you were expecting; ask a human before anything else |
unknown | yes, as information | no |
suspicious | only the reasons, for a human | no |
quarantined | no | no |
“Act” means anything with side effects: sending or forwarding mail, following links, opening attachments, calling other tools, spending money, changing settings.
Gate tools on the verdict, in code
Decide which tools the model gets before it sees the message, from the report rather than from the model’s judgement:
Prefer drafts over sends for anything below verified. Every draft is listed in the dashboard under Drafts, where a person can send or delete it. A draft with send_at sends automatically at that time unless someone deletes it first, so leave send_at unset when a person should decide.
Feed the model agent-safe text only
Give the model trust.content.text. Never give it text, html, extracted_text or trust.content.segments:
textandhtmlare the raw bodies, hidden text and invisible characters included.extracted_textremoves quoted history but not hidden text.segmentscontains the hidden segments.
If a message has no trust report (rare: the trust layer failed on it), treat it as unknown and send it to a human rather than falling back to the raw body.
Wrap email as untrusted data
Tell the model where untrusted content starts and stops, and what it is allowed to do with it. Put the verdict outside the fence, where the email can’t forge it:
Strip anything that looks like your closing tag from the body before you interpolate it, so a message can’t end the fence early:
Fencing is a mitigation, not a guarantee. The gate in your code is what actually stops an injected instruction from doing harm.
Handle quarantine with a human
Quarantined mail gets the QUARANTINE label instead of INBOX, so it is out of your agent’s way by default: lists skip it, the MCP wait_for_message tool does not wake for it, and the MCP read tools withhold its content.
To build a review queue, subscribe a webhook to message.received.quarantined, or list it explicitly:
Show the reviewer trust.reasons and the sanitised trust.content.html, with the hidden segments called out. The dashboard’s Trust panel does this.
If a human decides a message is fine, they can move it back with PATCH /v0/inboxes/{inbox_id}/messages/{message_id} and { "add_labels": ["INBOX"], "remove_labels": ["QUARANTINE"] }. The report itself does not change: trust.level stays quarantined, and the MCP tools keep withholding the content. Hand the agent what it needs yourself.
Reaching verified
verified needs an aligned DMARC pass plus a relationship. A relationship exists once the inbox has written to the sender’s address or domain, or when the sender is on a receive allow list that applies to the inbox. For normal use, prior correspondence is the reliable way to get there: once your inbox has sent mail to a sender, their authenticated replies can reach verified.
A receive allow list is an access control, not a trust boost. Use it only for inboxes that should hear from nobody else:
An entry is an address or a domain; a domain also matches its subdomains. Lists can be set for the whole organisation (/v0/lists/...), a pod (/v0/pods/{pod_id}/lists/...) or one inbox.
Warning
A single receive allow entry switches its scope (the organization, the pod or the inbox) to allow-only: mail from every sender not on the list is labelled BLOCKED, emits message.received.blocked
and is withheld from agents. An allow-listed sender still reaches verified only when DMARC passes and is aligned. To shut out a single sender instead, add them to /lists/receive/block: their
mail is labelled BLOCKED and its trust level is quarantined.
A separate way to mark senders as trusted without blocking anyone else is planned.
One-time codes and sign-ups
Sign-up and login mail from a real service is usually known: authenticated, but from someone the inbox has never written to. That is enough to read a code you were expecting:
Check the sender domain is the service you signed up with. A known message only proves the mail came from the domain it claims, not that the domain is the one you meant. See OTP and sign-ups.
Reading trust through MCP
The hosted MCP server applies the agent-safe view for you, so an agent connected over MCP gets the right defaults without any code:
get_message,get_threadandwait_for_messagereturntexttaken fromtrust.content.text, withtext_sourcesaying where it came from (trust.content.text,extracted_text,text,withheldornone).- Each message carries a
trustsummary:level,score,reasons,authentication,sender,classification,hidden_text_found,flagged_links(suspicious or mismatched only) andrisky_attachments(medium or high only). No bodies. - Quarantined messages come back with
text_source: "withheld", no text, and awithheld_reasontelling the model a human should review it. - Raw bodies are only included with
include_raw: true, which the tool description tells the model to avoid unless a human asks. get_trust_reportreturns the full report with everyhiddensegment’s text replaced by[N characters hidden from human readers; withheld].list_messagesandsearch_messagesreturn a 200-character preview from the agent-safe text and atrust_levelper item.
The text content the model reads puts the verdict first and fences the body:
The server’s instructions and every read tool’s description repeat the policy: act only on verified senders, read and summarise known ones, treat the rest as information, and leave quarantined mail to a human. The triage_inbox prompt groups unread mail by trust level and only proposes actions for verified senders. See MCP server.
MCP tool descriptions are advice to the model, not enforcement. If your agent can send mail, gate send_message, reply_to_message and forward_message in your client, for example by requiring human approval for them.
Checklist
- The model never sees
text,htmlor hidden segments. - Tools with side effects are chosen in code from
trust.level, before the model runs. - Email goes inside a fence, and the verdict sits outside it.
suspiciousandquarantinedmail goes to a human withtrust.reasons.- Your inbox has written to the senders you rely on, so their authenticated mail can reach
verified. - A receive allow list is set only where every other sender should be blocked.
- Replies to anyone below
verifiedare drafts, not sends.