MCP Email Server
Enables LLMs to read, send, and manage emails via POP3 and SMTP with TLS support.
README
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:
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
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:
EMAIL_USER=you@example.com
EMAIL_PASS=yourpassword
POP3_SERVER=pop.example.com
SMTP_SERVER=smtp.example.com
Then simply:
uvx git+https://github.com/ptbsare/email-mcp-server
# or
uv run main.py
Configuration
Config Priority (highest → lowest)
- CLI arguments — override everything
- Environment variables — override
.envfile .envfile — 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
# 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):
{
"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):
{
"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
envsection 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/<email_id>/
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}]
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/<id>/.
| 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}]}]
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"}}
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"}
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: "<h1>Hi</h1><p>Hello!</p>" |
attachments |
list[str] |
None |
Local file paths. Example: ["/tmp/chart.png"] |
Returns: {"status": "success"}
sendHtmlEmail(
toAddresses=["alice@example.com"],
subject="Report",
body="<h1>Report</h1><p>Sales up <b>20%</b>.</p>",
attachments=["/tmp/chart.png"]
)
Development Setup
Prerequisites
- Python 3.12+
- uv
Steps
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()beforegetEmailsById()ordeleteEmailsById() - Attachment Storage: Received attachments are saved to
/tmp/email_mcp_attachments/<email_id>/ - Security: Never commit your
.envfile — it's already in.gitignore - Config Priority: CLI args > environment variables >
.envfile
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
Recommended Servers
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.
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.
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.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
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.
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.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
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.