Skip to main content
Glama
My Mail MCP

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

With more than one account configured, every tool except list_accounts requires an account id (see Multiple mailboxes); it is optional with one account.

Tool

Inputs

Behavior

list_folders

optional account

Lists folders and IMAP flags

list_accounts

None

Lists configured account ids and addresses

search_messages

folder, query, limit, offset, optional since, before, from_address, unread_only

Filtered search returning uid, subject, from, date and flags; 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 sent_folder on the account if the Sent folder is not detected. The sender is always the configured mailbox.

since (inclusive) and before (exclusive) take YYYY-MM-DD and match whole days in the mail server's time zone, so "today" is since=<today>. 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 archive_folder or trash_folder on the account 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_ACCOUNTS

Required

JSON list of mailboxes; per-mailbox host, port and folder settings are keys in each entry (see below)

MCP_AUTH_TOKEN

Required, 32+ characters

Client bearer credential

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

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.

Multiple mailboxes

Mailboxes are configured with MAIL_ACCOUNTS, a JSON list with one entry per mailbox. In .env, put it inside single quotes (multi-line is fine). On Cloud Run it is the contents of a Secret Manager secret (see the deployment guide).

Single Yahoo mailbox (hosts default to Yahoo, so only three fields are needed):

MAIL_ACCOUNTS='[{"id":"yahoo","username":"you@yahoo.com","password":"yahoo-app-password"}]'

Two Yahoo mailboxes:

MAIL_ACCOUNTS='[
 {"id":"personal","username":"you@yahoo.com","password":"app-password-1"},
 {"id":"family","username":"family@yahoo.com","password":"app-password-2"}
]'

Yahoo and Gmail (non-Yahoo providers override the hosts):

MAIL_ACCOUNTS='[
 {"id":"yahoo","username":"you@yahoo.com","password":"yahoo-app-password"},
 {"id":"gmail","username":"you@gmail.com","password":"gmail-app-password",
  "imap_host":"imap.gmail.com","smtp_host":"smtp.gmail.com","save_sent_copy":false}
]'

To add a mailbox, append an entry with a unique id and restart the server.

Required per account: id (letters, digits, _, ., -), username, password. Optional: imap_host, imap_port, smtp_host, smtp_port, smtp_starttls, archive_folder, trash_folder, sent_folder (defaults match Yahoo) and save_sent_copy (default true; set false for Gmail, whose SMTP files sent mail itself).

  • Call list_accounts, then pass account to every other tool. Without it the call is rejected, so mail is never touched in the wrong mailbox. UIDs are per account. With one account, account can be omitted. Example, today's unread mail in Gmail: search_messages with {"account": "gmail", "since": "2026-10-26", "unread_only": true}.

  • With several accounts, use the folder names from list_folders for that account; they differ by provider (Inbox on Yahoo, INBOX and [Gmail]/Trash on Gmail).

  • A bad entry (duplicate or invalid id, placeholder password) stops the server at startup.

  • At most 3 simultaneous IMAP connections per account per server instance; extra requests wait up to a minute. The cap is not shared across instances, so Cloud Run scale-out (up to _MAX_INSTANCES, default 3) can reach that many times 3 connections. Lower _MAX_INSTANCES if your provider rejects logins during scale-out.

  • Logs show the account id (not the address): imap account=gmail op=search_messages ....

  • Moving or copying between accounts is not supported.

  • Gmail needs 2-Step Verification and an app password. Its folders are labels ([Gmail]/All Mail), so archive behaves differently from Yahoo; Gmail has not been tested beyond reading, searching and folder listing.

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. Mount MAIL_ACCOUNTS and MCP_AUTH_TOKEN as Secret Manager references (a single mailbox is a one-entry MAIL_ACCOUNTS list). 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.

A deployment can serve several mailboxes (see below). 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.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    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.

      https://mailera.app/api/mcp

    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.
      13 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
      -