mail-mcp

mail-mcp

Enables AI coding agents to search, read, and manage drafts across Gmail and Outlook mailboxes via MCP.

Category
Visit Server

README

mail-mcp

A local MCP server that lets AI coding agents (Claude Code and OpenAI Codex CLI) access your mailboxes: search, read messages/threads, read & download attachments, and create drafts — across multiple Gmail and personal Outlook accounts, routed by nickname.

Current capability: read-only + drafts. It never sends, deletes, or relabels mail. Sending/organizing are declared in the provider contract but gated off; enabling them later is a config change, not a rewrite (see Extending).

How safety is enforced

  • Outlook (Graph): we request Mail.Read + Mail.ReadWrite but not Mail.Send, so sending is impossible at the token level.
  • Gmail: there is no scope that grants drafts without also granting send (gmail.compose covers both). So for Gmail, "no send" is enforced at the application layer — no send tool is exposed and drafts.send/messages.send are never called. Keep this in mind before granting the send capability.

Install

Requires Python ≥ 3.11.

uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python -e ".[dev]"

Configure

.venv/bin/mail-mcp init            # creates ~/.config/mail-mcp/{config.toml,secrets,tokens,downloads}

Edit ~/.config/mail-mcp/config.toml (see config.example.toml). Each mailbox is one [accounts.<nickname>] block. Everything lives under $MAIL_MCP_HOME (default ~/.config/mail-mcp); set MAIL_MCP_HOME to relocate it.

Gmail OAuth (per Google account)

  1. Google Cloud Console → new project → enable the Gmail API.
  2. OAuth consent screen → User type External → add each Gmail address as a Test user (or publish to Production to avoid the 7-day refresh-token expiry in Testing mode).
  3. Credentials → Create OAuth client ID → Desktop app → download the JSON → save as ~/.config/mail-mcp/secrets/gmail_client_secret.json (the same client can serve multiple Gmail accounts).
  4. .venv/bin/mail-mcp auth gmail-personal

University / Workspace accounts (e.g. @g.ecc.u-tokyo.ac.jp): the admin may restrict third-party API access. If login fails with Error 400: admin_policy_enforced, your self-made client is blocked at the org level — Testing mode does not bypass this; only the Workspace admin can allowlist the client ID. Test a personal @gmail.com account first to confirm your setup, then try the university one.

Outlook OAuth (personal account)

  1. Azure Portal → Microsoft Entra ID → App registrations → New. Supported account types: Personal Microsoft accounts only.
  2. Authentication → Add platform Mobile and desktop applications → redirect http://localhost → mark as a public client.
  3. API permissions → Microsoft Graph → Delegated → add Mail.Read, Mail.ReadWrite, offline_access. Do not add Mail.Send.
  4. Put the Application (client) ID into the outlook block's client_id.
  5. .venv/bin/mail-mcp auth outlook

Check status any time: .venv/bin/mail-mcp accounts

Register with your AI client

Both launch the server over stdio. Use an absolute interpreter path and set MAIL_MCP_HOME explicitly so token discovery never depends on cwd or env forwarding.

Claude Code (user scope — available in every project):

claude mcp add --scope user mail \
  --env MAIL_MCP_HOME=/Users/<you>/.config/mail-mcp \
  -- /path/to/mail_mcp/.venv/bin/python -m mail_mcp

Codex CLI — add to ~/.codex/config.toml (Codex does not forward parent env by default, hence env_vars):

[mcp_servers.mail]
command = "/path/to/mail_mcp/.venv/bin/python"
args = ["-m", "mail_mcp"]
env_vars = ["HOME", "PATH"]

[mcp_servers.mail.env]
MAIL_MCP_HOME = "/Users/<you>/.config/mail-mcp"

Verify: claude mcp list (shows mail ✓ Connected) / Codex /mcp.

Tools

Tool Purpose
list_accounts list mailboxes, provider, capabilities, auth status
search_messages(account, query, limit=20) search (Gmail operators for Gmail; free-text $search for Outlook)
read_message(account, message_id, format="text") headers + body (text/html/full) + attachment list
read_thread(account, thread_id, format="text") all messages in a thread/conversation
list_attachments(account, message_id) attachment id/name/mime/size
download_attachment(account, message_id, attachment_id, dest_dir=None, include_base64=False) save to disk, return path
create_draft(account, to, subject, body, cc, bcc, reply_to_message_id, body_is_html, attachments) create an unsent draft

Extending

  • A new mailbox of an existing type → add an [accounts.<nick>] block + mail-mcp auth <nick>. No code.
  • A new mailbox type (e.g. IMAP) → implement MailProvider (src/mail_mcp/providers/base.py) and register it in providers/registry.py. The tool surface is unchanged.
  • Enable sending → add "send" to an account's capabilities. The send_message tool then registers automatically. For Graph, also add Mail.Send and re-run mail-mcp auth; Gmail needs no scope change. (Re-read the Gmail safety note first.)

Development

.venv/bin/pytest        # unit tests (no network)
.venv/bin/ruff check .
.venv/bin/mypy src

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured