Skip to content

Releases: MarcinWalendowski/email-local-mcp

Email Local MCP v0.3.0

Choose a tag to compare

@MarcinWalendowski MarcinWalendowski released this 01 Aug 20:38

Highlights

  • The app is now published under its author's name. The macOS bundle identifier
    changed from com.lokilabs.EmailLocalMCP to pl.marcinwalendowski.EmailLocalMCP.
    This one needs a manual reinstall. Sparkle identifies an app by its bundle
    identifier, so an installed 0.2.0 will not see this update and will keep reporting
    itself up to date. Download the DMG below and drag it over your existing copy — your
    accounts and credentials survive, because neither ~/.email-local-mcp/accounts.json
    nor the Keychain entries are keyed on the bundle id. Verified on a real install.
    Auto-update resumes normally from 0.3.0 onward.
  • Three security advisories patched, including one high (fast-uri host confusion).
    npm audit reports zero.
  • list_accounts now answers where your mail is handled, per account, so an agent
    asked the question replies from data rather than from the README.

Changes

See the 0.3.0 section of the changelog.

Notable non-change: Composio support was built as a third way to connect a mailbox and
is deliberately not in this build. Composio never releases the OAuth token, so such
an account's mail would be fetched and sent by their servers — and this app is sold on
the promise that your mail never leaves your machine. The code lives in src/hosted/,
excluded from the build, for a hosted deployment where that is what a user signed up
for. A guard now fails the build if anything shipped ever imports it.

Install

Download Email-Local-MCP-0.3.0-universal.dmg below (one universal build for Apple
Silicon and Intel, Node is bundled, no prerequisites). Open it and drag Email Local MCP
to Applications. The build is ad-hoc signed and not yet notarized, so the first launch
is blocked: open System Settings > Privacy & Security, scroll to the "Email Local MCP
was blocked" notice, and click Open Anyway.

CLI only: npx -y email-local-mcp or brew install marcinwalendowski/tap/email-local-mcp

Known limitations

  • Upgrading from 0.2.0 is manual, once, because of the bundle identifier change above.
  • Not notarized yet, so the first launch needs the Gatekeeper "Open Anyway" step.
  • macOS re-shows the Keychain "Always Allow" prompt after each app update while builds
    are ad-hoc signed (a Developer ID signature will end that).

Email Local MCP v0.2.0

Choose a tag to compare

@MarcinWalendowski MarcinWalendowski released this 01 Aug 15:29

Highlights

  • Your accounts come across on their own. If you used this project under a previous name (anymail-mcp, or gmail-mcp before that), the first start of v0.2.0 carries your account registry, App Passwords and OAuth refresh tokens forward. Nothing to run.

    v0.1.0 shipped deliberately without this, on the reasoning that the install base was small enough that re-adding accounts was cheaper. That got the comparison backwards: the maintainer pays a compatibility path once, but every user pays "re-add everything" individually, on opening a working app and finding it empty with nothing saying their data is still on disk. Fixed.

Changes

Added

  • Automatic import from a previous install. The registry with its default / read-only / provider flags, App Passwords, and OAuth refresh tokens plus client secrets. email-local-mcp import-legacy [--force] is the explicit form.

    Four rules, because every failure mode of a migration looks like success:

    • Copied, never moved. ~/.anymail-mcp/ and the old Keychain items are left exactly as they were. Delete them by hand once you are satisfied.
    • Merge, never overwrite. An account already configured under the new name wins, including its credential and its default flag.
    • Once, then never again. A marker at ~/.email-local-mcp/legacy-import.json means an account you delete later stays deleted.
    • Never fatal, never half-marked. A locked Keychain cannot stop the server starting, and does not write the marker either, so the next start retries. An account imported without its credential would look configured and fail on first connect.

Fixed

  • The CLI could never report failure to a script. process.exit(0) in the command branch overwrote process.exitCode, so a subcommand signalling partial failure exited 0 anyway.

Install

Download Email-Local-MCP-0.2.0-universal.dmg below (one universal build for Apple Silicon and Intel, Node is bundled, no prerequisites). Open it and drag Email Local MCP to Applications. The build is ad-hoc signed and not yet notarized, so the first launch is blocked: open System Settings > Privacy & Security, scroll to the "Email Local MCP was blocked" notice, and click Open Anyway.

Already running v0.1.0? The app checks for updates on launch and every 6 hours and installs them itself.

CLI only: npx -y email-local-mcp — or claude mcp add email-local -- npx -y email-local-mcp.

Known limitations

  • Not notarized yet, so the first launch needs the Gatekeeper "Open Anyway" step.
  • macOS re-shows the Keychain "Always Allow" prompt after each app update while builds are ad-hoc signed.
  • On a macOS beta/seed build, brew install of the formula can be blocked by Homebrew demanding an Xcode version Apple has only shipped as a Beta. Use the cask or npx until a stable Xcode for your macOS ships.

v0.1.0 — Email Local MCP

Choose a tag to compare

@MarcinWalendowski MarcinWalendowski released this 01 Aug 12:43

Renamed from AnyMail MCP, and now installable in one line.

Install

# CLI + MCP server, any platform
npx -y email-local-mcp            # or: claude mcp add email-local -- npx -y email-local-mcp

# macOS, via Homebrew
brew install marcinwalendowski/tap/email-local-mcp          # CLI + server
brew install --cask marcinwalendowski/tap/email-local-mcp   # menu-bar app

Or download the DMG below. One universal build for Apple Silicon and Intel, with Node bundled inside.

Breaking: if you already run AnyMail MCP

