apple-notes-mcp 2.9.11 → 2.9.12

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.
Files changed (3) hide show
  1. package/README.md +8 -1
  2. package/build/index.js +128 -67
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -982,6 +982,13 @@ Deletes a note (moves to Recently Deleted in Notes.app).
982
982
  Title-only deletion is rejected. If the note changed after the supplied hash
983
983
  was read, deletion is also rejected.
984
984
 
985
+ **Notes with large images.** Notes.app returns a note's body with each inline
986
+ image embedded as base64, so a note holding one 40 MB image has a body of about
987
+ 110 MB. Body reads accept up to 512 MB of output, and `delete-note` compares a
988
+ body longer than 5 MB against a private temporary file rather than embedding it
989
+ in the AppleScript. The comparison still covers the whole body, and the file
990
+ is removed when the delete finishes.
991
+
985
992
  **Copy-then-retire.** To delete an original only while its copy is still good,
986
993
  read both notes, verify the copy, and pass the copy as `guardNoteId` with its
987
994
  `contentHash` as `expectedGuardContentHash`. The copy's revision is re-read just
@@ -2462,7 +2469,7 @@ All configuration is optional — the server works out of the box. Override beha
2462
2469
 
2463
2470
  | Variable | Default | Description |
2464
2471
  |----------|---------|-------------|
