# MCP Email Server A Model Context Protocol (MCP) server for email operations (POP3/SMTP with TLS). Allows an LLM like Claude to read, send, and manage emails. ## Quick Start ### Option 1: uvx (recommended) No clone, no install — runs directly from GitHub: ```bash uvx git+https://github.com/ptbsare/email-mcp-server \ --email-user you@example.com \ --email-pass yourpassword \ --pop3-server pop.example.com \ --smtp-server smtp.example.com ``` First run caches the package; subsequent launches are instant. ### Option 2: Clone + run locally ```bash git clone https://github.com/ptbsare/email-mcp-server cd email-mcp-server uv pip install -e . uv run main.py --email-user you@example.com --email-pass yourpassword \ --pop3-server pop.example.com --smtp-server smtp.example.com ``` ### Option 3: .env file Create a `.env` file in the working directory: ```dotenv EMAIL_USER=you@example.com EMAIL_PASS=yourpassword POP3_SERVER=pop.example.com SMTP_SERVER=smtp.example.com ``` Then simply: ```bash uvx git+https://github.com/ptbsare/email-mcp-server # or uv run main.py ``` ## Configuration ### Config Priority (highest → lowest) 1. **CLI arguments** — override everything 2. **Environment variables** — override `.env` file 3. **`.env` file** — fallback defaults ### All Config Options | CLI Argument | Env Variable | Required | Default | Description | |---|---|---|---|---| | `--email-user` | `EMAIL_USER` | ✅ | — | Email address | | `--email-pass` | `EMAIL_PASS` | ✅ | — | Email password / app password | | `--pop3-server` | `POP3_SERVER` | ✅ | — | POP3 server hostname | | `--pop3-port` | `POP3_PORT` | | `995` | POP3 SSL port | | `--smtp-server` | `SMTP_SERVER` | ✅ | — | SMTP server hostname | | `--smtp-port` | `SMTP_PORT` | | `587` | SMTP port (auto `465` if `--smtp-use-ssl`) | | `--smtp-use-ssl` | `SMTP_USE_SSL` | | `false` | Use SMTP_SSL (port 465) instead of STARTTLS | | `--log-level` | `LOG_LEVEL` | | `INFO` | Logging: `DEBUG` / `INFO` / `WARNING` / `ERROR` | ### Examples: Mixing Config Sources ```bash # CLI args only (no .env needed): uv run main.py --email-user me@gmail.com --email-pass xxx \ --pop3-server pop.gmail.com --smtp-server smtp.gmail.com # .env file for credentials, CLI for servers: # .env: EMAIL_USER=me@gmail.com / EMAIL_PASS=xxx uv run main.py --pop3-server pop.gmail.com --smtp-server smtp.gmail.com # Env vars override .env: EMAIL_USER=other@gmail.com uv run main.py --pop3-server pop.gmail.com ... ``` ## Using with Claude Desktop Add to your Claude Desktop config file: **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json` **Windows:** `%APPDATA%/Claude/claude_desktop_config.json` ### With env vars (in config): ```json { "mcpServers": { "email-mcp-server": { "command": "uvx", "args": ["git+https://github.com/ptbsare/email-mcp-server"], "env": { "EMAIL_USER": "your-email@example.com", "EMAIL_PASS": "your-app-password", "POP3_SERVER": "pop.example.com", "SMTP_SERVER": "smtp.example.com" } } } } ``` ### With CLI args (in config): ```json { "mcpServers": { "email-mcp-server": { "command": "uvx", "args": [ "git+https://github.com/ptbsare/email-mcp-server", "--email-user", "your-email@example.com", "--email-pass", "your-app-password", "--pop3-server", "pop.example.com", "--smtp-server", "smtp.example.com" ] } } } ``` > **Tip:** The `env` section and CLI args can be used together. CLI args always take priority. ## Features - **Poll Emails:** List inbox email headers with configurable limit (`pollEmails`) - **Fetch Full Emails:** Get complete email content by ID, with automatic attachment extraction (`getEmailsById`) - **Delete Emails:** Remove emails by ID (`deleteEmailsById`) - **Send Emails:** Send plain text (`sendTextEmail`) or HTML (`sendHtmlEmail`) emails with optional file attachments - **Secure Connections:** POP3 over SSL (port 995), SMTP with STARTTLS (port 587) or direct SSL (port 465) - **Attachment Support:** Send local files as attachments; received attachments are auto-saved to `/tmp/email_mcp_attachments//` ## Tools ### `pollEmails(limit=50)` List recent email headers (no body). Returns newest first. Use this first to get IDs for `getEmailsById`/`deleteEmailsById`. | Parameter | Type | Default | Description | |---|---|---|---| | `limit` | `int` | `50` | Max emails to return, newest first | **Returns:** `[{"id": int, "Subject": str, "From": str, "Date": str, "Message-ID": str}]` ```python pollEmails(limit=10) # 10 most recent pollEmails() # default 50 ``` --- ### `getEmailsById(ids)` Fetch full email content (headers + body) by IDs from `pollEmails`. Attachments auto-saved to `/tmp/email_mcp_attachments//`. | Parameter | Type | Required | Description | |---|---|---|---| | `ids` | `list[int]` | ✅ | Email IDs from `pollEmails()`. Example: `[1, 3, 5]` | **Returns:** `[{"id": int, "headers": dict, "body": str, "attachments": [{"filename": str, "local_path": str, "size": int, "content_type": str}]}]` ```python getEmailsById(ids=[1, 3, 5]) ``` --- ### `deleteEmailsById(ids)` Permanently delete emails by IDs. **Irreversible.** Call `pollEmails` first. | Parameter | Type | Required | Description | |---|---|---|---| | `ids` | `list[int]` | ✅ | Email IDs from `pollEmails()`. Example: `[1, 2, 3]` | **Returns:** `{"deleted": [int], "failed": {"id": "error msg"}}` ```python deleteEmailsById(ids=[1, 2, 3]) ``` --- ### `sendTextEmail(toAddresses, subject, body, attachments=None)` Send a plain text email. Attachments: list of local file paths like `["/tmp/file.pdf"]`. | Parameter | Type | Required | Default | Description | |---|---|---|---|---| | `toAddresses` | `list[str]` | ✅ | — | Recipients. Example: `["alice@example.com"]` | | `subject` | `str` | ✅ | — | Subject line | | `body` | `str` | ✅ | — | Plain text body | | `attachments` | `list[str]` | | `None` | Local file paths. Example: `["/tmp/report.pdf"]` | **Returns:** `{"status": "success"}` ```python sendTextEmail( toAddresses=["alice@example.com"], subject="Hello", body="Hi Alice!", attachments=["/tmp/report.pdf"] ) ``` --- ### `sendHtmlEmail(toAddresses, subject, body, attachments=None)` Send an HTML email. Attachments: list of local file paths like `["/tmp/file.png"]`. | Parameter | Type | Required | Default | Description | |---|---|---|---|---| | `toAddresses` | `list[str]` | ✅ | — | Recipients. Example: `["alice@example.com"]` | | `subject` | `str` | ✅ | — | Subject line | | `body` | `str` | ✅ | — | HTML content. Example: `"

