@marlinjai/email-mcp 1.2.6 → 1.2.8

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.
@@ -1622,33 +1622,24 @@ var ImapAdapter = class {
1622
1622
  throw formatImapError(error, `Failed to open folder "${folder}"`);
1623
1623
  }
1624
1624
  try {
1625
- let realMessageCount = -1;
1626
- try {
1627
- const status = await this.client.status(folder, { messages: true });
1628
- realMessageCount = status.messages ?? -1;
1629
- } catch {
1630
- }
1631
- const mailboxExists = this.client.mailbox?.exists ?? -1;
1632
- const effectiveCount = Math.max(realMessageCount, mailboxExists);
1633
- if (effectiveCount <= 0) {
1625
+ const mailboxExists = this.client.mailbox?.exists ?? 0;
1626
+ if (mailboxExists === 0) {
1634
1627
  return [];
1635
1628
  }
1636
1629
  const criteria = this.buildSearchCriteria(query);
1637
1630
  const hasCriteria = Object.keys(criteria).length > 0;
1638
- let allUids;
1631
+ let allUids = [];
1639
1632
  try {
1640
1633
  const searchResult = await this.client.search(
1641
1634
  hasCriteria ? criteria : { all: true },
1642
1635
  { uid: true }
1643
1636
  );
1644
1637
  allUids = Array.isArray(searchResult) ? searchResult : [];
1645
- } catch (searchError) {
1646
- const errorMsg = String(searchError?.responseText || searchError?.message || "").toLowerCase();
1647
- const isInvalidMessage = errorMsg.includes("invalid message");
1648
- if (isInvalidMessage || !hasCriteria) {
1638
+ } catch {
1639
+ try {
1649
1640
  allUids = await this.collectUidsViaFetch(query);
1650
- } else {
1651
- throw searchError;
1641
+ } catch {
1642
+ return [];
1652
1643
  }
1653
1644
  }
1654
1645
  const offset = query.offset || 0;
@@ -1671,39 +1662,39 @@ var ImapAdapter = class {
1671
1662
  async collectUidsViaFetch(query) {
1672
1663
  if (!this.client) return [];
1673
1664
  const uids = [];
1674
- try {
1675
- for await (const msg of this.client.fetch("1:*", { uid: true, flags: true })) {
1676
- if (query.unreadOnly && msg.flags?.has("\\Seen")) continue;
1677
- if (query.starredOnly && !msg.flags?.has("\\Flagged")) continue;
1678
- uids.push(msg.uid);
1679
- }
1680
- return uids;
1681
- } catch {
1682
- const exists = this.client.mailbox?.exists ?? 0;
1683
- if (exists > 0) {
1684
- try {
1685
- for await (const msg of this.client.fetch(`1:${exists}`, { uid: true, flags: true })) {
1686
- if (query.unreadOnly && msg.flags?.has("\\Seen")) continue;
1687
- if (query.starredOnly && !msg.flags?.has("\\Flagged")) continue;
1688
- uids.push(msg.uid);
1689
- }
1690
- return uids;
1691
- } catch {
1665
+ const exists = this.client.mailbox?.exists ?? 0;
1666
+ const safeFetch = async (range) => {
1667
+ try {
1668
+ const messages = await this.client.fetchAll(range, { uid: true, flags: true });
1669
+ for (const msg of messages) {
1670
+ if (query.unreadOnly && msg.flags?.has("\\Seen")) continue;
1671
+ if (query.starredOnly && !msg.flags?.has("\\Flagged")) continue;
1672
+ uids.push(msg.uid);
1692
1673
  }
1674
+ return uids.length > 0;
1675
+ } catch {
1676
+ return false;
1693
1677
  }
1694
- const count = exists > 0 ? exists : 50;
1695
- for (let seq = 1; seq <= count; seq++) {
1696
- try {
1697
- for await (const msg of this.client.fetch(String(seq), { uid: true, flags: true })) {
1698
- if (query.unreadOnly && msg.flags?.has("\\Seen")) continue;
1699
- if (query.starredOnly && !msg.flags?.has("\\Flagged")) continue;
1700
- uids.push(msg.uid);
1701
- }
1702
- } catch {
1678
+ };
1679
+ if (await safeFetch("1:*")) return uids;
1680
+ uids.length = 0;
1681
+ if (exists > 0) {
1682
+ if (await safeFetch(`1:${exists}`)) return uids;
1683
+ uids.length = 0;
1684
+ }
1685
+ const count = exists > 0 ? exists : 50;
1686
+ for (let seq = 1; seq <= count; seq++) {
1687
+ try {
1688
+ const msgs = await this.client.fetchAll(String(seq), { uid: true, flags: true });
1689
+ for (const msg of msgs) {
1690
+ if (query.unreadOnly && msg.flags?.has("\\Seen")) continue;
1691
+ if (query.starredOnly && !msg.flags?.has("\\Flagged")) continue;
1692
+ uids.push(msg.uid);
1703
1693
  }
1694
+ } catch {
1704
1695
  }
1705
- return uids;
1706
1696
  }
1697
+ return uids;
1707
1698
  }
1708
1699
  /**
1709
1700
  * Fetches email data for a set of UIDs, either with full body or lightweight headers.
@@ -1711,19 +1702,27 @@ var ImapAdapter = class {
1711
1702
  async fetchEmails(uids, folder, returnBody) {
1712
1703
  if (!this.client) return [];
1713
1704
  const emails = [];
1714
- if (returnBody) {
1715
- for await (const msg of this.client.fetch(uids, { source: true, uid: true, flags: true })) {
1705
+ const fetchOpts = returnBody ? { source: true, uid: true, flags: true } : { envelope: true, uid: true, flags: true, bodyStructure: true };
1706
+ const uidRange = uids.join(",");
1707
+ let messages;
1708
+ try {
1709
+ messages = await this.client.fetchAll(uidRange, fetchOpts, { uid: true });
1710
+ } catch {
1711
+ messages = [];
1712
+ for (const uid of uids) {
1713
+ try {
1714
+ const batch = await this.client.fetchAll(String(uid), fetchOpts, { uid: true });
1715
+ messages.push(...batch);
1716
+ } catch {
1717
+ }
1718
+ }
1719
+ }
1720
+ for (const msg of messages) {
1721
+ if (returnBody) {
1716
1722
  const parsed = await simpleParser(msg.source);
1717
1723
  parsed.flags = msg.flags;
1718
1724
  emails.push(mapParsedEmail(parsed, folder, this.accountId, msg.uid));
1719
- }
1720
- } else {
1721
- for await (const msg of this.client.fetch(uids, {
1722
- envelope: true,
1723
- uid: true,
1724
- flags: true,
1725
- bodyStructure: true
1726
- })) {
1725
+ } else {
1727
1726
  const env = msg.envelope;
1728
1727
  emails.push({
1729
1728
  id: String(msg.uid),