apple-mail-mcp 1.5.2 → 1.5.4

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.
@@ -13,6 +13,23 @@
13
13
  * @module services/appleMailManager
14
14
  */
15
15
  import type { Message, MessageContent, Mailbox, Account, Attachment, HealthCheckResult, MailStats, BatchOperationResult, SyncStatus, RecentlyReceivedStats, MailRule, Contact, EmailTemplate, SerialEmailRecipient, SerialEmailResult } from "../types.js";
16
+ /**
17
+ * Emits AppleScript that builds a date into the variable `varName` from numeric
18
+ * components.
19
+ *
20
+ * This is locale-independent, unlike `date "May 30, 2026"` string coercion,
21
+ * which AppleScript parses using the system locale. On a non-English locale
22
+ * (e.g. pt_PT) the English month name throws "Invalid date and time (-30720)";
23
+ * because the comparison happens inside the per-message `try` in searchMessages,
24
+ * that error is swallowed and every message is skipped, so the search returns
25
+ * zero results even when matches exist. See issue #15.
26
+ *
27
+ * `day` is reset to 1 before assigning month/year so an existing day-of-month
28
+ * (e.g. 31) cannot overflow into the next month when the month is changed.
29
+ *
30
+ * Exported for unit testing.
31
+ */
32
+ export declare function buildAppleScriptDate(varName: string, d: Date): string;
16
33
  /**
17
34
  * Manager class for Apple Mail operations.
18
35
  *
@@ -237,6 +254,25 @@ export declare class AppleMailManager {
237
254
  /**
238
255
  * Move a message to a different mailbox.
239
256
  */
257
+ /**
258
+ * Move a message to a destination mailbox, with full nested-mailbox support.
259
+ *
260
+ * Resolving the destination as `mailbox "X" of account "Y"` only finds
261
+ * top-level mailboxes, so nested destinations (e.g. a "Moore" subfolder)
262
+ * silently failed. Instead we walk the target account's full mailbox tree and
263
+ * match by name. Resolution is:
264
+ * - account-scoped (won't move to a same-named mailbox in another account)
265
+ * - ambiguity-aware: if the name matches more than one mailbox in the
266
+ * account we refuse to guess and return an error — silently moving mail to
267
+ * the wrong folder is worse than failing.
268
+ * The source message is located by walking every account's tree breadth-first
269
+ * (top-level mailboxes like Inbox are checked first), so messages in nested
270
+ * mailboxes are found too.
271
+ *
272
+ * Returns a result object so batch callers can surface the specific failure
273
+ * (destination not found / ambiguous / message not found).
274
+ */
275
+ private moveMessageInternal;
240
276
  moveMessage(id: string, mailbox: string, account?: string): boolean;
241
277
  /**
242
278
  * Delete multiple messages at once.
@@ -1 +1 @@
1
- {"version":3,"file":"appleMailManager.d.ts","sourceRoot":"","sources":["../../src/services/appleMailManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"appleMailManager.d.ts","sourceRoot":"","sources":["../../src/services/appleMailManager.ts"],"names":[],"mappings":"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"}
@@ -89,6 +89,34 @@ function parseAppleScriptDate(dateStr) {
89
89
  const parsed = new Date(normalized);
90
90
  return isNaN(parsed.getTime()) ? new Date() : parsed;
91
91
  }
92
+ /**
93
+ * Emits AppleScript that builds a date into the variable `varName` from numeric
94
+ * components.
95
+ *
96
+ * This is locale-independent, unlike `date "May 30, 2026"` string coercion,
97
+ * which AppleScript parses using the system locale. On a non-English locale
98
+ * (e.g. pt_PT) the English month name throws "Invalid date and time (-30720)";
99
+ * because the comparison happens inside the per-message `try` in searchMessages,
100
+ * that error is swallowed and every message is skipped, so the search returns
101
+ * zero results even when matches exist. See issue #15.
102
+ *
103
+ * `day` is reset to 1 before assigning month/year so an existing day-of-month
104
+ * (e.g. 31) cannot overflow into the next month when the month is changed.
105
+ *
106
+ * Exported for unit testing.
107
+ */
108
+ export function buildAppleScriptDate(varName, d) {
109
+ return [
110
+ `set ${varName} to current date`,
111
+ `set day of ${varName} to 1`,
112
+ `set year of ${varName} to ${d.getFullYear()}`,
113
+ `set month of ${varName} to ${d.getMonth() + 1}`,
114
+ `set day of ${varName} to ${d.getDate()}`,
115
+ `set hours of ${varName} to ${d.getHours()}`,
116
+ `set minutes of ${varName} to ${d.getMinutes()}`,
117
+ `set seconds of ${varName} to ${d.getSeconds()}`,
118
+ ].join("\n ");
119
+ }
92
120
  /**
93
121
  * Builds an AppleScript command scoped to a specific account.
94
122
  */
