sofatools / mailsync
Let your agent search your mail. Without your password. Without a send button.
mailsync mirrors any number of mailboxes into one local SQLite file with full-text search and serves it to an AI agent through a read-only MCP server. The agent never sees your credentials and cannot send, move, flag or delete anything.
- IMAP + Exchange Server
- SQLite + FTS5
- MCP server (stdio)
- Read-only, end to end
mailsync syncproton: new 5work: new 3mailsync search invoice#7 2026-10-22 ap@corp.example.com Invoice 2026-311 needs your approval#1 2026-10-19 billing@example-hosting.com Your invoice INV-2026-0142The problem
Most ways to give an agent your mail give it too much.
You want to ask Claude “what did the landlord say about the deposit?”. Many mail MCP servers do that by logging in live: the password sits in the MCP client’s config, every question is a round trip to your mail server, and the same server often offers tools to send, move or delete. Hosted connectors cover Gmail or Microsoft 365, not Proton, GMX or the Exchange server at work.
What mailsync does
mailsync splits the job in two. The sync, which you run, gets the password from pass or an environment variable and reads your mailboxes without changing anything (EXAMINE and BODY.PEEK for IMAP, SyncFolderItems and GetItem for Exchange). The MCP server, which the agent talks to, opens the resulting SQLite file read-only and offers five search tools. No credentials, no network, no write tools.
Demo
Two mailboxes, one search
A Proton account through the Bridge and an Exchange account at work, synced into one file. On the left the CLI, on the right what an agent gets back from the MCP server for the same database.
mailsync syncproton: new 5work: new 3mailsync accountskey kind messages last_sync errorproton imap 5 2026-10-23T18:32:40+00:00 work ews 3 2026-10-23T18:32:40+00:00 mailsync search invoice#7 2026-10-22 ap@corp.example.com Invoice 2026-311 needs your approval#1 2026-10-19 billing@example-hosting.com Your invoice INV-2026-0142mailsync search "kündigung"#3 2026-10-21 service@fitness.example.de Bestätigung Ihrer Kündigungmailsync search "" --from @example.org --since 2026-10-15#2 2026-10-20 mara@example.org Flat viewing on Saturdaymailsync show 6From: Priya Raman <priya@corp.example.com>To: Sam Example <sam@corp.example.com>Subject: Q4 roadmap review – slidesDate: 2026-10-21T08:12:00+00:00Account: workFolder: InboxAttachments: roadmap-q4.pdf (482113 bytes) Slides for Thursday attached. Please add your numbers to page 6 before the review.mailsync mcpsearch_mail(query: "invoice", limit: 2)[ { "id": 7, "account": "work", "folder": "Inbox", "thread_key": "work:conv-2", "subject": "Invoice 2026-311 needs your approval", "sender_name": "Accounts Payable", "sender_email": "ap@corp.example.com", "date": "2026-10-22T14:03:00+00:00", "received_at": "2026-10-22T14:03:00+00:00", "is_read": false, "has_attachments": false, "snippet": "[Invoice] 2026-311 needs your approval" }, { "id": 1, "account": "proton", "folder": "INBOX", "thread_key": "proton:inv-0142@example-hosting.com", "subject": "Your invoice INV-2026-0142", "sender_name": "Example Hosting", "sender_email": "billing@example-hosting.com", "date": "2026-10-19T05:02:00+00:00", "received_at": "2026-10-19T05:02:00+00:00", "is_read": false, "has_attachments": false, "snippet": "Your [invoice] INV-2026-0142" } ]list_accounts()[ { "key": "proton", "kind": "imap", "display_name": "proton", "last_sync_at": "2026-10-23T18:32:40+00:00", "last_error": null, "folders": 2, "messages": 5 }, { "key": "work", "kind": "ews", "display_name": "work", "last_sync_at": "2026-10-23T18:32:40+00:00", "last_error": null, "folders": 1, "messages": 3 } ]
What’s included
mailsync sync: incremental (UIDVALIDITY/UID for IMAP,SyncFolderItemsstate for Exchange), resumable, in small batches; one failing account does not stop the others- Setup notes for Proton Mail (through Proton Mail Bridge), iCloud, GMX, any IMAP server, and Exchange Server (on-premises) through EWS with Basic or NTLM authentication
- One SQLite file with FTS5 full-text search over subject, sender and text; conversations grouped into threads
- CLI:
search,show,accounts,status, each with--json - MCP server (stdio) with five tools:
search_mail,get_mail,list_threads,get_thread,list_accounts, all annotated read-only; the database is opened withmode=ro - Passwords only from an environment variable or a command (
pass,op read,secret-tool…); never stored, logged or echoed - A systemd timer example, an example config and a README with a page per provider
What it does not do
- Sending, moving, deleting or flagging mail. Not as an option either.
- Attachment contents: mailsync stores name, type and size only.
- OAuth, so no Gmail and no Microsoft 365 / Exchange Online, where Microsoft is retiring EWS anyway.
- Proton labels (real folders are synced), and a web interface.
You need
- Python 3.12+ and uv; developed and used on Linux
- IMAP access to your mailboxes, or for Exchange: an on-premises Exchange Server with EWS and Basic or NTLM authentication
- For Proton: a paid Proton plan and Proton Mail Bridge running on the same machine
- An MCP client such as Claude Code or Claude Desktop
Status
What has been tested
Current release: 0.1.1.
Tested against real mailboxes: Proton Mail Bridge, iCloud, GMX, a hosted IMAP server and an on-premises Exchange Server with German folder names.
The sync, the search and the MCP tools are also covered by automated tests against a stand-in IMAP server and a mocked Exchange. Exchange Online (Microsoft 365) is not supported.
Alternatives
Compared with other ways to give an agent your mail
There are good free options. If one of them fits, use it; mailsync is for people who want several providers, Exchange included, behind one read-only, credential-free interface.
| Approach | Agent holds credentials | Can write | Providers | Works offline |
|---|---|---|---|---|
| mailsync | No | No (no write tools, database read-only) | IMAP, Proton via Bridge, iCloud, GMX, Exchange Server (on-premises) | Yes, searches the local mirror |
| Live IMAP MCP servers | Usually, in the MCP config | Often (send, move, delete) | IMAP | No |
| Hosted Gmail / Microsoft 365 connectors | OAuth token held by the AI service | Depends on the connector | Their own provider | No |
| notmuch or mu + mbsync, your own MCP glue | No | Up to you | IMAP (Exchange via extra tools) | Yes |
Categories, not individual products; details vary per project. Trademarks belong to their owners; no affiliation.
Price
Pay once. Keep the updates.
No subscription and no seats. You buy mailsync once and keep read access to its repository, so every later version is a git pull away.
The license key Polar sends is your proof of purchase; mailsync never checks it and never phones home.
- Read access to the private GitHub repository
- All future updates, via git pull
- A license key as proof of purchase
- Any number of your own devices
Checkout by Polar (Polar Software, Inc.) as Merchant of Record: Polar is the seller, issues the invoice and handles sales tax/VAT. You need a GitHub account. Terms
Questions
Does the agent ever see my password?
No. Passwords are only needed by mailsync sync, which you run (by hand or from a timer). They come from an environment variable or a command and are never written to the config, the database or the logs. The MCP server only has the database file.
Can the agent send, delete or mark mail as read?
No. There are no write tools, the MCP process opens the database read-only, and even the sync never changes anything on the server: IMAP folders are opened with EXAMINE and bodies fetched with BODY.PEEK, so read flags stay as they are.
Where does my mail end up?
In one SQLite file on your machine (default ~/.local/share/mailsync/mail.db). Nothing goes to a cloud service. The file holds your mail in plain text, so protect it the way you protect your mail client’s cache.
Gmail? Microsoft 365 / Exchange Online?
No. Both need OAuth, which mailsync does not do, and Microsoft is retiring EWS in Exchange Online. mailsync works with Exchange Server on-premises through EWS with Basic or NTLM authentication.
Which MCP clients work?
Anything that can start a stdio MCP server. The README has the one-liner for Claude Code (claude mcp add mailsync -- mailsync mcp) and the JSON for Claude Desktop.
What exactly do I get when I buy?
One payment, no subscription. You get read access to the private GitHub repository sofatools/mailsync – the full source, the documentation and every future update, which you fetch with git pull. Polar also issues a license key; it is your proof of purchase. mailsync does not check it and never phones home.
How do I get access to the repository?
You need a GitHub account. After checkout, Polar asks you to connect it and then invites that account to the repository with read access. You install straight from the private repository (for example uv tool install git+https://github.com/sofatools/mailsync) once git can use your GitHub login; the docs show how. There is no public package.
What does the license allow?
One purchaser, any number of your own devices and accounts. Not allowed: redistributing, reselling or publishing the source. The software comes as is, without warranty. Full license text.
Who sells it, and what about invoices, VAT and refunds?
The checkout is run by Polar, which acts as Merchant of Record: Polar is the seller on your invoice, calculates and remits sales tax or VAT, and handles refunds under its buyer terms. See Terms.
Where do bug reports go?
To the issue tracker of the private repository you get access to. There is no support contract and no promised response time; this is a small product made by one person.