Skip to main content
Glama
AlobarQuest

IMAP MCP Server

by AlobarQuest

IMAP MCP Server

Multi-account IMAP/SMTP MCP server for Claude. Connects multiple email accounts via a single deployment using FastMCP.

Setup

1. Install dependencies

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

2. Configure accounts

cp .env.example .env
# Edit .env with your IMAP/SMTP credentials

Each account is configured via numbered environment variables:

Variable

Required

Default

Description

IMAP_ACCOUNT_N_NAME

Yes

Short name used in tool calls

IMAP_ACCOUNT_N_EMAIL

Yes

Email address

IMAP_ACCOUNT_N_IMAP_HOST

Yes

IMAP server hostname

IMAP_ACCOUNT_N_IMAP_PORT

No

993

IMAP port

IMAP_ACCOUNT_N_SMTP_HOST

Yes

SMTP server hostname

IMAP_ACCOUNT_N_SMTP_PORT

No

587

SMTP port

IMAP_ACCOUNT_N_SMTP_SECURITY

No

starttls

starttls (port 587) or ssl (port 465)

IMAP_ACCOUNT_N_USERNAME

Yes

Login username

IMAP_ACCOUNT_N_PASSWORD

Yes

Login password

IMAP_ACCOUNT_N_TRASH_FOLDER

No

Trash

Folder name for soft deletes

Add as many accounts as needed by incrementing N (1, 2, 3...). Gaps in numbering are handled gracefully.

3. Run the server

python -m src.server

Starts on port 8000 with streamable-http transport by default.

4. Connect to Claude Desktop

Add as a remote MCP server in Claude Desktop settings:

https://imap-mcp.devonwatkins.com/mcp

Or for local development:

{
  "mcpServers": {
    "imap": {
      "url": "http://localhost:8000/mcp"
    }
  }
}

Related MCP server: IMAP MCP Server

Tools

Tool

Description

imap_list_accounts

List all configured accounts with connection status

imap_list_emails

List emails with filters (folder, unread, date, search)

imap_read_email

Read full email content by UID (uses PEEK, does not mark as read)

imap_search_emails

Full-text search across folders

imap_send_email

Send email via SMTP (generates Message-ID)

imap_mark_read

Mark emails as read/unread

imap_move_email

Move emails between folders

imap_list_folders

List mailbox folders

imap_delete_email

Delete emails (soft: move to trash, or permanent)

Every tool (except imap_list_accounts) takes an account parameter matching the account NAME.

Health Endpoints

Endpoint

Purpose

GET /health

Combined status with per-account details

GET /health/live

Liveness probe (process is up)

GET /health/ready

Readiness probe (at least one account can authenticate)

The readiness endpoint actively probes IMAP connectivity — it does not rely on cached state.

{"status": "ready", "accounts": {"adjustright": "connected", "watkinshomesales": "connected"}}

Error Handling

All tools return structured errors with stable codes:

{"error": true, "code": "AUTH_FAILED", "message": "...", "account": "adjustright"}

Error codes: AUTH_FAILED, CONNECTION_TIMEOUT, FOLDER_NOT_FOUND, EMAIL_NOT_FOUND, SEND_FAILED, ACCOUNT_NOT_FOUND

Docker

docker build -t imap-mcp-server .
docker run -p 8000:8000 --env-file .env imap-mcp-server

The Dockerfile includes bws CLI for fetching passwords from Bitwarden Secrets Manager at startup via start.sh.

Production Deployment

Deployed on Coolify as a Flavor A app (single container, source build).

  • Domain: https://imap-mcp.devonwatkins.com

  • Passwords: Fetched from BWS at startup (start.sh)

  • Health check: /health/live on port 8000

Tests

pip install pytest pytest-asyncio
python -m pytest tests/ -v

E2E Tests

# Read-only tests against production
python scripts/test_live.py

# Include mark/move/delete tests (restores state after)
python scripts/test_live.py --destructive

# Include send test (sends email to self)
python scripts/test_live.py --send

# Full suite
python scripts/test_live.py --destructive --send

# Test a specific account
python scripts/test_live.py --account watkinshomesales

Architecture

src/
  server.py     — FastMCP app, 9 tool definitions, health endpoints
  client.py     — Async IMAP (aioimaplib) and SMTP (aiosmtplib) clients
  accounts.py   — Account registry from IMAP_ACCOUNT_N_* env vars
  models.py     — Pydantic models for all request/response types
  errors.py     — Typed exceptions (AuthenticationError, FolderNotFoundError, etc.)
tests/          — 59 unit tests
scripts/        — E2E test suite and debug tools
start.sh        — Entrypoint that fetches BWS secrets before starting server

Key Design Decisions

  • Regular SEARCH, not UID SEARCH: Namecheap Private Email doesn't support UID SEARCH. We use regular SEARCH for sequence numbers, then FETCH (UID) to convert to stable UIDs.

  • Per-account asyncio.Lock: Prevents concurrent requests from corrupting IMAP folder selection state.

  • BODY.PEEK[]: Read operations never mark emails as read.

  • Lazy connections: IMAP connections are established on first use, not at startup. The readiness endpoint probes real connectivity.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Enables Claude to interact with email accounts via IMAP and SMTP, providing tools for searching, reading, sending, and managing emails across multiple providers.
    40
    393 npm
    94
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables Claude to read, search, draft, send, flag, and move email across multiple IMAP/SMTP mailboxes while keeping credentials local.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables Claude Code to manage email inboxes via IMAP, including reading, categorizing, phishing detection, archiving, junking, and sending emails with user permission.
    -