Proton Bridge MCP

What Proton Bridge MCP can do.

Reading, searching, filing, and the parts that stop and ask  ·  source on GitHub  ·  buy me a coffee  ·  Independently scored on Glama

What it can do

Search and read mail, pull attachments out and read them (including the text of PDF invoices), tag and file messages one at a time or in batches, reply in thread, and send or forward behind a confirmation step.

Anything that sends takes draft=true instead, which puts it in your Drafts for you to look at. That path needs no confirmation, because nothing goes anywhere.

Files can be attached to anything you send, though only from directories you've said are allowed. Reading any file on the machine and posting it out is how data walks off a computer, so the default is the attachments folder and widening it is your decision, not something an instruction in an email can talk it into.

ToolWhat it does
list_foldersEvery folder and label, read live each time. Name one and you get its counts, plus the UIDVALIDITY every uid in it depends on
poll_folderWhat has arrived since you last looked, and confirms a batch was handled
search_mailSearch by text, sender, subject, date range, unread and starred, in one folder or across every folder and label with duplicates collapsed. With nothing to search for, it lists the newest. Can also report each message's other labels and folders
get_headersHeaders with SPF, DKIM and DMARC verdicts, and Proton metadata
read_messageFull headers and body
list_attachmentsReal documents, kept apart from inline images and PGP keys
read_attachmentPulls the text out, PDFs included, and hands an image back so it can actually be looked at
save_attachmentWrites a file out, deleted again after 15 minutes unless you say otherwise
purge_attachmentsDeletes those files now
find_threadThe whole conversation, and which messages carry documents
replyReplies with correct threading, to everyone if you ask, with your own addresses stripped from Cc, gated
create_draftWrites into Drafts, never sends
update_draftReplaces a draft, keeping its threading
delete_draftMoves a draft to Trash, gated
send_draftSends a saved draft, gated
unsubscribeReports how to unsubscribe, and can send the email form
markRead, unread, star or unstar, one message or many in one pass
apply_labelTags one message or many, leaves them where they are
remove_labelTakes a label off one message or many, leaves them where they are, gated
move_to_folderFiles a message somewhere else, or many at once, gated for many
create_folder_or_labelNew folder or label, gated
rename_folder_or_labelRenames one, gated, and leaves Inbox, Sent, Trash and the rest of the built-in folders alone
delete_labelDeletes one label or several, messages keep their place and lose the tag, gated
sendGated, and can carry attachments
forwardGated

Three things it can't do, and won't pretend otherwise. Folders can be created and renamed but not deleted, because a folder is where a message actually lives and deleting one would have to decide what happens to the mail inside it, so that stays a job for the Proton app. Bridge has no access to Proton's server-side filters or auto-forwarding rules, so those stay a manual job in the Proton web app. And nothing here hard-deletes, the furthest it goes is Trash.

Watching for new mail

poll_folder hands back whatever has turned up since you last looked, which is what turns this from something that reads your mail when asked into something that can react to mail arriving.

The first poll on a folder returns nothing on purpose. It notes where the folder currently ends, so switching it on doesn't dump years of backlog into a conversation. It reads nothing as read either.

If you're doing something with each message that you'd rather not do twice, poll with advance=false. You get the batch and a checkpoint, the cursor stays where it was, and polling again hands you the same batch until you confirm, by polling once more with the checkpoint as commit. Crash halfway and you pick up where you left off instead of losing the lot. Confirming twice is harmless.

The cursor records the UIDVALIDITY next to the message number, so a folder that resyncs underneath you is spotted rather than acted on. When that happens it re-anchors to the current end and says so, because the alternative is replaying whatever those old numbers now point at.

Getting at attachments

Three situations, two tools. read_attachment pulls the text out and is what you want almost always, invoices included, and nothing touches the disk. save_attachment writes the file out for anything that isn't text, and works if whatever you're using can read files off disk. And read_attachment hands an image straight back so it can be looked at, which is the only route to a photo or a scan when the client can't reach the filesystem.

Images only for that last one, on purpose. Encoding a file to send it inline makes it a third bigger and drops it into the conversation as characters, and for a spreadsheet or a Word document that's a lot of context spent on something nothing can read. Images are different because they arrive as an image rather than as text, so they cost about what a picture costs and can actually be seen.

Searching everywhere

A message in Proton lives in one folder but also turns up under every label you've put on it, and again in All Mail. Sweep the lot naively and you get the same mail three times. search_mail across every folder matches on Message-ID, arrival time and size instead, so you get one entry per message with the other places it appears listed underneath, and it scans All Mail last as a safety net rather than treating it as a source. Every hit carries the UIDVALIDITY of the folder it was found in, because those differ per folder and a uid without one isn't safe to act on.

UIDs go stale

IMAP identifies a message by a number that's only meaningful until the folder resyncs. When that happens the number quietly starts pointing at something else, which is how the wrong message gets filed or trashed. Every folder reports a UIDVALIDITY alongside its uids, and if you hand one back with a uid that no longer matches, the tool refuses and asks you to search again rather than acting on the wrong mail.

Conversations aren't messages

Worth knowing before you trust an answer about attachments. Proton's app groups mail into conversations and shows a paperclip if anything in the thread has one. IMAP hands over individual messages with no grouping at all. A reply sitting in your inbox can be completely empty while the original, filed somewhere else, is carrying the PDFs. That's why find_thread exists, and why "no attachments" from a single message is an answer worth checking.