apple-mail-mcp 2.4.2 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -373,7 +373,7 @@ What routes to IMAP when an account is IMAP-configured:
373
373
  - **Folder ops:** `create-mailbox`, `rename-mailbox`, `delete-mailbox` — IMAP's `CREATE`/`RENAME`/`DELETE` succeed on the iCloud/Gmail/Workspace/Exchange mailboxes Mail.app's AppleScript bridge can't touch (#42).
374
374
  - **Message mutations:** `mark-as-read`/`unread`, `flag-message`/`unflag-message`, `move-message`, `delete-message`.
375
375
  - **Batch mutations (2.1):** `batch-mark-as-read`/`unread`, `batch-flag`/`unflag-messages`, `batch-move-messages`, `batch-delete-messages` — `imap:` ids are grouped by mailbox and applied as a single `UID STORE`/`UID MOVE`; numeric ids in the same batch still use AppleScript.
376
- - **Counts & stats (2.1):** `get-unread-count` and `list-mailboxes` use `STATUS`; `get-mail-stats` (with an `account`) uses `STATUS` + `SEARCH SINCE` — authoritative and fast even on huge mailboxes.
376
+ - **Counts & stats (2.1):** `get-unread-count` and `list-mailboxes` use `STATUS`; `get-mail-stats` uses `STATUS` + `SEARCH SINCE` — authoritative and fast even on huge mailboxes. As of v2.6.0 these prefer IMAP whenever it's configured (see *Read routing* below), merging across accounts when no `account` is given.
377
377
  - **Attachments (2.1):** `list-attachments`, `save-attachment`, `fetch-attachment` use `BODYSTRUCTURE` + `FETCH BODY[part]` for `imap:` ids — faster and able to see MIME-embedded attachments AppleScript misses.
378
378
  - **Threading (2.1):** `get-thread` links a conversation via `References`/`Message-ID` (`HEADER SEARCH`) for an `imap:` seed, falling back to subject grouping otherwise.
379
379
 
@@ -384,9 +384,34 @@ attachment/thread tools and it routes to IMAP automatically; bare numeric ids
384
384
  continue to use AppleScript. So an agent never has to know which backend a
385
385
  message came from — the id carries it.
386
386
 
387
- Routing is conservative: only a call whose explicit `account` matches the
388
- configured IMAP account goes to IMAP; everything else falls through to
389
- AppleScript.
387
+ **Read routing (v2.6.0): reads PREFER direct IMAP whenever IMAP is configured.**
388
+ The read tools `search-messages`, `get-thread`, `list-messages`,
389
+ `list-mailboxes`, `get-unread-count`, `get-mail-stats` — now go to IMAP whenever
390
+ any `APPLE_MAIL_MCP_IMAP_*` account is configured, not just when an explicit
391
+ matching `account` is passed. There are three cases:
392
+
393
+ - **Explicit IMAP account** — single-account IMAP (fast server-side path).
394
+ - **Explicit non-IMAP account** — AppleScript (that account isn't on IMAP).
395
+ - **No `account` given** — **merge across all accounts**: the query fans out over
396
+ *every* configured IMAP account, **and** AppleScript runs **only for the
397
+ accounts no IMAP config covers** (the account list is partitioned — accounts
398
+ already served by IMAP are *not* re-scanned via AppleScript). If every Mail
399
+ account is IMAP-configured, AppleScript is skipped entirely. The results are
400
+ merged so no account is dropped. Message lists still de-duplicate as a safety
401
+ net (preferring the IMAP copy, which carries the round-trippable `imap:` id) and
402
+ sort newest-first; count tools (`get-unread-count`, `get-mail-stats`) count each
403
+ account via exactly one backend so a coverage mismatch can never double- (or
404
+ under-) count.
405
+ - **Default mailbox is resolved per account.** When you don't pin a `mailbox`, a
406
+ fan-out search scopes each account to its own default — Gmail/Workspace to
407
+ `[Gmail]/All Mail`, every other IMAP host (iCloud, etc.) to `INBOX` (since
408
+ `[Gmail]/All Mail` is Gmail-only and selecting it elsewhere would silently drop
409
+ that account). Pin a `mailbox` to search a wider scope on non-Gmail accounts.
410
+
411
+ If IMAP is **not** configured at all, every read behaves exactly as before
412
+ (pure AppleScript). The three mailbox-**write** ops (`create-mailbox`,
413
+ `delete-mailbox`, `rename-mailbox`) remain conservative — they route to IMAP only
414
+ for an explicitly-named IMAP account, never on an omitted account.
390
415
 
391
416
  | Variable | Required | Default | Description |
392
417
  |----------|----------|---------|-------------|
@@ -596,6 +621,8 @@ Reply to an existing message.
596
621
  }
597
622
  ```
598
623
 
624
+ > **Transport (v2.5.0):** when SMTP is configured, `reply-to-message` sends via **clean SMTP**, threading the reply with proper RFC 5322 `In-Reply-To`/`References` headers (built from the original message) so it lands in the same conversation. When SMTP is not configured (or the original lacks the headers needed to thread), it falls back to Mail.app's AppleScript `reply … without opening window` — same reliable-from-background-process path as before. See [SMTP transport](#smtp-transport).
625
+
599
626
  **⚠️ Safety:** With the default `send: true`, sends real mail immediately and cannot be unsent. Confirm the recipients, subject, and body with the user before calling (or pass `send: false` to save a draft for review).
600
627
 
601
628
  ---
@@ -611,6 +638,8 @@ Forward a message to new recipients.
611
638
  | `body` | string | No | Message to prepend |
612
639
  | `send` | boolean | No | Send immediately (default: true, false = save as draft) |
613
640
 
641
+ > **Transport (v2.5.0):** when SMTP is configured, `forward-message` sends via **clean SMTP** (a fresh message with the original quoted, no threading headers — a forward starts a new conversation). When SMTP is not configured it falls back to Mail.app's AppleScript `forward … without opening window`. See [SMTP transport](#smtp-transport).
642
+
614
643
  **⚠️ Safety:** With the default `send: true`, sends real mail immediately and cannot be unsent. Confirm the recipients, subject, and body with the user before calling (or pass `send: false` to save a draft for review).
615
644
 
616
645
  ---
@@ -1128,6 +1157,8 @@ Prior to v1.4.0, `reply-to-message` and `forward-message` would send messages wi
1128
1157
 
1129
1158
  **Fix:** Replaced `with opening window` with `without opening window` for both `reply` and `forward` commands. With this approach, `set content` works immediately and reliably from background processes. `In-Reply-To` and `References` headers are still set correctly by Mail.app, and no GUI compose window is opened.
1130
1159
 
1160
+ **Update (v2.5.0):** when SMTP is configured, `reply-to-message` and `forward-message` now prefer **clean direct SMTP** instead of AppleScript — the same prefer-direct model as `send-email`. Replies are threaded with RFC 5322 `In-Reply-To`/`References` headers built from the original message; forwards start a new conversation. The AppleScript `without opening window` path above remains the fallback when SMTP is not configured (or, for replies, when the original message lacks the headers needed to thread).
1161
+
1131
1162
  See [#7](https://github.com/sweetrb/apple-mail-mcp/issues/7) for full details and the list of approaches that were tested.
1132
1163
 
1133
1164
  ### Backslash Escaping (Important for AI Agents)