This is a clean break and you reinstall once.

  • Auto-update stops. The bundle identifier changed from com.lokilabs.AnyMailMCP to com.lokilabs.EmailLocalMCP, and Sparkle identifies an app by that string. Your installed copy will never see this release. Install this one and auto-update resumes.
  • Accounts must be re-added. Credentials are keyed by Keychain service (anymail-mcp to email-local-mcp) and the registry moved from ~/.anymail-mcp/ to ~/.email-local-mcp/. Re-run email-local-mcp add <email> or email-local-mcp login <email>, then delete the stale anymail-mcp Keychain items and ~/.anymail-mcp/.
  • Re-register the MCP server. The old spawn command points at the old name.

No migration shim ships, deliberately: the install base is small enough that one reinstall is cheaper to reason about than a compatibility path that reads two Keychain services forever.

Why the rename

The npm names in this category are being taken fast. anymail-mcp was published by an unrelated author on 2026-07-27 and mailbridge-mcp by another on 2026-06-09, both IMAP/SMTP MCP servers with near-identical descriptions. Publishing under a name someone else owns was not an option.

Known limitations

The app is ad-hoc signed and not notarized, so the first launch is blocked: System Settings > Privacy & Security > Open Anyway. macOS remembers it.

AnyMail MCP v0.0.1-rc.2

Pre-release

Choose a tag to compare

@MarcinWalendowski MarcinWalendowski released this 15 Jul 08:57

[0.0.1-rc.2] - 2026-07-15

Changed — BREAKING

  • gmMsgIdid, gmThrIdthreadId across every tool's input and output.
    The engine serves iCloud, Fastmail and generic IMAP as well as Gmail, but the schema
    still named its ids after Gmail's X-GM-MSGID / X-GM-THRID — on a non-Gmail
    account the id is really folder+uidvalidity+uid. The fields were always documented
    as opaque and provider-defined; now they're named that way, matching what the code
    calls them internally and what Gmail's own API calls them.

    get_message and friends now take {id}; get_thread takes {threadId}. Note
    id is not messageId — the latter is still the RFC822 Message-ID header, and
    both appear on a message summary. Any agent that hardcoded the old field names must
    be updated; agents reading the schema each session need no change.

AnyMail MCP v0.0.1-rc.1

Pre-release

Choose a tag to compare

@MarcinWalendowski MarcinWalendowski released this 15 Jul 08:42

[0.0.1-rc.1] - 2026-07-15

First release candidate. The earlier v0.1.0v0.3.0 tags and releases have been
withdrawn and the version reset: this project is pre-1.0, the public version history
restarts here, and interfaces may still change without notice. Everything below is the
current feature set, not a diff against a withdrawn build.

Added

  • Multi-account, multi-provider email MCP engine (Node/TypeScript), exposing full
    CRUD over IMAP/SMTP to any MCP client. One agent session can span several mailboxes
    across different providers; every tool takes an optional account.
  • Providers — Gmail (labels, threads, native X-GM-RAW search) plus a generic
    IMAP/SMTP provider for iCloud, Fastmail, or any host
    (--provider icloud|fastmail|imap, with custom host/port). Non-Gmail accounts are
    folder-based: no labels, no server-side threads, text-only search. list_accounts
    reports each account's provider so an agent can tell which rules apply.
  • Per-message toolslist_accounts, search_messages, get_message,
    get_thread, list_labels, get_attachment, send_message, create_draft,
    create_label, modify_labels, mark_read, mark_unread, star, unstar,
    archive, move_message, trash_message, delete_message, add_account.
  • Query-first bulk toolsmark_all_read, bulk_modify_labels, bulk_move,
    bulk_trash, bulk_delete, empty_spam, empty_trash. Each takes
    {query?, mailbox?, dryRun?, confirm?, max?} and acts on the whole matching set in
    one pass instead of one call per message. dryRun:true previews the count and a
    sample; destructive or >100-message batches require confirm:true; partial failures
    are reported, never hidden. Spam and Trash are reachable via mailbox.
  • Resumable bulk — removing ops (trash / move / delete / empty) act on up to max
    (default 2000) messages per call and return {matched, affected, remaining, done};
    when done:false, re-run the same call to continue. Keeps a 10k-message sweep under
    the client's tool timeout.
  • Two transports from one engine — stdio, and an always-on local HTTP server on
    127.0.0.1:8765.
  • CLI for account management: add, list, test, default, remove,
    install, token. install registers the server into Claude Desktop, Claude Code,
    Cursor, VS Code and Windsurf.
  • macOS menu-bar app (Swift/AppKit) — supervises the engine, with an Add Account
    window (provider picker + custom IMAP host/port), Install into Agents, and Start at
    Login. The App Password never reaches the model: it is posted to the local engine,
    which stores it in the Keychain.
  • "Create an App Password" assistant in the app — opens the provider's page in your
    own browser, or hands the task to a local (Claude for Chrome) or cloud
    (ChatGPT / Claude.ai) agent. It never automates the provider's page itself; cloud
    options carry an inline full-mailbox exposure warning and are never the default.
  • Security — App Passwords only in the macOS Keychain; loopback-only bind;
    bearer-token auth on every request; Origin validation (DNS-rebinding defense);
    per-account read-only mode; confirm:true gate on permanent delete; stderr logging
    with secret redaction.

Note for anyone running a withdrawn 0.1–0.3 build

The stored identifiers were renamed from gmail-mcp to anymail-mcp, so an upgrade
will not find your existing accounts or App Passwords. To carry them over:

mv ~/.gmail-mcp ~/.anymail-mcp   # keeps accounts.json + your local server token

Then re-add each account (anymail-mcp add <email>) to write its App Password under
the new Keychain service, and delete the stale gmail-mcp entries in Keychain Access.
Gmail-specific names (imap.gmail.com, [Gmail]/Spam, the X-GM-* extensions) are
unrelated to this and unchanged.