npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

better-email-mcp

v0.6.4

Published

MCP server for email, calendar, tasks, and contacts via IMAP, JMAP, CalDAV, and CardDAV

Readme

better-email-mcp

An MCP server that gives LLM tools access to your email, calendar, tasks, and contacts — built to be the one you actually want to use.

Why "better"?

  • Virtually zero dependencies. The only runtime dependency is the MCP SDK itself. IMAP, SMTP, CalDAV, and CardDAV clients are implemented from scratch using Node built-ins — no third-party libraries in your supply chain.
  • Works with any provider. Supports IMAP/SMTP (Gmail, Outlook, self-hosted, etc.), Fastmail JMAP (email + contacts), and any CalDAV/CardDAV server (Fastmail, iCloud, Nextcloud, Radicale, etc.) for calendars, tasks, and contacts.
  • You control what the LLM can do. Disable any tool with a single environment variable — enforce read-only access, hide search, or strip it down to just what you need. Less tool clutter means better LLM performance.
  • Token-efficient. List and search responses return only essential fields by default. Pass verbose: true for full details when needed.

Token efficiency

All tool responses use compact JSON (no pretty-printing). List and search tools (list_messages, search_messages, list_events, search_events, list_tasks, search_tasks, list_contacts, search_contacts) return a lean field set by default — just enough to identify and triage each item. Pass verbose: true to get the full response with all fields.

Tool definition token cost (schema tokens consumed per request, estimated at ~3.5 chars/token):

Tools are only registered when the matching backend is configured. Combine rows to estimate your setup:

| Protocol | Tools | Est. tokens | |----------|-------|-------------| | IMAP | 6 | ~373 | | JMAP (EMAIL_FORMAT=html adds htmlBody) | 6 | ~380 | | CalDAV — calendar | 4 | ~192 | | CalDAV — tasks | 6 | ~371 | | CardDAV | 4 | ~206 |

Example totals: IMAP only ~373 · IMAP + CalDAV + Tasks ~935 · Full suite (JMAP + CalDAV + Tasks + CardDAV) ~1,148

Run npm run count-tokens for a per-tool breakdown. Use DISABLED_TOOLS to trim tools you don't need.

Default fields by tool type:

| Tool type | Default fields | Additional with verbose: true | |-----------|---------------|--------------------------------| | Email list/search | id, from, subject, date, snippet | to, cc, isRead, folder | | Calendar list/search | id, href, title, start, end, location, allDay | description, organizer, attendees, status, recurrence, calendar | | Task list/search | id, href, title, status, due, priority | description, categories, start, completed, percentComplete, recurrence, calendar | | Contact list/search | id, href, name, emails, phones | organization, title, address, notes, addressBook |

