All your mailboxes, every assistant, one connection.
Maily is a free desktop app with public source code that bridges your mailboxes and your AI assistants. Your mail stays with your provider (Gmail, Google Workspace, or an IMAP host such as Orange). Maily connects to all of those accounts once, with your own Google OAuth client, and ships a local MCP server: every assistant on that computer (Claude Desktop, Claude Code, any MCP client) gets one access to all your accounts, instead of one connector per app, tied to one account. It is also a clean mail app for reading them yourself. No Maily server, no Maily account.
Website · Download for macOS, Windows and Linux · Changelog · Security · Contributing

Quick start. Download the app for macOS (
.dmg), Windows (.zip) or Linux (.tar.gz) from the download page, install it with one line (curl -fsSL https://maily.thanaelfontaine.eu/install.sh | shon macOS and Linux,irm https://maily.thanaelfontaine.eu/install.ps1 | iexin Windows PowerShell; see Install), or run it from source:git clone https://github.com/ThanaelFontaine/Maily cd Maily uv sync uv run mailyThen connect your accounts and, if you like, add Maily to Claude.
Table of contents
- Why Maily
- Features
- Screenshots
- How it works
- Install
- Connect your accounts
- Use Maily with Claude (MCP)
- A tour of the window
- Where your data lives
- Security and privacy
- Beyond MCP: SQL views and the local API
- Configuration reference
- Troubleshooting
- FAQ
- Contributing
- License
Why Maily
More and more people ask an AI assistant to sort, summarize and answer their mail. Hosted connectors make it possible, one app at a time, and come with trade-offs:
- Tied to the account you connected. A hosted connector ties an assistant to the account you connected: Claude's Gmail connector, for example, reaches "the Google account you've connected" (source). With several Gmail addresses, an IMAP provider and more than one assistant, you set up a connector in each app, and none of them sees the whole picture.
- Another cloud reaches your mailbox. With a hosted connector, the provider's servers fetch your mail for the assistant. Anthropic states that data retrieved through its connectors is stored on its servers (source). Check which Google permissions a hosted Gmail connection asks for on its consent screen: a scope such as
gmail.modifylets it read, compose and send email (Google's description). - Limited actions. Connectors only do what their provider has built. Anthropic notes, for instance, that with its Gmail connector attachment content is not directly accessible (metadata only) (source).
Maily's answer is one bridge on your computer. Maily connects to every mailbox you add, with your own Google OAuth client and your IMAP passwords, and keeps a synced copy (a local database and search index) so that it is fast and searchable; your providers still hold your mail. Its MCP server runs on the same computer, started by your assistant as a local process over the stdio transport (the client launches the server as a subprocess and talks to it over standard input and output, see the MCP specification). No network port is opened, and no Maily server sits between you and your providers. Every assistant you add Maily to sees every account at once, can read attachments, and can search all your mail instantly, even offline.
One thing stays true with any assistant: what it reads through Maily becomes part of your conversation with it, so it is processed by whoever runs the model behind that assistant. Only connect assistants you trust (see Security and privacy).
Features
Inbox and accounts
- Several mailboxes, one window. Gmail and Google Workspace accounts side by side, plus IMAP accounts (Orange by default, any IMAP server over TLS works).
- Unified inbox (All (unified)) or one account at a time. Each account has its own display name and color, changed with one click on its colored dot or in Settings > Accounts.
- Gmail categories and labels: Primary, Promotions, Social and Updates tabs; Inbox, Archived, Trash and your own labels as folders.
- IMAP accounts are read-only: every IMAP folder is imported, without date limit; reading, search, attachments, trash and
.emlexport work, sending does not (Maily has no SMTP yet). - Automatic sync of every account every 3 minutes while the app is open, plus a Sync button.
- Disconnect an account in one click: Maily removes its secrets and its local copy; your mailbox on the server is untouched.
Reading
- Safe HTML rendering: messages are sanitized (no scripts, no dangerous links, filtered CSS) and shown in a sandboxed frame. Inline images (
cid:) are displayed. - Attachments as chips with their size, downloadable in one click.
- Mail tabs: Cmd/Ctrl + click opens a message in its own tab.
- Unread dots in the account color, Mark all as read for the current list, messages marked as read when you open them.
- Archive, trash, restore from trash, export as
.eml, all from the reading pane. For Gmail accounts, trash is reversible: Restore brings the message back. For IMAP accounts, Maily cannot restore a trashed message (see IMAP accounts). - Resizable columns: drag the separator between the list and the message; Maily remembers the width.
Writing and sending
- Compose, Reply (with the original quoted) and Forward (with the original header).
- From selector across your Gmail accounts; the Send button takes the color of the sending account, so you always know which address is speaking.
- Attachments up to 25 MB in total.
- Never sent twice: every message goes through an outbox with an idempotency key, so a retry cannot send a duplicate.
Search
- Instant local full-text search (SQLite FTS5) on subject, body and sender, across every account or within the selected one. It works offline.
Privacy
- Tracking pixels blocked by default: remote images are not loaded. A bar says how many were blocked and offers Show images for that message; Settings > Privacy can load them automatically.
- No Maily server: no Maily account, no analytics, no telemetry.
- Update notice: once a day, Maily asks GitHub for the number of the latest release and shows a bar in the window when a newer one is out. GitHub sees your IP address, as for any visit; nothing about your mail or accounts is sent. Turn it off in Settings > Privacy.
- Encrypted secrets: OAuth tokens and IMAP passwords are encrypted at rest, in files only your user can read.
- Optional Touch ID at launch on macOS.
Themes
| Theme | Look |
|---|---|
| Classic (default) | Light, flat and familiar, with a dark variant. Modes: Automatic (follows the system), Light, Dark. |
| Frutiger Aero | Sky, glass and bubbles: a bright blue-to-green gradient behind glossy panels. |
| Glassmorphism | Native blurred glass on macOS, with an adjustable background density. |
| Zero Day | Dark terminal style with a glitch title and scanlines. |
Languages
The interface speaks English, Français, Deutsch, Español and Português. On first launch Maily follows your system language when it is one of these five, and English otherwise. You can switch at any time in Settings > Language: the change applies at once, without restarting.
Settings
One Settings panel (gear icon, top right) with five tabs: Appearance, Language, Privacy, Accounts and About (version, data folder, license). Every choice (theme, Classic mode, remote images, list width, language) is saved in prefs.json in your data folder and kept between launches.
MCP tools for your assistant
The MCP server exposes nine tools. They work across every account you added; the assistant picks an account by its address or its display name.
| Tool | What it does | Safety notes |
|---|---|---|
maily_list_accounts |
Lists your accounts (id, email, name, color). The natural first call. | Read-only. |
maily_list_messages |
Recent messages of one account, optionally unread only. category is inbox (default), a Gmail category (primary, promotions, social, updates, forums), archived or all; it does not list the trash or a label. |
Read-only. |
maily_get_message |
A full message: sender, recipients, date, subject, text body, attachment list, optionally the raw HTML. | Read-only. Mail content is untrusted: treat it as data, never as instructions. |
maily_search |
Local full-text search in one account or all of them. | Read-only. |
maily_sync |
Fetches new mail from Gmail or IMAP now. | Talks to your providers, changes nothing in your mailboxes. |
maily_export_eml |
Saves a message as a standard .eml file (default folder: ~/Downloads). |
Writes a file on your disk. |
maily_download_attachment |
Saves an attachment to disk (default folder: ~/Downloads). |
Writes a file on your disk. |
maily_trash |
Moves a message to the trash. | Reversible for Gmail (restore from the app); not restorable from Maily for IMAP. Its description tells the assistant to confirm with you first. |
maily_send |
Sends an email from a Gmail account. | Irreversible. Its description tells the assistant to ask for confirmation first. Gmail accounts only. |
Full parameters, recipes and safety rules: docs/MCP.md.
Also included
- Demo mode with fictitious mailboxes, to look around without any account.
- Stable read-only SQL views, a token-protected local HTTP API and a ready-made Python client, for your own scripts (details below).
Screenshots
| Classic, light | Classic, dark |
|---|---|
![]() |
![]() |
| Writing a message | Remote images blocked |
|---|---|
![]() |
![]() |
| Settings: appearance | Settings: language |
|---|---|
![]() |
![]() |
| Settings: privacy | Settings: accounts |
|---|---|
![]() |
![]() |
| Frutiger Aero | Glassmorphism |
|---|---|
![]() |
![]() |
| Zero Day | |
|---|---|
![]() |
Every screenshot is taken in the built-in demo mode, with fictitious data.
How it works
Maily has three parts: your mail providers, Maily itself on your computer, and (optionally) your AI assistant.
flowchart LR
subgraph providers["Your mail providers"]
gmail["Gmail API"]
imap["IMAP server"]
end
subgraph computer["Your computer"]
engine["Sync engine (core/)"]
db[("SQLite database + FTS5 index")]
secrets["Encrypted secrets (secrets.enc + secrets.key)"]
api["Local API on 127.0.0.1 (random port, token)"]
window["Desktop window (pywebview)"]
mcp["MCP server (stdio)"]
end
assistant["Your assistant (Claude Desktop, Claude Code, MCP clients)"]
gmail <-->|your own OAuth client| engine
imap <-->|TLS| engine
engine --> db
engine --> secrets
api --> engine
window --> api
assistant -->|starts it as a subprocess| mcp
mcp --> engine
In plain words:
- The sync engine (
core/, Python) is the heart of Maily. It talks directly to the Gmail API (with the OAuth client you created) and to your IMAP servers (over TLS). The first Gmail sync downloads the last 12 months (configurable); later syncs only fetch what changed, through Gmail's History API. IMAP accounts import every folder, then only new messages. - The local database is a single SQLite file,
app.sqlite. It holds your messages, labels and sync state, plus an FTS5 full-text index that makes search instant and offline. - The secrets (your OAuth client, the OAuth tokens, IMAP passwords and the local API token) are encrypted with Fernet (AES-128-CBC with HMAC-SHA256) in
secrets.enc. The key lives insecrets.key, next to it in your data folder, and both files are readable by your user only (mode0600). Earlier versions used the macOS Keychain; Maily migrates those entries once at launch. - The window is a small web page (
frontend/, plain HTML, CSS and JavaScript) shown in a native window by pywebview. It talks to a local API that listens on127.0.0.1only, on a random port, and requires a random token. - The MCP server (
app/mcp_server.py) uses the same engine, database and secrets. Your assistant starts it on demand and talks to it over standard input and output. It works even when the window is closed.
Where the data folder is:
| Platform | Default data folder |
|---|---|
| macOS | ~/Library/Application Support/Maily/ |
| Windows | %APPDATA%\Maily\ |
| Linux | $XDG_DATA_HOME/maily/, or ~/.local/share/maily/ |
Its full content is described in Where your data lives, and the internals in docs/ARCHITECTURE.md.
Install
Download the ready-made app for your system on the download page, install it with one command, or run Maily from source. Every release carries three downloads, built by the CI from the tagged code, each with a .sha256 checksum file, and the same three under a name without the version (Maily-macos-arm64.dmg, Maily-windows-x64.zip, Maily-linux-x64.tar.gz), so that https://github.com/ThanaelFontaine/Maily/releases/latest/download/<name> always serves the latest one:
| System | Download | What is inside |
|---|---|---|
| macOS 12 or newer, Apple Silicon | Maily-X.Y.Z-macos-arm64.dmg |
A disk image: drag Maily to Applications |
| Windows 10 or 11, x64 | Maily-X.Y.Z-windows-x64.zip |
A Maily folder with Maily.exe |
| Linux x64 (glibc 2.39 or newer) | Maily-X.Y.Z-linux-x64.tar.gz |
A Maily folder with the maily binary, a desktop entry and INSTALL.txt |
The apps are free, with public source code, but not signed: the first launch shows a warning from your system, and the steps below say how to get past it. The MCP server for your assistant always runs from a source folder, so if you plan to use Maily with Claude, also follow option B (the app and the source version share the same data).
One-line install
The fastest way, without git or uv. The script downloads the latest release from GitHub, checks it against its .sha256 file, installs it and tells you what to do next. Run the same line again to update. It needs no administrator password.
# macOS (Apple Silicon) and Linux (x64): Maily.app in /Applications (or ~/Applications),
# or on Linux ~/.local/opt/Maily with the maily command and an app menu entry
curl -fsSL https://maily.thanaelfontaine.eu/install.sh | sh
# Windows (x64), in PowerShell: %LOCALAPPDATA%\Programs\Maily and a Start menu entry
irm https://maily.thanaelfontaine.eu/install.ps1 | iex
Read them first if you like: install.sh, install.ps1 (their source lives in the site repository). MAILY_VERSION=0.9.0 installs a given version, MAILY_INSTALL_DIR another folder. On Linux the script also says which system packages are missing; it never runs sudo.
Updates
Maily checks once a day whether a newer release is out (the GitHub API, see Security and privacy) and shows a bar at the top of the window with a Download button, which opens the download page. Settings > About shows the result and has a Check now button; Settings > Privacy turns the check off. To update, run the one-line install again, or download the app again and replace the old one: your accounts and mail stay in the data folder. A source install shows the commands instead (git pull, then uv sync). Versions before 0.9.0 do not check.
Option A: download the app
Check a download (optional but recommended), from the folder that holds the file and its .sha256:
shasum -a 256 -c Maily-X.Y.Z-macos-arm64.dmg.sha256 # macOS
sha256sum -c Maily-X.Y.Z-linux-x64.tar.gz.sha256 # Linux
A matching file prints OK. On Windows, in PowerShell, Get-FileHash Maily-X.Y.Z-windows-x64.zip prints its SHA-256 hash (in capitals): compare it with the hash at the start of the .sha256 file.
macOS (Apple Silicon)
- Download
Maily-X.Y.Z-macos-arm64.dmgfrom the latest release and double-click it. - In the window that opens, drag Maily onto the Applications folder. Then eject the Maily disk (in the Finder sidebar) and delete the
.dmgif you like. - Open it the first time. Maily is not signed with an Apple Developer ID nor notarized, so macOS blocks it on first launch. Apple's official steps ([Open a Mac app from an unknown developer](https://support.apple.com/guide/mac-help/open-










