Integrations · September 20, 2026
MCP or API Key for Agent Email? How to Choose
Remote MCP over OAuth or a project-scoped REST key: what each can and cannot do, who authorises it, how revocation differs, and why teams use both.
You already have an agent that does useful work. Giving it an inbox adds one decision before anything else: how does that agent receive permission to read and send email?
There are two routes, and they reach the same inbox through the same policy engine and the same send pipeline. This is the decision hub — the trade-offs, the capability differences that are genuinely structural, and links down to the full guide for each route. For the ground-level model of how agent inboxes work, read that first; for what to do with the credential once you have picked a route, see scoped credentials for agent email.
Start with where the agent runs, not what it can do
The question that settles it most of the time is not “which is more powerful”. It is “who is doing the connecting”.
If the agent lives inside an application someone else built — a desktop agent client, a hosted assistant — and the person connecting it is the person who owns the mailbox, use remote MCP. That person authorises it in a browser, picks the inboxes, and never sees a credential.
If the agent lives in a service you deploy, use a project-scoped API key. You own the runtime, the retry logic, the storage and the alerting, and a key is the credential shape that fits.
Everything below is refinement on that.
Two routes to the same inbox
| Decision | Remote MCP | REST API |
|---|---|---|
| Who starts setup | The mailbox owner, in an agent client | A developer, in your service |
| Where access is chosen | A browser consent screen naming project, inboxes and preset | Key creation: project, inbox IDs, scopes |
| Credential held by the agent | A connection grant token, expiring in 30 days | efa_test_/efa_live_ key, shown once |
| Who writes request code | Nobody — the client calls the tools | You do |
| How access stops | Revoke the connection grant | Revoke the API key |
| Attachment upload | Not available | Yes, reserve → put → complete |
| Webhook management | Not available | Yes |
| Event cursor replay | Not available | Yes |
The last three rows are the structural differences, and they matter more than the first four when you are choosing.
What MCP deliberately cannot do
The MCP surface exposes six tools: list_inboxes, list_threads, list_messages,
get_message, create_draft and send_message. That is the whole surface, and the
omissions are intentional.
It cannot upload attachment bytes. attachment_ids on a draft or send may only
reference existing, already-scanned attachments from the same inbox. There is no
file-transfer tool.
It cannot manage webhooks, keys, connections, policies or domains. Administrative
scopes — keys:manage, members:manage, billing:manage, policies:write,
inboxes:delete, messages:delete, messages:raw, exports:write — cannot be
granted to a connection at all. A connected agent cannot widen its own access or delete
the record of what it did.
It cannot return an unbounded result. A tool result over 131,072 characters is replaced with an error pointing you at the scoped REST API.
It cannot accept an API key. The /mcp endpoint rejects efa_ keys and browser
session tokens with HTTP 401 and a WWW-Authenticate: Bearer realm="mcp" challenge.
Only a connection grant token works. If you were hoping to skip the OAuth flow by
pasting a key, that path is closed by design rather than by oversight.
What a REST key cannot do for you
A key is a secret. That is its whole disadvantage.
It has to be stored somewhere, rotated by someone, and kept out of logs. It does not expire on its own unless you set an expiry. And it carries no record of a human having looked at a consent screen and agreed to a specific scope — the authorising identity is recorded, but the decision was a form submission, not a deliberate grant review.
It also does not help a user who is not a developer. If the person who needs the agent connected to their mailbox is not going to deploy a service, a key is the wrong shape.
Start with the smallest useful permission, either way
The three presets are identical across both routes, because both resolve to the same scope sets:
| Preset | Adds | Use when |
|---|---|---|
read | inboxes:read, threads:read, messages:read, attachments:read, events:read | Summarising or triaging. Nothing leaves. |
read_draft | drafts:read, drafts:write, drafts:submit | The agent proposes replies; a person approves them. |
read_draft_send | messages:send | The agent transmits directly, subject to inbox policy. |
read_draft is where almost every integration should start, and the constraint is
structural rather than advisory: a principal with drafts:submit and without
messages:send always gets approval_required back, with the reason code
draft_only_principal, even on an inbox configured for direct sending. Over MCP,
create_draft strips messages:send from the calling principal before it runs, so
that tool cannot transmit under any configuration.
Two rules apply to the grant itself on both routes. A credential can never carry a permission its creator lacks. And the effective permission is re-derived from current database state on every request, intersected with the current grant of the human who authorised it — so if that person’s role narrows, every credential they created narrows on the next call, with no revocation step.
Choose the actual inboxes, too. A single-purpose assistant should not reach every mailbox in the workspace, and keeping test and live projects separate means a development run cannot contact a real customer: the environment is baked into the key prefix and into the connection’s project, and neither can cross.
Prove the connection with one conversation
A successful authorisation screen proves a grant was created. A successful inbox call proves the client can use it. A delivered reply proves the mail workflow. These are three different checks and they fail for three different reasons.
Run them in a test project:
- Create the intended inbox and note whether it is test or live.
- Connect the client, or create the scoped key.
- Ask the agent to list inboxes. You should see exactly the ones you granted — no more.
- Create an inbound message you control. In test mode,
POST /v1/projects/{project_id}/test/inboundproduces a realmessage.receivedevent with"simulated": true. - Ask the agent to read it and draft a reply. Check the recipients on the draft against the message record, not against quoted text in the body.
- Approve it yourself, and watch it move to
queuedand thenaccepted. Remember thatacceptedmeans the provider acknowledged the submission, not that anyone received it. - Revoke the credential and confirm the next call returns HTTP 401.
Step 3 is the one people skip and the one that catches over-broad grants. The full sandbox walkthrough has the rest of the pre-live checklist.
Named-client compatibility
No named MCP client is certified, supported or one-click here. Every client is recorded
with client_trust_class: "unverified", and the client name on the consent screen is a
string the client supplied about itself.
That is not modesty — remote MCP support varies by client, by version, and sometimes by the user’s plan, and the parts that break are usually S256 PKCE or protected-resource metadata discovery. A client that implements remote MCP with OAuth and S256 PKCE should work; the seven-step check above is how you find out for the exact client and version you run. When a combination has actually been exercised end to end, it will be published with a version and a date.
Most teams end up with both
The two routes are not competitors. A common shape is a REST service that owns ingestion, webhook handling and retries, plus an MCP grant so a human’s agent client can work the same mailbox interactively. Both hit the same policy engine, so the approval queue and the recipient rules apply to both without being configured twice.
Email for Agents supplies email infrastructure for existing agents; it does not host a separate autonomous agent that decides what to send. Whichever route you take, the permission decision and the handling of send results are yours.
Next: the MCP email server in detail if you are connecting a client, the full REST loop if you are writing the integration, or how to give an AI agent its own email address for the end-to-end setup. The quickstart has both paths side by side.
Keep reading
MCP Email Server: Give Your Agent Client a Real Inbox
How a remote MCP email server works, what the consent screen must show, how to scope a grant to one inbox, and how to verify it before allowing sends.
Scoped Credentials for Agent Email: Read, Draft, Send
Give an agent the smallest useful email permission: project and inbox scoping, one-time secrets, draft-only grants, rotation, and revocation you can verify.
Agent Email API: Send, Receive and Reply in One Loop
Build the full two-way loop over REST: scoped keys, idempotent sends, the states a message moves through, inbound events, and replies that thread correctly.