2465
- | `APPLE_NOTES_MCP_MAX_BUFFER` | `67108864` (64 MB) | Max bytes captured from a single AppleScript invocation. Raise it if a very large export/list is truncated; lower it to cap memory. |
2472
+ | `APPLE_NOTES_MCP_MAX_BUFFER` | `67108864` (64 MB) | Max bytes captured from a single AppleScript invocation. Raise it if a very large export/list is truncated; lower it to cap memory. Reading one note body allows at least 512 MB regardless, since a body embeds its inline images. Output past the cap fails with an error naming this variable, not as a timeout. |
2466
2473
  | `APPLE_NOTES_MCP_MAX_ATTACHMENT_BYTES` | `26214400` (25 MB) | Max size of an attachment that [`fetch-attachment`](#fetch-attachment) will base64-encode inline. Larger attachments are rejected with an error pointing at [`save-attachment`](#save-attachment) (which streams to disk and has no such limit). Raise it to fetch bigger attachments inline; lower it to cap memory. |
2467
2474
  | `APPLE_NOTES_MCP_MAX_INLINE_IMAGE_BYTES` | `262144` (256 KB) | Per-image cap on the base64 payload kept inline in a [`get-note-content`](#get-note-content) response. Inline images over the cap are replaced with placeholders (with a warning appended) so an image-heavy note cannot exceed the MCP client's message limit and drop the connection; export the real files with [`save-attachment`](#save-attachment) or [`fetch-attachment`](#fetch-attachment). Raise it to keep bigger images inline. |
2468
2475
  | `APPLE_NOTES_MCP_CONFIG_FILE` | `~/Library/Application Support/apple-notes-mcp/config.json` | Path to the JSON config file (see below). |
package/build/index.js CHANGED
@@ -38983,6 +38983,7 @@ var StdioServerTransport = class {
38983
38983
 
38984
38984
  // src/utils/applescript.ts
38985
38985
  import { execFileSync } from "child_process";
38986
+ import { constants as bufferConstants } from "node:buffer";
38986
38987
 
38987
38988
  // src/utils/docsUrls.ts
38988
38989
  var FULL_DISK_ACCESS_GUIDE_URL = "https://github.com/sweetrb/apple-notes-mcp/blob/main/docs/FULL-DISK-ACCESS.md";
@@ -39020,6 +39021,21 @@ function envPositiveNumber(name) {
39020
39021
  function getMaxBuffer() {
39021
39022
  return envPositiveNumber("APPLE_NOTES_MCP_MAX_BUFFER") ?? DEFAULT_MAX_BUFFER_BYTES;
39022
39023
  }
39024
+ var MAX_OUTPUT_BYTES = bufferConstants.MAX_STRING_LENGTH;
39025
+ var NOTE_BODY_MAX_BUFFER_BYTES = Math.min(512 * 1024 * 1024, MAX_OUTPUT_BYTES);
39026
+ function noteBodyMaxBuffer() {
39027
+ return Math.min(Math.max(getMaxBuffer(), NOTE_BODY_MAX_BUFFER_BYTES), MAX_OUTPUT_BYTES);
39028
+ }
39029
+ function isOutputOverflowError(error2) {
39030
+ const code = error2 instanceof Error ? error2.code : void 0;
39031
+ return code === "ENOBUFS" || code === "ERR_STRING_TOO_LONG";
39032
+ }
39033
+ function outputOverflowMessage(maxBufferBytes) {
39034
+ const mib = 1024 * 1024;
39035
+ const limit = maxBufferBytes >= mib ? `${Math.round(maxBufferBytes / mib)} MB` : `${maxBufferBytes} bytes`;
39036
+ const remedy = maxBufferBytes >= MAX_OUTPUT_BYTES ? "That is the longest string Node.js can hold, so raising APPLE_NOTES_MCP_MAX_BUFFER will not help; remove or shrink the large image or attachment in Notes.app." : "Raise APPLE_NOTES_MCP_MAX_BUFFER (in bytes) to allow more.";
39037
+ return `Notes.app returned more than ${limit} of output, the most this server accepts from one AppleScript call. A note whose body carries large inline images or attachments can reach this. ${remedy}`;
39038
+ }
39023
39039
  var SCRIPT_TIMEOUT_HEADROOM_MS = 5e3;
39024
39040
  var MIN_ATTEMPT_BUDGET_MS = 1e3;
39025
39041
  function wrapWithTimeout(script, processTimeoutMs) {
@@ -39165,6 +39181,7 @@ function executeAppleScript(script, options = {}) {
39165
39181
  const timeoutMs = options.timeoutMs ?? callTimeoutMs() ?? envPositiveNumber("APPLE_NOTES_MCP_TIMEOUT_MS") ?? DEFAULT_TIMEOUT_MS;
39166
39182
  const maxRetries = options.maxRetries ?? envPositiveNumber("APPLE_NOTES_MCP_MAX_RETRIES") ?? DEFAULT_MAX_RETRIES;
39167
39183
  const retryDelayMs = options.retryDelayMs ?? envPositiveNumber("APPLE_NOTES_MCP_RETRY_DELAY_MS") ?? DEFAULT_RETRY_DELAY_MS;
39184
+ const maxBufferBytes = Math.min(options.maxBufferBytes ?? getMaxBuffer(), MAX_OUTPUT_BYTES);
39168
39185
  if (!script || !script.trim()) {
39169
39186
  return {
39170
39187
  success: false,
@@ -39195,7 +39212,7 @@ function executeAppleScript(script, options = {}) {
39195
39212
  killSignal: "SIGKILL",
39196
39213
  // Raise the output cap above Node's 1 MB default so large exports /
39197
39214
  // long notes aren't truncated into an ENOBUFS failure. (#16)
39198
- maxBuffer: getMaxBuffer()
39215
+ maxBuffer: maxBufferBytes
39199
39216
  });
39200
39217
  const duration3 = Date.now() - attemptStart;
39201
39218
  debugLog("AppleScript succeeded", {
@@ -39213,7 +39230,9 @@ function executeAppleScript(script, options = {}) {
39213
39230
  let errorMessage;
39214
39231
  let isTimeout = false;
39215
39232
  let rawError;
39216
- if (isTimeoutError(error2)) {
39233
+ if (isOutputOverflowError(error2)) {
39234
+ errorMessage = outputOverflowMessage(maxBufferBytes);
39235
+ } else if (isTimeoutError(error2)) {
39217
39236
  isTimeout = true;
39218
39237
  const timeoutSecs = Math.round(timeoutMs / 1e3);
39219
39238
  errorMessage = `Operation timed out after ${timeoutSecs} seconds. Notes.app may be unresponsive or the operation involves too many notes.`;
@@ -42130,8 +42149,8 @@ function scopeConflictMessage(reason) {
42130
42149
 
42131
42150
  // src/services/appleNotesManager.ts
42132
42151
  var import_turndown = __toESM(require_turndown_cjs(), 1);
42133
- import { existsSync as existsSync5 } from "fs";
42134
- import { homedir as homedir8 } from "os";
42152
+ import { existsSync as existsSync5, mkdtempSync as mkdtempSync2, rmSync as rmSync2, writeFileSync } from "fs";
42153
+ import { homedir as homedir8, tmpdir as tmpdir2 } from "os";
42135
42154
  import { join as join9 } from "path";
42136
42155
  var FIELD_SEP = "";
42137
42156
  var RECORD_SEP = "";
@@ -42442,6 +42461,34 @@ function buildAppLevelScript(command) {
42442
42461
  end tell
42443
42462
  `;
42444
42463
  }
42464
+ var INLINE_EXPECTED_BODY_LIMIT = MAX_CONTENT_LENGTH;
42465
+ var ExpectedBodies = class {
42466
+ directory;
42467
+ files = 0;
42468
+ /**
42469
+ * Returns AppleScript `setup` to run before the comparison (empty for a
42470
+ * literal) and the `operand` to compare the note's body against.
42471
+ * `variable` names the AppleScript variable a file-backed body is read into.
42472
+ */
42473
+ bind(body, variable) {
42474
+ if (body.length <= INLINE_EXPECTED_BODY_LIMIT) {
42475
+ return { setup: "", operand: `"${escapeHtmlForAppleScript(body)}"` };
42476
+ }
42477
+ this.directory ??= mkdtempSync2(join9(tmpdir2(), "apple-notes-expected-body-"));
42478
+ const file = join9(this.directory, `body-${this.files++}.html`);
42479
+ writeFileSync(file, body, { encoding: "utf8", mode: 384 });
42480
+ return {
42481
+ setup: `
42482
+ tell current application to set ${variable} to read (POSIX file "${escapePlainStringForAppleScript(file)}") as \xABclass utf8\xBB`,
42483
+ operand: variable
42484
+ };
42485
+ }
42486
+ /** Removes any temporary files. Safe to call more than once. */
42487
+ cleanup() {
42488
+ if (this.directory) rmSync2(this.directory, { recursive: true, force: true });
42489
+ this.directory = void 0;
42490
+ }
42491
+ };
42445
42492
  function folderDeleteFactsScript(id2) {
42446
42493
  if (!FOLDER_ID_PATTERN.test(id2)) throw new Error("An exact folder ID is required");
42447
42494
  return `
@@ -42803,7 +42850,7 @@ var AppleNotesManager = class {
42803
42850
  const safeTitle = escapePlainStringForAppleScript(title);
42804
42851
  const getCommand = `get body of note "${safeTitle}"`;
42805
42852
  const script = buildAccountScopedScript({ account: targetAccount }, getCommand);
42806
- const result = executeAppleScript(script);
42853
+ const result = executeAppleScript(script, { maxBufferBytes: noteBodyMaxBuffer() });
42807
42854
  if (!result.success) {
42808
42855
  throwIfAccountResolutionFailed(result.error);
42809
42856
  console.error(`Failed to get content of note "${title}":`, result.error);
@@ -42840,7 +42887,7 @@ var AppleNotesManager = class {
42840
42887
  const safeId = sanitizeId(id2);
42841
42888
  const getCommand = `get body of note id "${safeId}"`;
42842
42889
  const script = buildAppLevelScript(getCommand);
42843
- const result = executeAppleScript(script);
42890
+ const result = executeAppleScript(script, { maxBufferBytes: noteBodyMaxBuffer() });
42844
42891
  if (!result.success) {
42845
42892
  console.error(`Failed to get content of note with ID "${id2}":`, result.error);
42846
42893
  return { body: "", error: result.error };
@@ -43063,25 +43110,25 @@ var AppleNotesManager = class {
43063
43110
  */
43064
43111
  deleteNoteByIdIfUnchanged(id2, expectedBody, scope2, guards = []) {
43065
43112
  const safeId = sanitizeNoteId(id2);
43066
- validateLength(expectedBody, MAX_CONTENT_LENGTH, "Expected note content");
43067
- const safeExpectedBody = escapeHtmlForAppleScript(expectedBody);
43068
43113
  const trashIds = trashFolderIdList();
43069
- const guardChecks = guards.map((guard, index) => {
43070
- const safeGuardId = sanitizeNoteId(guard.id);
43071
- const ref = `__guardRef${index}`;
43072
- const folderVar = `__guardFolder${index}`;
43073
- const inactive = (reason) => `return "SAFETY_GUARD_INACTIVE:${index}:${reason}"`;
43074
- let bodyCheck = "";
43075
- if (guard.expectedBody !== void 0) {
43076
- validateLength(guard.expectedBody, MAX_CONTENT_LENGTH, "Expected guard note content");
43077
- const safeGuardBody = escapeHtmlForAppleScript(guard.expectedBody);
43078
- bodyCheck = `
43114
+ const bodies = new ExpectedBodies();
43115
+ let result;
43116
+ try {
43117
+ const guardChecks = guards.map((guard, index) => {
43118
+ const safeGuardId = sanitizeNoteId(guard.id);
43119
+ const ref = `__guardRef${index}`;
43120
+ const folderVar = `__guardFolder${index}`;
43121
+ const inactive = (reason) => `return "SAFETY_GUARD_INACTIVE:${index}:${reason}"`;
43122
+ let bodyCheck = "";
43123
+ if (guard.expectedBody !== void 0) {
43124
+ const expected2 = bodies.bind(guard.expectedBody, `__expectedGuardBody${index}`);
43125
+ bodyCheck = `${expected2.setup}
43079
43126
  set __guardBody to body of ${ref}
43080
43127
  considering case
43081
- if __guardBody is not "${safeGuardBody}" and __guardBody is not "${safeGuardBody}" & linefeed then return "SAFETY_GUARD_CONFLICT:${index}"
43128
+ if __guardBody is not ${expected2.operand} and __guardBody is not ${expected2.operand} & linefeed then return "SAFETY_GUARD_CONFLICT:${index}"
43082
43129
  end considering`;
43083
- }
43084
- return `
43130
+ }
43131
+ return `
43085
43132
  if not (exists note id "${safeGuardId}") then ${inactive("missing")}
43086
43133
  set ${ref} to note id "${safeGuardId}"
43087
43134
  if password protected of ${ref} then ${inactive("locked")}
@@ -43091,18 +43138,19 @@ var AppleNotesManager = class {
43091
43138
  end try
43092
43139
  if ${folderVar} is missing value then ${inactive("folder unknown")}${inRecentlyDeletedScript(folderVar, "__guardInTrash", trashIds)}
43093
43140
  if __guardInTrash then ${inactive("in Recently Deleted")}${bodyCheck}`;
43094
- }).join("");
43095
- const script = buildAppLevelScript(`
43141
+ }).join("");
43142
+ const expected = bodies.bind(expectedBody, "__expectedBody");
43143
+ const script = buildAppLevelScript(`
43096
43144
  set noteRef to note id "${safeId}"${buildScopeGuardScript("noteRef", scope2)}
43097
43145
  set originalFolder to missing value
43098
43146
  try
43099
43147
  set originalFolder to container of noteRef
43100
43148
  end try
43101
43149
  if originalFolder is missing value then return "SAFETY_CONTAINER_UNKNOWN"${inRecentlyDeletedScript("originalFolder", "__inTrash", trashIds)}
43102
- if __inTrash then return "SAFETY_IN_RECENTLY_DELETED"${guardChecks}
43150
+ if __inTrash then return "SAFETY_IN_RECENTLY_DELETED"${guardChecks}${expected.setup}
43103
43151
  set currentBody to body of noteRef
43104
43152
  considering case
43105
- if currentBody is not "${safeExpectedBody}" and currentBody is not "${safeExpectedBody}" & linefeed then return "SAFETY_CONFLICT"
43153
+ if currentBody is not ${expected.operand} and currentBody is not ${expected.operand} & linefeed then return "SAFETY_CONFLICT"
43106
43154
  delete noteRef
43107
43155
  end considering
43108
43156
  try
@@ -43110,7 +43158,10 @@ var AppleNotesManager = class {
43110
43158
  end try
43111
43159
  return "SAFETY_DELETED"
43112
43160
  `);
43113
- const result = executeMutationAppleScript(script);
43161
+ result = executeMutationAppleScript(script);
43162
+ } finally {
43163
+ bodies.cleanup();
43164
+ }
43114
43165
  if (!result.success) {
43115
43166
  console.error(`Failed guarded delete for note ID "${id2}":`, result.error);
43116
43167
  return { status: "failed" };
@@ -47592,8 +47643,8 @@ import { spawnSync } from "child_process";
47592
47643
 
47593
47644
  // src/services/nativeTags.ts
47594
47645
  import { execFileSync as execFileSync15 } from "node:child_process";
47595
- import { mkdtempSync as mkdtempSync2, writeFileSync, rmSync as rmSync2 } from "node:fs";
47596
- import { tmpdir as tmpdir2 } from "node:os";
47646
+ import { mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync2, rmSync as rmSync3 } from "node:fs";
47647
+ import { tmpdir as tmpdir3 } from "node:os";
47597
47648
  import { join as join16 } from "node:path";
47598
47649
 
47599
47650
  // src/services/shortcutConsent.ts
@@ -47696,10 +47747,10 @@ function runNativeTagsShortcut(input) {
47696
47747
  const status = nativeTagsStatus();
47697
47748
  if (!status.installed)
47698
47749
  throw new Error(`Import the supplied ${status.shortcut}.shortcut in Shortcuts first`);
47699
- const directory = mkdtempSync2(join16(tmpdir2(), "apple-notes-native-tags-"));
47750
+ const directory = mkdtempSync3(join16(tmpdir3(), "apple-notes-native-tags-"));
47700
47751
  try {
47701
47752
  const path10 = join16(directory, "request.json");
47702
- writeFileSync(path10, JSON.stringify(input), { mode: 384 });
47753
+ writeFileSync2(path10, JSON.stringify(input), { mode: 384 });
47703
47754
  execFileSync15("/usr/bin/shortcuts", ["run", status.identifier, "--input-path", path10], {
47704
47755
  encoding: "utf8",
47705
47756
  timeout: 6e4,
@@ -47714,14 +47765,14 @@ function runNativeTagsShortcut(input) {
47714
47765
  { shortcut: status.shortcut, code: error2?.code }
47715
47766
  );
47716
47767
  } finally {
47717
- rmSync2(directory, { recursive: true, force: true });
47768
+ rmSync3(directory, { recursive: true, force: true });
47718
47769
  }
47719
47770
  }
47720
47771
 
47721
47772
  // src/services/backgroundNotes.ts
47722
47773
  import { execFileSync as execFileSync16 } from "node:child_process";
47723
- import { mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync2, rmSync as rmSync3 } from "node:fs";
47724
- import { tmpdir as tmpdir3 } from "node:os";
47774
+ import { mkdtempSync as mkdtempSync4, writeFileSync as writeFileSync3, rmSync as rmSync4 } from "node:fs";
47775
+ import { tmpdir as tmpdir4 } from "node:os";
47725
47776
  import { join as join17 } from "node:path";
47726
47777
 
47727
47778
  // src/utils/appendMarkdown.ts
@@ -48047,10 +48098,10 @@ function runBackgroundShortcut(input, status = backgroundStatus()) {
48047
48098
  throw new Error(
48048
48099
  `Install the supplied "${status.shortcut}" Shortcut once; Shortcuts must list it exactly once`
48049
48100
  );
48050
- const directory = mkdtempSync3(join17(tmpdir3(), "apple-notes-background-"));
48101
+ const directory = mkdtempSync4(join17(tmpdir4(), "apple-notes-background-"));
48051
48102
  try {
48052
48103
  const file = join17(directory, "request.json");
48053
- writeFileSync2(
48104
+ writeFileSync3(
48054
48105
  file,
48055
48106
  JSON.stringify({
48056
48107
  operation: "",
@@ -48079,7 +48130,7 @@ function runBackgroundShortcut(input, status = backgroundStatus()) {
48079
48130
  throw Object.assign(error2, { shortcut: status.shortcut });
48080
48131
  }
48081
48132
  } finally {
48082
- rmSync3(directory, { recursive: true, force: true });
48133
+ rmSync4(directory, { recursive: true, force: true });
48083
48134
  }
48084
48135
  }
48085
48136
  function backgroundDependencies(manager) {
@@ -49607,9 +49658,12 @@ function readNoteStructure(id2, { dbPath: dbPath2 = NOTES_DB_PATH7, includeText
49607
49658
 
49608
49659
  // src/utils/bodyReadFailure.ts
49609
49660
  var LARGE_ATTACHMENT_BYTES = 5 * 1024 * 1024;
49661
+ var OUTPUT_OVERFLOW = /Notes\.app returned more than [\d.]+ (?:MB|bytes) of output/;
49610
49662
  function classifyBodyReadError(error2) {
49611
49663
  if (!error2) return "other";
49612
- if (/ENOBUFS|maxBuffer/i.test(error2)) return "buffer";
49664
+ if (OUTPUT_OVERFLOW.test(error2) || /ENOBUFS|maxBuffer|ERR_STRING_TOO_LONG/i.test(error2)) {
49665
+ return "buffer";
49666
+ }
49613
49667
  if (/timed out|timeout|-1712/i.test(error2)) return "timeout";
49614
49668
  return "other";
49615
49669
  }
@@ -49627,10 +49681,17 @@ function describeBodyReadFailure(title, error2, attachments) {
49627
49681
  const kind = classifyBodyReadError(error2);
49628
49682
  if (kind === "other") return base;
49629
49683
  const large = attachments ? largeAttachments(attachments) : [];
49630
- const cause = large.length > 0 ? `The note holds ${large.length === 1 ? "a large attachment" : "large attachments"} (${large.map((a) => `${a.name}, ${formatBytes2(a.bytes)}`).join(
49631
- "; "
49632
- )}). Notes.app returns images inside the note body as base64, so a large image makes the body too big to read in time.` : "Notes.app returns images inside the note body as base64, so a note with a very large image can take longer to read than the timeout allows.";
49633
- const remedy = kind === "buffer" ? "Raise APPLE_NOTES_MCP_MAX_BUFFER (bytes) and retry, or remove the attachment in Notes.app." : "Retry with a longer timeoutSeconds (up to 120) or raise APPLE_NOTES_MCP_TIMEOUT_MS. If it still fails, delete or shrink the attachment in Notes.app; delete-note needs a successful read to verify the note first.";
49684
+ const listed = large.map((a) => `${a.name}, ${formatBytes2(a.bytes)}`).join("; ");
49685
+ const holds = large.length > 0 ? `The note holds ${large.length === 1 ? "a large attachment" : "large attachments"} (${listed}). ` : "";
49686
+ if (kind === "buffer") {
49687
+ const cause2 = `${holds}Notes.app returns images inside the note body as base64, so a large image makes the body bigger than this server can read in one call.`;
49688
+ const remedy2 = "Retrying, or a longer timeoutSeconds, will not help. Remove or shrink the attachment in Notes.app, or delete the note there; delete-note needs a successful read to verify the note first.";
49689
+ return `${base}
49690
+
49691
+ ${cause2} ${remedy2}`;
49692
+ }
49693
+ const cause = large.length > 0 ? `${holds}Notes.app returns images inside the note body as base64, so a large image makes the body too big to read in time.` : "Notes.app returns images inside the note body as base64, so a note with a very large image can take longer to read than the timeout allows.";
49694
+ const remedy = "Retry with a longer timeoutSeconds (up to 120) or raise APPLE_NOTES_MCP_TIMEOUT_MS. If it still fails, delete or shrink the attachment in Notes.app; delete-note needs a successful read to verify the note first.";
49634
49695
  return `${base}
49635
49696
 
49636
49697
  ${cause} ${remedy}`;
@@ -51386,13 +51447,13 @@ import {
51386
51447
  closeSync as closeSync5,
51387
51448
  constants as constants5,
51388
51449
  fstatSync as fstatSync5,
51389
- mkdtempSync as mkdtempSync4,
51450
+ mkdtempSync as mkdtempSync5,
51390
51451
  openSync as openSync5,
51391
51452
  readFileSync as readFileSync3,
51392
- rmSync as rmSync4,
51393
- writeFileSync as writeFileSync3
51453
+ rmSync as rmSync5,
51454
+ writeFileSync as writeFileSync4
51394
51455
  } from "node:fs";
51395
- import { tmpdir as tmpdir4 } from "node:os";
51456
+ import { tmpdir as tmpdir5 } from "node:os";
51396
51457
  import { basename as basename5, extname as extname5, isAbsolute as isAbsolute3, join as join22 } from "node:path";
51397
51458
  var noteId = exactIdInput(
51398
51459
  "ICNote",
@@ -51633,10 +51694,10 @@ function attachFile(manager, args) {
51633
51694
  const bytes = localAttachment(path10);
51634
51695
  const beforeAttachments = manager.listAttachmentsById(id2);
51635
51696
  const beforeStored = storedAttachmentIds(manager, id2);
51636
- const directory = mkdtempSync4(join22(tmpdir4(), "notes-attachment-add-"));
51697
+ const directory = mkdtempSync5(join22(tmpdir5(), "notes-attachment-add-"));
51637
51698
  const temporaryFile = join22(directory, name);
51638
51699
  try {
51639
- writeFileSync3(temporaryFile, bytes, { mode: 384 });
51700
+ writeFileSync4(temporaryFile, bytes, { mode: 384 });
51640
51701
  if (readSnapshot(manager, id2).hash !== before.hash) throw new Error("Note revision changed");
51641
51702
  let returnedId;
51642
51703
  let transportUncertain = false;
@@ -51696,7 +51757,7 @@ function attachFile(manager, args) {
51696
51757
  } : {}
51697
51758
  };
51698
51759
  } finally {
51699
- rmSync4(directory, { recursive: true, force: true });
51760
+ rmSync5(directory, { recursive: true, force: true });
51700
51761
  }
51701
51762
  }
51702
51763
 
@@ -54686,11 +54747,11 @@ import {
54686
54747
  chmodSync,
54687
54748
  existsSync as existsSync14,
54688
54749
  mkdirSync as mkdirSync6,
54689
- mkdtempSync as mkdtempSync5,
54750
+ mkdtempSync as mkdtempSync6,
54690
54751
  readFileSync as readFileSync4,
54691
54752
  renameSync,
54692
- rmSync as rmSync5,
54693
- writeFileSync as writeFileSync4
54753
+ rmSync as rmSync6,
54754
+ writeFileSync as writeFileSync5
54694
54755
  } from "node:fs";
54695
54756
  import { homedir as homedir19, release as release3 } from "node:os";
54696
54757
  import { dirname as dirname8, join as join24, resolve as resolve5 } from "node:path";
@@ -54708,7 +54769,7 @@ var PUBLIC_HELPER_ACTIONS = /* @__PURE__ */ new Set([
54708
54769
  "transcribe"
54709
54770
  ]);
54710
54771
  var DEFAULT_TIMEOUT_MS2 = 3e4;
54711
- var MAX_OUTPUT_BYTES = 256 * 1024 * 1024;
54772
+ var MAX_OUTPUT_BYTES2 = 256 * 1024 * 1024;
54712
54773
  var publicManifestSchema = external_exports.object({
54713
54774
  schemaVersion: external_exports.literal(1),
54714
54775
  protocolVersion: external_exports.number().int(),
@@ -54836,7 +54897,7 @@ function callPublicHelper(action, fields = {}, deps = defaultPublicHelperDeps(),
54836
54897
  encoding: "utf8",
54837
54898
  timeout,
54838
54899
  killSignal: "SIGKILL",
54839
- maxBuffer: MAX_OUTPUT_BYTES
54900
+ maxBuffer: MAX_OUTPUT_BYTES2
54840
54901
  });
54841
54902
  const errno = result.error?.code;
54842
54903
  if (errno === "ETIMEDOUT" || result.signal && result.status === null)
@@ -54876,7 +54937,7 @@ async function callPublicHelperAsync(action, fields = {}, deps = defaultPublicHe
54876
54937
  };
54877
54938
  child.stdout?.on("data", (chunk) => {
54878
54939
  size += chunk.length;
54879
- if (size > MAX_OUTPUT_BYTES)
54940
+ if (size > MAX_OUTPUT_BYTES2)
54880
54941
  stop(new PublicHelperError("invalid_response", "The helper response is too large."));
54881
54942
  else chunks.push(chunk);
54882
54943
  });
@@ -55044,13 +55105,13 @@ function buildPublicHelper(checkOnly, deps = defaultPublicHelperBuildDeps()) {
55044
55105
  steps.push({ step: "find compiler", ok: true, detail: compiler });
55045
55106
  const installDir = publicHelperInstallDir(deps.env);
55046
55107
  mkdirSync6(installDir, { recursive: true, mode: 448 });
55047
- const staging = mkdtempSync5(join24(installDir, ".staging-"));
55108
+ const staging = mkdtempSync6(join24(installDir, ".staging-"));
55048
55109
  try {
55049
55110
  const stagedBinary = join24(staging, PUBLIC_HELPER_BINARY);
55050
55111
  const digestPath = join24(staging, "source-digest.swift");
55051
55112
  const plistPath = join24(staging, "Info.plist");
55052
- writeFileSync4(digestPath, sourceDigestSwift(sourceSha), { mode: 384 });
55053
- writeFileSync4(plistPath, publicHelperInfoPlist(), { mode: 384 });
55113
+ writeFileSync5(digestPath, sourceDigestSwift(sourceSha), { mode: 384 });
55114
+ writeFileSync5(plistPath, publicHelperInfoPlist(), { mode: 384 });
55054
55115
  const compile = deps.spawn(
55055
55116
  "/usr/bin/xcrun",
55056
55117
  publicHelperCompileArguments(deps.sourcePath, digestPath, plistPath, stagedBinary),
@@ -55112,14 +55173,14 @@ function buildPublicHelper(checkOnly, deps = defaultPublicHelperBuildDeps()) {
55112
55173
  };
55113
55174
  chmodSync(stagedBinary, 448);
55114
55175
  renameSync(stagedBinary, join24(installDir, PUBLIC_HELPER_BINARY));
55115
- writeFileSync4(
55176
+ writeFileSync5(
55116
55177
  join24(installDir, PUBLIC_HELPER_MANIFEST),
55117
55178
  JSON.stringify(manifest, null, 2) + "\n",
55118
55179
  { mode: 384 }
55119
55180
  );
55120
55181
  steps.push({ step: "install", ok: true, detail: installDir });
55121
55182
  } finally {
55122
- rmSync5(staging, { recursive: true, force: true });
55183
+ rmSync6(staging, { recursive: true, force: true });
55123
55184
  }
55124
55185
  const installation = inspectPublicHelper(deps);
55125
55186
  steps.push({
@@ -55669,10 +55730,10 @@ import {
55669
55730
  chmodSync as chmodSync2,
55670
55731
  existsSync as existsSync16,
55671
55732
  mkdirSync as mkdirSync7,
55672
- mkdtempSync as mkdtempSync6,
55733
+ mkdtempSync as mkdtempSync7,
55673
55734
  renameSync as renameSync2,
55674
- rmSync as rmSync6,
55675
- writeFileSync as writeFileSync5
55735
+ rmSync as rmSync7,
55736
+ writeFileSync as writeFileSync6
55676
55737
  } from "node:fs";
55677
55738
  import { release as release4 } from "node:os";
55678
55739
  import { join as join27 } from "node:path";
@@ -55697,7 +55758,7 @@ var HELPER_BINARY_NAME = "apple-notes-private-helper";
55697
55758
  var HELPER_SOURCE_RELATIVE = "native/private-helper/apple-notes-private-helper.m";
55698
55759
  var MANIFEST_NAME = "manifest.json";
55699
55760
  var DEFAULT_TIMEOUT_MS3 = 2e4;
55700
- var MAX_OUTPUT_BYTES2 = 4 * 1024 * 1024;
55761
+ var MAX_OUTPUT_BYTES3 = 4 * 1024 * 1024;
55701
55762
  var manifestSchema = external_exports.object({
55702
55763
  schemaVersion: external_exports.literal(1),
55703
55764
  protocolVersion: external_exports.number().int(),
@@ -55881,7 +55942,7 @@ function callPrivateHelper(action, fields = {}, deps = defaultDeps2(), options =
55881
55942
  encoding: "utf8",
55882
55943
  timeout,
55883
55944
  killSignal: "SIGKILL",
55884
- maxBuffer: MAX_OUTPUT_BYTES2,
55945
+ maxBuffer: MAX_OUTPUT_BYTES3,
55885
55946
  env: deps.env
55886
55947
  });
55887
55948
  const errno = result.error?.code;
@@ -56080,7 +56141,7 @@ function buildPrivateHelper(checkOnly, deps = defaultBuildDeps()) {
56080
56141
  steps.push({ step: "find compiler", ok: true, detail: compiler });
56081
56142
  const installDir = helperInstallDir(deps.env);
56082
56143
  mkdirSync7(installDir, { recursive: true, mode: 448 });
56083
- const staging = mkdtempSync6(join27(installDir, ".staging-"));
56144
+ const staging = mkdtempSync7(join27(installDir, ".staging-"));
56084
56145
  try {
56085
56146
  const stagedBinary = join27(staging, HELPER_BINARY_NAME);
56086
56147
  const compile = deps.spawn(
@@ -56160,12 +56221,12 @@ function buildPrivateHelper(checkOnly, deps = defaultBuildDeps()) {
56160
56221
  };
56161
56222
  chmodSync2(stagedBinary, 448);
56162
56223
  renameSync2(stagedBinary, join27(installDir, HELPER_BINARY_NAME));
56163
- writeFileSync5(join27(installDir, MANIFEST_NAME), JSON.stringify(manifest, null, 2) + "\n", {
56224
+ writeFileSync6(join27(installDir, MANIFEST_NAME), JSON.stringify(manifest, null, 2) + "\n", {
56164
56225
  mode: 384
56165
56226
  });
56166
56227
  steps.push({ step: "install", ok: true, detail: installDir });
56167
56228
  } finally {
56168
- if (existsSync16(staging)) rmSync6(staging, { recursive: true, force: true });
56229
+ if (existsSync16(staging)) rmSync7(staging, { recursive: true, force: true });
56169
56230
  }
56170
56231
  const installation = inspectInstallation(deps);
56171
56232
  steps.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apple-notes-mcp",
3
- "version": "2.9.11",
3
+ "version": "2.9.12",
4
4
  "description": "MCP server for Apple Notes - create, search, update, and manage notes via Claude and other AI assistants",
5
5
  "type": "module",
6
6
  "main": "build/index.js",