imap-mcp
Connects to Gmail over IMAP using an app password to search and read mail without changing read/unread state. When enabled, it can also create reply drafts and request sending, with Gmail-specific sent-copy handling.
Connects to iCloud Mail over IMAP using an app-specific password to search and read messages without altering message flags. Optional draft and send workflows can be enabled per mailbox.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
imap-mcp: your mail for Claude and other AI clients
A small, self-hosted MCP server that reads several IMAP mailboxes the way an email client does and gives Claude (and other AI clients you allow) search-and-read access to them as a custom connector. Reading never changes your mail. Where you switch it on, a client can also put a reply draft into a mailbox's Drafts folder, and ask to send one of its drafts; nothing is sent until you read the frozen message and press Send on the approval page yourself.
You run it on your own server behind HTTPS, add your mailboxes, then add one URL in Claude. Mailbox passwords stay on your server, encrypted.
claude.ai ──HTTPS + OAuth──▶ Caddy / Cloudflare Tunnel ──▶ imap-mcp (Docker) ──IMAPS / SMTPS──▶ your mail serversA personal project, shared as is. It is used by its author every day, but there is no promise of support, fixes or compatibility. Read the security model before you point it at real mail, and report security problems privately (see SECURITY.md).
中文简介: imap-mcp 是一个自己部署的 MCP 服务器,让 Claude 等 AI 客户端以只读方式搜索、阅读你的多个 IMAP 邮箱(读信绝不改变已读/未读状态)。可以按邮箱打开“回复草稿”;也可以打开“发送”,但每一封都要你在确认页上用 主人密码 + TOTP 看过并放行才会发出。支持多个 AI 客户端各自的邮箱白名单和权限,所有写操作都记审计日志。 对中文、日文邮件(GBK、Big5、Shift_JIS、ISO-2022-JP 等编码和中文文件夹名)做了专门处理。个人项目,不承诺支持。
Core guarantees
Reading never changes a message. Folders are opened only with
EXAMINE, bodies are read only withBODY.PEEK[...], and every IMAP command passes an allowlist before it reaches the socket. Unread mail stays unread. The tests compare the flags of every message before and after every operation.Drafts and sending are separate. Reply drafts are off unless you switch them on, per server and per mailbox, for a client you granted
mail:draft. Sending is a separate switch per mailbox that needs SMTP settings of its own. Each path uses its own IMAP connection with its own, narrower allowlist.Every message sent is approved by a human. A client can only ask to send a draft it wrote. The server freezes the exact bytes, pushes you a link, and sends only after you sign in (owner password + TOTP), read the whole message on
/approve/<id>and press Send. Requests expire after 30 minutes; pressing twice sends once; a draft changed after the request is never sent.Per-client mailbox allowlists. Several AI clients can share one server, each with its own credentials, scopes (
mail:read,mail:draft) and list of mailboxes it may see. Credentials are revocable one by one.An append-only audit log. Every draft, send request, approval, rejection, SMTP result and admin change is recorded (SQLite plus an append-only JSONL file). Bodies are never stored, only their SHA-256; subjects and recipients are blanked after 90 days by default.
Related MCP server: mcp-mail-bridge
What a client can do with it
Tool | What it does |
| The mailboxes this client may see: id, name, address |
| One mailbox's folders, with Chinese and Japanese names decoded (已发送, 送信済み), optional counts |
| Search one, several or all mailboxes by sender, recipient, subject, text, date range, unread; newest first |
| Headers, plain-text body (HTML converted), attachment list |
| Text out of PDF, Word, Excel, PowerPoint, text, CSV, HTML and .eml attachments; images up to 3 MB as images |
| Recent unread, unanswered mail that looks urgent, with a score and the reasons |
| A whole conversation across mailboxes, oldest first |
| People by part of a name or address, with how much mail went each way (needs the local archive) |
| How fresh the local archive is, per mailbox and folder (needs the local archive) |
| Only where drafts are on and the client holds |
| The reply drafts this server wrote |
| The audit log of drafts and send requests |
| Only where sending is on: ask to send one of this client's drafts. Freezes it and notifies you; sends nothing by itself |
| Where this client's send requests stand (waiting, sent, failed, unknown) |
| Withdraw a send request that hasn't been sent |
Mail in GB2312/GBK/GB18030, Big5, Shift_JIS, ISO-2022-JP and UTF-8 is decoded, including the usual mislabelled cases (GBK characters inside "gb2312", raw 8-bit GBK subjects, encoded words in quotes).
Quick start (Docker)
You need a server with Docker and the compose plugin, and a (sub)domain pointing at it, for example
mail-mcp.example.com. Full guide, including roles, TOTP, sending, upgrades and backups:
docs/DEPLOY.md.
git clone https://github.com/xercn/imap-mcp.git && cd imap-mcp
cp .env.example .env
docker compose build
docker compose run --rm imap-mcp gen-secret-key # -> IMAP_MCP_SECRET_KEY in .env (keep a copy)
docker compose run --rm imap-mcp hash-password # -> IMAP_MCP_ADMIN_PASSWORD_HASH in .env
# set IMAP_MCP_PUBLIC_URL=https://mail-mcp.example.com in .env
sudo chown -R 10001 config # the container runs as uid 10001 and writes config/
docker compose run --rm imap-mcp account add --preset gmail # asks for address, id, password; tests a read-only login
docker compose run --rm imap-mcp config check
# put your domain in deploy/Caddyfile, then:
docker compose --profile caddy up -d
curl https://mail-mcp.example.com/healthz # -> okThen in claude.ai: Customize → Connectors → Add custom connector, URL https://mail-mcp.example.com/mcp, keep
OAuth sign-in (register automatically, no client ID or secret), Connect, and sign in with the owner password on the
page that opens. Claude Code:
claude mcp add --transport http mail https://mail-mcp.example.com/mcpThe reading tools are marked read-only, so you can set them to "always allow".
Configuration
Everything about your mailboxes and clients lives in the config/ folder and in .env; nothing is in the code.
Changes to the TOML files apply to the next request, without a restart.
File | What it holds |
| Public URL, owner password hash, secret key, roles, global switches ( |
| One |
| AI clients: auth ( |
| Urgent-mail rules and VIP senders ( |
No file holds a password or token. Mailbox and SMTP passwords are encrypted with IMAP_MCP_SECRET_KEY in the data
volume (or come from password_env / password_file); tokens and sessions are stored only as SHA-256 hashes.
Common commands (run as docker compose run --rm imap-mcp ..., or docker compose exec imap-mcp imap-mcp ...):
imap-mcp presets # known providers
imap-mcp account add [--preset NAME] | list | test --all | set-password ID | edit ID --set key=value
imap-mcp account drafts ID on|off # reply drafts for one mailbox (no restart)
imap-mcp account smtp ID --sent-copy append # SMTP settings (asks for the password; tests the login, sends nothing)
imap-mcp account send ID on|off # sending for one mailbox
imap-mcp client list | add NAME | grant NAME mail:draft | accounts NAME ID... | token NAME | revoke NAME
imap-mcp vip add boss@example.com @client.example
imap-mcp admin totp-setup # binds TOTP; turns on /admin
imap-mcp send list | send show s_... # send requests (approve them on the web page)
imap-mcp config check # checks every file, offlineThe /admin page (after admin totp-setup) does the same for mailboxes, clients, SMTP and the send switch, shows
connection status and the audit log, and lists send requests.
Providers (presets only fill in server, port and security; check them against your provider):
Gmail: IMAP with an app password. Add
exclude_folders = ["[Gmail]/All Mail"]. For sending,sent_copy = "server"(Gmail files sent mail itself).iCloud:
imap.mail.me.com, an app-specific password. Some servers answer EXAMINE as READ-WRITE; the command guard still allows onlyBODY.PEEK.QQ / 163 / 126: the authorization code from the web mail settings; 163 and 126 need
send_id = true.Alibaba enterprise mail (阿里企业邮箱): the administrator must allow IMAP for third-party clients. See known limitations. For sending,
sent_copy = "append".China Telecom mail (189, enterprise editions): presets
189,ct-qiye,ct-qiye-hk,ct-bnet,ct-xinchuang.Microsoft 365 / Outlook.com no longer accept passwords over IMAP and are not supported.
Security model
Who can call it. claude.ai connects with OAuth 2.1 against this server's own sign-in page: dynamic client registration, PKCE, redirects only to Claude's callbacks, one-hour access tokens and rotating refresh tokens. No token is issued without the owner password (plus TOTP once bound). Failed sign-ins are rate-limited per IP and globally. Other clients use bearer tokens minted from the CLI or admin page, which expire (365 days by default). Optionally,
/mcpcan be limited to Anthropic's published outbound IP range (IMAP_MCP_ALLOWED_CLIENT_IPS; see the comment in.env.exampleand check the official list).What a caller can do. Scopes and mailbox allowlists per client, checked on every request; revocation applies to the next request. Rate limits per client and per mailbox; a connection cap per mailbox.
Three IMAP channels, three allowlists. Read:
EXAMINE,SEARCH,FETCHwithPEEKonly. Drafts:APPENDonly to the drafts folder and only with(\Draft \Seen); noSTOREorEXPUNGEat all. Send:APPENDonly to Sent with(\Seen), and one optional+FLAGS.SILENT (\Answered)on the original. Anything else raises before it reaches the server.Sending. Plain text only, no attachments, at most 10 recipients, From one of the mailbox's identities, per-mailbox and global hourly/daily limits. The approval page shows the whole frozen message; Send is a POST with the session, a CSRF token and the hash of what you saw. If the connection breaks mid-send the message is never resent automatically: Sent is checked, or you are asked.
IMAP_MCP_SEND=offstops all sending at once.The admin page. Owner password + TOTP, 30-minute sessions, CSRF and same-origin checks on every POST, no OAuth or bearer token opens it, and the admin cookie doesn't open
/mcp. Every change goes to the audit log. Passwords and tokens are never shown back.Logs. One line per MCP call (tool, client, mailbox, time, result); never arguments, queries or mail.
Prompt injection. Mail is written by other people. A crafted message can try to steer the model. With drafts and sending off, the worst it can do is show the model mail it can already read. With drafts on, the worst is a draft you don't send. With sending on, nothing leaves without your approval: read the whole message on the approval page, including the recipients, before you press Send.
Known limitations
Alibaba enterprise mail refuses server-side text search. It answers
BADto every SUBJECT/FROM/TO/TEXT search (in any charset, English too) and drops the connection after four. imap-mcp switches such a mailbox to local filtering after the first refusal; setsearch = "local"to skip even that. Subject, sender, recipient and date filters then read the headers of every message in the folder (in memory, read-only); full-text search checks only the newest 200 messages and says so in the result.Sending is plain text only, without attachments.
OAuth-only providers (Microsoft 365, Outlook.com) are not supported.
Push notifications for send approvals use Bark (iOS). Without a Bark key, send requests wait in the admin page's list and expire after 30 minutes unless you open them there.
The
serverole keeps no archive, sofind_contactsandsync_statusare not available there, andurgent_mailreads the inbox live with fewer signals.
Development
python -m venv .venv && . .venv/bin/activate
pip install -e '.[test,browser]'
python -m playwright install chromium
pytestThe tests start throwaway local IMAP servers (Dovecot when installed, otherwise pymap) and a local SMTP receiver,
with Chinese, Japanese, HTML-only and attachment-heavy test mail, and use only test passwords; nothing touches a
real mailbox. Tests that need Dovecot (apt install dovecot-imapd) or a browser are skipped without them.
Before a release, run the full suite with nothing skipped, plus the Docker end-to-end flows:
scripts/release-check.sh # pytest with IMAP_MCP_REQUIRE_BROWSER=1 (browser tests fail instead of skipping)
python tests/e2e_drafts_docker.py # drafts against the built image; ends with "FLAGS UNCHANGED: True"
python tests/e2e_send_docker.py # draft -> send request -> approval page -> exactly one message receivedThe end-to-end scripts need Docker and Dovecot on the host; set E2E_SKIP_BUILD=1 to use an image you built
yourself. Design notes for the local archive: docs/L1_SCHEMA.md (Chinese). Release history:
CHANGELOG.md.
Built on the official MCP Python SDK (mcp 2.3.0, Streamable HTTP).
License
Apache License 2.0. Copyright 2026 Martin Liu.
Related MCP Connectors
Give AI agents their own email inboxes: list, read and send mail via scoped, revocable OAuth grants.
Search and triage all your mailboxes; draft replies and campaigns; send only as you allow.
Email for AI agents: read, search and send from your Gmail, Outlook, Yahoo, iCloud or IMAP inbox.
Private, EU-hosted email for AI agents over JMAP: read, search, reply, draft, organize, send.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to securely access IMAP mailboxes with read-focused tools for searching, reading, listing messages, and creating drafts, while deliberately preventing sending or deleting emails.MIT
- AlicenseNot gradedqualityCmaintenanceEnables an LLM client to read and manage email over IMAP/SMTP with read-only mailbox operations and safe, idempotent send/reply, without mutating messages or risking duplicate sends.Apache 2.0
- AlicenseNot gradedqualityBmaintenanceGives AI assistants read-only access to several IMAP mailboxes, letting them list accounts, search, read messages and read threads across accounts without marking anything as read. Drafting and archiving are opt-in, per-account capabilities that never send or delete mail.MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to read IMAP mailboxes and create drafts without sending them. Supports multiple accounts and folders, read-only message fetching, and search, with sending deliberately disabled so drafts are reviewed and sent manually.MIT