Content
# Proton Mail Bridge MCP Server
A Model Context Protocol (MCP) server that connects to Proton Mail via Proton Bridge's IMAP/SMTP interface, exposing email operations to AI assistants like Claude and LMStudio.
**Status**: Phase 1 / Proof of Concept
## Features
### Available MCP Tools
1. **list_emails** - List emails from a specified folder
2. **read_email** - Read full email content by ID
3. **send_email** - Send new emails (plain text, no attachments)
4. **search_emails** - Search emails by criteria
5. **list_folders** - List all available mail folders
## Prerequisites
### System Requirements
- **Python 3.10+**
- **Proton Bridge** installed and running
- **Proton Mail account** with valid credentials
### Proton Bridge Setup
1. Download and install [Proton Bridge](https://proton.me/mail/bridge)
2. Launch Proton Bridge and log in with your Proton account
3. Generate Bridge credentials:
- In Proton Bridge, go to Settings
- Copy the Bridge username and password (NOT your Proton account password)
4. Verify Bridge is running on default ports:
- IMAP: `127.0.0.1:1143`
- SMTP: `127.0.0.1:1025`
## Installation
### 1. Clone/Download the Project
```bash
cd /path/to/proton-mcp-server
```
### 2. Create Virtual Environment (Recommended)
```bash
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
```
### 3. Install Dependencies
```bash
pip install -r requirements.txt
```
### 4. Configure the Server
Choose one of three configuration methods:
#### Option A: Environment Variables (.env file) - Recommended
```bash
cp .env.example .env
# Edit .env with your actual credentials
```
Edit `.env`:
```ini
PROTON_USERNAME=your_bridge_username@proton.me
PROTON_PASSWORD=your_bridge_password
IMAP_HOST=127.0.0.1
IMAP_PORT=1143
SMTP_HOST=127.0.0.1
SMTP_PORT=1025
ATTACHMENT_DOWNLOAD_PATH=/tmp/proton-attachments
MAX_EMAIL_RESULTS=50
```
#### Option B: Config File (config.json)
Create `config.json`:
```json
{
"proton_username": "your_bridge_username@proton.me",
"proton_password": "your_bridge_password",
"imap_host": "127.0.0.1",
"imap_port": 1143,
"smtp_host": "127.0.0.1",
"smtp_port": 1025,
"attachment_download_path": "/tmp/proton-attachments",
"max_email_results": 50
}
```
#### Option C: Command-Line Arguments
Pass configuration via CLI:
```bash
python server.py \
--proton-username your_bridge_username@proton.me \
--proton-password your_bridge_password \
--imap-host 127.0.0.1 \
--imap-port 1143
```
**Priority Order**: CLI args > Environment variables > Config file
## Running the Server
### Standalone Mode (for testing)
```bash
python server.py
```
The server will start and listen on stdin/stdout for MCP protocol messages.
### With LMStudio
1. Open LMStudio settings
2. Navigate to MCP Servers configuration
3. Add a new server:
```json
{
"name": "proton-mail-bridge",
"command": "python",
"args": ["/path/to/proton-mcp-server/server.py"],
"env": {
"PROTON_USERNAME": "your_bridge_username@proton.me",
"PROTON_PASSWORD": "your_bridge_password"
}
}
```
4. Restart LMStudio
### With Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
```json
{
"mcpServers": {
"proton-mail-bridge": {
"command": "python",
"args": ["/path/to/proton-mcp-server/server.py"],
"env": {
"PROTON_USERNAME": "your_bridge_username@proton.me",
"PROTON_PASSWORD": "your_bridge_password"
}
}
}
}
```
Restart Claude Desktop.
## Usage Examples
Once connected to an AI assistant:
### List Recent Emails
```
"List my recent emails from INBOX"
```
### Read Specific Email
```
"Read email ID 42 and include attachments"
```
### Send Email
```
"Send an email to john@example.com with subject 'Meeting Tomorrow' and body 'Let's meet at 3pm'"
```
### Search Emails
```
"Search for emails containing 'invoice' in the subject"
```
### List Folders
```
"Show me all my email folders"
```
## API Reference
### list_emails
List emails from a folder.
**Parameters:**
- `folder` (optional, default: "INBOX") - Folder name
- `limit` (optional, default: 50, max: 50) - Max results
- `unread_only` (optional, default: false) - Only unread emails
**Returns:**
```json
{
"emails": [
{
"id": "123",
"from": "sender@example.com",
"to": ["you@proton.me"],
"subject": "Hello",
"date": "2026-02-09T10:30:00Z",
"unread": true,
"has_attachments": true,
"preview": "First 200 chars...",
"folder": "INBOX"
}
]
}
```
### read_email
Read full email content.
**Parameters:**
- `email_id` (required) - Email ID from list_emails
- `include_attachments` (optional, default: false) - Include base64 content
**Returns:**
```json
{
"id": "123",
"from": "sender@example.com",
"to": ["you@proton.me"],
"cc": [],
"subject": "Hello",
"date": "2026-02-09T10:30:00Z",
"body_text": "Plain text body",
"body_html": "<html>...</html>",
"attachments": [
{
"filename": "document.pdf",
"size": 102400,
"content_type": "application/pdf",
"content_base64": "JVBERi0xLjQK..."
}
]
}
```
### send_email
Send a new email.
**Parameters:**
- `to` (required) - Array of recipient emails
- `subject` (required) - Email subject
- `body` (required) - Plain text body
- `cc` (optional) - Array of CC recipients
- `bcc` (optional) - Array of BCC recipients
**Returns:**
```json
{
"success": true,
"message_id": "<generated_id@proton.me>"
}
```
### search_emails
Search emails by criteria.
**Parameters:**
- `query` (required) - Search string
- `folder` (optional, default: "INBOX") - Folder to search
- `search_in` (optional, default: ["subject", "from", "body"]) - Fields to search
- `limit` (optional, default: 50, max: 50) - Max results
**Returns:** Same format as `list_emails`
### list_folders
List all mail folders.
**Parameters:** None
**Returns:**
```json
{
"folders": [
{"name": "INBOX", "message_count": 42},
{"name": "Sent", "message_count": 128},
{"name": "Drafts", "message_count": 3}
]
}
```
## Error Handling
All operations return errors in a consistent format:
```json
{
"error": "Connection to Proton Bridge failed",
"error_type": "ConnectionError",
"details": "Could not connect to 127.0.0.1:1143"
}
```
Common error types:
- `ConnectionError` - Bridge not running or wrong host/port
- `AuthenticationError` - Invalid credentials
- `FolderNotFoundError` - Folder doesn't exist
- `EmailNotFoundError` - Email ID not found
- `ValidationError` - Missing required parameters
## Troubleshooting
### "Connection refused" error
**Problem**: Cannot connect to Proton Bridge
**Solutions**:
1. Verify Proton Bridge is running
2. Check Bridge ports in Settings (should be 1143/1025)
3. Ensure no firewall blocking localhost connections
### "Authentication failed" error
**Problem**: Invalid credentials
**Solutions**:
1. Use Bridge password, NOT Proton account password
2. Regenerate Bridge password in Bridge Settings
3. Check username includes full email (@proton.me)
### "Email not found" error
**Problem**: Invalid email ID
**Solutions**:
1. Use `list_emails` to get valid IDs
2. Email IDs are folder-specific (IMAP UIDs)
3. Don't reuse IDs after emails are deleted
### Attachments not saving
**Problem**: Permission denied or path doesn't exist
**Solutions**:
1. Ensure `ATTACHMENT_DOWNLOAD_PATH` is writable
2. Server automatically creates directory
3. Check disk space
## Architecture Overview
### Project Structure
```
proton-mcp-server/
├── server.py # MCP server entry point
├── imap_client.py # IMAP operations module
├── smtp_client.py # SMTP operations module
├── config.py # Configuration management
├── models.py # Email data structures
├── requirements.txt # Python dependencies
├── .env.example # Example configuration
└── README.md # This file
```
### Modular Design
The codebase is designed for extensibility:
- **config.py**: Priority-based configuration loader
- **models.py**: Data classes for emails, attachments, responses
- **imap_client.py**: All IMAP operations (reading, searching, listing)
- **smtp_client.py**: All SMTP operations (sending)
- **server.py**: MCP protocol handler and tool definitions
### Adding New Features (Phase 2)
To extend functionality:
1. **Add new IMAP operations**: Edit `imap_client.py`
2. **Add new SMTP operations**: Edit `smtp_client.py`
3. **Add new MCP tools**:
- Define tool in `server.py::handle_list_tools()`
- Add handler in `server.py::handle_call_tool()`
4. **Add new data models**: Define in `models.py`
Example: Adding "mark as read" functionality:
```python
# imap_client.py
def mark_as_read(self, email_id: str) -> Dict[str, Any]:
# Implementation here
pass
# server.py - add to handle_call_tool()
elif name == "mark_as_read":
email_id = arguments.get("email_id")
result = imap_client.mark_as_read(email_id=email_id)
```
## Phase 2 Roadmap
Features planned for future releases:
- [ ] Reply/forward emails
- [ ] Mark read/unread
- [ ] Move emails to folders
- [ ] Delete emails
- [ ] Send emails with attachments
- [ ] Retry logic with exponential backoff
- [ ] Pagination for large result sets
- [ ] Result caching
- [ ] Async operations (if needed)
## Technical Notes
### IMAP/SMTP Line Endings
Proton Bridge requires CR/LF (`\r\n`) line endings for authentication. Python's `imaplib` and `smtplib` handle this automatically.
### Email ID Format
Email IDs are IMAP UIDs (unique identifiers per folder). They are:
- Folder-specific (ID "5" in INBOX ≠ ID "5" in Sent)
- Persistent within a folder
- Sequential but not necessarily consecutive
### Date Format
All dates use ISO 8601 format: `2026-02-09T10:30:00Z` (UTC timezone)
### Attachment Handling
- Metadata always returned (filename, size, type)
- Content only included if `include_attachments=true`
- Content is base64-encoded
- Files saved to `ATTACHMENT_DOWNLOAD_PATH`
## Security Considerations
### Credentials
- **Never commit `.env` file** to version control
- Use Bridge-generated passwords (unique per device)
- Rotate Bridge passwords periodically
### Network
- Bridge only listens on localhost (127.0.0.1)
- No external network exposure by default
- STARTTLS used for IMAP/SMTP connections
### Attachments
- Saved to local filesystem (configure secure path)
- Consider disk space limits
- Clean up old attachments periodically
## Contributing
This is a Phase 1 proof of concept. Contributions welcome for:
- Bug fixes
- Phase 2 features
- Documentation improvements
- Test coverage
## License
[Specify your license here]
## Support
For issues and questions:
1. Check Troubleshooting section above
2. Verify Proton Bridge is properly configured
3. Test with Proton Bridge's built-in IMAP/SMTP test
## Acknowledgments
Built using:
- [Model Context Protocol (MCP)](https://modelcontextprotocol.io/)
- [Proton Mail Bridge](https://proton.me/mail/bridge)
- Python standard library (imaplib, smtplib, email)
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available