tutorials
Your inbox is now an MCP server: connect Claude to your email
July 2, 2026

An inbox you can only scroll is a dead end for AI. Expose it as an MCP server and Claude can read it, triage it, and answer it, all on your data, with your rules.
The reason AI assistants are bad at email isn't the models; it's access. Your mail lives behind a vendor's UI, and the assistant can't get to it without screen-scraping or a brittle integration. Tinbox flips this: because your inbox is a database you own, Tinbox can expose it as a proper MCP server, and any MCP-capable assistant can connect to it directly.
This walkthrough wires Claude up to a Tinbox inbox, shows it reading and triaging real mail, and sends a reply, covering both the OAuth path (for the Claude app) and the static-bearer path (for Claude Code and headless use).
A quick, accurate note on what MCP is
MCP is the Model Context Protocol, an open standard for connecting AI assistants to external tools and data sources. An MCP server advertises a set of tools (typed, named functions) and resources; an MCP client (the AI app) discovers those tools and lets the model call them, with the results fed back into the conversation. It's transport-agnostic JSON-RPC; Tinbox serves it over HTTPS from a Worker in your account.
So "your inbox is an MCP server" means: Tinbox publishes tools like search_messages, read_thread, triage, and send_email, and Claude can invoke them. The model never gets raw database access; it calls the tools you exposed, scoped by the token you issued. If you are weighing MCP against just exposing a plain HTTP API to the agent, the reasons MCP beats a REST API for email agents makes the case, and the reasons to connect Claude to your inbox covers what you actually get out of it.
Step 1: Enable the MCP endpoint
If you've already run npx tinbox init, the MCP server is part of your deployment. Confirm the endpoint:
npx tinbox mcp status
MCP server: https://mail.yourdomain.com/mcp
Transport: HTTPS (JSON-RPC)
Auth modes: oauth, bearer
Tools: search_messages, read_thread, list_threads,
triage, draft_reply, send_email, summarize
Status: ready
That /mcp URL is the address you'll give Claude. It's on your domain, in your account, with no Tinbox-hosted hop in the middle.
Step 2a: Connect the Claude app (OAuth)
For the Claude desktop or web app, OAuth is the one-click path. Tinbox implements OAuth 2.1 with PKCE and dynamic client registration, so Claude can register itself and walk you through consent, with no manual client-ID juggling.
In Claude, add a custom connector pointing at your MCP URL:
Settings → Connectors → Add custom connector
Name: My Inbox
URL: https://mail.yourdomain.com/mcp
Claude opens your Tinbox consent screen in the browser. You're already signed in to your own inbox, so you just approve the scopes:
Claude is requesting access to "My Inbox":
✓ Read messages and threads
✓ Search your mailbox
☐ Send email on your behalf [grant]
[ Approve ] [ Deny ]
Approve, and Claude is connected. The tokens are issued by your Tinbox instance and reuse its session. Tinbox never phones home, and we never see your mail.
Step 2b: Connect Claude Code (static bearer)
Headless clients (Claude Code, a CI job, a script) can't do an interactive OAuth dance, so they use a static bearer token. Mint one, scoped to what you want it to do:
# Read-only token (search + summarize, no sending)
npx tinbox token create --scope read --name "claude-code-ro"
Token created (read):
tbx_live_8f3a91c4d27b0e6a5f1c...
Store it securely. It won't be shown again.
Wire it into Claude Code's MCP config (.mcp.json in your project, or your user settings):
{
"mcpServers": {
"inbox": {
"url": "https://mail.yourdomain.com/mcp",
"headers": {
"Authorization": "Bearer tbx_live_8f3a91c4d27b0e6a5f1c..."
}
}
}
}
Now Claude Code can call your inbox tools from the terminal. Want it to be able to send? Mint a full-scope token instead:
npx tinbox token create --scope full --name "claude-code-send"
Scoping at the token level is the safety boundary: a leaked read-only token can't send mail as you.
Step 3: Watch Claude actually work the inbox
With the connector live, you can talk to your mail in natural language. A few real exchanges:
Triage:
You: What needs my attention in the inbox today?
Claude: (calls
list_threads, thentriage) Three things stand out:
- Invoice dispute from billing@acme.co, flagged as a complaint, 2 days unanswered.
- Demo request from a new lead at fin.io, no reply yet.
- An OTP code email that's just noise; safe to ignore.
Summarize a thread:
You: Summarize the thread with billing@acme.co.
Claude: (calls
read_thread,summarize) Acme says they were charged twice on the May invoice. They've attached two receipts with the same amount. They want a refund of the duplicate and confirmation it won't recur.
Draft and send:
You: Draft a reply apologizing, confirming the refund, and asking for nothing further. Send it.
Claude: (calls
draft_reply, shows it, thensend_emailonce you confirm) Sent. Refund-confirmation reply delivered to billing@acme.co.
The model isn't guessing at your mail from a screenshot; it's calling typed tools against your D1 inbox and getting structured results back.
How interpreters make triage smarter
Notice Claude already knew the invoice email was a complaint and the OTP was noise. That's not the model eyeballing it; it's Tinbox's interpreters. Inbound mail runs through classifiers (algorithmic ones for OTPs, receipts, calendar invites; LLM-backed ones for complaints, churn risk, urgency) and the verdicts are stored on the message. So when Claude calls list_threads or triage, the classifications come back as structured signal it can act on, instead of re-deriving them every time. Your inbox does the first pass; the assistant does the judgment.
Failure modes you'll actually hit
401 Unauthorized: invalid or expired token
The bearer token was revoked, mistyped, or you're using an OAuth-only deployment. Re-mint with npx tinbox token create.
403 Forbidden: scope 'send' not granted for this token
You asked Claude to send with a read-only token. That's the guardrail working; mint a --scope full token if you really want send capability.
Claude connected but lists no tools
The connector URL is missing the /mcp path, or DNS for mail.yourdomain.com isn't resolving yet. Check npx tinbox mcp status.
Why this matters
The vendors that hold your mail won't hand an AI assistant the keys to it; your lock-in is their product. When the inbox is a database in your own account, exposing it to your assistant is a config change, not a negotiation. That's the quiet superpower of owning the stack: your tools can finally reach your data.
- introducing-tinbox: the inbox, sender, newsletter, and MCP layer are one stack on your own Cloudflare account
- 10 things to know before you run an email MCP server: the operational and security gotchas before you point an assistant at real mail
Deploy this yourself: npx tinbox init yourdomain.com
Frequently asked questions
What is an MCP email server?
MCP (Model Context Protocol) is an open standard for connecting AI assistants to tools and data. An MCP email server exposes your inbox (reading, searching, triaging, sending) as MCP tools, so an assistant like Claude can operate on your real mail with your permission.
How does Claude authenticate to my inbox?
Two ways. The Claude desktop/web app uses OAuth: you click connect, approve once, and it's wired up. Headless clients (Claude Code, scripts, CI) use a static bearer token you generate and pass in the server config.
Can the AI actually send email, or only read it?
Both, scoped by the token. A read-only token lets the assistant search and summarize; a full token lets it draft and send. You choose the scope when you mint the token, so you can keep send capability behind an explicit grant.


