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

proton-mail-mcp

v0.5.0

Published

MCP server for Proton Mail — send, read, and search email over SMTP and IMAP

Readme

Proton Mail MCP Server

npm version License: MIT

A Model Context Protocol (MCP) server that gives AI assistants full access to your Proton Mail account -- send, read, search, and organize email over SMTP and IMAP.

Features

  • Send, reply, and forward email via Proton Mail SMTP with threading headers
  • Read email via IMAP through Proton Mail Bridge
  • Attachments -- send files (base64) and download attachments from received messages
  • Search messages by sender, recipient, subject, body, date, and flags
  • Organize -- move, delete, and flag/unflag messages
  • List folders with message and unread counts
  • Safety first -- delete moves to Trash by default, read-only mode via READONLY=true, MCP tool annotations for client-side confirmation prompts
  • Security hardened -- input validation, credential sanitization, rate limiting, attachment size limits
  • Works with any MCP-compatible client (Claude Desktop, Claude Code, Cursor, etc.)

Prerequisites

Quick Start

Add to your MCP client

Add the following to your client's MCP server configuration (Claude Desktop, Claude Code, Cursor, etc.):

{
  "mcpServers": {
    "protonmail": {
      "command": "npx",
      "args": ["-y", "proton-mail-mcp"],
      "env": {
        "PROTONMAIL_USERNAME": "[email protected]",
        "PROTONMAIL_PASSWORD": "your-smtp-password"
      }
    }
  }
}

That's it — npx will download and run the server automatically. See Configuration for all available environment variables.

Install from source

If you prefer to run from a local clone:

git clone https://github.com/sethbang/proton-mail-mcp.git
cd proton-mail-mcp
npm install
npm run build

Then use this MCP config instead:

{
  "mcpServers": {
    "protonmail": {
      "command": "node",
      "args": ["/absolute/path/to/proton-mail-mcp/build/index.js"],
      "env": {
        "PROTONMAIL_USERNAME": "[email protected]",
        "PROTONMAIL_PASSWORD": "your-smtp-password"
      }
    }
  }
}

Tools

Sending

All send tools return the Message-ID of the sent message in their response, which can be used to locate the message via IMAP search. send_email also attempts a best-effort lookup of the sent copy UID in the Sent folder.

send_email

Send an email using Proton Mail SMTP.

| Parameter | Required | Description | |-----------|----------|-------------| | to | Yes | Recipient address(es), comma-separated | | subject | Yes | Subject line | | body | Yes | Plain text or HTML content | | isHtml | No | Whether body is HTML (default: false) | | cc | No | CC recipient(s), comma-separated | | bcc | No | BCC recipient(s), comma-separated | | replyTo | No | Reply-To address (Proton SMTP may rewrite unauthenticated values) | | fromName | No | Display name for the From field | | attachments | No | Array of {filename, content, contentType} (base64-encoded content) |

reply_email

Reply to a message with proper threading headers (In-Reply-To, References). Includes the quoted original message with attribution by default.

| Parameter | Required | Description | |-----------|----------|-------------| | uid | Yes | UID of the message to reply to | | body | Yes | Reply body content | | folder | No | Folder containing the original message (default: INBOX) | | isHtml | No | Whether body is HTML (default: false) | | cc | No | Additional CC recipients, comma-separated | | bcc | No | BCC recipients, comma-separated | | replyAll | No | Reply to all recipients instead of just sender (default: false) | | includeQuote | No | Include quoted original message below reply (default: true) |

forward_email

Forward a message to new recipients with threading headers. Original attachments are carried forward by default.

| Parameter | Required | Description | |-----------|----------|-------------| | uid | Yes | UID of the message to forward | | to | Yes | Recipient address(es), comma-separated | | folder | No | Folder containing the original message (default: INBOX) | | body | No | Optional message to prepend above the forwarded content | | isHtml | No | Whether body is HTML (default: false) | | cc | No | CC recipients, comma-separated | | bcc | No | BCC recipients, comma-separated | | includeAttachments | No | Include original attachments in the forward (default: true) |

save_draft

Save an email as a draft without sending it. The draft is placed in the Drafts folder for the user to review and send manually. Returns the draft UID when available.

| Parameter | Required | Description | |-----------|----------|-------------| | to | Yes | Recipient address(es), comma-separated | | subject | Yes | Subject line | | body | Yes | Plain text or HTML content | | isHtml | No | Whether body is HTML (default: false) | | cc | No | CC recipient(s), comma-separated | | bcc | No | BCC recipient(s), comma-separated | | replyTo | No | Reply-To address (Proton SMTP may rewrite unauthenticated values) | | fromName | No | Display name for the From field | | folder | No | Folder to save draft in (default: Drafts) |

Reading

list_folders

List all mailbox folders with message and unread counts. No parameters.

list_messages

List recent messages from a folder. Supports UID-based pagination.

| Parameter | Required | Description | |-----------|----------|-------------| | folder | No | Folder path (default: INBOX) | | limit | No | Max messages to return, 1-100 (default: 20) | | beforeUid | No | Fetch messages with UIDs before this value (for pagination) |

read_message

Read a specific message by UID. Returns full headers, body, and attachment metadata. Prefers plain text; strips HTML tags from HTML-only messages. Body-part selection skips parts marked Content-Disposition: attachment, so a text/plain attachment sitting next to an HTML body is never returned as the body.

| Parameter | Required | Description | |-----------|----------|-------------| | uid | Yes | Message UID (from list_messages or search_messages) | | folder | No | Folder path (default: INBOX) | | preferHtml | No | Return raw HTML instead of stripped text (default: false) | | maxBodyLength | No | Max body length before truncation, 100-500000 (default: 50000) | | showHeaders | No | Include In-Reply-To, References, Reply-To, List-Unsubscribe, List-ID in an Extra Headers section (default: false) | | stripUrls | No | Drop anchor URLs from stripped-HTML output, keeping only link text. Useful for summarizing newsletters (default: false) |

