Apple Mail MCP Server
Read, search, send and organise mail in the macOS Mail app from an MCP client
Read, search, file and send mail on any IMAP and SMTP account from an MCP client
By Zhongsheng Ji (individual) Python Local · stdio Communication
67 popularity score ★ 378 ↓ 14k/mo
Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.
It needs MCP_EMAIL_SERVER_EMAIL_ADDRESS, MCP_EMAIL_SERVER_PASSWORD, MCP_EMAIL_SERVER_IMAP_HOST. Replace each <NAME> with your value.
claude mcp add email -e MCP_EMAIL_SERVER_EMAIL_ADDRESS=<MCP_EMAIL_SERVER_EMAIL_ADDRESS> -e MCP_EMAIL_SERVER_PASSWORD=<MCP_EMAIL_SERVER_PASSWORD> -e MCP_EMAIL_SERVER_IMAP_HOST=<MCP_EMAIL_SERVER_IMAP_HOST> -- uvx mcp-email-server@latest stdio{
"mcpServers": {
"email": {
"command": "uvx",
"args": [
"mcp-email-server@latest",
"stdio"
],
"env": {
"MCP_EMAIL_SERVER_EMAIL_ADDRESS": "<MCP_EMAIL_SERVER_EMAIL_ADDRESS>",
"MCP_EMAIL_SERVER_PASSWORD": "<MCP_EMAIL_SERVER_PASSWORD>",
"MCP_EMAIL_SERVER_IMAP_HOST": "<MCP_EMAIL_SERVER_IMAP_HOST>"
}
}
}
}{
"mcpServers": {
"email": {
"command": "uvx",
"args": [
"mcp-email-server@latest",
"stdio"
],
"env": {
"MCP_EMAIL_SERVER_EMAIL_ADDRESS": "<MCP_EMAIL_SERVER_EMAIL_ADDRESS>",
"MCP_EMAIL_SERVER_PASSWORD": "<MCP_EMAIL_SERVER_PASSWORD>",
"MCP_EMAIL_SERVER_IMAP_HOST": "<MCP_EMAIL_SERVER_IMAP_HOST>"
}
}
}
}{
"servers": {
"email": {
"type": "stdio",
"command": "uvx",
"args": [
"mcp-email-server@latest",
"stdio"
],
"env": {
"MCP_EMAIL_SERVER_EMAIL_ADDRESS": "<MCP_EMAIL_SERVER_EMAIL_ADDRESS>",
"MCP_EMAIL_SERVER_PASSWORD": "<MCP_EMAIL_SERVER_PASSWORD>",
"MCP_EMAIL_SERVER_IMAP_HOST": "<MCP_EMAIL_SERVER_IMAP_HOST>"
}
}
}
}[mcp_servers.email]
command = "uvx"
args = ["mcp-email-server@latest", "stdio"]
[mcp_servers.email.env]
MCP_EMAIL_SERVER_EMAIL_ADDRESS = "<MCP_EMAIL_SERVER_EMAIL_ADDRESS>"
MCP_EMAIL_SERVER_PASSWORD = "<MCP_EMAIL_SERVER_PASSWORD>"
MCP_EMAIL_SERVER_IMAP_HOST = "<MCP_EMAIL_SERVER_IMAP_HOST>"gemini mcp add --scope user -e MCP_EMAIL_SERVER_EMAIL_ADDRESS=<MCP_EMAIL_SERVER_EMAIL_ADDRESS> -e MCP_EMAIL_SERVER_PASSWORD=<MCP_EMAIL_SERVER_PASSWORD> -e MCP_EMAIL_SERVER_IMAP_HOST=<MCP_EMAIL_SERVER_IMAP_HOST> email uvx -- mcp-email-server@latest stdioOpens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.
It needs MCP_EMAIL_SERVER_EMAIL_ADDRESS, MCP_EMAIL_SERVER_PASSWORD, MCP_EMAIL_SERVER_IMAP_HOST. Replace each <NAME> with your value.
claude mcp add email -e MCP_EMAIL_SERVER_EMAIL_ADDRESS=<MCP_EMAIL_SERVER_EMAIL_ADDRESS> -e MCP_EMAIL_SERVER_PASSWORD=<MCP_EMAIL_SERVER_PASSWORD> -e MCP_EMAIL_SERVER_IMAP_HOST=<MCP_EMAIL_SERVER_IMAP_HOST> -- docker run -i --rm -e MCP_EMAIL_SERVER_EMAIL_ADDRESS -e MCP_EMAIL_SERVER_PASSWORD -e MCP_EMAIL_SERVER_IMAP_HOST ghcr.io/wh1isper/mcp-email-server{
"mcpServers": {
"email": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"MCP_EMAIL_SERVER_EMAIL_ADDRESS",
"-e",
"MCP_EMAIL_SERVER_PASSWORD",
"-e",
"MCP_EMAIL_SERVER_IMAP_HOST",
"ghcr.io/wh1isper/mcp-email-server"
],
"env": {
"MCP_EMAIL_SERVER_EMAIL_ADDRESS": "<MCP_EMAIL_SERVER_EMAIL_ADDRESS>",
"MCP_EMAIL_SERVER_PASSWORD": "<MCP_EMAIL_SERVER_PASSWORD>",
"MCP_EMAIL_SERVER_IMAP_HOST": "<MCP_EMAIL_SERVER_IMAP_HOST>"
}
}
}
}{
"mcpServers": {
"email": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"MCP_EMAIL_SERVER_EMAIL_ADDRESS",
"-e",
"MCP_EMAIL_SERVER_PASSWORD",
"-e",
"MCP_EMAIL_SERVER_IMAP_HOST",
"ghcr.io/wh1isper/mcp-email-server"
],
"env": {
"MCP_EMAIL_SERVER_EMAIL_ADDRESS": "<MCP_EMAIL_SERVER_EMAIL_ADDRESS>",
"MCP_EMAIL_SERVER_PASSWORD": "<MCP_EMAIL_SERVER_PASSWORD>",
"MCP_EMAIL_SERVER_IMAP_HOST": "<MCP_EMAIL_SERVER_IMAP_HOST>"
}
}
}
}{
"servers": {
"email": {
"type": "stdio",
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"MCP_EMAIL_SERVER_EMAIL_ADDRESS",
"-e",
"MCP_EMAIL_SERVER_PASSWORD",
"-e",
"MCP_EMAIL_SERVER_IMAP_HOST",
"ghcr.io/wh1isper/mcp-email-server"
],
"env": {
"MCP_EMAIL_SERVER_EMAIL_ADDRESS": "<MCP_EMAIL_SERVER_EMAIL_ADDRESS>",
"MCP_EMAIL_SERVER_PASSWORD": "<MCP_EMAIL_SERVER_PASSWORD>",
"MCP_EMAIL_SERVER_IMAP_HOST": "<MCP_EMAIL_SERVER_IMAP_HOST>"
}
}
}
}[mcp_servers.email]
command = "docker"
args = ["run", "-i", "--rm", "-e", "MCP_EMAIL_SERVER_EMAIL_ADDRESS", "-e", "MCP_EMAIL_SERVER_PASSWORD", "-e", "MCP_EMAIL_SERVER_IMAP_HOST", "ghcr.io/wh1isper/mcp-email-server"]
[mcp_servers.email.env]
MCP_EMAIL_SERVER_EMAIL_ADDRESS = "<MCP_EMAIL_SERVER_EMAIL_ADDRESS>"
MCP_EMAIL_SERVER_PASSWORD = "<MCP_EMAIL_SERVER_PASSWORD>"
MCP_EMAIL_SERVER_IMAP_HOST = "<MCP_EMAIL_SERVER_IMAP_HOST>"gemini mcp add --scope user -e MCP_EMAIL_SERVER_EMAIL_ADDRESS=<MCP_EMAIL_SERVER_EMAIL_ADDRESS> -e MCP_EMAIL_SERVER_PASSWORD=<MCP_EMAIL_SERVER_PASSWORD> -e MCP_EMAIL_SERVER_IMAP_HOST=<MCP_EMAIL_SERVER_IMAP_HOST> email docker -- run -i --rm -e MCP_EMAIL_SERVER_EMAIL_ADDRESS -e MCP_EMAIL_SERVER_PASSWORD -e MCP_EMAIL_SERVER_IMAP_HOST ghcr.io/wh1isper/mcp-email-serverMCP_EMAIL_SERVER_EMAIL_ADDRESS |
Required: Email address of the account set by environment variables. |
|---|---|
MCP_EMAIL_SERVER_PASSWORD |
Required: Password or app password for the account. |
MCP_EMAIL_SERVER_IMAP_HOST |
Required: IMAP server host; port 993 with SSL by default. |
MCP_EMAIL_SERVER_SMTP_HOST |
Optional: SMTP server host; needed to send (port 465 by default). |
MCP_EMAIL_SERVER_ACCOUNT_NAME |
Optional: Name of the account; 'default' if unset. |
MCP_EMAIL_SERVER_ALLOWED_RECIPIENTS |
Optional: Addresses mail may go to; empty blocks sending, * allows all. |
MCP_EMAIL_SERVER_ALLOWED_MUTATIONS |
Optional: Kinds of change allowed (draft, organize, delete, send, append); all by default. |
MCP_EMAIL_SERVER_ENABLE_ATTACHMENT_DOWNLOAD |
Optional: Allows saving attachments to disk; false by default. |
MCP_EMAIL_SERVER_ENABLE_ATTACHMENT_CONTENT |
Optional: Allows returning attachment bytes to the client; false by default. |
MCP_EMAIL_SERVER_CONFIG_PATH |
Optional: Path to the config file instead of ~/.config/mcp-email-server/config.toml. |
In a container, a setting goes in with -e NAME=value after docker run.
mcp-email-server connects an MCP client to ordinary mailboxes over IMAP for reading and SMTP for sending. It is not tied to one provider, so it works with any account that allows password sign-in over those protocols. It runs on your own machine over stdio by default, and it can also serve SSE or Streamable HTTP. It can hold several accounts.
Version 1.13.1 registers 21 tools (counted in app.py at that tag). An assistant can list accounts and mailboxes, search a mailbox by its headers, and then fetch message bodies. It can send, forward, save drafts, add messages to a mailbox, and set flags and tags. It can also move, archive and delete messages, fetch attachments, and run raw IMAP or SMTP commands through email_command. Searches return 10 messages per page by default, up to 100 with page_size. Bodies are cut at 20,000 characters by default (max_body_length, up to 100,000), and body_offset fetches the rest.
Since 1.0.0 ("Local Email App V2"), you add accounts and passwords through a local web UI (`mcp-email-server ui`) or the CLI. As an alternative, you can configure a single account with environment variables. The MCP side has no tool to add accounts or change credentials: the add_email_account tool from 0.16.0 and earlier was removed. A local policy controls what tools may do: which kinds of change are allowed (draft, organize, delete, send, append), which recipients may be mailed, and which senders' mail is shown.
| Runtime | Python 3.11+orDocker |
|---|
Python 3.11 or later, run through uv (`uvx`), or Docker for the ghcr.io image (Linux amd64/arm64, from 1.6.2). You need an email account that allows IMAP sign-in with a password, plus SMTP details if you want to send. Configure the account before the client starts it: either run `uvx mcp-email-server@latest ui` once, or set MCP_EMAIL_SERVER_EMAIL_ADDRESS, MCP_EMAIL_SERVER_PASSWORD and MCP_EMAIL_SERVER_IMAP_HOST.
Sign-in is by password only: the docs describe no OAuth flow, so an account whose provider blocks plain password sign-in needs an app password. Nothing can be sent until you add allowed recipients: an empty allowed_recipients list blocks sending. Attachment download and attachment content are both off by default. email_command is off unless allow_protocol_commands is turned on for the account outside MCP. Deleting messages, and the fallback way of moving them, need a server with UIDPLUS. Environment variables configure one account only. Settings from 0.16.0 and earlier are not imported automatically; they keep running in legacy mode.
A good fit for anyone who wants an assistant to work on a personal or work mailbox from any provider that speaks IMAP/SMTP, with local control over what it may change or whom it may mail. Everything runs on your own machine, and passwords never pass through the assistant. If your mail account only allows OAuth sign-in, look for a server that supports it. If you want an assistant that only reads mail, set allowed_mutations to [] and leave allowed_recipients empty: by default every kind of change is allowed.
list_available_accountslist_allowed_recipientslist_allowed_senderslist_email_tagslist_emails_metadataget_emails_contentlist_mailboxessend_emailforward_emailsave_draftsave_to_mailboxcreate_mailboxset_email_flagsmark_emails_as_readset_email_tagsmove_emailsarchive_emailsdelete_emailsget_attachment_contentdownload_attachmentemail_command