Skip to main content
Glama
LeeFlannery

imap-mcp

by LeeFlannery

imap-mcp

All your mailboxes, one MCP server, read-only.

Point it at any number of IMAP accounts (Gmail, Fastmail, iCloud, Migadu, self-hosted, anything that speaks IMAP) and your MCP client can list, search, and read across every one of them in a single call. Ask "what's unread across all my accounts?" or "find the invoice from Hetzner" and get answers that span providers, not one inbox at a time.

Strictly read-only. No send, no delete, no flag changes, no folder moves. Every fetch uses BODY.PEEK, so reading a message never marks it as read. Your mailboxes look exactly the same after a session as before it.

No secrets on disk. The config file names an environment variable per account; passwords only ever exist in the server process environment. Bring your own secret manager, or just export a variable.

Why IMAP

Assistant mail integrations usually connect one Gmail or one Outlook account. IMAP is the protocol nearly every provider already speaks, so one small server covers your whole mail footprint with a single read-only code path, no OAuth apps to register, and nothing granted write access.

Related MCP server: IMAP Mini MCP

Quickstart

Requires Python 3.12+ and uv.

git clone https://github.com/LeeFlannery/imap-mcp
cd imap-mcp
cp accounts.example.toml accounts.toml
$EDITOR accounts.toml           # add your accounts
export PERSONAL_IMAP_PASSWORD='...'
uv run imap-mcp                 # starts the MCP server on stdio

That's it. Register it with your MCP client (below) and start asking about your mail.

Configure accounts

accounts.toml is gitignored and holds no secrets:

[[account]]
key = "personal"                        # short id used in tool calls
label = "you@example.com (Fastmail)"    # optional, defaults to email
email = "you@example.com"               # IMAP login
host = "imap.fastmail.com"
port = 993                              # optional, defaults to 993
password_env = "PERSONAL_IMAP_PASSWORD" # env var holding the password
enabled = true                          # optional, defaults to true

Add one [[account]] block per mailbox. enabled = false keeps an account listed but never logs into it. Set IMAP_MCP_ACCOUNTS=/path/to/accounts.toml to keep the config outside the repo.

Provider cheat sheet

Provider

Host

Password

Gmail / Google Workspace

imap.gmail.com

App password (requires 2FA; the spaces Google shows are stripped automatically)

Fastmail

imap.fastmail.com

App password

iCloud

imap.mail.me.com

App-specific password

Yahoo

imap.mail.yahoo.com

App password

Migadu

imap.migadu.com

Mailbox password

Outlook.com / Microsoft 365

not supported

Microsoft has retired IMAP basic auth; OAuth is not implemented here

All standard providers use port 993 (implicit TLS), the default.

Passwords

Each account's password_env names an environment variable that must be set when the server runs. Any of these work:

# plain export in the shell that launches your MCP client
export PERSONAL_IMAP_PASSWORD='...'

# direnv, sops, pass, whatever you already use

# 1Password: put op:// references in an env file and wrap the command
op run --env-file=op.env -- uv run imap-mcp

Register with an MCP client

Claude Code

claude mcp add imap -- uv run --directory /path/to/imap-mcp imap-mcp

Or in .mcp.json / your user MCP config:

{
  "mcpServers": {
    "imap": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/imap-mcp", "imap-mcp"]
    }
  }
}

Claude Desktop and other clients

Same command and args in the client's MCP server config (claude_desktop_config.json, etc.). Any stdio MCP client works.

Either way, the password env vars must be visible to the spawned process: export them in the environment the client launches from, or wrap the command in your secret injector, e.g. "command": "op", "args": ["run", "--env-file=/path/to/op.env", "--", "uv", "run", ...].

Tools

list_accounts() configured accounts with live status. Run this first; it tells you which mailboxes are queryable and what to pass as account.

{"account": "personal", "email": "you@example.com", "enabled": true, "status": "ok"}

list_emails(account?, since?, unread_only?, limit?) recent mail, newest first. Omit account to merge all enabled accounts into one timeline.

search_emails(query, account?, since?, limit?) free-text search over sender, subject, and body. Also cross-account unless you name one.

Both return compact rows:

{"account": "personal", "id": "4711", "from": "billing@hetzner.com",
 "subject": "Invoice 2026-07", "date": "2026-07-03T09:12:44+00:00",
 "unread": true, "snippet": "Your invoice for July..."}

get_email(account, id) one full message by the id from a row, with plain-text body preferred over HTML. Reading it does not mark it read.

Dates are ISO (YYYY-MM-DD); since filters everywhere; limit applies per account when merging. If one account is down, its error comes back as a row and the other accounts still answer.

Troubleshooting

  • status: "no-credential": the account's password_env variable is not set in the server's environment. Remember the server inherits its env from whatever launched it (your MCP client), not from your interactive shell.

  • status: "unreachable: MailboxLoginError" on Gmail/iCloud/Yahoo: you're using the account password; these providers require an app password (see cheat sheet).

  • Config not found: the server looks for accounts.toml next to pyproject.toml, or wherever IMAP_MCP_ACCOUNTS points.

Development

uv run pytest

31 tests, no network: the IMAP layer is faked. The suite locks in the read-only contract (mark_seen=False on every fetch), per-account error isolation, and config handling.

License

MIT

Install Server
A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    -
    quality
    D
    maintenance
    A read-only MCP server that enables users to interact with the Gmail API to search messages, retrieve threads, and download attachments. It supports standard Gmail query operators and requires OAuth authentication for secure read-only access to mailbox data.
    Last updated
    1
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    A lightweight MCP server for interacting with IMAP email accounts to read messages, manage folders, and compose draft replies. It supports standard providers and local bridges, providing tools for searching, fetching attachments, and organizing mailboxes without the ability to send or delete emails.
    Last updated
    19
    6
  • A
    license
    -
    quality
    C
    maintenance
    A unified MCP server for email access across Gmail, Outlook, iCloud, and generic IMAP providers, enabling search, send, organize, and batch operations.
    Last updated
    271
    17
    MIT
  • A
    license
    -
    quality
    B
    maintenance
    Read-only MCP server for Gmail that enables searching threads, reading messages, and listing labels without any write access.
    Last updated
    202
    MIT

View all related MCP servers

Related MCP Connectors

  • Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.

  • Read-only MCP server for ClassQuill, a tutoring-business-management platform.

  • Federated commerce search across independent WooCommerce merchants. Keyless, read-only MCP server.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/LeeFlannery/imap-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server