Hi

Hello!

"` | | `attachments` | `list[str]` | | `None` | Local file paths. Example: `["/tmp/chart.png"]` | **Returns:** `{"status": "success"}` ```python sendHtmlEmail( toAddresses=["alice@example.com"], subject="Report", body="

Report

Sales up 20%.

", attachments=["/tmp/chart.png"] ) ``` --- ## Development Setup ### Prerequisites - Python 3.12+ - [uv](https://github.com/astral-sh/uv) ### Steps ```bash git clone https://github.com/ptbsare/email-mcp-server cd email-mcp-server uv pip install -e . uv run main.py --help ``` ## Important Notes - **App Passwords:** If your email provider uses 2FA, generate an App Password for `EMAIL_PASS` - **Email IDs:** POP3 IDs are session-specific. Call `pollEmails()` before `getEmailsById()` or `deleteEmailsById()` - **Attachment Storage:** Received attachments are saved to `/tmp/email_mcp_attachments//` - **Security:** Never commit your `.env` file — it's already in `.gitignore` - **Config Priority:** CLI args > environment variables > `.env` file ## Project Structure ``` email-mcp-server/ ├── main.py # MCP server entry point (all logic) ├── pyproject.toml # Package config & dependencies ├── uv.lock # Dependency lock file ├── .env # Credentials (create your own) ├── .gitignore └── README.md ``` ## License MIT