bulk_move
Move many messages in a single IMAP operation. Accepts either an explicit uids array or match criteria (XOR, not both). Supports dryRun: true to preview which UIDs would be affected without making changes — match-based dry-runs run the SEARCH results through a FETCH-based existence pass so the previ
How to use it
Project documentation lists bulk_move for the Proton Mail MCP MCP server. Add the server to your MCP client (Claude Desktop, Cursor, Windsurf and others), then check which tools your installed version makes available. Tool availability can depend on configuration and credentials. A server handshake does not verify this tool’s behavior. See the full listing for setup details.
Install Proton Mail MCP
npx -y proton-mail-mcpOther tools in Proton Mail MCP (31)
Delete many messages in a single IMAP operation. Same XOR uids/match input and dryRun support as bulkmove. Defaults to soft-delete via the resolved Trash path. A subject/body match appends a staleness warning — Proton's content SEARCH lags ~30–60s, so recent mail can be silently missed; prefer from:
Add or remove flags on many messages in a single IMAP operation. Same XOR uids/match input and dryRun support. Reports notApplied: string[] for flags the server silently dropped across every affected UID (e.g. Proton's user-keyword drop).
Add or remove Proton labels on many messages in a single IMAP operation. Same XOR uids/match input and dryRun support as the other bulk tools. Adds are batched (one COPY of the joined UID range per label); removes walk each label mailbox by Message-ID. Reports notApplied: string[] for labels with no
Return a count of messages matching optional criteria, backed by IMAP SEARCH. No envelope fetch — just a number.
Create a new mailbox folder. Idempotent — succeeds silently if the folder already exists. Restricted to the Folders/ namespace (e.g. Folders/Receipts); root-level paths are rejected with an actionable error. Labels/... paths are rejected with a redirect to the dedicated createlabel tool. . and .. pa
Create a new Proton label. Pass the bare label name; the Labels/ prefix is added internally. Idempotent. The response returns the full Labels/X path — copy that into updatemessagelabels.labelsToAdd (which requires the full path, not the bare name).
Delete a folder or label container. Restricted to the Folders/ and Labels/ namespaces so system mailboxes (INBOX, Sent, Trash, etc.) cannot be removed.
Delete a message. By default moves to Trash for safety (resolved via special-use annotation); set permanent=true to permanently expunge. Returns the new UID in Trash when available. Soft-deleting a message that is already in Trash is a no-op on the server; the tool detects this and returns an action
Delete all messages in a thread. Per-folder by default; set acrossFolders: true for cross-folder walk.
Download an attachment by MIME part number. Use listattachments or readmessage first to see available parts. By default returns base64-encoded content inline. Bad part numbers produce an actionable error listing known parts.
Permanently empty a folder via atomic UID EXPUNGE (client.messageDelete). Requires confirm: true. By default restricted to Trash and Junk to prevent accidents; set allowAnyFolder: true to target any folder. Pass dryRun: true to preview the count that would be deleted without touching any mail (no co
Add or remove flags on all messages in a thread. Per-folder by default; set acrossFolders: true for cross-folder walk.
Return total/unread counts plus scanned-envelope aggregations: oldest message date, newest message date, and total message bytes. Response includes scanned and truncated fields for transparency.
Forward a message to new recipients. Original attachments are carried forward by default. Unlike reply, a forward does not set In-Reply-To/References — it starts its own conversation and leaves the original message's \Answered flag untouched.
Get all messages in a conversation thread by walking In-Reply-To and References headers. Returns messages sorted chronologically (oldest first).
List attachment metadata (part numbers, filenames, types, sizes) for a message without downloading the body. Composes with downloadattachment for bulk extraction. The reported size is the decoded file size (roughly what you get on save), estimated from the IMAP-encoded octet count — base64 parts are
List all mailbox folders with message and unread counts. No parameters. Counts come from a cached IMAP STATUS that Proton Bridge can serve stale — for an exact count (e.g. before deleting or emptying a folder), use countmessages or folderstats, which query the live mailbox. The output includes a foo
List recent messages from a folder. Supports UID-based pagination.
Mark all unread messages in a folder as read. Optionally limit to messages older than a given date. Pass dryRun: true to preview the affected count without flipping any flags.
Move a message to a different folder. Returns the new UID in the destination folder when available (requires UIDPLUS server support).
Move all messages in a thread to a destination folder. Identified by Message-ID. Per-folder by default; set acrossFolders: true to walk INBOX + Sent + All Mail. When the walk surfaces a thread member only via All Mail (e.g. the message actually lives in Folders/Archive), the server expands the searc
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
Rename an existing folder or label. Restricted to the Folders/ and Labels/ namespaces on both from and to so system mailboxes (INBOX, Sent, Trash, etc.) can't be renamed — without this guard, renamefolder(from: "INBOX", to: ...) would succeed against Proton Mail Bridge and relocate INBOX's contents.
Reply to all original recipients (sender + TO + CC), excluding the authenticated user. Same threading + quoting semantics as replyemail. Use this instead of replyemail + replyAll: true for clarity. Self-exclusion covers the whole recipient set including the primary To: replying-all to a message you
Reply to a message with proper threading headers (In-Reply-To, References). Includes the quoted original message with attribution by default.
Save an email as a draft without sending it. The draft is placed in the user's \Drafts special-use folder (resolved at runtime; falls back to literal Drafts if no annotation). Returns the draft UID when available.
Search messages by various criteria. Date filters use IMAP semantics: since is inclusive, before is exclusive.
Send an email using Proton Mail SMTP.
Return a sender frequency table over a configurable date range, sorted by message count descending. Collapses display-name variants of the same address. Each row carries a direction: "self""received" tag so callers scanning All Mail (which spans Sent) can tell outbound from inbound.
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, CustomTag). Unknown \-prefixed names are rejected.
Add or remove Proton labels on a message. Labels live under the Labels/ namespace and are additive — the message stays in its source folder while gaining or losing label tags.