Email MCP Server
Integrates with Gmail email accounts to enable reading, searching, sending, managing, scheduling, and analyzing emails via IMAP/SMTP, including provider-specific label management.
Integrates with GMX email accounts to enable reading, searching, sending, managing, scheduling, and analyzing emails via IMAP/SMTP.
Integrates with iCloud email accounts to enable reading, searching, sending, managing, scheduling, and analyzing emails via IMAP/SMTP.
Integrates with ProtonMail email accounts to enable reading, searching, sending, managing, scheduling, and analyzing emails via IMAP/SMTP.
Integrates with Zoho email accounts to enable reading, searching, sending, managing, scheduling, and analyzing emails via IMAP/SMTP.
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., "@Email MCP Server show my unread emails from today"
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.
Email MCP Server
An MCP (Model Context Protocol) server providing comprehensive email capabilities via IMAP and SMTP.
Enables AI assistants to read, search, send, manage, schedule, and analyze emails across multiple accounts. Exposes 47 tools, 7 prompts, and 6 resources over the MCP protocol with OAuth2 support (experimental), email scheduling, calendar extraction, analytics, provider-aware label management, real-time IMAP IDLE watcher with AI-powered triage, customizable presets and static rules, and a guided setup wizard.
Highlights
Feature | email-mcp | Typical MCP email |
Multi-account | ✅ | ❌ |
Send / reply / forward | ✅ | ✅ |
Drafts & templates | ✅ | ❌ |
Labels & bulk ops | ✅ provider-aware | ❌ |
Schedule future emails | ✅ | ❌ |
Real-time IMAP IDLE watcher | ✅ | ❌ |
AI triage with presets | ✅ | ❌ |
Desktop & webhook alerts | ✅ | ❌ |
Calendar (ICS) extraction | ✅ | ❌ |
Email analytics | ✅ | ❌ |
OAuth2 (Gmail / M365) | ✅ experimental | ❌ |
Guided setup wizard | ✅ auto-detect | ❌ |
Related MCP server: Email MCP Server
Table of Contents
Security
All connections use TLS/STARTTLS encryption
Passwords are never logged; audit trail records operations without credentials
Token-bucket rate limiter prevents abuse (configurable per account)
OAuth2 XOAUTH2 authentication for Gmail and Microsoft 365 (experimental)
Attachment downloads capped at 5 MB with base64 encoding
Background
Most MCP email implementations provide only basic read/send. This server aims to be a full-featured email client for AI assistants, covering the entire lifecycle: reading, composing, managing, scheduling, and analyzing email — all from a single MCP server.
Key design decisions:
XDG-compliant config — TOML at
~/.config/email-mcp/config.tomlMulti-account — Operate across multiple IMAP/SMTP accounts simultaneously
Layered services — Business logic is decoupled from MCP wiring for testability
Provider auto-detection — Gmail, Outlook, Yahoo, iCloud, Fastmail, ProtonMail, Zoho, GMX
Install
Requires Node.js ≥ 22.
# Run directly (no install needed)
npx @codefuturist/email-mcp setup
# or
pnpm dlx @codefuturist/email-mcp setup
# Or install globally
npm install -g @codefuturist/email-mcp
# or
pnpm add -g @codefuturist/email-mcpDocker
No Node.js required — just Docker.
# Latest stable release
docker pull ghcr.io/codefuturist/email-mcp:latest
# Pin to an exact version (immutable)
docker pull ghcr.io/codefuturist/email-mcp:0.2.3
# Auto-update patches within a minor version
docker pull ghcr.io/codefuturist/email-mcp:0.2
# Track a major version (won't cross breaking-change boundary)
docker pull ghcr.io/codefuturist/email-mcp:0
# Pin to an exact git commit (immutable, CI traceability)
docker pull ghcr.io/codefuturist/email-mcp:sha-abc1234
# Or build from source
docker build -t ghcr.io/codefuturist/email-mcp .Tag convention: Tags follow bare semver (no
vprefix), matching Docker ecosystem standards (e.g.node:24,nginx:1.25). Thelatesttag is only updated on stable releases, never pre-releases.
Note: The server uses stdio transport. Config must be created on the host first (via
npx @codefuturist/email-mcp setupor manually) and mounted into the container.
Usage
Setup
# Add an email account interactively (recommended)
email-mcp account add
# Or use the legacy alias
email-mcp setup
# Or create a template config manually
email-mcp config initThe setup wizard auto-detects server settings, tests connections, saves config, and outputs the MCP client config snippet.
Test Connections
email-mcp test # all accounts
email-mcp test personal # specific accountConfigure Your MCP Client
Recommended — use the guided installer (auto-detects Claude Desktop, VS Code, Cursor, Windsurf):
email-mcp installOr add manually using the snippets below.
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"email": {
"command": "npx",
"args": ["-y", "@codefuturist/email-mcp", "stdio"]
}
}
}Option 1 — Extensions gallery (easiest):
Open the Extensions view (⇧⌘X / Ctrl+Shift+X)
Search
@mcp email-mcpClick Install (user-wide) or right-click → Install in Workspace
Option 2 — Workspace config (.vscode/mcp.json, committed to source control):
{
"servers": {
"email": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@codefuturist/email-mcp", "stdio"]
}
}
}Option 3 — User config (settings.json, applies to all workspaces):
Open the Command Palette → Preferences: Open User Settings (JSON) and add:
{
"mcp": {
"servers": {
"email": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@codefuturist/email-mcp", "stdio"]
}
}
}
}Edit ~/.cursor/mcp.json:
{
"mcpServers": {
"email": {
"command": "npx",
"args": ["-y", "@codefuturist/email-mcp", "stdio"]
}
}
}Edit ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"email": {
"command": "npx",
"args": ["-y", "@codefuturist/email-mcp", "stdio"]
}
}
}Edit ~/.config/zed/settings.json:
{
"context_servers": {
"email": {
"command": {
"path": "npx",
"args": ["-y", "@codefuturist/email-mcp", "stdio"]
}
}
}
}Add to ~/.vibe/config.toml:
[[mcp_servers]]
name = "email-mcp"
transport = "stdio"
command = "npx"
args = ["-y", "@codefuturist/email-mcp", "stdio"]To pass credentials directly instead of using a config file, use the env field:
[[mcp_servers]]
name = "email-mcp"
transport = "stdio"
command = "npx"
args = ["-y", "@codefuturist/email-mcp", "stdio"]
env = { "EMAIL_ACCOUNTS" = "<your-accounts-json>" }MCP tools are exposed as email-mcp_<tool_name> (e.g. email-mcp_list_emails). Restart Vibe after editing the config.
Run the server in a container — mount your config directory read-only:
docker run --rm -i \
-v ~/.config/email-mcp:/home/node/.config/email-mcp:ro \
ghcr.io/codefuturist/email-mcpFor MCP client configuration (e.g. Claude Desktop):
{
"mcpServers": {
"email": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-v", "~/.config/email-mcp:/home/node/.config/email-mcp:ro",
"ghcr.io/codefuturist/email-mcp"
]
}
}
}{
"mcpServers": {
"email": {
"command": "npx",
"args": ["-y", "@codefuturist/email-mcp", "stdio"],
"env": {
"MCP_EMAIL_ADDRESS": "you@gmail.com",
"MCP_EMAIL_PASSWORD": "your-app-password",
"MCP_EMAIL_IMAP_HOST": "imap.gmail.com",
"MCP_EMAIL_SMTP_HOST": "smtp.gmail.com"
}
}
}
}CLI Commands
email-mcp [command]
Commands:
stdio Run as MCP server over stdio (default)
account list List all configured accounts
account add Add a new email account interactively
account edit [name] Edit an existing account
account delete [name] Remove an account
setup Alias for 'account add'
test Test connections for all or a specific account
install Register email-mcp with MCP clients interactively
install status Show registration status for detected clients
install remove Unregister email-mcp from MCP clients
config show Show config (passwords masked)
config edit Edit global settings (rate limit, read-only)
config path Print config file path
config init Create template config
scheduler check Process pending scheduled emails
scheduler list Show all scheduled emails
scheduler install Install OS-level scheduler (launchd/crontab)
scheduler uninstall Remove OS-level scheduler
scheduler status Show scheduler installation status
help Show helpConfiguration
Located at $XDG_CONFIG_HOME/email-mcp/config.toml (default: ~/.config/email-mcp/config.toml).
[settings]
rate_limit = 10 # max emails per minute per account
[[accounts]]
name = "personal"
email = "you@gmail.com"
full_name = "Your Name"
password = "your-app-password"
[accounts.imap]
host = "imap.gmail.com"
port = 993
tls = true
[accounts.smtp]
host = "smtp.gmail.com"
port = 465
tls = true
starttls = false
verify_ssl = true
[accounts.smtp.pool]
enabled = true
max_connections = 1
max_messages = 100OAuth2 (experimental)
Note: OAuth2 support is experimental. Token refresh and provider-specific flows may require additional testing in your environment.
[[accounts]]
name = "work"
email = "you@company.com"
full_name = "Your Name"
[accounts.oauth2]
provider = "google" # or "microsoft"
client_id = "your-client-id"
client_secret = "your-client-secret"
refresh_token = "your-refresh-token"
[accounts.imap]
host = "imap.gmail.com"
port = 993
tls = true
[accounts.smtp]
host = "smtp.gmail.com"
port = 465
tls = true
[accounts.smtp.pool]
enabled = true
max_connections = 1
max_messages = 100Environment Variables
For single-account setups (overrides config file):
Variable | Default | Description |
| required | Email address |
| required | Password or app password |
| required | IMAP server hostname |
| required | SMTP server hostname |
|
| Account name |
| — | Display name |
| Login username | |
|
| IMAP port |
|
| IMAP TLS |
|
| SMTP port |
|
| SMTP TLS |
|
| SMTP STARTTLS |
|
| Verify SSL certificates |
|
| Enable SMTP transport pooling |
|
| Max pooled SMTP connections |
|
| Max messages per pooled connection |
|
| Max sends per minute |
Email Scheduling
The scheduler enables future email delivery with a layered architecture:
MCP auto-check — Processes the queue on server startup and every 60 seconds while the MCP server is running
CLI —
email-mcp scheduler checkfor manual or cron-based processingOS-level daemon —
email-mcp scheduler installsets up launchd (macOS) or crontab (Linux) to run every minute, independently of the MCP server
Important — the daemon must be installed for reliable delivery. Without it, scheduled emails only fire while an AI client is actively connected. Your machine also needs to be running at the scheduled time; if it's asleep or off, the daemon will process overdue emails on next wake/startup. Failed sends are retried up to 3 times before being marked
failed.
Setting up the daemon
# Install (macOS launchd / Linux crontab — runs every minute)
email-mcp scheduler install
# Verify it's running
email-mcp scheduler status
# View pending / sent / failed scheduled emails
email-mcp scheduler list
# Trigger a manual check immediately
email-mcp scheduler check
# Remove the daemon
email-mcp scheduler uninstallScheduled emails are stored as JSON files in ~/.local/state/email-mcp/scheduled/ with status-based locking. Each entry tracks attempts (max 3) and the last error, so you can inspect failures with scheduler list.
Real-time Watcher & AI Hooks
The IMAP IDLE watcher monitors configured mailboxes in real-time using persistent IDLE connections (separate from tool connections). When new emails arrive:
Static rules — Pattern-match on from/to/subject → apply labels, flag, or mark read instantly (no AI)
AI triage — Remaining emails are analyzed via MCP sampling with a customizable preset prompt
Notify mode — Falls back to logging if AI triage is disabled
Configure in config.toml:
[settings.watcher]
enabled = true
folders = ["INBOX"]
idle_timeout = 1740 # 29 minutes (IMAP spec max is 30)
[settings.hooks]
on_new_email = "triage" # "triage" | "notify" | "none"
preset = "inbox-zero" # "inbox-zero" | "gtd" | "priority-focus" | "notification-only" | "custom"
auto_label = true # apply AI-suggested labels
auto_flag = true # flag urgent emails
batch_delay = 5 # seconds to batch before triage
# User context — appended to preset's AI prompt
custom_instructions = """
I'm a software engineer. Emails from @mycompany.com are always high priority.
Newsletters I read: TL;DR, Hacker Newsletter.
"""
# Static rules — run BEFORE AI, skip AI if matched
[[settings.hooks.rules]]
name = "GitHub Notifications"
match = { from = "*@github.com" }
actions = { labels = ["Dev"], mark_read = true }
[[settings.hooks.rules]]
name = "Newsletter Archive"
match = { from = "*@substack.com|*@buttondown.email" }
actions = { labels = ["Newsletter"] }
[[settings.hooks.rules]]
name = "VIP Contacts"
match = { from = "ceo@company.com|cto@company.com" }
actions = { flag = true, labels = ["VIP"] }Presets
Preset | Focus | Suggested Labels |
| Aggressive categorization + archiving | Newsletter, Notification, Updates, Finance, Social, Promo |
| Getting Things Done contexts | @Action, @Waiting, @Reference, @Someday, @Delegated |
| Simple priority classification (default) | (none — just priority + flag) |
| No AI triage, just log | (none) |
| User defines full system prompt | User-defined |
Static Rules
Static rules use glob-style patterns (*@github.com) with | as OR separator (*@github.com|*@gitlab.com). All conditions within a match are AND'd. First matching rule wins.
Available actions: labels (string array), flag (boolean), mark_read (boolean), alert (boolean — forces desktop notification).
Alerts
Urgency-based multi-channel notification routing — grab attention for important emails even when you're not looking at the chat. All channels are opt-in and disabled by default.
Priority | Desktop | Sound | MCP Log Level | Webhook |
| ✅ Banner | 🔊 Alert |
| ✅ |
| ✅ Banner | 🔇 Silent |
| ✅ |
| ❌ | ❌ |
| ❌ |
| ❌ | ❌ |
| ❌ |
[settings.hooks.alerts]
desktop = true # OS-level notifications (macOS/Linux/Windows)
sound = true # play sound for urgent emails
urgency_threshold = "high" # minimum priority to trigger desktop alert
webhook_url = "https://ntfy.sh/my-email-alerts" # optional: Slack, Discord, ntfy.sh, etc.
webhook_events = ["urgent", "high"]Supported platforms: macOS (Notification Center via osascript), Linux (notify-send), Windows (PowerShell toast). Zero npm dependencies — uses native OS commands.
Notification setup by platform:
Desktop notifications use osascript (built-in). The terminal app running the MCP server needs notification permission:
Open System Settings → Notifications & Focus
Find your terminal app (Terminal, iTerm2, VS Code, Cursor, etc.)
Enable Allow Notifications and choose Banners or Alerts
Ensure Focus / Do Not Disturb is not blocking notifications
Use check_notification_setup to diagnose and test_notification to verify.
Requires notify-send from libnotify. For sound alerts, paplay is also needed:
# Ubuntu / Debian
sudo apt install libnotify-bin pulseaudio-utils
# Fedora
sudo dnf install libnotify pulseaudio-utils
# Arch
sudo pacman -S libnotifyDesktop notifications require a running display server (X11/Wayland) — they will not work in headless/SSH sessions.
Uses PowerShell toast notifications (built-in):
Open Settings → System → Notifications
Ensure Notifications is turned on
Set Focus Assist to allow notifications
If using Windows Terminal, ensure its notifications are enabled
AI-configurable: The AI can check, test, and configure notifications at runtime:
check_notification_setup— diagnose platform support and show setup instructionstest_notification— send a test notification to verify everything worksconfigure_alerts— enable/disable desktop, sound, threshold, webhook (with optional persist to config file)
Webhook payload:
{
"event": "email.urgent",
"account": "work",
"sender": { "name": "John CEO", "address": "ceo@company.com" },
"subject": "Q4 Review Due Today",
"priority": "urgent",
"labels": ["VIP"],
"rule": "VIP Contacts",
"timestamp": "2026-02-18T11:30:00Z"
}Static rules can force desktop notifications with alert = true, regardless of urgency threshold:
[[settings.hooks.rules]]
name = "VIP Contacts"
match = { from = "ceo@company.com" }
actions = { flag = true, alert = true, labels = ["VIP"] }Features:
Auto-reconnect — Exponential backoff (1s → 60s) on connection failures
Batching — Groups arrivals within a configurable delay to reduce AI calls
Rate limiting — Max 10 sampling calls per minute
Graceful degradation — Falls back to notify mode if client doesn't support sampling
Resource subscriptions — Pushes
notifications/resources/updatedfor unread counts
API
Tools (47)
Read (14)
Tool | Description |
| List all configured email accounts |
| List folders with unread counts and special-use flags |
| Paginated email listing with date, sender, subject, and flag filters |
| Read full email content with attachment metadata |
| Fetch full content of multiple emails in a single call (max 20) |
| Get read/flag/label state of an email without fetching the body |
| Search by keyword across subject, sender, and body |
| Download an email attachment by filename |
| Discover the real folder(s) an email resides in (resolves virtual folders) |
| Extract unique contacts from recent email headers |
| Reconstruct a conversation thread via References/In-Reply-To |
| List available email templates |
| Email analytics — volume, top senders, daily trends |
| Connection health, latency, quota, and IMAP capabilities |
Write (9)
Tool | Description |
| Send a new email (plain text or HTML, CC/BCC) |
| Reply with proper threading (In-Reply-To, References) |
| Forward with original content quoted |
| Save an email draft to the Drafts folder |
| Send an existing draft and remove from Drafts |
| Apply a template with variable substitution |
| Schedule an email for future delivery |
| List scheduled emails by status |
| Cancel a pending scheduled email |
Manage (7)
Tool | Description |
| Move email between folders |
| Move to Trash or permanently delete |
| Mark as read/unread, flag/unflag |
| Batch operation on up to 100 emails |
| Create a new mailbox folder |
| Rename an existing mailbox folder |
| Permanently delete a mailbox and contents |
Labels (5)
Tool | Description |
| Discover available labels (auto-detects provider strategy) |
| Add a label to an email (ProtonMail folders, Gmail X-GM-LABELS, or IMAP keywords) |
| Remove a label from an email |
| Create a new label |
| Delete a label |
Watcher & Alerts (6)
Tool | Description |
| Show IMAP IDLE connections, folders being monitored, and last-seen UIDs |
| List available AI triage presets with descriptions and suggested labels |
| Show current hooks configuration — preset, rules, and custom instructions |
| Update alert/notification settings at runtime |
| Diagnose desktop notification support and provide setup instructions |
| Send a test notification to verify OS permissions are configured |
Calendar & Reminders (6)
Tool | Description |
| Extract ICS/iCalendar events from an email |
| Analyze an email to detect events and reminder-worthy content |
| Add an email event to the local calendar (macOS/Linux) |
| Create a reminder in macOS Reminders.app from an email |
| List all available local calendars |
| Check whether the local calendar is accessible |
Prompts (7)
Prompt | Description |
| Categorize and prioritize unread emails with suggested actions |
| Summarize an email conversation thread |
| Draft a context-aware reply to an email |
| Compose a new email from provided context and instructions |
| Extract actionable tasks from email threads |
| Summarize upcoming calendar events from emails |
| Suggest emails to archive, delete, or unsubscribe from |
Resources (6)
Resource | URI | Description |
Accounts |
| List of configured accounts |
Mailboxes |
| Folder tree for an account |
Unread |
| Unread email summary |
Templates |
| Available email templates |
Stats |
| Email statistics snapshot |
Scheduled |
| Pending scheduled emails |
Provider Auto-Detection
Provider | Domains |
Gmail | gmail.com |
Outlook / Hotmail | outlook.com, hotmail.com, live.com |
Yahoo Mail | yahoo.com, ymail.com |
iCloud | icloud.com, me.com, mac.com |
Fastmail | fastmail.com |
ProtonMail Bridge | proton.me, protonmail.com |
Zoho Mail | zoho.com |
GMX | gmx.com, gmx.de, gmx.net |
Architecture
src/
├── main.ts — Entry point and subcommand routing
├── server.ts — MCP server factory
├── logging.ts — MCP protocol logging bridge
├── cli/ — Interactive CLI commands
│ ├── account-commands.ts — Account CRUD (list, add, edit, delete)
│ ├── setup.ts — Legacy setup alias → account add
│ ├── test.ts — Connection tester
│ ├── config-commands.ts — Config management (show, edit, path, init)
│ ├── install-commands.ts — MCP client registration (install, status, remove)
│ ├── providers.ts — Provider auto-detection + OAuth2 endpoints (experimental)
│ └── scheduler.ts — Scheduler CLI
├── config/ — Configuration layer
│ ├── xdg.ts — XDG Base Directory paths
│ ├── schema.ts — Zod validation schemas
│ └── loader.ts — Config loader (TOML + env vars)
├── connections/
│ └── manager.ts — Lazy persistent IMAP/SMTP with OAuth2 (experimental)
├── services/ — Business logic
│ ├── imap.service.ts — IMAP operations
│ ├── label-strategy.ts — Provider-aware label strategy (ProtonMail/Gmail/IMAP keywords)
│ ├── smtp.service.ts — SMTP operations
│ ├── template.service.ts — Email template engine
│ ├── oauth.service.ts — OAuth2 token management (experimental)
│ ├── calendar.service.ts — ICS/iCalendar parsing
│ ├── scheduler.service.ts — Email scheduling queue
│ ├── watcher.service.ts — IMAP IDLE real-time watcher with auto-reconnect
│ ├── hooks.service.ts — AI triage via MCP sampling + static rules + auto-labeling/flagging
│ ├── notifier.service.ts — Multi-channel notification dispatcher (desktop/sound/webhook)
│ ├── presets.ts — Built-in hook presets (inbox-zero, gtd, priority-focus, etc.)
│ └── event-bus.ts — Typed EventEmitter for internal email events
├── tools/ — MCP tool definitions (42)
├── prompts/ — MCP prompt definitions (7)
├── resources/ — MCP resource definitions (6)
├── safety/ — Audit trail and rate limiter
└── types/ — Shared TypeScript typesMaintainers
Contributing
PRs accepted. Please conform to the standard-readme specification when editing this README.
# Development workflow
pnpm install
pnpm typecheck # type check
pnpm check # lint and format
pnpm build # build
pnpm start # runLicense
Available Tools
49 toolsadd_labelAIdempotent
Add a label to an email. For ProtonMail, this copies the email into the corresponding Labels/ folder. For Gmail and standard IMAP, this sets a keyword flag on the message.
Inputs: label (required), account (required), emailId (required), mailbox (required).
add_to_calendarA
Add an email event to the local calendar (macOS Calendar.app / Linux via xdg-open). Automatically extracts event data from the email: ICS attachments, meeting URL (Zoom/Teams/Meet), conference dial-in / ID / passcode, attendees, and email body excerpt. All relevant email attachments (PDFs, docs, etc.) are saved locally and linked in the event notes. A native confirmation dialog is shown on macOS before the event is written. Returns one of: added | cancelled | timed_out | no_display.
Inputs: account (required), email_id (required), confirm, mailbox, +3 more.
analyze_email_for_schedulingARead-only
Analyze an email to detect calendar events and/or reminder-worthy content. Returns structured analysis so the AI can decide whether to call add_to_calendar, create_reminder, both, or neither. Use this as the first step before creating any scheduling resource.
Inputs: account (required), email_id (required), mailbox.
apply_templateA
Apply an email template with variable substitution. Use action "preview" to see the result, "draft" to save as draft, or "send" to send immediately.
Inputs: account (required), template (required), variables (required), to, +1 more.
bulk_actionADestructive
Batch operation on multiple emails by UID list. Supports mark_read, mark_unread, flag, unflag, move, and delete. Max 100 IDs per call. Returns success/failure counts.
Inputs: ids (required), action (required), account (required), mailbox, +1 more.
cancel_scheduledADestructive
Cancel a scheduled email. Removes it from the queue and deletes the associated draft.
Inputs: schedule_id (required).
check_calendar_permissionsARead-only
Check whether the local calendar is accessible. On macOS, verifies Calendar.app access (requires Privacy & Security → Calendars permission). Returns granted status and step-by-step setup instructions if access is denied.
Inputs: no named parameters.
check_healthARead-only
Check connection health, quota, and capabilities for email accounts. Useful for diagnosing issues.
Inputs: account.
check_notification_setupARead-only
Diagnose desktop notification support on this platform. Checks if required OS tools are available and provides setup instructions to enable notification permissions (macOS, Linux, Windows).
Inputs: no named parameters.
configure_alertsA
Update alert/notification settings at runtime. Changes take effect immediately. Use save=true to persist changes to the config file. Omit any field to leave it unchanged.
Inputs: save, sound, desktop, webhook_url, +2 more.
create_labelA
Create a new label. For ProtonMail, creates a folder under Labels/. For standard IMAP keywords, labels are auto-created on first use — this is a no-op.
Inputs: name (required), account (required).
create_mailboxAIdempotent
Create a new mailbox (folder). Use '/' as separator for nested folders (e.g., 'Work/Projects'). Use list_mailboxes to see existing folders.
Inputs: path (required), account (required).
create_reminderA
Create a reminder in macOS Reminders.app from an email. Shows a native confirmation dialog before adding. Use for action items, deadlines, and follow-up tasks extracted from emails. Use analyze_email_for_scheduling first to let the AI decide if a reminder is appropriate.
Inputs: account (required), email_id (required), notes, title, +5 more.
delete_emailADestructive
Delete an email. By default moves to Trash. Set permanent=true for permanent deletion (⚠️ irreversible). The mailbox must be a real folder. Use find_email_folder first if the email was found in a virtual folder.
Inputs: account (required), emailId (required), mailbox, permanent.
delete_labelADestructive
Delete a label. For ProtonMail, deletes the label folder. For standard IMAP keywords, labels cannot be deleted server-wide — use remove_label on individual emails.
Inputs: name (required), account (required).
delete_mailboxADestructive
⚠️ DESTRUCTIVE: Permanently delete a mailbox and ALL its contents. This cannot be undone. Use list_mailboxes to verify the folder path.
Inputs: path (required), account (required).
download_attachmentARead-only
Download an email attachment by filename. First use get_email to see available attachments and their filenames. Returns base64-encoded content for files ≤5MB.
Inputs: id (required), account (required), filename (required), mailbox.
extract_calendarARead-only
Extract calendar events (ICS/iCalendar) from an email. Returns structured event data including time, location, attendees, and status.
Inputs: account (required), email_id (required), mailbox.
extract_contactsARead-only
Extract unique contacts from recent email headers. Returns contacts sorted by frequency (most frequent first). Useful for finding frequent correspondents or building an address book.
Inputs: account (required), limit, mailbox.
find_email_folderARead-only
Find which real mailbox folder(s) an email belongs to. Required before move_email or delete_email when the email was found in a virtual folder (e.g., "All Mail", "Starred"). Returns the real folder path to use as sourceMailbox.
Inputs: account (required), emailId (required), sourceMailbox.
forward_emailA
Forward an email to new recipients with optional additional message. Original email is quoted below.
Inputs: to (required), account (required), emailId (required), cc, +3 more.
get_emailARead-only
Get the full content of a specific email by ID. Does NOT mark the email as seen (uses IMAP BODY.PEEK — non-destructive). Use format="text" to strip HTML, or format="stripped" to also remove quoted replies and signatures. Use maxLength to cap the body size for large emails. Set markRead=true only when you want to explicitly mark the email as read.
Inputs: account (required), emailId (required), format, mailbox, +2 more.
get_emailsARead-only
Fetch the full content of multiple emails in a single call (max 20). More efficient than calling get_email repeatedly when triaging or summarising several emails. Does NOT mark emails as seen. Defaults to format="text" (HTML stripped) for compact, AI-friendly output.
Inputs: ids (required), account (required), format, mailbox, +1 more.
get_email_statsARead-only
Get email statistics and analytics for a mailbox. Shows volume, top senders, daily trends, and read/flagged counts.
Inputs: account (required), period, mailbox.
get_email_statusARead-only
Get the current read/flag/label state of an email without fetching its body. Much cheaper than get_email when you only need to check whether an email is unread, flagged, or which labels it has. Also useful to confirm the result of a mark_email call. Does NOT mark the email as seen.
Inputs: account (required), emailId (required), mailbox.
get_hooks_configARead-only
Get the current AI hooks configuration including preset, rules, and custom instructions.
Inputs: no named parameters.
get_threadARead-only
Reconstruct a full email conversation thread by following References and In-Reply-To headers. Returns all related messages. Does NOT mark emails as seen. Use format="text" to strip HTML, or format="stripped" to also remove quoted replies. Use newestFirst=true to show the most recent message in full and older messages as header-only summaries. Use get_email first to obtain the message_id.
Inputs: account (required), message_id (required), format, mailbox, +2 more.
get_watcher_statusARead-only
Get the status of IMAP IDLE watcher connections and recent activity.
Inputs: no named parameters.
list_accountsARead-only
List all configured email accounts. Call this first to discover available account names for use with other tools.
Inputs: no named parameters.
list_calendarsARead-only
List all available local calendars (macOS Calendar.app / Linux default). Use the returned calendar names with add_to_calendar to target a specific calendar.
Inputs: no named parameters.
list_emailsARead-only
List emails in a mailbox with optional filters. Returns paginated results with metadata (read/unread 🔵, flagged ⭐, replied ↩️, attachments 📎, labels 🏷️). Use get_email to fetch full body content. ProtonMail note: labels are represented as IMAP folders — use list_labels to discover them, then list_emails with mailbox="Labels/X" to find labeled emails.
Inputs: account (required), from, page, seen, +8 more.
list_eventsARead-only
List local calendar events with optional filters. Search by title, date range, or calendar name. Use to check for existing events before creating new ones, or to verify a recently added event. Returns event id, title, start/end time, location, and calendar name.
Inputs: to, from, limit, title, +1 more.
list_labelsARead-only
List available labels for an email account. Auto-detects the label system: ProtonMail folder-labels, Gmail X-GM-LABELS, or IMAP keywords. ProtonMail note: labels are represented as IMAP folders under the Labels/ prefix. Use list_emails with mailbox="Labels/" to find emails tagged with a ProtonMail label.
Inputs: account (required).
list_mailboxesARead-only
List all mailbox folders for an account with unread counts and special-use flags. Use list_accounts first to get the account name.
Inputs: account (required).
list_presetsARead-only
List all available AI triage presets with their descriptions and suggested labels.
Inputs: no named parameters.
list_remindersARead-only
List reminders from macOS Reminders.app with optional filters. Search by title or list name. By default only shows incomplete reminders. Use to check for existing reminders before creating new ones, or to verify a recently added reminder. Returns reminder id, title, due date, completion status, priority, and list name.
Inputs: limit, title, list_name, include_completed.
list_scheduledARead-only
List scheduled emails. Shows pending, sent, or all scheduled emails.
Inputs: status, account.
list_templatesARead-only
List all available email templates. Templates are TOML files in ~/.config/email-mcp/templates/ with {{variable}} placeholders for subject and body.
Inputs: no named parameters.
mark_emailAIdempotent
Change email flags — mark as read/unread, flag/unflag. Idempotent: marking an already-read email as read is a no-op.
Inputs: id (required), action (required), account (required), mailbox.
move_emailAIdempotent
Move an email to a different mailbox folder. The sourceMailbox must be a real folder, not a virtual one like "All Mail". Use find_email_folder first if the email was discovered in a virtual folder.
Inputs: account (required), emailId (required), sourceMailbox (required), destinationMailbox (required).
remove_labelAIdempotent
Remove a label from an email. For ProtonMail, this removes the email from the label folder. For Gmail and standard IMAP, this removes a keyword flag.
Inputs: label (required), account (required), emailId (required), mailbox (required).
rename_mailboxA
Rename an existing mailbox (folder). Use list_mailboxes to see current folder paths.
Inputs: path (required), account (required), new_path (required).
reply_emailA
Reply to an email with proper threading (In-Reply-To & References headers). Use get_email first to read the original.
Inputs: body (required), account (required), emailId (required), html, +3 more.
save_draftA
Save an email draft to the Drafts folder. Compose over time, then use send_draft to send it. Use list_emails with the Drafts mailbox to see saved drafts.
Inputs: body (required), account (required), subject (required), cc, +4 more.
schedule_emailA
Schedule an email to be sent at a specific time in the future. The email is queued locally and sent automatically when the time arrives.
Inputs: to (required), body (required), account (required), send_at (required), +5 more.
search_emailsARead-only
Search emails by keyword across subject, sender, and body. Omit query (or pass an empty string) to use it as a pure filter — e.g. find all emails with attachments from a specific recipient without a keyword. Supports additional filters for recipient, attachments, size, and reply status.
Inputs: account (required), to, page, query, +6 more.
send_draftADestructive
Send an existing draft email and remove it from Drafts. The draft is fetched, sent via SMTP, then deleted. Use list_emails with the Drafts mailbox to find draft IDs.
Inputs: id (required), account (required), mailbox.
send_emailA
Send a new email. Supports plain text or HTML body, CC, and BCC.
Inputs: to (required), body (required), account (required), subject (required), +4 more.
test_notificationA
Send a test desktop notification to verify that OS permissions are correctly configured. Use check_notification_setup first to diagnose any issues.
Inputs: sound.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 49 tools
Every tool targets a distinct action and resource, from reading (list_emails, get_email, get_emails, get_email_status, search_emails) to writing (send_email, reply_email, forward_email, save_draft, send_draft) to management (move_email, delete_email, mark_email, labels, bulk_action). Even similar operations like add_to_calendar and create_reminder are clearly differentiated by their descriptions.
All tool names follow a consistent verb_noun pattern with underscores (e.g., list_accounts, get_email, create_reminder, delete_mailbox). Compound verbs like analyze_email_for_scheduling and check_notification_setup still adhere to the same convention.
With 49 tools, this server is very heavy. The breadth of features (email, calendar, reminders, notifications, templates, analytics) justifies a larger count, but 49 still exceeds the practical limit for an agent to efficiently navigate and select from, making the set feel bloated.
The email lifecycle is thoroughly covered: send, reply, forward, draft, schedule, move, delete, mark, label, search, and attachments. The additional calendar, reminder, template, and analytics features address secondary needs, and helper tools like find_email_folder and analyze_email_for_scheduling fill potential gaps.
Maintenance
Related MCP Connectors
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Email inboxes for AI agents: send, receive, reply, search, and manage threaded email over MCP.
Hosted email MCP for AI agents with inboxes, send/receive, memory, recovery, and credits.
An MCP server that provides email capabilities, hosted on Alpic platform
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that enables AI models to read, search, and send emails via IMAP and SMTP protocols. It supports various providers like Gmail and Outlook, allowing for tasks such as retrieving unread messages, searching by sender, and managing mailbox folders.-
- AlicenseAqualityCmaintenanceAn MCP server providing comprehensive email capabilities via IMAP and SMTP, enabling AI assistants to read, search, send, manage, schedule, and analyze emails across multiple accounts.52905 npm156LGPL 3.0
- AlicenseBqualityCmaintenanceAn MCP server that exposes IMAP operations as tools for AI assistants, enabling email management including listing mailboxes, reading, searching, moving, flagging emails, and creating drafts.727 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to read, search, send, manage, schedule, and analyze emails across multiple IMAP/SMTP accounts via MCP, with features like OAuth2, calendar extraction, analytics, and real-time email watching.222 npmLGPL 3.0