# PIM MCP Server A self-hosted MCP server for managing your email, calendar, and contacts through AI assistants. Connect your existing mail server (IMAP/SMTP) and CalDAV/CardDAV services to any MCP-compatible client. ## Prerequisites - Docker and Docker Compose (recommended), OR Python 3.12+ - An email account with IMAP/SMTP access - (Optional) A CalDAV server for calendars (Nextcloud, Fastmail, Radicale, etc.) - (Optional) A CardDAV server for contacts ## Setup ### Option 1: Docker Compose (Recommended) 1. **Clone the repository** ```bash git clone https://github.com/your-repo/pim-mcp-server.git cd pim-mcp-server ``` 2. **Create your environment file** ```bash cp .env.example .env ``` 3. **Edit `.env` with your credentials** ```bash # Required: Generate an API key MCP_API_KEY=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))") # Then edit .env with your mail server details nano .env ``` 4. **Start the server** ```bash docker compose up -d ``` 5. **Verify it's running** ```bash curl http://localhost:8000/mcp ``` ### Option 2: Local Python 1. **Clone and setup environment** ```bash git clone https://github.com/your-repo/pim-mcp-server.git cd pim-mcp-server python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate pip install -r requirements.txt ``` 2. **Configure** ```bash cp .env.example .env nano .env # Add your credentials ``` 3. **Initialize database** ```bash # Create initial migration (first time only) alembic revision --autogenerate -m "Initial tables" alembic upgrade head ``` 4. **Run** ```bash python src/server.py ``` ## Configuration Edit `.env` with your service credentials. Only configure the services you want to use. ### Minimal Setup (Email Only) ```bash # Server MCP_API_KEY=your-secret-key-here PORT=8000 # Email 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 # Disable other services ENABLE_CALENDAR=false ENABLE_CONTACTS=false ``` ### Full Setup (Email + Calendar + Contacts) ```bash # Server MCP_API_KEY=your-secret-key-here PORT=8000 # Email (IMAP/SMTP) IMAP_HOST=imap.example.com IMAP_PORT=993 IMAP_USERNAME=you@example.com IMAP_PASSWORD=your-password SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USERNAME=you@example.com SMTP_PASSWORD=your-password SMTP_FROM_EMAIL=you@example.com SMTP_FROM_NAME=Your Name # Calendar (CalDAV) CALDAV_URL=https://caldav.example.com/dav CALDAV_USERNAME=you@example.com CALDAV_PASSWORD=your-password # Contacts (CardDAV) CARDDAV_URL=https://carddav.example.com/dav CARDDAV_USERNAME=you@example.com CARDDAV_PASSWORD=your-password ``` ### Provider-Specific Examples
Fastmail ```bash IMAP_HOST=imap.fastmail.com IMAP_PORT=993 SMTP_HOST=smtp.fastmail.com SMTP_PORT=587 CALDAV_URL=https://caldav.fastmail.com/dav/calendars/user/you@fastmail.com CARDDAV_URL=https://carddav.fastmail.com/dav/addressbooks/user/you@fastmail.com ``` Use an [app-specific password](https://www.fastmail.help/hc/en-us/articles/360058752854).
Nextcloud ```bash # Use your mail server for IMAP/SMTP IMAP_HOST=mail.example.com SMTP_HOST=mail.example.com # Nextcloud for CalDAV/CardDAV CALDAV_URL=https://cloud.example.com/remote.php/dav CARDDAV_URL=https://cloud.example.com/remote.php/dav CALDAV_USERNAME=your-nextcloud-user CARDDAV_USERNAME=your-nextcloud-user ```
Gmail ```bash IMAP_HOST=imap.gmail.com IMAP_PORT=993 SMTP_HOST=smtp.gmail.com SMTP_PORT=587 ``` You must use an [App Password](https://support.google.com/accounts/answer/185833) (not your regular password). Note: Gmail's CalDAV/CardDAV requires OAuth2, which is not currently supported.
Mailcow ```bash IMAP_HOST=mail.example.com SMTP_HOST=mail.example.com CALDAV_URL=https://mail.example.com/SOGo/dav CARDDAV_URL=https://mail.example.com/SOGo/dav ```
Radicale (Self-hosted) ```bash CALDAV_URL=https://radicale.example.com/user/ CARDDAV_URL=https://radicale.example.com/user/ ```
## Connecting to MCP Clients ### MCP Inspector (Testing) ```bash npx @modelcontextprotocol/inspector ``` - Transport: **Streamable HTTP** - URL: `http://localhost:8000/mcp` ### Claude Desktop Add to your Claude Desktop config (`~/.config/claude/claude_desktop_config.json` on Linux/Mac): ```json { "mcpServers": { "pim": { "transport": "http", "url": "http://localhost:8000/mcp" } } } ``` ### Poke Go to [poke.com/settings/connections](https://poke.com/settings/connections) and add your server URL. ## Available Tools Once connected, your AI assistant can use these tools: | Category | Tools | |----------|-------| | **Email** | `list_mailboxes`, `list_emails`, `read_email`, `search_emails`, `move_email`, `delete_email`, `send_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` | ## Database Migrations The server uses SQLModel with Alembic for database migrations. ### When you update the code ```bash # Pull latest changes git pull # Run any new migrations alembic upgrade head # Restart docker compose restart # or: python src/server.py ``` ### Adding custom fields 1. Edit `src/database/models.py` 2. Generate migration: `alembic revision --autogenerate -m "Description"` 3. Apply: `alembic upgrade head` ## Troubleshooting ### Connection refused - Check the server is running: `docker compose ps` or `curl localhost:8000/mcp` - Check logs: `docker compose logs -f` ### Authentication failed (IMAP/SMTP) - Verify credentials in `.env` - Many providers require app-specific passwords (Gmail, Fastmail, etc.) - Check if 2FA is enabled on your account ### CalDAV/CardDAV not working - Verify the URL is correct (try opening it in a browser) - Check if your provider requires a specific URL format - Some providers need the full path including username ### Service disabled If you see "service: disabled (not configured)", check that: - All required env vars are set (host, username, password) - `ENABLE_*` is not set to `false` ### View logs ```bash # Docker docker compose logs -f # Local # Logs print to stdout ``` ## Project Structure ``` ├── src/ │ ├── server.py # Entry point │ ├── config.py # Environment configuration │ ├── database/ # SQLModel ORM │ │ ├── models.py # Table definitions │ │ └── connection.py # Database connection │ ├── models/ # Pydantic models (API) │ ├── services/ # Business logic │ └── tools/ # MCP tool definitions ├── migrations/ # Alembic migrations ├── docker-compose.yml ├── Dockerfile ├── .env.example └── requirements.txt ``` ## Security Notes - Never commit `.env` files - Use app-specific passwords where available - The Docker container runs as non-root - Consider running behind a reverse proxy with HTTPS for remote access - The `MCP_API_KEY` is optional but recommended for production ## License MIT