Yigit Colakoglu ba57c5fba4
All checks were successful
Build And Test / publish (push) Successful in 48s
Add email flags and unsubscribe features
- Add set_email_flags tool for IMAP flags (standard + custom keywords)
- Add unsubscribe_email tool with List-Unsubscribe header parsing
- Support RFC 8058 one-click unsubscribe
- Add UnsubscribeInfo model to email responses
- Add data field to OperationResult for extra context
- Include test.sh script for MCP server testing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 17:23:49 -08:00
2025-12-30 15:16:45 -08:00
2025-12-30 15:16:45 -08:00
2025-12-30 15:16:45 -08:00
2025-12-30 15:16:45 -08:00
2025-12-30 15:16:45 -08:00
2025-12-30 15:16:45 -08:00
2025-12-30 15:16:41 -08:00
2025-12-30 15:16:45 -08:00
2025-12-30 15:45:50 -08:00
2025-12-30 17:17:17 -08:00

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

  1. Clone the repository

    git clone https://github.com/your-repo/pim-mcp-server.git
    cd pim-mcp-server
    
  2. Create your environment file

    cp .env.example .env
    
  3. Edit .env with your credentials

    # 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

    docker compose up -d
    
  5. Verify it's running

    curl http://localhost:8000/mcp
    

Option 2: Local Python

  1. Clone and setup environment

    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

    cp .env.example .env
    nano .env  # Add your credentials
    
  3. Initialize database

    # Create initial migration (first time only)
    alembic revision --autogenerate -m "Initial tables"
    alembic upgrade head
    
  4. Run

    python src/server.py
    

Configuration

Edit .env with your service credentials. Only configure the services you want to use.

Minimal Setup (Email Only)

# 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)

# 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
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.

Nextcloud
# 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
IMAP_HOST=imap.gmail.com
IMAP_PORT=993
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587

You must use an App Password (not your regular password).

Note: Gmail's CalDAV/CardDAV requires OAuth2, which is not currently supported.

Mailcow
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)
CALDAV_URL=https://radicale.example.com/user/
CARDDAV_URL=https://radicale.example.com/user/

Connecting to MCP Clients

MCP Inspector (Testing)

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):

{
  "mcpServers": {
    "pim": {
      "transport": "http",
      "url": "http://localhost:8000/mcp"
    }
  }
}

Poke

Go to 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

# 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

# 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

Description
No description provided
Readme 269 KiB
Languages
Python 96.9%
Shell 2%
Dockerfile 0.7%
Mako 0.4%