MCP Hub
Back to servers

Email MCP Server

Enables email management for a single mailbox via IMAP and SMTP protocols. Supports reading, searching, and sending emails with threading support through stdio or HTTP transports.

glama
Updated
Apr 8, 2026

email-mcp

Small personal MCP server for a single mailbox over IMAP + SMTP.

It is aimed at a private setup first:

  • one mailbox
  • credentials supplied through environment variables
  • read mail over IMAP
  • send mail over SMTP
  • works well with Yandex Mail defaults, but can be pointed at any IMAP/SMTP provider

What I changed

This repo originally worked only in stdio mode. That is fine for local MCP clients, but ChatGPT web integration needs an HTTP MCP endpoint. The server now supports:

  • stdio for local/dev use
  • streamable-http for ChatGPT web app use
  • sse for compatibility

I also fixed a mail-threading issue:

  • the old reply_to parameter only set the Reply-To header
  • real replies should usually use In-Reply-To and References
  • read_email now returns those headers so they can be passed back into send_email

And I improved read_email output by returning:

  • decoded headers
  • attachment metadata
  • message threading headers

Attachment support

This version supports both reading and sending attachments.

Download an attachment from a received email

  1. Call read_email(uid=..., folder="INBOX")
  2. Inspect the attachments list
  3. Use attachment_index with get_attachment(...)

get_attachment(...) returns:

  • filename
  • content_type
  • size_bytes
  • content_base64

Send attachments in outgoing email

send_email(...) accepts an attachments list.

Each item can be one of:

{"path": "/path/to/file.pdf"}
{"filename": "note.txt", "content_text": "hello from MCP"}
{"filename": "report.pdf", "content_base64": "JVBERi0x...", "content_type": "application/pdf"}

Sent folder behavior

After SMTP send succeeds, the same MIME message is appended to your IMAP sent folder.

By default that folder name is:

Sent

You can override it if your mailbox uses a different IMAP folder name:

export SENT_FOLDER="Sent"
# or
export MAILBOX_SENT_FOLDER="Sent"

If sent mail does not show up, first run list_folders() and use the exact folder name returned by your mailbox.

Files

  • server.py — MCP tool definitions and transport startup
  • mail_ops.py — IMAP/SMTP implementation
  • requirements.txt — Python dependencies

Environment

Required:

export MAILBOX_EMAIL="you@example.com"
export MAILBOX_PASSWORD="your-app-password"

Optional provider settings:

export IMAP_HOST="imap.yandex.com"
export IMAP_PORT="993"
export SMTP_HOST="smtp.yandex.com"
export SMTP_PORT="465"

Optional sent-folder setting:

export SENT_FOLDER="Sent"

Optional MCP server settings:

export MCP_TRANSPORT="stdio"
export MCP_HOST="0.0.0.0"
export MCP_PORT="8000"

Aliases also supported for convenience:

export YANDEX_EMAIL="you@yandex.ru"
export YANDEX_APP_PASSWORD="..."

Install

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Run locally with stdio

python server.py

This is the right mode for local MCP clients that spawn the process directly.

Run for ChatGPT web app

ChatGPT web needs a public HTTPS MCP endpoint. Start the server in HTTP mode:

python server.py --transport streamable-http --host 0.0.0.0 --port 8000

Then expose that port through a public HTTPS tunnel or reverse proxy, and register the resulting MCP URL in ChatGPT.

Tools exposed

list_folders()

Lists available IMAP folders.

search_emails(folder="INBOX", text=None, unseen_only=False, since_date=None, limit=30)

Searches messages by IMAP criteria.

Returns items like:

  • uid
  • subject
  • from
  • to
  • date
  • flags
  • size_bytes

read_email(uid, folder="INBOX")

Fetches a full message without marking it read.

Returns:

  • decoded headers
  • message_id
  • in_reply_to
  • references
  • attachments
  • body_plain
  • body_html

get_attachment(uid, folder="INBOX", attachment_index=None, filename=None)

Fetches a single attachment and returns it as base64.

send_email(...)

Sends a message through SMTP.

Important parameters:

  • reply_to_header — sets the Reply-To header
  • in_reply_to — threading header
  • references — threading header
  • attachments — optional list of attachment specs

For a real reply, use in_reply_to and usually also references.

Yandex notes

Typical Yandex defaults are:

  • IMAP: imap.yandex.com:993 over SSL/TLS
  • SMTP: smtp.yandex.com:465 over SSL/TLS

Use an app password, not your main account password.

Next sensible upgrades

  • inline/embedded image attachments
  • attachment size limits and streaming
  • move/archive/delete tools with confirmation
  • OAuth instead of env-based credentials
  • tests with mocked IMAP/SMTP backends

Reviews

No reviews yet

Sign in to write a review