@@ -326,18 +354,28 @@ export class AppleMailManager {
326
354
  // are additional AND filters. Date filtering stays post-fetch below — `whose`
327
355
  // date comparisons are unreliable in Mail.app AppleScript. See buildSearchCondition.
328
356
  const searchCondition = buildSearchCondition({ query, from, subject, isRead, isFlagged });
329
- // Build date filter AppleScript.
330
- // Note: dateFrom/dateTo are already validated by DATE_FILTER_SCHEMA (alphanumeric + safe
331
- // punctuation only), so escapeForAppleScript() below is belt-and-suspenders it won't
332
- // alter valid date strings but guards against future schema changes.
357
+ // Build the date-bound comparison. The comparison dates are constructed in
358
+ // AppleScript from numeric components (see buildAppleScriptDate) and compared
359
+ // against `msgDate` (set per-message below) rather than coerced from a
360
+ // locale-formatted string — `date "May 30, 2026"` throws on non-English system
361
+ // locales, and that swallowed error silently zeroes out results. See issue #15.
362
+ // dateFrom/dateTo are already validated by DATE_FILTER_SCHEMA as parseable dates.
363
+ let dateSetup = "";
333
364
  let dateFilter = "";
334
365
  if (dateFrom || dateTo) {
335
366
  const dateChecks = [];
336
367
  if (dateFrom) {
337
- dateChecks.push(`date received of msg >= date "${escapeForAppleScript(dateFrom)}"`);
368
+ dateSetup += buildAppleScriptDate("_dateFrom", new Date(dateFrom)) + "\n ";
369
+ dateChecks.push("msgDate >= _dateFrom");
338
370
  }
339
371
  if (dateTo) {
340
- dateChecks.push(`date received of msg <= date "${escapeForAppleScript(dateTo)}"`);
372
+ const to = new Date(dateTo);
373
+ // A date-only upper bound (no time component) is treated as end-of-day so
374
+ // messages received later that same day are still included.
375
+ if (!/\d:\d/.test(dateTo))
376
+ to.setHours(23, 59, 59, 0);
377
+ dateSetup += buildAppleScriptDate("_dateTo", to) + "\n ";
378
+ dateChecks.push("msgDate <= _dateTo");
341
379
  }
342
380
  dateFilter = dateChecks.join(" and ");
343
381
  }
@@ -346,7 +384,7 @@ export class AppleMailManager {
346
384
  // Search a specific mailbox
347
385
  const targetMailbox = this.resolveMailbox(mailbox, targetAccount);
348
386
  searchCommand = `
349
- set outputText to ""
387
+ ${dateSetup}set outputText to ""
350
388
  set theMailbox to mailbox "${escapeForAppleScript(targetMailbox)}"
351
389
  set allMessages to messages of theMailbox ${searchCondition}
352
390
  set msgCount to 0
@@ -373,7 +411,7 @@ export class AppleMailManager {
373
411
  else {
374
412
  // Search ALL mailboxes — iterate every mailbox in the account, dedup by message ID
375
413
  searchCommand = `
376
- set outputText to ""
414
+ ${dateSetup}set outputText to ""
377
415
  set msgCount to 0
378
416
  set seenIds to {}
379
417
  repeat with mb in mailboxes
@@ -1096,21 +1134,53 @@ export class AppleMailManager {
1096
1134
  /**
1097
1135
  * Move a message to a different mailbox.
1098
1136
  */
1099
- moveMessage(id, mailbox, account) {
1137
+ /**
1138
+ * Move a message to a destination mailbox, with full nested-mailbox support.
1139
+ *
1140
+ * Resolving the destination as `mailbox "X" of account "Y"` only finds
1141
+ * top-level mailboxes, so nested destinations (e.g. a "Moore" subfolder)
1142
+ * silently failed. Instead we walk the target account's full mailbox tree and
1143
+ * match by name. Resolution is:
1144
+ * - account-scoped (won't move to a same-named mailbox in another account)
1145
+ * - ambiguity-aware: if the name matches more than one mailbox in the
1146
+ * account we refuse to guess and return an error — silently moving mail to
1147
+ * the wrong folder is worse than failing.
1148
+ * The source message is located by walking every account's tree breadth-first
1149
+ * (top-level mailboxes like Inbox are checked first), so messages in nested
1150
+ * mailboxes are found too.
1151
+ *
1152
+ * Returns a result object so batch callers can surface the specific failure
1153
+ * (destination not found / ambiguous / message not found).
1154
+ */
1155
+ moveMessageInternal(id, mailbox, account) {
1100
1156
  const targetAccount = this.resolveAccount(account);
1101
1157
  const targetMailbox = this.resolveMailbox(mailbox, targetAccount);
1102
1158
  const safeMailbox = escapeForAppleScript(targetMailbox);
1103
1159
  const safeAccount = escapeForAppleScript(targetAccount);
1104
1160
  const script = buildAppLevelScript(`
1105
1161
  try
1162
+ -- \`mailboxes of account\` is already flat: it includes nested mailboxes
1163
+ -- (named by path, e.g. "Processed/Vendors"). Descending via \`mailboxes of mb\`
1164
+ -- is unreliable (it double-prepends the parent path), so we DON'T recurse —
1165
+ -- we match against this flat list by exact name and use the reference directly
1166
+ -- (addressing \`mailbox "X" of account "Y"\` only finds some top-level mailboxes).
1167
+ set destName to "${safeMailbox}"
1168
+ set destMatches to {}
1169
+ repeat with mb in (mailboxes of account "${safeAccount}")
1170
+ if (name of mb) is destName then set end of destMatches to mb
1171
+ end repeat
1172
+ if (count of destMatches) is 0 then return "error:Destination mailbox \\"" & destName & "\\" not found in account \\"${safeAccount}\\""
1173
+ if (count of destMatches) > 1 then return "error:Destination mailbox \\"" & destName & "\\" is ambiguous (" & (count of destMatches) & " matches) in account \\"${safeAccount}\\"; disambiguate or move by full path"
1174
+ set destMailbox to item 1 of destMatches
1175
+
1176
+ -- Find the message by id. The flat mailbox list already covers nested
1177
+ -- mailboxes, so this reaches messages in subfolders without recursing.
1106
1178
  repeat with acct in accounts
1107
- repeat with mb in mailboxes of acct
1179
+ repeat with mb in (mailboxes of acct)
1108
1180
  try
1109
1181
  set matchingMsgs to (messages of mb whose id is ${Number(id)})
1110
1182
  if (count of matchingMsgs) > 0 then
1111
- set msg to item 1 of matchingMsgs
1112
- set destMailbox to mailbox "${safeMailbox}" of account "${safeAccount}"
1113
- move msg to destMailbox
1183
+ move (item 1 of matchingMsgs) to destMailbox
1114
1184
  return "ok"
1115
1185
  end if
1116
1186
  end try
@@ -1121,12 +1191,21 @@ export class AppleMailManager {
1121
1191
  return "error:" & errMsg
1122
1192
  end try
1123
1193
  `);
1124
- const result = executeAppleScript(script, { timeoutMs: 60000 });
1125
- if (!result.success || result.output.startsWith("error:")) {
1126
- console.error(`Failed to move message: ${result.error || result.output}`);
1127
- return false;
1194
+ const result = executeAppleScript(script, { timeoutMs: 90000 });
1195
+ if (!result.success) {
1196
+ return { success: false, error: result.error || "AppleScript execution failed" };
1128
1197
  }
1129
- return true;
1198
+ if (result.output.startsWith("error:")) {
1199
+ return { success: false, error: result.output.slice("error:".length) };
1200
+ }
1201
+ return { success: true };
1202
+ }
1203
+ moveMessage(id, mailbox, account) {
1204
+ const { success, error } = this.moveMessageInternal(id, mailbox, account);
1205
+ if (!success) {
1206
+ console.error(`Failed to move message: ${error}`);
1207
+ }
1208
+ return success;
1130
1209
  }
1131
1210
  // ===========================================================================
1132
1211
  // Batch Operations
@@ -1160,11 +1239,11 @@ export class AppleMailManager {
1160
1239
  batchMoveMessages(ids, mailbox, account) {
1161
1240
  const results = [];
1162
1241
  for (const id of ids) {
1163
- const success = this.moveMessage(id, mailbox, account);
1242
+ const { success, error } = this.moveMessageInternal(id, mailbox, account);
1164
1243
  results.push({
1165
1244
  id,
1166
1245
  success,
1167
- error: success ? undefined : "Failed to move message",
1246
+ error: success ? undefined : error || "Failed to move message",
1168
1247
  });
1169
1248
  }
1170
1249
  return results;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apple-mail-mcp",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "description": "MCP server for Apple Mail - read, search, send, and manage emails via Claude",
5
5
  "type": "module",
6
6
  "main": "build/index.js",