Skip to content

Releases: marlinjai/email-mcp

v1.3.0: cross-account transfer + Gmail offset fix

Choose a tag to compare

@marlinjai marlinjai released this 14 Jun 13:33

Added

  • email_transfer tool — move or copy emails between accounts (e.g. iCloud/Outlook into Gmail) while preserving the original message intact (sender, date, threading) by transferring the raw MIME. With deleteAfter=true the source copy is trashed only after a confirmed import, making it a safe cross-account move. Backed by new optional provider primitives getRawMessage() / appendRawMessage() implemented for Gmail, IMAP+iCloud, and Outlook.

Fixed

  • Gmail search offset was ignored, so paginating an inbox returned the same first page every time. Gmail's API has no numeric offset (only an opaque pageToken), so search() now pages forward through the lightweight message-id list to the offset + limit window and fetches full bodies only for that window. IMAP and Outlook already honored offset.

v1.2.7

Choose a tag to compare

@marlinjai marlinjai released this 16 Mar 09:39

Fixed

  • iCloud Junk/Trash folder search rewritten — fetchAll() replaces async iterators so IMAP errors are properly catchable
  • Any SEARCH failure now triggers FETCH fallback (no longer requires "Invalid message number" pattern match)
  • Empty folder defaults changed from -1 to 0 for correct detection

v1.2.6

Choose a tag to compare

@marlinjai marlinjai released this 16 Mar 09:33

Fixed

  • Empty folder detection now handles unknown message counts — effectiveCount <= 0 instead of === 0 prevents search attempts when both STATUS and mailbox.exists return unknown (-1), fixing "Invalid message number" errors on empty iCloud folders

v1.2.5

Choose a tag to compare

@marlinjai marlinjai released this 15 Mar 22:32

Fixed

  • email-mcp-setup bin now includes shebang (#!/usr/bin/env node) and executable permissions — previously failed when invoked via npx email-mcp-setup

v1.2.4

Choose a tag to compare

@marlinjai marlinjai released this 15 Mar 21:52

Fixed

  • iCloud Junk folder search no longer fails with "Invalid message number" — uses STATUS command to get real message count when mailbox.exists reports 0
  • SEARCH fallback now triggers on "Invalid message number" even with text-based search criteria
  • Multi-level FETCH fallback chain: FETCH 1:* → explicit range → individual sequence fetches

Added

  • client.noop() before search to refresh stale IMAP connection state
  • client.status() pre-check for real message count
  • 6 new iCloud Junk folder fallback tests

v1.2.3

Choose a tag to compare

@marlinjai marlinjai released this 20 Feb 13:39

Fixed

  • IMAP/iCloud deleteEmail() and batchDelete() no longer hardcode 'Trash' as move destination — now uses resolveFolder('Trash') to find the provider-specific trash folder (e.g., iCloud's "Deleted Messages")
  • Deleting emails already in the trash folder now uses permanent delete instead of attempting to move trash→trash
  • sourceFolder parameter in delete operations is now resolved through resolveFolder(), so passing "Trash" on iCloud correctly opens "Deleted Messages"

v1.2.2

Choose a tag to compare

@marlinjai marlinjai released this 20 Feb 12:36

Fixed

  • Outlook OAuth tokens now refresh automatically mid-session — getProvider() detects expired tokens and reconnects instead of failing with "JWT is not well formed"
  • Token refresh errors now propagate instead of being silently swallowed
  • Invalid Date handling in token expiry check

v1.2.1

Choose a tag to compare

@marlinjai marlinjai released this 20 Feb 11:50

Fixed

  • iCloud IMAP search no longer fails with "Invalid message number" — falls back to direct FETCH when UID SEARCH is rejected by the server
  • Outlook "Id is malformed" errors on older messages — Graph API now uses immutable IDs (Prefer: IdType="ImmutableId") that survive folder moves

Added

  • collectUidsViaFetch() fallback for IMAP servers that reject UID SEARCH ALL (e.g. iCloud)
  • fetchEmails() extracted method for reusable UID-based email fetching
  • Early return when IMAP mailbox reports zero messages

v1.2.0

Choose a tag to compare

@marlinjai marlinjai released this 20 Feb 11:21

Fixes

  • Outlook automatic token renewal — tokens no longer expire and require manual re-authentication. Uses MSAL file-based cache persistence with acquireTokenSilent() for reliable automatic refresh.
  • IMAP search errors now surface actual server diagnostics instead of opaque "Command failed"

Changes

  • Outlook auth persists MSAL token cache to ~/.email-mcp/msal-cache.json
  • refreshTokenIfNeeded() now logs refresh failures instead of silently swallowing them
  • Added msal_home_account_id field for MSAL account identification

Full changelog: https://github.com/marlinjai/email-mcp/blob/main/CHANGELOG.md

v1.1.2

Choose a tag to compare

@marlinjai marlinjai released this 19 Feb 21:10

Fixed

  • IMAP folder search errors now surface actual server response instead of opaque "Command failed"
  • Search on iCloud Junk folder no longer fails silently — added folder resolution that matches by path, name, special-use flag, or common aliases
  • ImapFlow search() returning false on server rejection no longer crashes with TypeError on .slice()

Added

  • formatImapError() helper that extracts responseText, serverResponseCode, and mailboxMissing from ImapFlow errors
  • resolveFolder() method that resolves folder names against the server's folder list
  • Outlook batch requests now use sequential numeric IDs to avoid case-insensitive collision
  • Outlook API endpoints now URL-encode message IDs and folder paths