Local MCP server for multi-account IMAP/SMTP email (tested on iCloud)
Project description
email-mcp
Local MCP server for multi-account IMAP/SMTP email (iCloud + Gmail via app-specific passwords). Never marks mail read. Cross-folder search, idempotent sends, TLS verified.
Status
- Tested against iCloud only. The design is provider-generic (Gmail config is included as an example), but only iCloud has been exercised end-to-end so far. Gmail/others are untested — use at your own risk and please report back.
- macOS only (uses the macOS Keychain via
keyring).
Requirements
- An app-specific password for each mailbox, stored in your macOS Keychain (see Configure / Get an app-specific password). The password is read from the Keychain at runtime — it is never written to disk, logged, or returned by any tool.
- You must grant Keychain permission. The first time the server reads the password,
macOS shows a dialog: "… wants to use your confidential information stored in
'email-mcp' in your keychain." — click Allow (or Always Allow). This grants
access to only that one
email-mcpitem, nothing else in your Keychain. Note the prompt is tied to the specific Python binary running the server, so it may re-ask if you switch interpreters.
Install
pip install email-mcp # or: pipx install email-mcp
This provides an email-mcp command (and python -m email_mcp.server).
Configure
- Create your account registry at
~/.config/email-mcp/accounts.yml(seeconfig/accounts.example.ymlfor the format). Override the location with theEMAIL_MCP_ACCOUNTSenv var if you prefer. - Store each account's app-specific password in the macOS Keychain:
python -m email_mcp.setup_cli icloud-personal
(For local development you can instead setEMAIL_MCP_PASSWORDin a.env.)
Register with Claude Code
claude mcp add email --scope user -- email-mcp
Tools
list_accounts, set_default_account, list_folders, get_emails (recency by default; search via query/filters), send_email (idempotent), mark_email, move_email.
Get an app-specific password
- iCloud: appleid.apple.com -> Sign-In & Security -> App-Specific Passwords.
- Gmail: myaccount.google.com -> Security -> App passwords.
Develop
python3.12 -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file email_mcp-0.1.1.tar.gz.
File metadata
- Download URL: email_mcp-0.1.1.tar.gz
- Upload date:
- Size: 12.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73b5491588103886f5e9e3e748301c094077886f785b391e8eb7a7b3c0ba7273
|
|
| MD5 |
6ebbda8100e8b756e7fdfac4ebcb24de
|
|
| BLAKE2b-256 |
5e8184ef0bd61df8c1e1da38c41ec872e8b9790fe29903957188c2ec24a82f76
|
Provenance
The following attestation bundles were made for email_mcp-0.1.1.tar.gz:
Publisher:
publish.yml on swapnilsurdi/email_mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
email_mcp-0.1.1.tar.gz -
Subject digest:
73b5491588103886f5e9e3e748301c094077886f785b391e8eb7a7b3c0ba7273 - Sigstore transparency entry: 1677043927
- Sigstore integration time:
-
Permalink:
swapnilsurdi/email_mcp@925d1a9c535167369c39d88961dd6c0d3de77552 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/swapnilsurdi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@925d1a9c535167369c39d88961dd6c0d3de77552 -
Trigger Event:
push
-
Statement type:
File details
Details for the file email_mcp-0.1.1-py3-none-any.whl.
File metadata
- Download URL: email_mcp-0.1.1-py3-none-any.whl
- Upload date:
- Size: 17.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f49ee5085703c5d9e0723304c4c58ffcccb55133a7efb6414ef2547b6312ec0
|
|
| MD5 |
61a6bb2fc8b6dc0193fc5a274828e172
|
|
| BLAKE2b-256 |
b0a30ae3072643047eccc661be5552a8f52c0e9172409b296db1c4486571bf12
|
Provenance
The following attestation bundles were made for email_mcp-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on swapnilsurdi/email_mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
email_mcp-0.1.1-py3-none-any.whl -
Subject digest:
1f49ee5085703c5d9e0723304c4c58ffcccb55133a7efb6414ef2547b6312ec0 - Sigstore transparency entry: 1677043931
- Sigstore integration time:
-
Permalink:
swapnilsurdi/email_mcp@925d1a9c535167369c39d88961dd6c0d3de77552 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/swapnilsurdi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@925d1a9c535167369c39d88961dd6c0d3de77552 -
Trigger Event:
push
-
Statement type: