255 lines
7.4 KiB
Markdown
255 lines
7.4 KiB
Markdown
# MCP Email Server
|
|
|
|
A Dockerized MCP (Model Context Protocol) email assistant for law firms and legal teams.
|
|
|
|
Integrates:
|
|
- Multiple IMAP/SMTP email accounts
|
|
- Shared/public folder support
|
|
- New-message tracking and flagging
|
|
- Conflict check search
|
|
- Triage guidance using personnel/chain-of-command
|
|
|
|
Designed to be consumed by LLMs via MCP (Streamable HTTP) in Open WebUI.
|
|
|
|
## Quick start (single account)
|
|
|
|
1. Build:
|
|
|
|
docker build -t mcp-email-server /home/user/wall-o/mcp-email-server
|
|
|
|
2. Run (example):
|
|
|
|
docker run -d \
|
|
-p 8000:8000 \
|
|
-e API_KEY="your_api_key_here" \
|
|
-e LOG_LEVEL="DEBUG" \
|
|
-e IMAP_HOST=imap.example.com \
|
|
-e IMAP_PORT=993 \
|
|
-e IMAP_USE_SSL=true \
|
|
-e IMAP_USERNAME="user@example.com" \
|
|
-e IMAP_PASSWORD="secret" \
|
|
-e SMTP_HOST=smtp.example.com \
|
|
-e SMTP_PORT=587 \
|
|
-e SMTP_USE_TLS=true \
|
|
-e SMTP_USE_SSL=false \
|
|
-e SMTP_USERNAME="user@example.com" \
|
|
-e SMTP_PASSWORD="secret" \
|
|
-e SMTP_FROM="user@example.com" \
|
|
-e DEFAULT_CC="supervisor@example.com" \
|
|
-e BUSINESS_DESCRIPTION="A law firm handling corporate and litigation matters." \
|
|
-e PERSONNEL_JSON='[{"name":"Jane Doe","role":"Managing Partner","email":"jane@example.com","escalates_to":null},{"name":"John Smith","role":"Associate","email":"john@example.com","escalates_to":"Jane Doe"}]' \
|
|
mcp-email-server
|
|
|
|
3. Health check:
|
|
|
|
http://localhost:8000/health
|
|
|
|
4. MCP endpoint:
|
|
|
|
- POST http://localhost:8000/mcp
|
|
- Uses JSON-RPC 2.0 (methods: initialize, tools/list, tools/call)
|
|
|
|
5. Integrate with Open WebUI (MCP Streamable HTTP):
|
|
|
|
- Admin Settings → External Tools → Add Server
|
|
- Type: MCP (Streamable HTTP)
|
|
- Server URL: http://<your-server>:8000/mcp
|
|
- Auth: Bearer
|
|
- Key: your_api_key_here
|
|
- Save, then enable tools in a chat.
|
|
|
|
## Multi-account configuration
|
|
|
|
The server can manage multiple IMAP/SMTP accounts. Tools accept an optional "account" parameter; if omitted, the default account is used.
|
|
|
|
You have two main options:
|
|
|
|
1) Inline JSON (ACCOUNTS_JSON)
|
|
|
|
Set ACCOUNTS_JSON with a JSON array of accounts.
|
|
|
|
Copy-paste template (single line, for docker run):
|
|
|
|
-e ACCOUNTS_JSON='[{"id":"account1","name":"Primary Firm Inbox","imap_host":"imap.primary.com","imap_port":993,"imap_use_ssl":true,"imap_username":"user@primary.com","imap_password":"CHANGE_ME_1","smtp_host":"smtp.primary.com","smtp_port":587,"smtp_use_tls":true,"smtp_use_ssl":false,"smtp_username":"user@primary.com","smtp_password":"CHANGE_ME_1","smtp_from":"user@primary.com"},{"id":"account2","name":"Secondary Inbox","imap_host":"imap.secondary.com","imap_port":993,"imap_use_ssl":true,"imap_username":"user@secondary.com","imap_password":"CHANGE_ME_2","smtp_host":"smtp.secondary.com","smtp_port":587,"smtp_use_tls":true,"smtp_use_ssl":false,"smtp_username":"user@secondary.com","smtp_password":"CHANGE_ME_2","smtp_from":"user@secondary.com"}]'
|
|
|
|
Human-readable equivalent (for reference):
|
|
|
|
ACCOUNTS_JSON='[
|
|
{
|
|
"id": "account1",
|
|
"name": "Primary Firm Inbox",
|
|
"imap_host": "imap.primary.com",
|
|
"imap_port": 993,
|
|
"imap_use_ssl": true,
|
|
"imap_username": "user@primary.com",
|
|
"imap_password": "CHANGE_ME_1",
|
|
"smtp_host": "smtp.primary.com",
|
|
"smtp_port": 587,
|
|
"smtp_use_tls": true,
|
|
"smtp_use_ssl": false,
|
|
"smtp_username": "user@primary.com",
|
|
"smtp_password": "CHANGE_ME_1",
|
|
"smtp_from": "user@primary.com"
|
|
},
|
|
{
|
|
"id": "account2",
|
|
"name": "Secondary Inbox",
|
|
"imap_host": "imap.secondary.com",
|
|
"imap_port": 993,
|
|
"imap_use_ssl": true,
|
|
"imap_username": "user@secondary.com",
|
|
"imap_password": "CHANGE_ME_2",
|
|
"smtp_host": "smtp.secondary.com",
|
|
"smtp_port": 587,
|
|
"smtp_use_tls": true,
|
|
"smtp_use_ssl": false,
|
|
"smtp_username": "user@secondary.com",
|
|
"smtp_password": "CHANGE_ME_2",
|
|
"smtp_from": "user@secondary.com"
|
|
}
|
|
]'
|
|
|
|
2) JSON file (ACCOUNTS_CONFIG_PATH)
|
|
|
|
Mount a JSON file and set ACCOUNTS_CONFIG_PATH. Example:
|
|
|
|
docker run -d \
|
|
-p 8000:8000 \
|
|
-v /path/to/accounts.json:/etc/mcp-email/accounts.json:ro \
|
|
-e API_KEY="your_api_key_here" \
|
|
-e ACCOUNTS_CONFIG_PATH="/etc/mcp-email/accounts.json" \
|
|
mcp-email-server
|
|
|
|
Use the same structure as ACCOUNTS_JSON.
|
|
|
|
Default account:
|
|
|
|
- Use DEFAULT_ACCOUNT="firm_main" to set the default.
|
|
- If not set:
|
|
- If only one account exists, it is default.
|
|
- Otherwise, an account with id "default" is preferred, or the first one is used.
|
|
|
|
Tool usage with multiple accounts:
|
|
|
|
- Most tools accept an "account" field. Examples:
|
|
- list_folders: { "account": "firm_main" }
|
|
- search_messages: { "account": "secondary", "folder": "INBOX", "query": "conflict" }
|
|
- send_email: { "account": "firm_main", "to": ["client@example.com"], "subject": "...", "body": "..." }
|
|
- If "account" is omitted, the default account is used.
|
|
|
|
A new tool is available:
|
|
|
|
- list_accounts:
|
|
- Lists all configured accounts and shows which is default.
|
|
|
|
## Environment variables
|
|
|
|
See env.example for a full list.
|
|
|
|
Core:
|
|
|
|
- API_KEY:
|
|
- If set, all /mcp requests must include:
|
|
Authorization: Bearer <API_KEY>
|
|
- Leave empty to disable auth (not recommended in production).
|
|
|
|
- LOG_LEVEL:
|
|
- e.g., INFO, DEBUG, ERROR (default: INFO)
|
|
|
|
Single-account IMAP (only if not using ACCOUNTS_JSON/ACCOUNTS_CONFIG_PATH):
|
|
|
|
- IMAP_HOST
|
|
- IMAP_PORT
|
|
- IMAP_USE_SSL
|
|
- IMAP_USERNAME
|
|
- IMAP_PASSWORD
|
|
|
|
Single-account SMTP:
|
|
|
|
- SMTP_HOST
|
|
- SMTP_PORT
|
|
- SMTP_USE_TLS
|
|
- SMTP_USE_SSL
|
|
- SMTP_USERNAME
|
|
- SMTP_PASSWORD
|
|
- SMTP_FROM
|
|
|
|
Optional email:
|
|
|
|
- DEFAULT_CC: Comma-separated CC addresses.
|
|
- DEFAULT_BCC: Comma-separated BCC addresses.
|
|
- BUSINESS_DESCRIPTION: Context for the LLM (e.g., firm description).
|
|
- PERSONNEL_JSON: JSON array of personnel/chain-of-command:
|
|
- Example:
|
|
[
|
|
{
|
|
"name": "Jane Doe",
|
|
"role": "Managing Partner",
|
|
"email": "jane@example.com",
|
|
"escalates_to": null
|
|
},
|
|
{
|
|
"name": "John Smith",
|
|
"role": "Associate",
|
|
"email": "john@example.com",
|
|
"escalates_to": "Jane Doe"
|
|
}
|
|
]
|
|
- SCHEDULED_SEND_INTERVAL: Seconds between checks for scheduled emails (default: 10).
|
|
|
|
HTML and signature:
|
|
|
|
- Emails (send_email, reply_to_message, forward_message, schedule_send) default to HTML (html=true) unless explicitly set to false.
|
|
- EMAIL_HTML_SIGNATURE: Optional HTML signature appended to HTML emails.
|
|
- Inline HTML example:
|
|
-e EMAIL_HTML_SIGNATURE='<div style="font-size:12px;">Best regards,<br>Jane Doe<br>Associate</div>'
|
|
- Template file example:
|
|
- Mount the file:
|
|
-v /path/to/signature.html:/etc/mcp-email/signature.html:ro
|
|
- Set env:
|
|
-e EMAIL_HTML_SIGNATURE='/etc/mcp-email/signature.html'
|
|
If the value is an existing file path, its contents are used as the signature.
|
|
|
|
## MCP tools
|
|
|
|
All tools are exposed via MCP (Streamable HTTP) at POST /mcp.
|
|
|
|
General:
|
|
|
|
- list_accounts
|
|
|
|
Email:
|
|
|
|
- list_folders
|
|
- search_messages
|
|
- get_new_messages
|
|
- sync_seen
|
|
- mark_as_read
|
|
- flag_message
|
|
- move_message
|
|
- copy_message
|
|
- apply_label
|
|
- remove_label
|
|
- list_labels
|
|
- get_unread_summary
|
|
- send_email
|
|
- reply_to_message
|
|
- forward_message
|
|
- save_draft
|
|
- list_attachments
|
|
- download_attachment
|
|
- search_attachments
|
|
- schedule_send
|
|
- export_conversation
|
|
- conflict_check_search
|
|
- get_triage_config
|
|
|
|
Notes:
|
|
|
|
- IMAP operations use UIDs for stability.
|
|
- Conflict check search scans subject lines across specified folders for given terms.
|
|
- New-message tracking is in-memory per container instance.
|
|
- For production:
|
|
- Always set API_KEY.
|
|
- Use HTTPS and secure IMAP/SMTP settings.
|