@marlinjai/email-mcp 1.2.3 → 1.2.5

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
@@ -202,6 +202,13 @@ pnpm test:watch
202
202
  pnpm test:integration
203
203
  ```
204
204
 
205
+ ## Support
206
+
207
+ If this project is useful to you, consider supporting its development:
208
+
209
+ - [GitHub Sponsors](https://github.com/sponsors/marlinjai)
210
+ - [Buy Me a Coffee](https://buymeacoffee.com/marlinjai)
211
+
205
212
  ## License
206
213
 
207
214
  MIT
package/dist/index.js CHANGED
@@ -8387,6 +8387,10 @@ var init_adapter3 = __esm({
8387
8387
  } catch {
8388
8388
  folder = requestedFolder;
8389
8389
  }
8390
+ try {
8391
+ await this.client.noop();
8392
+ } catch {
8393
+ }
8390
8394
  let lock;
8391
8395
  try {
8392
8396
  lock = await this.client.getMailboxLock(folder);
@@ -8394,8 +8398,15 @@ var init_adapter3 = __esm({
8394
8398
  throw formatImapError(error48, `Failed to open folder "${folder}"`);
8395
8399
  }
8396
8400
  try {
8401
+ let realMessageCount = -1;
8402
+ try {
8403
+ const status = await this.client.status(folder, { messages: true });
8404
+ realMessageCount = status.messages ?? -1;
8405
+ } catch {
8406
+ }
8397
8407
  const mailboxExists = this.client.mailbox?.exists ?? -1;
8398
- if (mailboxExists === 0) {
8408
+ const effectiveCount = Math.max(realMessageCount, mailboxExists);
8409
+ if (effectiveCount === 0) {
8399
8410
  return [];
8400
8411
  }
8401
8412
  const criteria = this.buildSearchCriteria(query);
@@ -8408,7 +8419,9 @@ var init_adapter3 = __esm({
8408
8419
  );
8409
8420
  allUids = Array.isArray(searchResult) ? searchResult : [];
8410
8421
  } catch (searchError) {
8411
- if (!hasCriteria) {
8422
+ const errorMsg = String(searchError?.responseText || searchError?.message || "").toLowerCase();
8423
+ const isInvalidMessage = errorMsg.includes("invalid message");
8424
+ if (isInvalidMessage || !hasCriteria) {
8412
8425
  allUids = await this.collectUidsViaFetch(query);
8413
8426
  } else {
8414
8427
  throw searchError;
@@ -8426,18 +8439,47 @@ var init_adapter3 = __esm({
8426
8439
  }
8427
8440
  /**
8428
8441
  * Fallback UID collection when UID SEARCH fails (e.g. iCloud "Invalid message number").
8429
- * Uses FETCH 1:* with sequence numbers to collect UIDs directly, optionally filtering
8430
- * by flag-based criteria (unread, starred).
8442
+ * Uses a multi-level fallback chain:
8443
+ * 1. FETCH 1:* with sequence numbers
8444
+ * 2. FETCH 1:N using mailbox.exists as explicit range
8445
+ * 3. Individual sequence number fetches (slowest but most resilient)
8431
8446
  */
8432
8447
  async collectUidsViaFetch(query) {
8433
8448
  if (!this.client) return [];
8434
8449
  const uids = [];
8435
- for await (const msg of this.client.fetch("1:*", { uid: true, flags: true })) {
8436
- if (query.unreadOnly && msg.flags?.has("\\Seen")) continue;
8437
- if (query.starredOnly && !msg.flags?.has("\\Flagged")) continue;
8438
- uids.push(msg.uid);
8450
+ try {
8451
+ for await (const msg of this.client.fetch("1:*", { uid: true, flags: true })) {
8452
+ if (query.unreadOnly && msg.flags?.has("\\Seen")) continue;
8453
+ if (query.starredOnly && !msg.flags?.has("\\Flagged")) continue;
8454
+ uids.push(msg.uid);
8455
+ }
8456
+ return uids;
8457
+ } catch {
8458
+ const exists = this.client.mailbox?.exists ?? 0;
8459
+ if (exists > 0) {
8460
+ try {
8461
+ for await (const msg of this.client.fetch(`1:${exists}`, { uid: true, flags: true })) {
8462
+ if (query.unreadOnly && msg.flags?.has("\\Seen")) continue;
8463
+ if (query.starredOnly && !msg.flags?.has("\\Flagged")) continue;
8464
+ uids.push(msg.uid);
8465
+ }
8466
+ return uids;
8467
+ } catch {
8468
+ }
8469
+ }
8470
+ const count = exists > 0 ? exists : 50;
8471
+ for (let seq = 1; seq <= count; seq++) {
8472
+ try {
8473
+ for await (const msg of this.client.fetch(String(seq), { uid: true, flags: true })) {
8474
+ if (query.unreadOnly && msg.flags?.has("\\Seen")) continue;
8475
+ if (query.starredOnly && !msg.flags?.has("\\Flagged")) continue;
8476
+ uids.push(msg.uid);
8477
+ }
8478
+ } catch {
8479
+ }
8480
+ }
8481
+ return uids;
8439
8482
  }
8440
- return uids;
8441
8483
  }
8442
8484
  /**
8443
8485
  * Fetches email data for a set of UIDs, either with full body or lightweight headers.