mail-mcp
A self-hosted MCP server that gives AI agents full email superpowers.
README
<div align="center">
<img src="https://mailts.anishhs.com/logo-icon.png" alt="mail-mcp" width="38" />
mail-mcp
A self-hosted MCP server that gives AI agents full email superpowers.
Read, search, send, reply, manage mailboxes and accounts — over any SMTP/IMAP provider.
</div>
✨ Features
| Feature | Description |
|---|---|
| 📨 20 MCP tools | Read, search, send, reply, forward, draft, flag, move, delete, bulk send, templates, queue |
| 🔐 Secure multi-account | Credentials encrypted at rest (AES-256-GCM); passwords never pass through the agent |
| ⚡ Efficient reads | BODYSTRUCTURE-driven selective fetch — text only, no attachment bytes wasted |
| 🗄️ Postgres-backed | Accounts managed at runtime via the agent; persists across restarts |
| 🌐 Provider-agnostic | Gmail, Fastmail, Outlook, or any IMAP/SMTP server |
| 🐳 Docker-ready | Single container; deploy to Cloud Run, Fly.io, Railway, or anywhere |
🚀 Quick Start
Single account (no database needed)
# .env
API_KEYS=your-secret-key
IMAP_HOST=imap.gmail.com
IMAP_PORT=993
IMAP_USER=you@gmail.com
IMAP_PASS=your-app-password
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=you@gmail.com
SMTP_PASS=your-app-password
npm install && npm run dev
# → Listening on http://localhost:3000/mcp
Multi-account with Postgres
# .env
API_KEYS=your-secret-key
DATABASE_URL=postgresql://user:pass@host/dbname?sslmode=require
MAIL_MCP_SECRET=any-random-string-32-chars
SERVER_URL=https://your-server.example.com
# Optional default account (always loaded from env)
IMAP_HOST=imap.gmail.com
IMAP_USER=you@gmail.com
IMAP_PASS=your-app-password
SMTP_HOST=smtp.gmail.com
SMTP_USER=you@gmail.com
SMTP_PASS=your-app-password
The mail_mcp_accounts table is created automatically on first run. Add more accounts via the agent at any time.
🔧 Configuration
| Variable | Required | Default | Description |
|---|---|---|---|
API_KEYS |
✅ | — | Comma-separated Bearer tokens for MCP auth |
DATABASE_URL |
Multi-account | — | Standard Postgres connection string |
MAIL_MCP_SECRET |
With DB | — | Encryption key for credentials at rest |
SERVER_URL |
Recommended | — | Public URL — shown in agent password setup guides |
PORT |
No | 3000 |
HTTP listen port |
IMAP_HOST / SMTP_HOST |
No | — | Single default account from env |
Copy
.env.exampleto.envand fill in your values.
Config loading order
IMAP_HOST / SMTP_HOST → always loaded as the "default" account
DATABASE_URL → additionally loads more accounts from Postgres
Neither set → startup error
📧 MCP Tools
<details> <summary><strong>Read & Search</strong></summary>
| Tool | Description |
|---|---|
list_emails |
List emails with optional filters (unread, limit) |
get_email |
Fetch full email — text/html via BODYSTRUCTURE, attachment metadata from structure tree |
search_emails |
Search by from, to, subject, body, date range, flags |
get_thread |
Fetch full conversation thread by Message-ID |
get_attachments |
List attachment metadata or download with base64 content |
watch_inbox |
Watch for new emails via IMAP IDLE |
</details>
<details> <summary><strong>Send & Compose</strong></summary>
| Tool | Description |
|---|---|
send_email |
Send immediately via SMTP or HTTP transport |
reply_email |
Reply to a message — auto-fills In-Reply-To / References |
reply_all_email |
Reply-all, excluding self from recipients |
forward_email |
Forward with original body quoted |
save_draft |
Save to Drafts folder |
send_calendar_invite |
Send iCal VEVENT with RSVP |
</details>
<details> <summary><strong>Bulk & Templates</strong></summary>
| Tool | Description |
|---|---|
bulk_send |
Send personalised emails to a list with per-row variable substitution |
bulk_send_calendar_invite |
Send individual calendar invites to a list |
define_template |
Define a reusable email template with variables |
list_templates |
List defined templates |
preview_template |
Preview a template with sample data |
send_template |
Send using a defined template |
</details>
<details> <summary><strong>Queue</strong></summary>
| Tool | Description |
|---|---|
queue_email |
Enqueue for async delivery with retries and priority |
queue_stats |
View queue depth and processing stats |
queue_pause / queue_resume |
Pause or resume the queue |
queue_drain |
Wait for queue to empty |
queue_cancel |
Cancel a queued message |
list_dead_letters |
List permanently failed messages |
retry_dead_letter |
Retry a dead-lettered message |
</details>
<details> <summary><strong>Flags & Organisation</strong></summary>
| Tool | Description |
|---|---|
mark_emails |
Set/clear seen, flagged, answered |
move_emails |
Move to another mailbox (IMAP MOVE or COPY+DELETE) |
copy_emails |
Copy to another mailbox |
delete_emails |
Permanently delete (mark + EXPUNGE) |
sync_incremental |
Fetch messages changed since a CONDSTORE mod-sequence |
</details>
<details> <summary><strong>Mailboxes</strong></summary>
| Tool | Description |
|---|---|
list_mailboxes |
List all IMAP folders |
get_mailbox_status |
Message counts and sync metadata |
create_mailbox |
Create a new folder |
rename_mailbox |
Rename a folder |
delete_mailbox |
Delete a folder |
</details>
<details> <summary><strong>Accounts</strong></summary>
| Tool | Description |
|---|---|
list_accounts |
List accounts with default status and capabilities |
add_account |
Add account to DB — returns curl command for password setup |
update_account |
Update host, port, user, label |
remove_account |
Remove account from DB |
set_default_account |
Switch the default account |
reload_config |
Reload accounts without restarting |
health_check |
Live IMAP/SMTP connectivity probe |
</details>
🔑 Secure Password Flow
Passwords never pass through the agent. The agent guides you to set them directly:
You: "Add my work Gmail, imap.gmail.com, work@company.com"
Agent: Account "work" saved. Set your credentials:
curl -X POST https://your-server/accounts/work/password \
-H "Authorization: Bearer <your MAIL_MCP_SECRET value>" \
-H "Content-Type: application/json" \
-d '{"imap_pass":"your-app-password","smtp_pass":"your-app-password"}'
Credentials are encrypted at rest. Account activates immediately.
🌐 HTTP Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/health |
None | Server health check |
GET |
/accounts |
API_KEYS |
List accounts (no passwords) |
PATCH |
/accounts/:name |
API_KEYS |
Update non-sensitive fields |
DELETE |
/accounts/:name |
API_KEYS |
Remove an account |
POST |
/accounts/:name/password |
MAIL_MCP_SECRET |
Set encrypted credentials |
The password endpoint deliberately uses
MAIL_MCP_SECRET— notAPI_KEYS— so the agent (which knowsAPI_KEYS) is cryptographically prevented from setting credentials.
🚢 Deployment
Docker
docker build -t mail-mcp .
docker run -p 3000:3000 --env-file .env mail-mcp
Cloud Run (GCP)
gcloud run deploy mail-mcp \
--image gcr.io/YOUR_PROJECT/mail-mcp \
--region us-central1 \
--allow-unauthenticated \
--update-secrets="DATABASE_URL=DATABASE_URL:latest,API_KEYS=API_KEYS:latest,MAIL_MCP_SECRET=MAIL_MCP_SECRET:latest" \
--set-env-vars="SERVER_URL=https://your-service-url"
See deploy/ for Fly.io, Azure Container Apps, and AWS App Runner guides.
CI/CD
Two workflows:
ci.yml — runs automatically on every push to main and every PR:
- Typecheck → Build → Test → Security audit (parallel)
deploy.yml — triggered manually from GitHub Actions → Run workflow:
- Leave version empty → reads version from
package.json, creates git tag, deploys - Enter version (e.g.
v0.1.0) → rollback to that existing tag's original commit - Source code on
mainis never modified by deploys or rollbacks
Two separate approval gates:
| Gate | Environment | Action |
|---|---|---|
| 1 | tag |
Create / validate the release tag |
| 2 | production |
Build image and deploy to Cloud Run |
Required GitHub secrets:
GCP_PROJECT_ID · GCP_REGION · GCP_WORKLOAD_IDENTITY_PROVIDER · GCP_SERVICE_ACCOUNT · SERVER_URL
GCP Secret Manager secrets: DATABASE_URL, API_KEYS, MAIL_MCP_SECRET
Set up both environments in GitHub → Settings → Environments with required reviewers.
🛠️ Development
git clone https://github.com/anishhs-gh/mail-mcp
cd mail-mcp
npm install
cp .env.example .env # fill in your credentials
npm run dev # hot reload on http://localhost:3000
npm test # 22 unit tests
npm run build # production build
⚡ Powered by @mailts/core
mail-mcp is built on top of <img src="https://mailts.anishhs.com/logo-icon.png" alt="mailts" width="12" /> @mailts/core — a modern, native TypeScript SMTP/IMAP library with zero legacy dependencies, built from the ground up for Node 18+.
What mailts brings to this MCP:
- BODYSTRUCTURE parsing — selective MIME section fetch means only text parts are downloaded when reading email; attachment bytes are never transferred unless explicitly requested
ImapSession.search()— full IMAP SEARCH through the session lock, no raw client exposuretextOnlyfetch mode — BODYSTRUCTURE-driven, fetches text/plain and text/html only in a single round-trip- Native TLS, DKIM, OAuth2, IDLE — zero legacy dependencies, built for Node 18+
- SMTP queue with priority scheduling — built-in retry logic, dead-letter handling, and external queue driver support
mailts is also open source — check it out at github.com/anishhs-gh/mailts
🤝 Contributing
Contributions are welcome! Please read CONTRIBUTING.md and CODE_OF_CONDUCT.md first.
📄 License
MIT © 2026 Anish Shekh
<div align="center">
Built by Anish Shekh
</div>
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。