apple-mail-mcp 2.10.6 → 2.10.7
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/build/index.js +35 -13
- package/docs/IMAP-SETUP.md +16 -2
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -81653,9 +81653,8 @@ function sameImapAccount(left, right, deps) {
|
|
|
81653
81653
|
if (aliases.has(left) && aliases.has(right)) return true;
|
|
81654
81654
|
}
|
|
81655
81655
|
const specs = listImapAccountSpecs();
|
|
81656
|
-
const
|
|
81657
|
-
const
|
|
81658
|
-
const rightSpec = specs.find((spec) => matches(right, spec));
|
|
81656
|
+
const leftSpec = specs.find((spec) => specMatchesSelector(spec, left));
|
|
81657
|
+
const rightSpec = specs.find((spec) => specMatchesSelector(spec, right));
|
|
81659
81658
|
return leftSpec !== void 0 && leftSpec === rightSpec;
|
|
81660
81659
|
}
|
|
81661
81660
|
function depsForAccount(account, deps) {
|
|
@@ -81667,14 +81666,21 @@ function depsForAccount(account, deps) {
|
|
|
81667
81666
|
function depsForMessageRef(ref, deps) {
|
|
81668
81667
|
return depsForAccount(ref.account, deps);
|
|
81669
81668
|
}
|
|
81669
|
+
function specMatchesSelector(spec, selector) {
|
|
81670
|
+
return spec.accountLabel === selector || spec.user === selector || (spec.aliases?.includes(selector) ?? false);
|
|
81671
|
+
}
|
|
81670
81672
|
function str(v) {
|
|
81671
81673
|
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
81672
81674
|
}
|
|
81675
|
+
function imapIdentityKey(spec) {
|
|
81676
|
+
return `${spec.host.trim().toLowerCase()}:${spec.port}:${spec.user.trim()}`;
|
|
81677
|
+
}
|
|
81673
81678
|
function listImapAccountSpecs(env = process.env) {
|
|
81674
81679
|
const specs = [];
|
|
81680
|
+
const seen = /* @__PURE__ */ new Set();
|
|
81675
81681
|
const user = env[IMAP_ENV.user]?.trim();
|
|
81676
81682
|
if (user) {
|
|
81677
|
-
|
|
81683
|
+
const legacy = {
|
|
81678
81684
|
accountLabel: env[IMAP_ENV.account]?.trim() || user,
|
|
81679
81685
|
user,
|
|
81680
81686
|
host: env[IMAP_ENV.host]?.trim() || "imap.gmail.com",
|
|
@@ -81682,7 +81688,9 @@ function listImapAccountSpecs(env = process.env) {
|
|
|
81682
81688
|
password: env[IMAP_ENV.password],
|
|
81683
81689
|
keychainService: env[IMAP_ENV.keychainService]?.trim(),
|
|
81684
81690
|
keychainAccount: env[IMAP_ENV.keychainAccount]?.trim()
|
|
81685
|
-
}
|
|
81691
|
+
};
|
|
81692
|
+
specs.push(legacy);
|
|
81693
|
+
seen.add(imapIdentityKey(legacy));
|
|
81686
81694
|
}
|
|
81687
81695
|
const json = env[IMAP_ENV.accounts]?.trim();
|
|
81688
81696
|
if (json) {
|
|
@@ -81694,12 +81702,22 @@ function listImapAccountSpecs(env = process.env) {
|
|
|
81694
81702
|
const u = str(a.user);
|
|
81695
81703
|
if (!u) continue;
|
|
81696
81704
|
const label = str(a.account) || str(a.accountLabel) || u;
|
|
81697
|
-
|
|
81705
|
+
const host = str(a.host) || "imap.gmail.com";
|
|
81698
81706
|
const port = a.port ? Number(a.port) : 993;
|
|
81707
|
+
const key = imapIdentityKey({ host, port, user: u });
|
|
81708
|
+
if (seen.has(key)) {
|
|
81709
|
+
const owner = specs.find((s) => imapIdentityKey(s) === key);
|
|
81710
|
+
if (owner && owner.accountLabel !== label && !owner.aliases?.includes(label)) {
|
|
81711
|
+
(owner.aliases ??= []).push(label);
|
|
81712
|
+
}
|
|
81713
|
+
continue;
|
|
81714
|
+
}
|
|
81715
|
+
if (specs.some((s) => s.accountLabel === label)) continue;
|
|
81716
|
+
seen.add(key);
|
|
81699
81717
|
specs.push({
|
|
81700
81718
|
accountLabel: label,
|
|
81701
81719
|
user: u,
|
|
81702
|
-
host
|
|
81720
|
+
host,
|
|
81703
81721
|
port,
|
|
81704
81722
|
password: str(a.password),
|
|
81705
81723
|
keychainService: str(a.keychainService),
|
|
@@ -81737,7 +81755,7 @@ function specToConfig(spec) {
|
|
|
81737
81755
|
}
|
|
81738
81756
|
function isImapAccount(account, env = process.env) {
|
|
81739
81757
|
if (!account) return false;
|
|
81740
|
-
return listImapAccountSpecs(env).some((s) => s
|
|
81758
|
+
return listImapAccountSpecs(env).some((s) => specMatchesSelector(s, account));
|
|
81741
81759
|
}
|
|
81742
81760
|
function shouldUseImap(account, env = process.env) {
|
|
81743
81761
|
return listImapAccountSpecs(env).length > 0 && (account === void 0 || isImapAccount(account, env));
|
|
@@ -81760,12 +81778,12 @@ function resolveImapConfig(env = process.env, account) {
|
|
|
81760
81778
|
const specs = listImapAccountSpecs(env);
|
|
81761
81779
|
if (specs.length === 0) {
|
|
81762
81780
|
throw new Error(
|
|
81763
|
-
`IMAP not configured. Set ${IMAP_ENV.user} (login address) to enable it. ${SETUP_HINT}`
|
|
81781
|
+
`IMAP not configured. Set ${IMAP_ENV.user} (login address), or ${IMAP_ENV.accounts} for multiple accounts, to enable it. ${SETUP_HINT}`
|
|
81764
81782
|
);
|
|
81765
81783
|
}
|
|
81766
81784
|
let spec;
|
|
81767
81785
|
if (account) {
|
|
81768
|
-
spec = specs.find((s) => s
|
|
81786
|
+
spec = specs.find((s) => specMatchesSelector(s, account));
|
|
81769
81787
|
if (!spec) {
|
|
81770
81788
|
throw new Error(
|
|
81771
81789
|
`No IMAP account matching "${account}". Configured: ${specs.map((s) => s.accountLabel).join(", ")}.`
|
|
@@ -81977,7 +81995,7 @@ function errText(e) {
|
|
|
81977
81995
|
var poolConnect = defaultConnect;
|
|
81978
81996
|
var pools = /* @__PURE__ */ new Map();
|
|
81979
81997
|
function poolKey(cfg) {
|
|
81980
|
-
return
|
|
81998
|
+
return imapIdentityKey(cfg);
|
|
81981
81999
|
}
|
|
81982
82000
|
function imapIdleMs() {
|
|
81983
82001
|
const raw = process.env.APPLE_MAIL_MCP_IMAP_IDLE_MS;
|
|
@@ -82035,7 +82053,7 @@ async function acquirePooled(cfg) {
|
|
|
82035
82053
|
}
|
|
82036
82054
|
}
|
|
82037
82055
|
async function imapHealthCheck(deps = {}) {
|
|
82038
|
-
if (!deps.config &&
|
|
82056
|
+
if (!deps.config && listImapAccountSpecs().length === 0) {
|
|
82039
82057
|
return { configured: false, ok: false };
|
|
82040
82058
|
}
|
|
82041
82059
|
let cfg;
|
|
@@ -82773,7 +82791,11 @@ async function runDoctor(mailManager2) {
|
|
|
82773
82791
|
checks.push({
|
|
82774
82792
|
name: `IMAP: ${label}`,
|
|
82775
82793
|
status: h.ok ? "ok" : "fail",
|
|
82776
|
-
|
|
82794
|
+
// `h.error` is optional on the health-check result, so interpolating it
|
|
82795
|
+
// bare printed the literal string "connection failed: undefined" for
|
|
82796
|
+
// any failure that carried no message (issue #138). Never render that:
|
|
82797
|
+
// an unexplained failure is still worth naming, but as words.
|
|
82798
|
+
detail: h.ok ? `connected to ${h.host}` : `connection failed: ${h.error ?? "the health check reported no detail"}. Check the Keychain password and host/port.`
|
|
82777
82799
|
});
|
|
82778
82800
|
}
|
|
82779
82801
|
}
|
package/docs/IMAP-SETUP.md
CHANGED
|
@@ -199,6 +199,20 @@ Each array entry accepts: `account`, `user`, `host`, `port`, `password`
|
|
|
199
199
|
(discouraged — prefer Keychain), `keychainService`, `keychainAccount`. Each
|
|
200
200
|
account keeps its own pooled IMAP connection.
|
|
201
201
|
|
|
202
|
+
**The array alone is enough.** You do not need the legacy single-account vars:
|
|
203
|
+
listing every account in `APPLE_MAIL_MCP_IMAP_ACCOUNTS` and setting none of
|
|
204
|
+
`APPLE_MAIL_MCP_IMAP_USER` / `_ACCOUNT` / `_HOST` is fully supported, and the
|
|
205
|
+
first array entry becomes the default account. (Before 2.10.7 that shape worked
|
|
206
|
+
for every tool but made `doctor` report `connection failed: undefined` for each
|
|
207
|
+
account — see #138.)
|
|
208
|
+
|
|
209
|
+
**Don't declare the same mailbox twice.** If the legacy vars already describe a
|
|
210
|
+
mailbox, do not also give it an array entry — even under a different `account`
|
|
211
|
+
nickname. An account's identity is its resolved `(host, port, user)`, not its
|
|
212
|
+
label, so the duplicate is recognised and collapsed rather than counted twice
|
|
213
|
+
(the extra nickname still works as an alias). Before 2.10.7 it was counted
|
|
214
|
+
twice, inflating `get-unread-count` and `get-mail-stats`.
|
|
215
|
+
|
|
202
216
|
---
|
|
203
217
|
|
|
204
218
|
## Step 4 (optional) — SMTP sending
|
|
@@ -333,14 +347,14 @@ GUI is ignoring.
|
|
|
333
347
|
| Variable | Purpose |
|
|
334
348
|
|----------|---------|
|
|
335
349
|
| `APPLE_MAIL_MCP_DEFAULT_ACCOUNT` | Account used when a tool omits `account` (name or email). |
|
|
336
|
-
| `APPLE_MAIL_MCP_IMAP_USER` | Primary IMAP login
|
|
350
|
+
| `APPLE_MAIL_MCP_IMAP_USER` | Primary IMAP login. Setting it enables IMAP — but so does `APPLE_MAIL_MCP_IMAP_ACCOUNTS` on its own; either is sufficient. |
|
|
337
351
|
| `APPLE_MAIL_MCP_IMAP_ACCOUNT` | Mail.app account name to match for routing (default = USER). |
|
|
338
352
|
| `APPLE_MAIL_MCP_IMAP_HOST` | IMAP host (default `imap.gmail.com`). |
|
|
339
353
|
| `APPLE_MAIL_MCP_IMAP_PORT` | IMAP port (default `993`, implicit TLS). |
|
|
340
354
|
| `APPLE_MAIL_MCP_IMAP_PASSWORD` | Password (discouraged; prefer Keychain). |
|
|
341
355
|
| `APPLE_MAIL_MCP_IMAP_KEYCHAIN_SERVICE` | Keychain item service/server name. |
|
|
342
356
|
| `APPLE_MAIL_MCP_IMAP_KEYCHAIN_ACCOUNT` | Keychain item account (default = USER). |
|
|
343
|
-
| `APPLE_MAIL_MCP_IMAP_ACCOUNTS` | JSON array of
|
|
357
|
+
| `APPLE_MAIL_MCP_IMAP_ACCOUNTS` | JSON array of accounts (multi-account). Sufficient on its own; also enables IMAP. |
|
|
344
358
|
| `APPLE_MAIL_MCP_IMAP_IDLE` | `1` to enable IMAP IDLE new-mail push. |
|
|
345
359
|
| `APPLE_MAIL_MCP_IMAP_IDLE_MS` | Pooled-connection idle timeout in ms (default `30000`; `0` = never close). |
|
|
346
360
|
| `APPLE_MAIL_MCP_STATS_BUDGET_MS` | Per-account wall-clock budget for `get-mail-stats` in ms (default `25000`, minimum `1000`). |
|
package/package.json
CHANGED