list_attachments

List attachment metadata (part numbers, filenames, types, sizes) for a message without downloading the body. Composes with download_attachment for bulk extraction.

| Parameter | Required | Description | |-----------|----------|-------------| | uid | Yes | Message UID | | folder | No | Folder containing the message (default: INBOX) |

download_attachment

Download an attachment by MIME part number. Use list_attachments or read_message first to see available parts. Returns base64-encoded content. Bad part numbers produce an actionable error listing known parts.

| Parameter | Required | Description | |-----------|----------|-------------| | uid | Yes | Message UID | | partNumber | Yes | MIME part number (from read_message / list_attachments) | | folder | No | Folder containing the message (default: INBOX) |

search_messages

Search messages by various criteria. Date filters use IMAP semantics: since is inclusive, before is exclusive.

| Parameter | Required | Description | |-----------|----------|-------------| | folder | No | Folder to search (default: INBOX) | | from | No | Filter by sender | | to | No | Filter by recipient | | subject | No | Filter by subject (substring match) | | body | No | Filter by body content (substring match) | | since | No | Messages on or after this date (YYYY-MM-DD, inclusive) | | before | No | Messages strictly before this date (YYYY-MM-DD, exclusive) | | seen | No | true = read, false = unread | | flagged | No | Filter by flagged/starred status | | limit | No | Max results, 1-100 (default: 20) |

get_thread

Get all messages in a conversation thread by walking In-Reply-To and References headers. Returns messages sorted chronologically (oldest first).

Prefer messageId — Message-IDs are globally unique, so this sidesteps the UID-collision footgun (UIDs are per-folder in IMAP) and walks INBOX + Sent + All Mail by default to catch replies that span folders. Output rows are tagged UID X @FolderName to disambiguate per-folder copies.

| Parameter | Required | Description | |-----------|----------|-------------| | messageId | No | RFC 5322 Message-ID (preferred over uid+folder) | | uid | No | UID of a thread message (used when messageId is omitted; folder-scoped) | | folder | No | Folder the UID lives in when using uid mode (default: INBOX) | | folders | No | Override the default folder walk when messageId is set (default: ["INBOX", "Sent", "All Mail"]) | | limit | No | Max messages to return, 1-50 (default: 25) |

Organizing

move_message

Move a message to a different folder. Returns the new UID in the destination folder when available (requires UIDPLUS server support).

| Parameter | Required | Description | |-----------|----------|-------------| | uid | Yes | Message UID | | destination | Yes | Destination folder path (e.g. Archive, Trash, Spam) | | folder | No | Source folder (default: INBOX) |

delete_message

Delete a message. By default moves to Trash for safety; set permanent=true to permanently expunge. Returns the new UID in Trash when available.

| Parameter | Required | Description | |-----------|----------|-------------| | uid | Yes | Message UID | | folder | No | Folder containing the message (default: INBOX) | | permanent | No | If true, permanently expunge instead of moving to Trash (default: false) |

update_message_flags

Add or remove flags on a message. RFC 3501 system flags: \Seen (read), \Flagged (starred), \Answered, \Draft, \Deleted, \Recent. User-defined keywords without a backslash prefix are also accepted (alphanumeric + underscore, e.g. Important, Custom_Tag). Unknown \-prefixed names are rejected.

| Parameter | Required | Description | |-----------|----------|-------------| | uid | Yes | Message UID | | folder | No | Folder containing the message (default: INBOX) | | flagsToAdd | No | Flags to add (e.g. ["\\Seen", "\\Flagged"]) | | flagsToRemove | No | Flags to remove (e.g. ["\\Seen"]) |

mark_all_read

Mark all unread messages in a folder as read. Optionally limit to messages older than a given date.

| Parameter | Required | Description | |-----------|----------|-------------| | folder | No | Folder to mark as read (default: INBOX) | | olderThan | No | Only mark messages strictly before this date (YYYY-MM-DD, exclusive) |

Configuration

Environment Variables

SMTP (required):

| Variable | Default | Description | |----------|---------|-------------| | PROTONMAIL_USERNAME | -- | Your Proton Mail email address | | PROTONMAIL_PASSWORD | -- | Your SMTP password (not your login password) | | PROTONMAIL_HOST | smtp.protonmail.ch | SMTP host | | PROTONMAIL_PORT | 587 | SMTP port | | PROTONMAIL_SECURE | false | Use TLS (true for port 465) |

IMAP (for read/search tools):

| Variable | Default | Description | |----------|---------|-------------| | IMAP_HOST | 127.0.0.1 | Proton Mail Bridge host | | IMAP_PORT | 1143 | Bridge IMAP port | | IMAP_SECURE | false | Use TLS | | IMAP_USERNAME | falls back to SMTP username | Bridge username | | IMAP_PASSWORD | falls back to SMTP password | Bridge password |

Other:

| Variable | Default | Description | |----------|---------|-------------| | DEBUG | false | Enable verbose logging to stderr | | READONLY | false | Disable all mutating tools (send, reply, forward, move, delete, flags) |

Development

npm run build          # Compile TypeScript
npm run watch          # Compile in watch mode
npm run test           # Run tests
npm run test:watch     # Run tests in watch mode
npm run lint           # Lint with ESLint
npm run format         # Format with Prettier
npm run inspector      # Launch MCP inspector

Acknowledgments

Originally based on protonmail-mcp by amotivv, inc.

License

MIT -- see LICENSE for details.