Give Your Claude Agent Its Own Email Address via MCP: A 5-minute, code-free tutorial
Your agent can reason, browse the web, and call APIs — but the moment it hits a signup form it stalls on the one thing it doesn't have: an email address. This tutorial wires a real, private inbox into Claude over the Model Context Protocol (MCP), so your agent can register for a service, wait for the verification email, and pull the code out on its own. Start to finish, about five minutes and zero lines of code.
Why your agent needs its own email address
Almost every account on the web is gated by email: sign-up confirmations, one-time codes, magic links, password resets, receipts. A human clears these in seconds. An autonomous agent with no inbox simply can't get past step two — and bolting the flow onto a human's mailbox is the wrong fix for three reasons.
Isolation. If ten agents share your personal Gmail, their verification codes collide and one compromised agent can read everyone's mail. Identity. An address the agent controls today should still receive that account's password reset next month — you want a stable identity, not a throwaway you've lost the keys to. Blast radius. An address you can spin up and destroy per task, scoped to a single API key, keeps one experiment from touching anything else you own.
DevInbox gives the agent an inbox it can create in milliseconds and read as structured data, on devinbox.io or on your own verified domain. Inboxes come in two flavours: temporary (throwaway, auto-expiring, ideal for a single flow) and persistent (a lasting identity that keeps receiving mail). The rest of this guide connects that capability to Claude over MCP and runs the full sign-up-and-verify loop end to end.
What you'll build in the next five minutes
By the end, Claude — in Claude Code, Claude Desktop, or claude.ai — will drive five DevInbox tools with plain-English prompts: create_inbox to provision an address, wait_for_email to block until the message lands, test_template and create_template to define an extraction pattern, and get_last_email to return the parsed result. No SDK, no glue code, no polling loop.
It's worth being clear about why MCP beats the usual ways of handing an agent a mailbox. Here is how the three common approaches stack up for the specific job of giving an agent an inbox it controls. Full disclosure: we build DevInbox, so read the last column with that in mind — the trade-offs in the other two are real either way.
| Capability | Gmail API + OAuth | Shared human inbox | DevInbox MCP |
|---|---|---|---|
| Time to first inbox | Hours (GCP project, OAuth consent) | Minutes, but not the agent's own | Seconds, one tool call |
| Provisions a brand-new address on demand | No (uses an existing account) | No | Yes |
| Per-agent isolation | Hard | None | Yes — one scoped key per agent |
| One-call blocking wait for new mail | No (Pub/Sub push to set up) | No | Yes — wait_for_email |
| Deterministic no-LLM extraction | No | No | Yes — templates |
| Native to Claude via MCP | No | No | Yes |
| Agent can send / reply from the address | Yes | Yes (manual) | Roadmap (receive, extract, forward today) |
| Automation posture at scale | Elevated ToS / ban risk | Varies | Built for unattended use |
The Gmail API is a genuinely capable, send-capable mailbox, and if your agent must send as well as receive it stays on the table. What it isn't is fast to provision or safe to hand to a fleet: every new identity means an OAuth consent screen, a Google Cloud project, Pub/Sub for push delivery, and automation that Google's terms discourage at scale. DevInbox trades outbound send — for now; see the FAQ — for instant, isolated, disposable inboxes the agent manages itself.
Step 1: Create an account and a scoped API key
Sign up at devinbox.io. The Free tier gives you three persistent inboxes, unlimited temporary inboxes, and 1,000 emails a month — no credit card required, which is plenty to run this tutorial and then some.
Once you're in, open Settings > API Keys and create a key. Grant it only the scopes the agent needs. For the flow below that's inbox:write (create the inbox), inbox:read (wait for and read mail), and config:write (save an extraction template). Leave admin off. You can also confine a key to a single project, so one agent — or one whole fleet — can never see another's inboxes. Copy the key somewhere safe; you'll paste it into the MCP connection next.
One key per agent
Agents run unattended, so give them least-privilege keys. A key scoped to inbox:read + inbox:write and confined to one project means a misbehaving agent can only touch its own inboxes — never your account or another fleet's mail.
Step 2: Connect the DevInbox MCP server to Claude
The DevInbox MCP server is hosted at https://mcp.devinbox.io and speaks streamable HTTP — nothing to install. You authenticate by sending your API key as a bearer token on every request; a request without it is rejected with 401 before any tool runs.
In Claude Code, a single command registers it:
claude mcp add --transport http devinbox https://mcp.devinbox.io \
--header "Authorization: Bearer YOUR_DEVINBOX_API_KEY"
For claude.ai or Claude Desktop, add the server to your MCP configuration instead:
{
"mcpServers": {
"devinbox": {
"type": "http",
"url": "https://mcp.devinbox.io",
"headers": { "Authorization": "Bearer YOUR_DEVINBOX_API_KEY" }
}
}
}
Restart the client and the twelve DevInbox tools appear in the tool list. Prefer to keep mail metadata off the hosted bridge? The same server also runs locally over stdio, reading the key from a DEVINBOX_API_KEY environment variable — the details are in the AI Agents docs. Either way, that's the entire integration. From here you talk to Claude in English and it calls the tools.
Step 3: Let the agent create its own inbox
Ask the agent to provision an address. A prompt this plain is enough:
Claude calls create_inbox and gets back the address, the inbox key (the handle every other tool uses), and an IMAP/SMTP password:
create_inbox() ->
address: agent-3f9c@devinbox.io
key: 3f9c8a2b7d1e4f60
password: 7Kq2m…9Xt # IMAP / SMTP password
type: temporary
The address agent-3f9c@devinbox.io is live immediately and will accept mail from anyone. By default create_inbox makes a temporary inbox; ask for a persistent one when you want the identity to stick around (more on that below). Hold on to the key — 3f9c8a2b7d1e4f60 here — because wait_for_email and get_last_email are addressed by it, not by the email string.
Step 4: Wait for the verification email
Now hand the address to whatever the agent uses to reach the outside world — Claude's own browsing, a computer-use session, a Playwright MCP, or a plain HTTP call to the target's signup endpoint. DevInbox only receives; it does not fill in the form for you. Once the form is submitted, tell the agent to wait:
The agent calls wait_for_email with the inbox key and a timeout. This is a server-side long-poll: the call blocks until a message arrives or the timeout elapses, so there's no polling loop and no tokens burned spinning on an empty inbox.
wait_for_email(inbox_key="3f9c8a2b7d1e4f60", timeout_s=90) ->
from: noreply@example-saas.com
subject: Confirm your email address
received: 2026-07-17T14:02:11Z
body: Welcome to Example SaaS! Your verification code
is 482913. It expires in 10 minutes.
If nothing arrives inside the window, the tool returns cleanly so the agent can decide whether to retry or trigger a resend. In practice most transactional mail lands in a second or two, and the call returns the instant it does — you get the latency of a webhook with the simplicity of a function call.
Step 5: Extract the OTP with a template
The agent now has the raw email, but you rarely want the whole body — you want the code. DevInbox extracts it with a template: a plain string with {{variable}} placeholders that the parser turns into a regular expression and matches against the message. It is deterministic — the same email always yields the same JSON — and it runs with no LLM call and no token cost, which matters when a fleet does this thousands of times a day.
Have the agent dry-run a pattern first with test_template, which validates against sample text and saves nothing:
test_template(
body_pattern="Your verification code is {{code}}",
sample="Your verification code is 482913. It expires in 10 minutes."
) ->
matchSuccess: true
extracted: { "code": "482913" }
Happy with the match, save it once with create_template, then pull the parsed value from the newest message with get_last_email:
create_template(key="saas-otp",
body_pattern="Your verification code is {{code}}") -> saved
get_last_email(inbox_key="3f9c8a2b7d1e4f60", template="saas-otp") ->
{ "code": "482913" }
That { "code": "482913" } is structured data the agent can drop straight into the verification field. The same pattern handles magic-link URLs, order numbers, or anything else with a stable surrounding phrase — define {{reset_link}} or {{order_id}} and the parser does the rest. And because templates are keyed and reusable, the next time the agent meets this sender it skips the definition step and goes straight to get_last_email.
The canonical agent loop
create inbox → browser fills the signup form → wait_for_email → define & dry-run a template → get_last_email parsed → agent completes signup. Steps three onward are the interesting part: when the agent meets a sender it has never seen, it writes its own extraction template at runtime and verifies it before saving.
Persistent vs. temporary: a lasting agent identity
The inbox above is temporary — perfect for a one-shot signup, and it ages out on its own so there's nothing to clean up. When the agent registers an account it will need to log back into, create a persistent inbox instead, so the address and its history survive. That's what lets the account your agent opened today still receive its password reset next month.
Persistent inboxes count against your plan's inbox quota — three on Free, fifteen on Developer at $15/mo, more on higher tiers — while temporary inboxes are unlimited on every tier. So the rule of thumb is simple: temporary for throwaway flows, persistent when the identity has to last. Every inbox is also a real mailbox with full IMAP and SMTP access, so anything in your existing email tooling can read it too, not just the MCP tools and REST API.
One more thing worth knowing: every MCP tool is a thin wrapper over the public REST API at https://api.devinbox.io. Anything the agent does conversationally, your own code can do directly with an X-Api-Key header — the same POST /mailboxes and long-poll wait primitives — so you can prototype the loop in Claude and then lift the identical calls into a scheduled job or CI pipeline without switching providers.
Frequently asked questions
Do I need to write any code to give my Claude agent an email address?
No. Once the MCP server is connected, you drive everything with natural-language prompts and Claude calls the tools. Writing code is optional: because each tool wraps the DevInbox REST API, you can drop the same calls into a script later if you want to run the loop unattended.
Is the inbox a real address that other services will accept?
Yes. It's a genuine, deliverable mailbox on devinbox.io — or on your own verified custom domain on any paid tier — with real IMAP and SMTP access alongside the API. Third-party signup and verification emails arrive exactly as they would in any other inbox.
Can my Claude agent reply to or send email from this address?
Not today. DevInbox is built to receive, extract, and forward — outbound send and reply from an inbox is on the roadmap, not shipped. If your flow needs the agent to send mail as well, pair DevInbox for inbound with a transactional sender for outbound.
How is wait_for_email different from just polling the inbox?
wait_for_email is a single server-side long-poll: it holds the connection open and returns the moment a matching message arrives, or when the timeout you set elapses. There's no retry loop for the agent to manage and no tokens spent re-checking an empty inbox — one call, one result.
Do extraction templates use an LLM?
No. A template is a {{variable}} pattern compiled to a regular expression, so extraction is deterministic — the same email always produces the same JSON — with no model call and no token cost. That's what makes it safe to run at high volume and reliable enough to feed straight into a form field.
How do I keep a fleet of agents isolated from each other?
Issue one scoped API key per agent and confine it to a single project. Grant only the scopes it needs — typically inbox:read, inbox:write, and config:write — and skip admin. Each key becomes the agent's bearer token in its MCP connection, so no agent can see another's inboxes.
Give your agent an inbox it controls
Free tier: 3 persistent inboxes, unlimited temporary inboxes, 1,000 emails a month. No credit card. Connect the MCP server and your Claude agent is signing itself up in minutes.