AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Mcp Server Email

mcp-boutquin-mcp-server-email · by boutquin

Multi-account IMAP/SMTP email server for the Model Context Protocol (MCP). 22 tools — read, send, search, organize, thread, batch. Connection pooling, rate limiting, retry, OAuth2.

No reviews yet
0 installs
41 views
0.0% view→install

Install

$ agentstack add mcp-boutquin-mcp-server-email

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-boutquin-mcp-server-email)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
6mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Mcp Server Email? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

mcp-server-email

[](https://github.com/boutquin/mcp-server-email/actions/workflows/ci.yml) [](https://codecov.io/gh/boutquin/mcp-server-email) [](https://go.dev) [](LICENSE) [](https://modelcontextprotocol.io)

Multi-account email server for the Model Context Protocol. Gives LLMs full email access — read, send, search, organize — over IMAP/SMTP with connection pooling, rate limiting, and retry. Designed as the remote-email counterpart to apple-bridge (local Mail.app access).

Quick Start

  1. Install

``bash go install github.com/boutquin/mcp-server-email/cmd/mcp-server-email@latest ``

  1. Create a config file (~/.config/mcp-email/accounts.json)

For well-known providers (Gmail, Outlook, Yahoo, iCloud, Fastmail, Zoho), host and port are auto-detected from the email domain — just provide credentials:

``json [ { "id": "hello", "email": "hello@gmail.com", "username": "hello@gmail.com", "password": "app-password-here" } ] ``

For custom mail servers, specify host and port explicitly:

``json [ { "id": "work", "email": "hello@example.com", "imap_host": "mail.example.com", "imap_port": 993, "smtp_host": "mail.example.com", "smtp_port": 465, "username": "hello@example.com", "password": "app-password-here" } ] ``

``bash chmod 600 ~/.config/mcp-email/accounts.json ``

  1. Add to Claude Code (~/.claude.json)

``json { "mcpServers": { "email": { "command": "mcp-server-email", "env": { "EMAIL_CONFIG_FILE": "~/.config/mcp-email/accounts.json" } } } } ``

  1. Restart Claude Code — the email_* tools are now available.

Installation

Go Install (recommended for Go developers)

go install github.com/boutquin/mcp-server-email/cmd/mcp-server-email@latest

Homebrew (macOS/Linux)

brew install boutquin/tap/mcp-server-email

Binary Download

Download pre-built binaries for your platform from GitHub Releases.

Available for: Linux (amd64, arm64), macOS (amd64, arm64), Windows (amd64, arm64).

Docker

docker run --rm \
  -e EMAIL_ACCOUNTS='[{"id":"main","email":"user@example.com","imap_host":"mail.example.com","imap_port":993,"smtp_host":"mail.example.com","smtp_port":465,"username":"user@example.com","password":"app-password"}]' \
  ghcr.io/boutquin/mcp-server-email:latest

MCP Bundle (Claude Desktop)

Download the .mcpb file from Releases and open in Claude Desktop.

Build from source

git clone https://github.com/boutquin/mcp-server-email.git
cd mcp-server-email
go build -o mcp-server-email ./cmd/mcp-server-email

Configuration

Accounts are loaded once at startup. Changes require a server restart.

Config file vs environment variable

| Approach | Best for | |----------|----------| | EMAIL_CONFIG_FILE — path to a JSON file | Production use. File can be permission-locked (chmod 600) | | EMAIL_ACCOUNTS — inline JSON in env var | Testing, CI, or containerized deployments |

If both are set, EMAIL_ACCOUNTS takes precedence.

Account JSON schema

[
  {
    "id": "hello",
    "email": "hello@example.com",
    "imap_host": "mail.example.com",
    "imap_port": 993,
    "smtp_host": "mail.example.com",
    "smtp_port": 465,
    "username": "hello@example.com",
    "password": "app-password-here"
  }
]

| Field | Required | Description | |-------|----------|-------------| | id | Yes | Unique account identifier | | email | Yes | Email address | | imap_host | No | IMAP server hostname | | imap_port | No | IMAP port (993 = implicit TLS, 143 = STARTTLS) | | smtp_host | No | SMTP server hostname | | smtp_port | No | SMTP port (465 = implicit TLS, 587 = STARTTLS) | | username | Yes | Login username | | password | Yes** | App password or account password | | use_starttls | No | Override TLS auto-detection (true/false) | | insecure_skip_verify | No | Skip TLS certificate verification (dev/testing) | | auth_method | No | "password" (default) or "oauth2" | | oauth_client_id | No | OAuth2 client ID (required when auth_method is "oauth2") | | oauth_client_secret | No | OAuth2 client secret | | oauth_token_file | No | Override token file path |

Host and port are auto-detected for well-known providers (see below). Required for custom servers. *Not required when using OAuth2 authentication.

Provider auto-detection

When imap_host/smtp_host are omitted, the server detects settings from the email domain:

| Provider | Domains | IMAP | SMTP | |----------|---------|------|------| | Gmail | gmail.com, googlemail.com | imap.gmail.com:993 | smtp.gmail.com:587 | | Outlook | outlook.com, hotmail.com, live.com | outlook.office365.com:993 | smtp.office365.com:587 | | Yahoo | yahoo.com | imap.mail.yahoo.com:993 | smtp.mail.yahoo.com:587 | | iCloud | icloud.com, me.com, mac.com | imap.mail.me.com:993 | smtp.mail.me.com:587 | | Fastmail | fastmail.com, fastmail.fm | imap.fastmail.com:993 | smtp.fastmail.com:587 | | Zoho | zoho.com, zohomail.com | imap.zoho.com:993 | smtp.zoho.com:587 |

Explicit host/port in the config always takes precedence over auto-detection.

TLS modes

TLS mode is auto-detected from port:

| Port | Protocol | Mode | |------|----------|------| | 993 | IMAP | Implicit TLS | | 143 | IMAP | STARTTLS | | 465 | SMTP | Implicit TLS | | 587 | SMTP | STARTTLS |

Override with "use_starttls": true or "use_starttls": false in the account object. Omit for auto-detection (recommended).

OAuth2 authentication

For providers that support it (Gmail, Outlook), you can use OAuth2 instead of app passwords. This uses the device code flow (RFC 8628) — no browser redirect needed.

  1. Create OAuth2 credentials in the provider's developer console (Google Cloud Console or Azure AD)
  1. Configure the account with auth_method: "oauth2":

``json [ { "id": "gmail", "email": "user@gmail.com", "username": "user@gmail.com", "auth_method": "oauth2", "oauth_client_id": "your-client-id.apps.googleusercontent.com", "oauth_client_secret": "your-client-secret" } ] ``

  1. On first connection, the server initiates the device code flow — printing a verification URL and code to stderr. Visit the URL and enter the code to authorize.
  1. Tokens are persisted in ~/.config/mcp-email/tokens/ and automatically refreshed. Subsequent connections reuse the stored token without re-authorization.

Supported OAuth2 providers: Gmail (gmail.com, googlemail.com) and Outlook (outlook.com, hotmail.com, live.com).

Environment variables

| Variable | Required | Default | Description | |----------|----------|---------|-------------| | EMAIL_CONFIG_FILE | Yes | — | Path to JSON config file | | EMAIL_ACCOUNTS | Yes | — | JSON array of account configs (inline) | | EMAIL_DEFAULT_ACCOUNT | No | First account | Default account ID | | EMAIL_IMAP_TIMEOUT_MS | No | 30000 | IMAP operation timeout (ms) | | EMAIL_SMTP_TIMEOUT_MS | No | 30000 | SMTP operation timeout (ms) | | EMAIL_IMAP_RATE_LIMIT | No | 60 | IMAP requests/minute/account | | EMAIL_SMTP_RATE_LIMIT | No | 100 | SMTP sends/hour/account | | MAX_ATTACHMENT_SIZE_MB | No | 18 | Max size per attachment (MB) | | MAX_TOTAL_ATTACHMENT_SIZE_MB | No | 18 | Max total attachment size per message (MB) | | MAX_DOWNLOAD_SIZE_MB | No | 25 | Max attachment download size (MB) | | EMAIL_POOL_CLOSE_TIMEOUT_MS | No | 5000 | Pool close timeout (ms) | | EMAIL_DEBUG | No | false | Debug logging to stderr | | LOG_LEVEL | No | info | Log level: debug, info, warn, error | | LOG_FORMAT | No | json | Log format: json or text |

*One of EMAIL_CONFIG_FILE or EMAIL_ACCOUNTS is required.

Config file permissions

The config file contains account passwords. Always restrict access:

chmod 600 ~/.config/mcp-email/accounts.json

Tools (22)

Account & folder tools

| Tool | Description | Key params | |------|-------------|------------| | email_accounts | List configured accounts with connection status | — | | email_folders | List all folders with unread/total counts | account? | | email_folder_create | Create new folder | name, account? |

Message listing

| Tool | Description | Key params | |------|-------------|------------| | email_list | List messages in folder | folder?, limit?, offset?, includeBody?, account? | | email_unread | List unread messages | folder?, limit?, includeBody?, account? | | email_search | Search subject and body | query, from?, to?, since?, before?, folder?, limit?, includeBody?, account? |

Message operations

| Tool | Description | Key params | |------|-------------|------------| | email_get | Get full message by ID | id | | email_read_body | Read email body with pagination | id, offset?, limit?, format? | | email_move | Move message to folder | id, destination | | email_copy | Copy message to folder | id, destination | | email_delete | Delete message (trash or permanent expunge) | id, permanent? | | email_mark_read | Mark as read/unread | id, read | | email_flag | Flag/unflag message | id, flagged | | email_reply | Reply to a message (sets In-Reply-To, References, quotes body) | id, body, all?, cc?, bcc?, isHtml?, account? | | email_forward | Forward a message (re-attaches original attachments) | id, to, body?, cc?, bcc?, isHtml?, account? | | email_batch | Batch operations on multiple messages | action, ids, destination?, permanent?, read?, flagged? |

Attachments & threads

| Tool | Description | Key params | |------|-------------|------------| | email_attachment_list | List attachments on a message | id | | email_attachment_get | Download attachment by index | id, index, saveTo? | | email_thread | Get conversation thread (searches across INBOX, Sent, Archive, and All Mail) | id |

Send & drafts

| Tool | Description | Key params | |------|-------------|------------| | email_send | Send via SMTP with optional attachments | to, subject, body, cc?, bcc?, replyTo?, isHtml?, attachments?, account? | | email_draft_create | Save draft with optional attachments | to?, subject?, body?, cc?, bcc?, isHtml?, attachments?, account? | | email_draft_send | Send existing draft | id |

All optional account params default to the configured default account.

Search

email_search searches both subject and body using IMAP SEARCH OR (SUBJECT "q") (BODY "q").

Optional filters narrow the candidate set server-side before body scanning:

| Filter | Format | Example | |--------|--------|---------| | from | Email address or name | "alice@example.com" | | to | Email address or name | "bob@example.com" | | since | YYYY-MM-DD | "2026-01-01" | | before | YYYY-MM-DD | "2026-02-01" |

The existing operation timeout (default 30s) prevents hung body searches on large mailboxes.

Attachments

email_send and email_draft_create accept an attachments parameter — an array of file references on the server host:

{
  "attachments": [
    {"path": "/tmp/report.pdf"},
    {"path": "/tmp/data.csv", "filename": "Q1-data.csv", "content_type": "text/csv"}
  ]
}

| Parameter | Required | Description | |-----------|----------|-------------| | path | Yes | Absolute file path on the server host | | filename | No | Override display filename (defaults to basename of path) | | content_type | No | MIME type (auto-detected from file extension if omitted) |

Limits (defaults): 18 MB per file, 18 MB total (pre-base64 encoding; stays under 25 MB SMTP cap after encoding). Configurable via MAX_ATTACHMENT_SIZE_MB and MAX_TOTAL_ATTACHMENT_SIZE_MB environment variables.

Download limit: Attachment downloads (email_attachment_get) are capped at 25 MB by default, configurable via MAX_DOWNLOAD_SIZE_MB.

Validation failures (missing file, non-absolute path, size exceeded) return INVALID_ARGUMENT.

Message IDs

Message IDs are composite strings encoding account, mailbox, and UID:

{account}:{mailbox}:{uid}

Example: hello:INBOX:12345

All CRUD tools (email_get, email_move, email_copy, email_delete, email_mark_read, email_flag, email_draft_send) extract the account and folder from the ID — no separate params needed.

Error Codes

All errors are returned as MCP tool errors with a structured code prefix:

| Code | Meaning | |------|---------| | AUTH_FAILED | IMAP/SMTP authentication failed | | CONNECTION_FAILED | Cannot connect to server | | ACCOUNT_NOT_FOUND | Unknown account ID | | FOLDER_NOT_FOUND | Mailbox doesn't exist | | MESSAGE_NOT_FOUND | UID not found in mailbox | | INVALID_ARGUMENT | Missing/invalid parameter (including attachment validation) | | TIMEOUT | Operation timed out | | INTERNAL | Unexpected server error |

Resources

| URI | Description | |-----|-------------| | email://status | Server version, account connection state, rate limit configuration |

Comparison with apple-bridge

This server and apple-bridge share an Email model and parameter semantics (limit, includeBody, folder, query) so LLMs can work with both interchangeably. Key differences:

| Aspect | mcp-server-email | apple-bridge | |--------|------------------|--------------| | Transport | IMAP/SMTP (remote) | Mail.app (local) | | Tool prefix | email_* | mail_* | | Message ID | {account}:{mailbox}:{uid} | RFC 5322 Message-ID | | Folder create | Supported | Not supported (Mail.app requires UI) | | Copy message | Supported | Not supported | | Draft send | Supported | Not supported (Mail.app uses compose UI) | | Attachments (send) | File path on server host | Not yet supported |

Development

Prerequisites

Build

go build ./...

Unit tests

make test
# or: go test -race -count=1 ./...

Unit tests use mock implementations of the imap.Operations and smtp.Operations interfaces — no live mail server needed.

Benchmarks

go test -bench=. -benchmem ./...

| Benchmark | Package | What it measures | |-----------|---------|------------------| | BenchmarkPoolGetRelease | imap | Connection pool acquire/release cycle | | BenchmarkExtractAttachments | imap | MIME attachment extraction | | BenchmarkHtmlToText | tools | HTML-to-plain-text conversion | | BenchmarkLimiterAllow | retry | Rate limiter (sequential) | | BenchmarkLimiterAllow_Parallel | retry | Rate limiter (concurrent) |

Fuzz testing

Fuzz targets ship with seed corpora in testdata/fuzz/ directories. Run a specific target:

go test -fuzz=FuzzParseMessageID ./internal/models/ -fuzztime=30s

| Target | Package | What it fuzzes | |--------|---------|----------------| | FuzzBuildSearchCriteria | imap | IMAP search query builder | | FuzzExtractAttachmentByIndex | imap | Attachment index boundary handling | | FuzzExtractContentType | imap | MIME content-type parser | | FuzzParseMessageID | models | Composite message ID codec | | FuzzHtmlToText | tools | HTML-to-text sanitizer | | FuzzSplitAddresses | tools | Email address list splitter |

Lint

make lint
# or: gol

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [boutquin](https://github.com/boutquin)
- **Source:** [boutquin/mcp-server-email](https://github.com/boutquin/mcp-server-email)
- **License:** MIT
- **Homepage:** https://modelcontextprotocol.io

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.