Skip to main content
Glama
dherenj84

My Mail MCP

by dherenj84

My Mail MCP

My Mail MCP — email tools for AI agents

A self-hosted, provider-configurable email MCP server. Yahoo is the initial target. Built with FastMCP 4.1.3, pinned in pyproject.toml and uv.lock. One stateless Python container; no database or application action quota.

Status: mailbox management preview

Implemented: authenticated Streamable HTTP MCP, health endpoint, folder listing, paginated text search, reading, flag updates, moving/copying, archiving, trashing/restoring, permanent deletion, and creating/renaming/deleting user folders. Message references include folder, UID and UIDVALIDITY to reject stale identifiers. Attachment metadata is included; attachment downloads are not implemented yet. Search pagination bounds the returned data, but currently searches all matching UIDs.

Planned: drafts, attachment transfer and GitHub Actions deployment configuration. OAuth (Auth0 JWT validation) is implemented; see Auth0 setup. Cloud Build deployment is configured. Sending is implemented but untested against live Yahoo SMTP. Yahoo reading has been manually verified locally through VS Code Copilot. Mutation tools have automated coverage but have not been tested against a live Yahoo mailbox; other providers and Cloud Run remain unverified.

Related MCP server: Mail-MCP

Tools

Tool

Inputs

Behavior

list_folders

None

Lists folders and IMAP flags

search_messages

folder, query, limit, offset

Text search; empty query lists messages

read_message

folder, uid, uid_validity

Reads body and attachment metadata

update_flags

folder, uids, uid_validity, optional read, starred, answered

Sets chosen flags without replacing others

move_messages

folder, uids, uid_validity, destination

Moves to an existing folder

copy_messages

folder, uids, uid_validity, destination

Copies while retaining originals

archive_messages

folder, uids, uid_validity

Moves to resolved Archive

trash_messages

folder, uids, uid_validity

Moves to resolved Trash

restore_messages

folder, uids, uid_validity, optional destination

Moves out of Trash; default destination INBOX

permanently_delete_messages

folder, uids, uid_validity

Irreversibly deletes specified messages

create_folder

folder

Creates a user folder

rename_folder

folder, new_name, uid_validity

Renames a user folder without children

delete_folder

folder, uid_validity

Deletes an empty user folder without children

send_message

to, subject, body, optional cc, bcc

Sends a plain-text email and saves a copy to Sent

reply_message

folder, uid, uid_validity, body, optional reply_all, cc

Threaded reply quoting the original

forward_message

folder, uid, uid_validity, to, optional body, cc

Inline forward; attachments are listed, not sent

Sending is irreversible. Tools advertise destructiveHint so clients can ask for confirmation; the server also limits messages to 20 recipients and rejects header injection. Set MAIL_SENT_FOLDER if the Sent folder is not detected. The sender is always the configured mailbox.