The folder, calendar, and addressBook fields are automatically included in lean responses when no filter is applied (listing across all), and omitted when filtering by a specific one (since it's redundant).

Setup

Install and run directly with npx — no clone needed:

npx better-email-mcp

Or install globally:

npm install -g better-email-mcp

For local development:

git clone https://github.com/samteezy/better-email-mcp.git
cd better-email-mcp
npm install
npm run build

Configuration

The server is configured entirely through environment variables.

Backend selection

| Variable | Description | Default | |----------|-------------|---------| | EMAIL_BACKEND | "jmap" or "imap" | "jmap" | | EMAIL_FORMAT | "plain" or "html" | "plain" |

When set to html, the send_message tool requires an htmlBody field in addition to textBody, and messages are sent as multipart with both plain text and HTML. When set to plain (the default), only textBody is exposed — the LLM cannot generate HTML email.

JMAP (Fastmail)

| Variable | Required | Description | |----------|----------|-------------| | JMAP_TOKEN | Yes | Fastmail API token | | JMAP_SESSION_URL | No | JMAP session URL (default: https://api.fastmail.com/.well-known/jmap) |

To get a token, go to Fastmail Settings > Privacy & Security > API tokens and create a token with the email scopes you need.

IMAP

| Variable | Required | Description | |----------|----------|-------------| | IMAP_HOST | Yes | IMAP server hostname (e.g. imap.gmail.com) | | IMAP_USER | Yes | Login username | | IMAP_PASSWORD | Yes | Login password or app-specific password | | IMAP_PORT | No | Server port (default: 993) | | IMAP_TLS | No | Use TLS (default: true) |

SMTP (sending from IMAP)

To enable sending with the IMAP backend, configure an SMTP server:

| Variable | Required | Description | |----------|----------|-------------| | SMTP_HOST | No | SMTP server hostname (e.g. smtp.gmail.com). Enables sending. | | SMTP_PORT | No | Server port (default: 587). Use 465 for implicit TLS. | | SMTP_USER | When SMTP_HOST set | SMTP login username | | SMTP_PASSWORD | When SMTP_HOST set | SMTP login password | | SMTP_TLS | No | Enable TLS (default: true). Port 465 uses implicit TLS; port 587 uses STARTTLS. | | SMTP_FROM | No | Sender address (defaults to SMTP_USER) |

If SMTP_HOST is not set, the IMAP backend is read-only and the send_message tool is not registered.

CalDAV (calendar)

Calendar and task tools activate when CALDAV_URL is set. Works alongside any email backend. Tasks use CalDAV VTODO — supported by Fastmail, iCloud, Nextcloud, Radicale, and most CalDAV servers.

| Variable | Required | Description | |----------|----------|-------------| | CALDAV_URL | Yes | CalDAV principal or calendar-home URL | | CALDAV_USERNAME | Yes | HTTP Basic auth username | | CALDAV_PASSWORD | Yes | HTTP Basic auth password | | CALDAV_DEFAULT_CALENDAR | No | Default calendar name — when set, tools scope to this calendar automatically |

Contacts

When using the JMAP backend, contact tools activate automatically via JMAP Contacts (RFC 9610) — no extra configuration needed. To use CardDAV instead (or with the IMAP backend), set CARDDAV_URL:

CardDAV (optional override)

| Variable | Required | Description | |----------|----------|-------------| | CARDDAV_URL | Yes | CardDAV principal or addressbook-home URL | | CARDDAV_USERNAME | Yes | HTTP Basic auth username | | CARDDAV_PASSWORD | Yes | HTTP Basic auth password | | CARDDAV_DEFAULT_ADDRESS_BOOK | No | Default address book name — when set, tools scope to this book automatically |

Disabling tools

Set DISABLED_TOOLS to a comma-separated list of tool names to prevent them from being registered:

DISABLED_TOOLS=send_message,search_messages

This is useful for enforcing read-only access or reducing context for the LLM. When using CALDAV_DEFAULT_CALENDAR or CARDDAV_DEFAULT_ADDRESS_BOOK, you can also disable list_calendars or list_address_books since the LLM no longer needs to discover them.

Attachment downloads

The get_attachment tool supports a saveTo parameter that writes the file to disk instead of returning base64 content. For security, saveTo paths are restricted to a base directory:

ATTACHMENT_DIR=~/Downloads  # default; set to change the allowed directory

Usage with MCP clients

JMAP (Fastmail) — email + contacts

{
  "mcpServers": {
    "email": {
      "command": "npx",
      "args": ["better-email-mcp"],
      "env": {
        "EMAIL_BACKEND": "jmap",
        "JMAP_TOKEN": "your-fastmail-api-token"
      }
    }
  }
}

Contact tools are included automatically via JMAP — no CardDAV setup needed.

IMAP

{
  "mcpServers": {
    "email": {
      "command": "npx",
      "args": ["better-email-mcp"],
      "env": {
        "EMAIL_BACKEND": "imap",
        "IMAP_HOST": "imap.example.com",
        "IMAP_USER": "[email protected]",
        "IMAP_PASSWORD": "your-password",
        "SMTP_HOST": "smtp.example.com",
        "SMTP_USER": "[email protected]",
        "SMTP_PASSWORD": "your-password"
      }
    }
  }
}

JMAP + CalDAV (Fastmail, all features)

{
  "mcpServers": {
    "email": {
      "command": "npx",
      "args": ["better-email-mcp"],
      "env": {
        "EMAIL_BACKEND": "jmap",
        "JMAP_TOKEN": "your-fastmail-api-token",
        "CALDAV_URL": "https://caldav.fastmail.com/",
        "CALDAV_USERNAME": "[email protected]",
        "CALDAV_PASSWORD": "your-app-password"
      }
    }
  }
}

Email and contacts use JMAP (automatic), calendar uses CalDAV. To use CardDAV for contacts instead, set CARDDAV_URL (this overrides JMAP contacts).

Tools

Email

| Tool | Description | |------|-------------| | list_folders | List all email folders/mailboxes | | list_messages | List recent messages with optional folder, limit, and offset | | get_message | Get a single message by ID, including full body and attachment metadata | | search_messages | Search messages by text query | | get_attachment | Download an email attachment by part ID. Returns base64 content, or saves to disk if saveTo path is provided | | send_message | Send an email (JMAP, or IMAP with SMTP configured) |

Calendar (CalDAV)

| Tool | Description | |------|-------------| | list_calendars | List all calendars | | list_events | List calendar events with optional calendar filter and limit | | get_event | Get a single event by href, including full details | | search_events | Search events by text query (matches title, description, location) |

Tasks (CalDAV VTODO)

| Tool | Description | |------|-------------| | list_tasks | List tasks (excludes completed/cancelled by default; pass includeCompleted: true to show all) | | get_task | Get a single task by href, including full details | | search_tasks | Search tasks by text query (matches title, description, categories) | | create_task | Create a new task with title, due date, priority, categories | | update_task | Update an existing task's fields | | complete_task | Mark a task as completed |

Contacts (CardDAV)

| Tool | Description | |------|-------------| | list_address_books | List all address books | | list_contacts | List contacts with optional address book filter and limit | | get_contact | Get a single contact by href, including full details | | search_contacts | Search contacts by name, email, phone, or organization |