Files
dav-imap-mcp/README.md
Yigit Colakoglu 767f076048
All checks were successful
Build And Test / publish (push) Successful in 49s
Add tool call logging and reply fields
2026-01-01 15:24:06 -08:00

193 lines
4.9 KiB
Markdown

# DAV/IMAP MCP Server
A self-hosted MCP server that connects IMAP/SMTP, CalDAV, and CardDAV to MCP-compatible clients. It exposes email, calendar, and contacts tools and can optionally send new email notifications to a Poke webhook.
## Features
- Email tools over IMAP/SMTP (list, read, search, send, drafts, flags, unsubscribe)
- Calendar tools over CalDAV (list, create, update, delete)
- Contacts tools over CardDAV (list, create, update, delete)
- Optional email notifications via webhook with IMAP IDLE or polling
- SQLite cache with Alembic migrations
- API key auth for the MCP endpoint
## Quickstart (Docker Compose)
1. Copy the environment template:
```bash
cp .env.example .env
```
2. Edit `.env` with your credentials.
3. Start the server:
```bash
docker compose up -d
```
4. Verify it is running:
```bash
curl http://localhost:8000/mcp
```
## Local Run (Python)
```bash
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# Edit .env
python src/server.py
```
## Configuration
All settings are read from `.env`. Configure only the services you want to enable.
### Minimal email-only setup
```bash
MCP_API_KEY=your-secret-key
PORT=8000
IMAP_HOST=imap.example.com
IMAP_USERNAME=you@example.com
IMAP_PASSWORD=your-password
SMTP_HOST=smtp.example.com
SMTP_USERNAME=you@example.com
SMTP_PASSWORD=your-password
SMTP_FROM_EMAIL=you@example.com
ENABLE_CALENDAR=false
ENABLE_CONTACTS=false
```
### Full setup (email + calendar + contacts)
```bash
MCP_API_KEY=your-secret-key
PORT=8000
IMAP_HOST=imap.example.com
IMAP_PORT=993
IMAP_USERNAME=you@example.com
IMAP_PASSWORD=your-password
IMAP_USE_SSL=true
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME=you@example.com
SMTP_PASSWORD=your-password
SMTP_USE_TLS=true
SMTP_FROM_EMAIL=you@example.com
SMTP_FROM_NAME=Your Name
CALDAV_URL=https://caldav.example.com/dav
CALDAV_USERNAME=you@example.com
CALDAV_PASSWORD=your-password
ICS_CALENDARS=Team|https://example.com/team.ics,Family|https://example.com/family.ics
ICS_CALENDAR_TIMEOUT=20
ICS_CALENDARS=Team|https://example.com/team.ics,Family|https://example.com/family.ics
ICS_CALENDAR_TIMEOUT=20
CARDDAV_URL=https://carddav.example.com/dav
CARDDAV_USERNAME=you@example.com
CARDDAV_PASSWORD=your-password
```
ICS calendars are optional and read-only. Set `ICS_CALENDARS` to a comma-separated list of entries, each as `name|url` or just `url` if you want the name inferred.
### Email notifications (Poke webhook)
Enable notifications to send new-email alerts to Poke. The server will use IMAP IDLE when available and fall back to polling.
```bash
ENABLE_EMAIL_NOTIFICATIONS=true
NOTIFICATION_MAILBOXES=INBOX,Updates
NOTIFICATION_POLL_INTERVAL=60
NOTIFICATION_IDLE_TIMEOUT=1680
POKE_WEBHOOK_URL=https://poke.com/api/v1/inbound-sms/webhook
POKE_API_KEY=your-poke-api-key
POKE_WEBHOOK_TIMEOUT=30
POKE_WEBHOOK_MAX_RETRIES=3
```
## MCP Client Setup
### MCP Inspector
```bash
npx @modelcontextprotocol/inspector
```
- Transport: Streamable HTTP
- URL: `http://localhost:8000/mcp`
### Claude Desktop
```json
{
"mcpServers": {
"pim": {
"transport": "http",
"url": "http://localhost:8000/mcp"
}
}
}
```
### Poke
Add your MCP endpoint at https://poke.com/settings/connections.
## Available Tools
| Category | Tools |
| --- | --- |
| Email | `list_mailboxes`, `list_emails`, `list_drafts`, `read_email`, `search_emails`, `move_email`, `delete_email`, `delete_draft`, `save_draft`, `edit_draft`, `send_email`, `set_email_flags`, `unsubscribe_email` |
| Calendar | `list_calendars`, `list_events`, `get_event`, `create_event`, `update_event`, `delete_event` |
| Contacts | `list_addressbooks`, `list_contacts`, `get_contact`, `create_contact`, `update_contact`, `delete_contact` |
| System | `get_server_info` |
### Replying to an email
Use `reply_to_email_id` on `save_draft`, `edit_draft`, or `send_email` to create a reply without a separate tool.
- Provide `reply_to_email_id` (and optionally `reply_mailbox`, default `INBOX`).
- `reply_all=true` includes original recipients; otherwise it replies to the sender/Reply-To.
- If `to`/`subject` are omitted, they are derived from the original email; `body` is still required.
Example (send a reply):
```json
{
"tool": "send_email",
"args": {
"reply_to_email_id": "12345",
"reply_mailbox": "INBOX",
"reply_all": true,
"body": "Thanks — sounds good to me."
}
}
```
## Database and Migrations
The server uses SQLite (default: `/data/cache.db`) and Alembic.
```bash
alembic revision --autogenerate -m "Describe change"
alembic upgrade head
```
## Troubleshooting
- Connection refused: check `docker compose ps` or `curl http://localhost:8000/mcp`
- Auth errors: confirm `MCP_API_KEY` and client config
- IMAP/SMTP failures: verify credentials and app-specific passwords
- CalDAV/CardDAV failures: confirm base URL and username
## License
MIT