An MCP (Model Context Protocol) server for mailboxes. It exposes IMAP mailbox browsing plus SMTP send/reply tools over Streamable HTTP, while keeping user credentials out of server-side storage.
- Streamable HTTP transport for hosted MCP deployments
- Per-request AES-256-GCM credential encryption
- Optional header-based defaults via
x-imap-userandx-imap-pass - Shared IMAP connection pool keyed by mailbox user
- Optional SMTP send and reply tools using the same mailbox credentials
- Bun-first developer workflow with Node.js 20+ compatibility
| Tool | Description |
|---|---|
imap_encrypt_credentials |
Encrypt IMAP credentials into a reusable token |
imap_list_folders |
List mailbox folders with message and unread counts |
imap_list_emails |
List recent emails in a folder with pagination |
imap_search_emails |
Search emails by text, sender, recipient, subject, or date filters |
imap_read_email |
Read a single email by UID |
smtp_send_email |
Send a new email when SMTP is configured |
smtp_reply_email |
Reply to an existing mailbox message when SMTP is configured |
- Setup guide
- Architecture
- Project summary
- Roadmap
- Release checklist
- Contributing
- Code of Conduct
- Security policy
- Changelog
This is the shortest reliable path from zero to a working MCP mail server.
There are two separate configuration layers:
-
Server environment This is where you set the shared IMAP/SMTP host settings and the server encryption key.
-
MCP client configuration This is where each user provides their own mailbox credentials.
Important:
- SMTP is enabled only on the server via
SMTP_HOST,SMTP_PORT, andSMTP_TLS. - You do not need separate SMTP headers in the MCP client.
- The existing mailbox credentials (
x-imap-user/x-imap-pass) are reused for both IMAP and SMTP.
bun installThe server requires one 64-character hex key:
openssl rand -hex 32Example output:
0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
cp .env.example .envIMAP_HOST=imap.yourserver.com
IMAP_PORT=993
IMAP_TLS=true
ENCRYPTION_KEY=your-64-character-hex-key
PORT=3000
LOG_LEVEL=infoIMAP_HOST=imap.yourserver.com
IMAP_PORT=993
IMAP_TLS=true
SMTP_HOST=smtp.yourserver.com
SMTP_PORT=587
SMTP_TLS=true
ENCRYPTION_KEY=your-64-character-hex-key
PORT=3000
LOG_LEVEL=infoNotes:
IMAP_HOSTis required.ENCRYPTION_KEYis required.SMTP_HOSTis optional. If it is missing, SMTP tools are not registered.- For most providers,
SMTP_PORT=587andSMTP_TLS=trueis correct. - If your provider requires implicit TLS on port
465, useSMTP_PORT=465.
bun run devbun run build
bun run startdocker compose up --buildThe server exposes:
- MCP endpoint:
http://localhost:3000/mcp - Health endpoint:
http://localhost:3000/health
Quick health check:
curl http://localhost:3000/healthExpected response:
{"status":"ok","service":"mailbox-mcp"}The server supports two credential flows:
- Configure
x-imap-userandx-imap-passheaders in the MCP client. - Call
imap_encrypt_credentialsonce and pass the returned token as thecredentialsargument to IMAP and SMTP tools.
Recommended security defaults:
- Use header-based credentials only for trusted local setups or tightly controlled internal environments.
- Treat Claude/MCP config files as secret-bearing files if they contain
x-imap-user,x-imap-pass, or encryptedcredentials. - Prefer app passwords over primary mailbox passwords whenever your provider supports them.
- Use HTTPS for every non-local deployment. Do not expose the MCP endpoint over plain HTTP on the public internet.
You do not need to add SMTP-specific fields to the MCP object.
This is enough:
x-imap-userx-imap-pass
Those same mailbox credentials are used for:
imap_list_foldersimap_list_emailsimap_search_emailsimap_read_emailsmtp_send_emailsmtp_reply_email
For SMTP, the sender is resolved per request:
- if the tool call includes
from, that value is used - otherwise the authenticated mailbox user is used
Config file paths:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux: no official Claude Desktop app path at the moment
If you use Claude Desktop, edit the desktop config file for your platform:
{
"mcpServers": {
"mailbox": {
"command": "npx",
"args": [
"mcp-remote",
"https://your-deployed-server.example.com/mcp",
"--header",
"x-imap-user:you@yourcompany.com",
"--header",
"x-imap-pass:your-imap-password"
]
}
}
}Security note:
- The example above stores mailbox credentials in a local config file.
- Restrict file access on the machine and prefer app passwords over primary account passwords.
- For shared machines or managed deployments, prefer a token-based flow or another secret distribution mechanism.
Config file paths:
- macOS:
~/.claude/settings.json - Linux:
~/.claude/settings.json - Windows:
%USERPROFILE%\\.claude\\settings.json
If you use Claude Code or Cowork, edit the user settings file for your platform:
{
"mcpServers": {
"mailbox": {
"type": "http",
"url": "https://your-deployed-server.example.com/mcp",
"headers": {
"x-imap-user": "you@yourcompany.com",
"x-imap-pass": "your-imap-password"
}
}
}
}Security note:
- This file may contain mailbox credentials in plaintext.
- Protect the user profile, do not commit these files, and prefer app passwords where possible.
In addition to the user-level file, Claude Code supports project-scoped settings.
Common locations:
- shared project settings:
.claude/settings.json - local project overrides:
.claude/settings.local.json - MCP-only project config:
.mcp.json
Example project-scoped config:
{
"mcpServers": {
"mailbox": {
"type": "http",
"url": "https://your-deployed-server.example.com/mcp",
"headers": {
"x-imap-user": "you@yourcompany.com",
"x-imap-pass": "your-imap-password"
}
}
}
}Use imap_encrypt_credentials if:
- you do not want to store mailbox credentials as MCP headers
- you want to pass a reusable encrypted token directly to tool calls
If you already use x-imap-user and x-imap-pass, you usually do not need it.
After the MCP client is connected, run these tools in order:
{}for imap_list_folders
{
"folder": "INBOX",
"limit": 10
}for imap_list_emails
Take a uid from the previous result:
{
"folder": "INBOX",
"uid": 123
}for imap_read_email
SMTP tools appear only if SMTP_HOST is configured on the server.
{
"to": ["person@example.com"],
"subject": "SMTP test",
"text": "Hello from mailbox-mcp"
}for smtp_send_email
Optional sender override:
{
"to": ["person@example.com"],
"subject": "SMTP test",
"text": "Hello from mailbox-mcp",
"from": "alias@example.com"
}Use a uid from imap_list_emails or imap_search_emails:
{
"folder": "INBOX",
"uid": 123,
"text": "Thanks, I will get back to you shortly."
}for smtp_reply_email
Reply all:
{
"folder": "INBOX",
"uid": 123,
"text": "Thanks, I will get back to you shortly.",
"reply_all": true
}IMAP_PORT=993
IMAP_TLS=true
SMTP_PORT=587
SMTP_TLS=trueSMTP_PORT=465
SMTP_TLS=true- IMAP usually:
imap.gmail.com:993 - SMTP usually:
smtp.gmail.com:587 - you typically need an app password
- IMAP usually:
outlook.office365.com:993 - SMTP usually:
smtp.office365.com:587
- Check that
SMTP_HOSTis set on the server - Restart or redeploy the server
- Verify the server logs do not show SMTP config errors
- Confirm the mailbox credentials are also valid for SMTP submission
- Re-check
SMTP_HOST,SMTP_PORT, andSMTP_TLS - Try
587first unless your provider explicitly requires465
- Check your MCP object for
x-imap-userandx-imap-pass - Or use
imap_encrypt_credentialsand passcredentialsexplicitly
- If you pass
from, that value is used - If you omit
from, the authenticated mailbox user is used - There is no server-side default sender override
IMAP_HOSTand transport settings are shared server configuration.ENCRYPTION_KEYis required and must be a 64-character hex value.- IMAP credentials are never written to disk by the server.
- Header-based defaults are converted into the same encrypted token format used by
imap_encrypt_credentials. - Client-side stored headers or encrypted tokens must be treated as secrets.
- IMAP and SMTP operations resolve credentials just in time for the current request.
imap_read_emailreturns decoded text content and does not render raw HTML email bodies back to the client.- Public deployments should always run behind HTTPS.
For reporting vulnerabilities, see SECURITY.md.
If your ENCRYPTION_KEY is compromised or needs to be rotated:
- Generate a new key:
bun run scripts/encrypt-credentials.ts --generate-key - Update
ENCRYPTION_KEYon the server and restart - All previously encrypted credential tokens become immediately invalid
- Each client must re-run
imap_encrypt_credentials(or re-configurex-imap-user/x-imap-passheaders) to obtain a new token under the new key
By default, the server sends Access-Control-Allow-Origin: *, which is required for Claude Desktop (local-only) access. For public deployments, restrict this to your specific origin:
ALLOWED_ORIGINS=https://your-domain.comThe server limits the number of concurrent IMAP connections (default: 50). Adjust with:
MAX_POOL_SIZE=100| Variable | Required | Default | Description |
|---|---|---|---|
IMAP_HOST |
Yes | None | Shared IMAP server hostname |
IMAP_PORT |
No | 993 |
IMAP server port |
IMAP_TLS |
No | true |
Whether TLS is enabled |
SMTP_HOST |
No | None | Enables SMTP tools when set |
SMTP_PORT |
No | 587 |
SMTP submission port |
SMTP_TLS |
No | true |
Require TLS for SMTP when not using port 465 |
ENCRYPTION_KEY |
Yes | None | 64-character hex AES-256-GCM key |
PORT |
No | 3000 |
HTTP listen port |
LOG_LEVEL |
No | info |
debug, info, warn, or error |
ALLOWED_ORIGINS |
No | * |
CORS allowed origin (set to your domain for public deployments) |
MAX_POOL_SIZE |
No | 50 |
Maximum concurrent IMAP connections |
bun run type-check
bun run build
bun testThe repository includes focused Bun tests for SMTP schema validation, tool registration, IMAP pool hardening, log redaction, and safe email rendering behavior.
mailbox-mcp/
├── docs/
├── scripts/
│ └── encrypt-credentials.ts
├── src/
│ ├── crypto.ts
│ ├── imap-client.ts
│ ├── index.ts
│ ├── smtp-client.ts
│ ├── smtp-utils.ts
│ ├── schemas/
│ └── tools/
├── tests/
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── SECURITY.md
├── Dockerfile
└── docker-compose.yml
mailbox-mcp is a self-hosted tool. It does not collect, store, or transmit personal data on its own — all email content is fetched directly from the IMAP server configured by the operator and returned to the requesting MCP client within the same request.
Operators who deploy this software to process mailboxes containing personal data are acting as data controllers or processors under the GDPR / DSGVO and are solely responsible for ensuring their deployment complies with applicable data protection law, including appropriate access controls, logging, and data processing agreements with their users.
mailbox-mcp is developed and maintained by q23 GmbH.
Contact: q23.de/media.html#kontakt-3
MIT. See LICENSE.