Search returns newest UID first (mailbox arrival order, not necessarily the message's Date header). Search totals reflect the initial UID snapshot; messages removed before fetching are omitted and reported in unavailable_uids. limit is 1–100; use next_offset for pagination. Pass the folder, UID and UIDVALIDITY from search to read a message. Reads reject messages over 10 MiB and truncate bodies at 100,000 characters, with body_truncated indicating truncation. Reading leaves flags unchanged.

Modifying a mailbox

Message modifications accept 1–100 distinct positive integer UIDs from the same folder. Always use a fresh search result's uid_validity. Missing UIDs, stale folder versions, invalid destinations, and read-only folders reject the request before changing messages. Concurrent mailbox changes can still occur after these checks.

For example, after searching INBOX, call update_flags with the returned folder, UIDVALIDITY, uids: [<uid>], and read: true or starred: true. Omitted flag fields stay unchanged. To undo a flag change, explicitly pass false.

Archive and Trash are resolved through IMAP special-use flags and standard-name fallbacks. Set MAIL_ARCHIVE_FOLDER or MAIL_TRASH_FOLDER if discovery is ambiguous or fails. These folders must already exist; they are not created automatically. Trash is recoverable until the provider purges it. Restore uses current UIDs from Trash and defaults to INBOX; the original folder is not recorded.

Moving changes UIDs. Search the destination again before operating on moved or copied messages. The result returns destination and refresh_destination: true; it deliberately does not reuse source UIDs as destination references.

Moves prefer atomic IMAP MOVE. Servers without MOVE must support UIDPLUS for the copy/delete/UID EXPUNGE fallback. Permanent deletion always requires UIDPLUS and expunges only the requested UIDs, never unrelated deleted messages. Unsupported servers fail before writing. Multi-command operations are not transactions: a failed move may leave a copy in the destination, and a failed delete may leave messages marked for deletion. Refresh both folders before retrying; automatic retries can create duplicates. Copies are also not safe to retry automatically.

Folder renaming and deletion require UIDVALIDITY from a search of the folder (including empty search results). Detected/configured system folders and INBOX are protected. Folders with children must be handled from the leaves upward. Delete checks that a folder is empty first; concurrent deliveries are not locked. Folder hierarchy delimiters are returned by list_folders.

Local development

Install uv first. The project defaults to Python 3.12; uv can download it if needed:

uv sync --locked
cp .env.example .env
# Edit .env with your own mailbox and a random MCP token of at least 32 characters.
uv run --locked my-mail-mcp

uv manages .venv automatically; shell activation is unnecessary. Development dependencies are included by default. Commit uv.lock to keep installations reproducible. To run checks:

uv run --locked pytest -q
uv run --locked ruff check src tests

Add dependencies with uv add <package> or uv add --dev <package>. Use uv lock --upgrade to intentionally update locked versions.

Never commit .env. Generate a token with openssl rand -hex 32. Create a dedicated Yahoo app password in Yahoo Account Security. The server refuses to start without mailbox credentials and an MCP token, or when configured with the known placeholder credentials. Replace the GCP placeholders before deploying. Clients connect to /mcp/ with Authorization: Bearer <MCP_AUTH_TOKEN>. GET /health checks the process, without connecting to the mailbox. Bearer authentication is an initial integration option; browser-based connector OAuth is available for browser-based connectors such as ChatGPT; see Auth0 setup.

VS Code Copilot setup

Start the server separately, then create .vscode/mcp.json:

{
  "inputs": [
    {
      "id": "mail-mcp-token",
      "type": "promptString",
      "description": "MCP_AUTH_TOKEN from your local .env",
      "password": true
    }
  ],
  "servers": {
    "my-mail-mcp": {
      "type": "http",
      "url": "http://localhost:8080/mcp/",
      "headers": {"Authorization": "Bearer ${input:mail-mcp-token}"}
    }
  }
}

Enter the same token used by the server when prompted. Client configuration formats vary: the example uses VS Code's servers format and interactive inputs. VS Code also supports portable workspace-root .mcp.json configurations with mcpServers, but those do not support VS Code input variables. Local credential-bearing configurations are ignored by Git. Ask Copilot to list folders, then read your latest email.

Configuration

Variable

Default

Purpose

MAIL_USERNAME

Required

Mailbox login

MAIL_PASSWORD

Required

App password; keep secret

MCP_AUTH_TOKEN

Required, 32+ characters

Client bearer credential

MAIL_IMAP_HOST

imap.mail.yahoo.com

IMAP hostname

MAIL_IMAP_PORT

993

IMAP port, implicit TLS required

MAIL_ARCHIVE_FOLDER

Auto-detected

Optional exact Archive folder override

MAIL_TRASH_FOLDER

Auto-detected

Optional exact Trash folder override

AUTH_ISSUER_URL

Unset

Auth0 issuer (with trailing slash); enables OAuth with PUBLIC_BASE_URL

PUBLIC_BASE_URL

Unset

Public HTTPS base URL; tokens must have audience <base>/mcp

PORT

8080

HTTP listening port

MAIL_SMTP_HOST

smtp.mail.yahoo.com

Used for sending

MAIL_SMTP_PORT

465

Used for sending

MAIL_SMTP_STARTTLS

false

Used for sending

Environment variables take precedence over .env. IMAP certificate and hostname verification remain enabled, using system trust plus Certifi's CA bundle. The server binds to all interfaces; use localhost for local clients and HTTPS when exposing it remotely. The bearer credential grants access to this mailbox.

Container / Cloud Run

docker build -t my-mail-mcp:local .
docker run --rm --name my-mail-mcp-local --env-file .env -p 127.0.0.1:8080:8080 my-mail-mcp:local

Cloud Run supplies PORT. Configure mailbox settings as environment variables and MAIL_PASSWORD / MCP_AUTH_TOKEN as Secret Manager references. The service account needs access only to those secrets. Cloud Run IAM and the application's bearer authentication are separate layers; client access must be configured accordingly. cloudbuild.yaml runs checks, builds and pushes to Artifact Registry, then deploys Cloud Run with Secret Manager references. Follow the deployment guide for one-time setup and GitHub triggers. Start with the deployment guide, then enable OAuth with Auth0 setup if you want ChatGPT access.

OAuth for ChatGPT via Auth0 is documented in Auth0 setup. The static bearer token keeps working alongside it.

One mailbox per deployment. Change IMAP settings for another compatible provider; providers requiring OAuth need an additional authentication implementation. Yahoo/provider limits and cloud hosting charges still apply.

Verification and release scope

Tests use mocked mailboxes and do not need Yahoo credentials. CI checks Python 3.11/3.12, lint, formatting, package build, and Docker build. GitHub CI does not deploy or publish. The Cloud Build configuration deploys when explicitly submitted or attached to a configured trigger. Local Docker validation passed on Linux ARM64: all 68 tests in the builder container, non-root runtime, HTTP health/authentication, discovery of the tools, and live Yahoo folder listing. No live mail mutations were tested. Cloud Run runtime validation remains pending.

This preview exposes read and write operations. Mutation tools advertise their write/destructive behavior to MCP clients. Permanent deletion is irreversible; use Trash for recoverable deletion. Email content is untrusted input and must never be treated as instructions authorizing mailbox changes. No message database is maintained; content is returned to your MCP client, which controls its own retention.

License

MIT.

Related MCP Connectors

  • Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.

    https://www.primitive.dev/mcp
  • Email inboxes for AI agents: send, receive, reply, search, and manage threaded email over MCP.

    https://mcp.agentmail.to/mcp
  • Your agent needs a mailbox of its own — to receive, thread, draft and send, with attachments, without borrowing your personal inbox or your company's SMTP. **What you can ask for** • "Create an inbox for this agent and tell me its address." • "Read the new messages in this thread and draft a reply." • "Send this message with the attachment and wait for the response." • "Search this inbox for everything from that domain." • "Show delivery metrics and the events on this inbox." **How to use it** Point any MCP client at https://mcp.aisa.one/mail/mcp and sign in with OAuth — there is no key to create or paste. 49 tools: create and delete inboxes, list and read messages, raw message bodies, attachments, threads, drafts and draft attachments, send and reply, message search, inbox events, metrics, and list entries — reads and writes. **Why this rather than the source** A real inbox an agent owns, rather than an SMTP credential it borrows from a human. **It is also a door to the rest** The same login reaches 26 sources and 580+ operations. Find the contact elsewhere in the catalogue, then write to them from here — without adding a second server. **What it costs** Finding and inspecting an operation is free. Running one is billed per call at API prices, with no seat and no monthly minimum, and every call takes max_price_usd so an agent cannot overspend by accident. **Where else it reaches** https://mcp.aisa.one/sales/mcp finds the person to write to.

  • Email for AI agents: read, search and send from your Gmail, Outlook, Yahoo, iCloud or IMAP inbox.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    An 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.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables secure mailbox access and email management via IMAP/SMTP, with tools for reading, searching, organizing, sending, and deleting emails, designed for local use and compatible with MCP clients like ChatGPT.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Connects any IMAP/SMTP mailbox to AI agents via MCP, enabling email read, search, send, reply, and management through natural language.
    7 npm
    MIT
  • F
    license
    B
    quality
    B
    maintenance
    Enables external AI agents to read, send, and manage email over IMAP/SMTP via MCP, including inbox listing, search, drafts, scheduled/batch sending, and operations like reply, archive, and labels.
    30
    3
    -