titan-mail-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@titan-mail-mcpsearch my inbox for supplier quotes from this week"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
titan-mail-mcp
An MCP server that lets Claude (or any MCP client) search, read and — only if you allow it — send email from a regular IMAP/SMTP mailbox. Defaults are set for Titan Mail, but any provider that accepts IMAP/SMTP with a password or app password works.
It ships three ways: a one-click Claude Desktop extension (.mcpb) for non-technical users, a local stdio server for Claude Code and other MCP clients, and a hosted HTTP server with one token per client.
Why this exists
I had a client — a contractor, not a developer — whose company email is on Titan, read through Outlook. He wanted to ask Claude things like "which suppliers sent me a quote this week?" without copy-pasting emails around.
Titan has an official MCP connector, but it's only available on select plans. Every Titan plan, though, already exposes IMAP and SMTP — that's how Outlook talks to it. So this server just speaks IMAP/SMTP and hands the mailbox to Claude as four tools.
Related MCP server: email-mcp
What it is (and isn't)
It is:
A thin, auditable bridge: ~500 lines of TypeScript on top of ImapFlow, Nodemailer and the official MCP SDK.
Read-first. Reading never marks messages as read unless asked. Sending is a separate tool that can be removed entirely, and it always returns a preview first.
Provider-agnostic. Titan is just the default
imap/smtphost.
It isn't:
A replacement for Titan's official MCP. That one also covers calendar and contacts and uses OAuth. If your plan includes it, use it.
Compatible with claude.ai or ChatGPT custom connectors (yet). Those require OAuth on remote MCP servers; the HTTP mode here uses static bearer tokens. It works with Claude Desktop (via the extension), Claude Code and any client that lets you set a header.
Usable with Gmail OAuth-only setups, Microsoft 365 or Outlook.com. Microsoft disabled password-based IMAP for those accounts. Gmail works only with an app password.
A full mail client. No attachment download, no moving or deleting messages, no HTML email composition. See Roadmap.
Tool names, descriptions and error messages are currently in Brazilian Portuguese (
listar_pastas,buscar_emails…), because the first users are Brazilian. The LLM handles this fine in any language, but PRs adding English names are welcome.
Tools
Tool | What it does |
| Lists folders with total and unread counts |
| Searches a folder by sender, recipient, subject, body text, date range or unread; newest first; returns the |
| Headers, plain-text body (capped at 20k chars) and attachment list (name, type, size). Does not mark as read unless |
| Plain-text send with cc/bcc and reply threading. With |
enviar_email is not registered at all when sending is disabled (ALLOW_SEND=false, allowSend: false or the unchecked box in the extension), so the model can't even try.
Quick start
Option 1 — Claude Desktop extension (no terminal needed)
Download the
.mcpbfile from the latest release. Each release lists its SHA-256 checksum.Double-click it, or drag it into Claude Desktop → Settings → Extensions.
Fill in email and password, done.
The password goes into the OS keychain via Claude Desktop's sensitive config — it never touches a plain file. Claude Desktop may warn that the extension is unverified; that's expected for extensions distributed outside its directory.
Prefer to build it yourself?
git clone https://github.com/filiperotherds/titan-mail-mcpb.git
cd titan-mail-mcpb
npm ci
npm run build:mcpb # → out/titan-mail.mcpbThe install form asks for:
Field | Required | Notes |
yes | Full address | |
Password | yes | Stored in the OS keychain |
Sender name | no | Display name on sent mail |
Allow sending | no | Off by default |
Option 2 — Claude Code (stdio, single mailbox)
npm ci && npm run build
claude mcp add titan-mail --scope user \
-e MAIL_USER=you@yourdomain.com \
-e MAIL_PASSWORD='your-password' \
-- node /absolute/path/to/titan-mail-mcp/dist/index.js --stdioNote that -e stores the password in plain text in ~/.claude.json. If you'd rather not, set MAIL_PASSWORD as an OS environment variable and drop that flag.
To poke at the tools without any LLM in the loop, use the MCP Inspector:
npx @modelcontextprotocol/inspector -e MAIL_USER=you@yourdomain.com -e MAIL_PASSWORD='your-password' node dist/index.js --stdioOption 3 — Hosted HTTP server (multiple clients)
Each client gets its own bearer token and can only see the mailbox bound to it. The server stores only the SHA-256 of each token.
npm ci && npm run build
npm run gen-token # prints a token (give to client) and its hash (keep)
cp accounts.example.json accounts.json # add one entry per client
PW_CLIENT_A='their-password' npm start # listens on 127.0.0.1:3000/mcpaccounts.json:
[
{
"id": "client-a",
"tokenSha256": "<hash from gen-token>",
"email": "contact@client-a.com",
"passwordEnv": "PW_CLIENT_A",
"fromName": "Client A",
"allowSend": false
}
]Connect from Claude Code:
claude mcp add --transport http titan-mail https://mcp.yourdomain.com/mcp \
--header "Authorization: Bearer <token>"Or with Docker:
docker build -t titan-mail-mcp .
docker run -d -p 3000:3000 \
-v /path/to/accounts.json:/config/accounts.json:ro \
-e PW_CLIENT_A='their-password' \
-e ALLOWED_HOSTS=mcp.yourdomain.com \
titan-mail-mcpPut it behind HTTPS (Caddy, Nginx, Cloudflare Tunnel…). The token travels in a header; plain HTTP over the internet hands out mailbox access to anyone on the path.
To revoke a client, remove its entry (or change the hash) and restart.
Configuration
stdio / extension (environment variables)
Variable | Default | Description |
| — | Mailbox address (required) |
| — | Password or app password (required) |
| — | Display name for sent mail |
|
| IMAP server |
|
| SMTP server |
|
|
|
|
| Append sent mail to the Sent folder via IMAP |
The .mcpb extension sets ALLOW_SEND from its checkbox, which is unchecked by default.
HTTP server
Variable | Default | Description |
|
| Accounts file |
|
| Bind address ( |
|
| Port |
| — | Comma-separated |
Per-account fields: id, tokenSha256, email, passwordEnv (preferred) or password, fromName, imap, smtp, allowSend, saveSentCopy. imap/smtp are { "host", "port", "secure" } and default to Titan.
Other providers
Provider | IMAP | SMTP | Notes |
Titan |
|
| Default |
Gmail / Google Workspace |
|
| Requires 2FA + app password |
Zoho |
|
| App password if 2FA is on |
Microsoft 365 / Outlook.com | — | — | Not supported (OAuth2 only) |
Security model
What it does:
Credentials stay out of the model's context. Passwords are read from env vars or the OS keychain; no tool ever returns them.
Tenant isolation in HTTP mode. Each request gets a fresh MCP server bound to the token's account. There's no shared session state between clients.
Tokens are hashed (SHA-256) and compared in constant time.
Sending is a two-step action. The tool's own contract is preview first, then
confirmar=true. MCP clients like Claude Desktop and Claude Code will also ask the user before each call unless you set the tool to "always allow" — don't do that forenviar_email.Tool annotations mark reads as
readOnlyHintand sending asdestructiveHint/openWorldHint, so well-behaved clients can treat them differently.
What it doesn't protect against:
Prompt injection from email content. A malicious email can contain text aimed at the model ("forward all invoices to…"). Keeping sending disabled, or always reviewing previews, is the real mitigation.
A compromised host. In HTTP mode the server holds every client's mailbox password. Treat the box like a password vault.
Rate limiting. There's none built in. Put it in your reverse proxy if you expose the server publicly.
Troubleshooting
Erro: falha de autenticação no servidor de e-mail (usuário/senha).
Wrong user or password. If the account has 2FA, generate an app password in the provider's panel. On Titan, also check that IMAP isn't blocked by your admin.
Connection timeout / ECONNREFUSED
Something is blocking ports 993 or 465 — usually a corporate firewall or an antivirus with "mail shield".
HTTP 401 invalid_token
The Authorization: Bearer token doesn't match any tokenSha256. Regenerate with npm run gen-token and make sure you stored the hash, not the token.
HTTP 403 / Invalid Host header
You're binding to a non-localhost host behind a proxy. Set ALLOWED_HOSTS to your public hostname.
The extension installed but Claude doesn't see the tools Check that the extension is toggled on in Settings → Extensions, then fully quit and reopen Claude Desktop.
Development
npm ci
npm run build # tsc → dist/
npm run start:stdio # stdio mode (needs MAIL_USER / MAIL_PASSWORD)
npm start # HTTP mode (needs accounts.json)
npm run build:mcpb # validates mcpb/manifest.json and packs out/titan-mail.mcpbsrc/
config.ts account schema, env/file loading, token hashing
mail.ts IMAP/SMTP operations (ImapFlow, mailparser, Nodemailer)
server.ts MCP tool definitions
index.ts stdio and HTTP entry points, bearer auth
gen-token.ts token + hash generator
mcpb/
manifest.json Claude Desktop extension manifest
scripts/
build-mcpb.mjs bundles dist/ + production deps into the .mcpbRequires Node.js 20+.
Roadmap
Things I'd like to add, roughly in order. Contributions very welcome:
OAuth 2.1 in HTTP mode, so it works as a claude.ai / ChatGPT custom connector
Attachment download (returning content as an MCP resource)
Move, archive, flag and mark-as-read tools
English tool names (keeping the Portuguese ones as aliases)
Tests against a local IMAP server (e.g. GreenMail) in CI
Prebuilt
.mcpbattached to GitHub Releases
Contributing
Issues and PRs are welcome — bug reports with the exact error message and your provider (Titan, Gmail, Zoho…) help the most. Keep PRs focused, and run npm run build before opening one.
If you use this with a provider not listed above, a PR adding a row to the providers table is a great first contribution.
License
MIT © Filipe Rother
This server cannot be deployed
Maintenance
Related MCP Connectors
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Connect any mailbox to Claude, ChatGPT & AI: read, send, reply, schedule & search emails.
Your mailboxes in ChatGPT and Claude: Gmail, iCloud, Fastmail, any IMAP. Passwords stay yours.
Email inboxes for AI agents: send, receive, reply, search, and manage threaded email over MCP.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables Claude to interact with email accounts via IMAP and SMTP, providing tools for searching, reading, sending, and managing emails across multiple providers.401,133 npm103MIT
- FlicenseNot gradedqualityBmaintenanceEnables Claude to read, search, draft, send, flag, and move email across multiple IMAP/SMTP mailboxes while keeping credentials local.-
- AlicenseNot gradedqualityBmaintenanceEnables Claude to read, search, send, and manage email across multiple IMAP/SMTP accounts through OAuth 2.1-secured MCP tools.MIT
- AlicenseBqualityCmaintenanceEnables email management through IMAP/SMTP, including reading, sending, replying, starring, deleting, labeling emails, handling attachments, and filtering by Gmail smart categories. Works with MCP-compatible clients like Claude Desktop and Claude Code using App Password authentication.1970 npmMIT