apple-notes-mcp 2.15.15 → 2.15.17

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 +2 -0
  2. package/build/index.js +106 -29
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -728,6 +728,8 @@ Retrieves the full content of a specific note.
728
728
 
729
729
  **Note:** Either `id` or `title` must be provided. Using `id` is recommended as it's unique and avoids issues with duplicate titles.
730
730
 
731
+ **Busy Notes.app:** with an `id` and Full Disk Access, the note's existence and password flag are read from the NoteStore database (as `get-note-structure` does), so only the body read goes through Notes.app. A timeout is always reported as `timeout_indeterminate`, never as `not_found`, even when an automatic retry then fails differently; and when Notes.app cannot resolve an id the database still holds, the error is `notes_unavailable`. Retry in a moment, or use `get-note-structure` for a read that does not need Notes.app.
732
+
731
733
  **Large images:** Notes.app returns images inside the body as base64, so a note holding a very large image (tens of MB) can take longer to read than the timeout allows. When the read times out or overflows the output buffer, the error says so and, with Full Disk Access, names the attachments of 5 MB or more. Retry with a larger `timeoutSeconds`; `delete-note` accepts the same argument, and it needs a successful read to verify the note before deleting it.
732
734
 
733
735
  **Example - Using ID (recommended):**
package/build/index.js CHANGED
@@ -45558,7 +45558,7 @@ function visit(schema, fnOrHandlers) {
45558
45558
  return run(schema);
45559
45559
  }
45560
45560
 
45561
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
45561
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
45562
45562
  function isZ4Schema(s) {
45563
45563
  const schema = s;
45564
45564
  return !!schema._zod;
@@ -48573,7 +48573,7 @@ function date4(params) {
48573
48573
  return _coercedDate(ZodDate2, params);
48574
48574
  }
48575
48575
 
48576
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
48576
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
48577
48577
  var LATEST_PROTOCOL_VERSION = "2025-11-25";
48578
48578
  var SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"];
48579
48579
  var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
@@ -50104,7 +50104,7 @@ var UrlElicitationRequiredError = class extends McpError {
50104
50104
  }
50105
50105
  };
50106
50106
 
50107
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
50107
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
50108
50108
  function isTerminal(status) {
50109
50109
  return status === "completed" || status === "failed" || status === "cancelled";
50110
50110
  }
@@ -51393,7 +51393,7 @@ var zodToJsonSchema = (schema, options) => {
51393
51393
  return combined;
51394
51394
  };
51395
51395
 
51396
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
51396
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
51397
51397
  function mapMiniTarget(t) {
51398
51398
  if (!t)
51399
51399
  return "draft-7";
@@ -51435,7 +51435,7 @@ function parseWithCompat(schema, data) {
51435
51435
  return result.data;
51436
51436
  }
51437
51437
 
51438
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
51438
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
51439
51439
  var DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
51440
51440
  var Protocol = class {
51441
51441
  constructor(_options) {
@@ -52412,7 +52412,7 @@ function mergeCapabilities(base, additional) {
52412
52412
  return result;
52413
52413
  }
52414
52414
 
52415
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
52415
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
52416
52416
  var import_ajv = __toESM(require_ajv(), 1);
52417
52417
  var import_ajv_formats = __toESM(require_dist(), 1);
52418
52418
  function createDefaultAjvInstance() {
@@ -52480,7 +52480,7 @@ var AjvJsonSchemaValidator = class {
52480
52480
  }
52481
52481
  };
52482
52482
 
52483
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
52483
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
52484
52484
  var ExperimentalServerTasks = class {
52485
52485
  constructor(_server) {
52486
52486
  this._server = _server;
@@ -52693,7 +52693,7 @@ var ExperimentalServerTasks = class {
52693
52693
  }
52694
52694
  };
52695
52695
 
52696
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
52696
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
52697
52697
  function assertToolsCallTaskCapability(requests, method, entityName) {
52698
52698
  if (!requests) {
52699
52699
  throw new Error(`${entityName} does not support task creation (required for ${method})`);
@@ -52728,7 +52728,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
52728
52728
  }
52729
52729
  }
52730
52730
 
52731
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
52731
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
52732
52732
  var Server = class extends Protocol {
52733
52733
  /**
52734
52734
  * Initializes this server with the given name and version information.
@@ -53099,7 +53099,7 @@ var Server = class extends Protocol {
53099
53099
  }
53100
53100
  };
53101
53101
 
53102
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
53102
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
53103
53103
  var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
53104
53104
  function isCompletable(schema) {
53105
53105
  return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
@@ -53113,7 +53113,7 @@ var McpZodTypeKind;
53113
53113
  McpZodTypeKind2["Completable"] = "McpCompletable";
53114
53114
  })(McpZodTypeKind || (McpZodTypeKind = {}));
53115
53115
 
53116
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/uriTemplate.js
53116
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/uriTemplate.js
53117
53117
  var MAX_TEMPLATE_LENGTH = 1e6;
53118
53118
  var MAX_VARIABLE_LENGTH = 1e6;
53119
53119
  var MAX_TEMPLATE_EXPRESSIONS = 1e4;
@@ -53335,7 +53335,7 @@ var UriTemplate = class _UriTemplate {
53335
53335
  }
53336
53336
  };
53337
53337
 
53338
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
53338
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
53339
53339
  var TOOL_NAME_REGEX = /^[A-Za-z0-9._-]{1,128}$/;
53340
53340
  function validateToolName(name) {
53341
53341
  const warnings = [];
@@ -53393,7 +53393,7 @@ function validateAndWarnToolName(name) {
53393
53393
  return result.isValid;
53394
53394
  }
53395
53395
 
53396
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
53396
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
53397
53397
  var ExperimentalMcpServerTasks = class {
53398
53398
  constructor(_mcpServer) {
53399
53399
  this._mcpServer = _mcpServer;
@@ -53408,7 +53408,7 @@ var ExperimentalMcpServerTasks = class {
53408
53408
  }
53409
53409
  };
53410
53410
 
53411
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
53411
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
53412
53412
  function toolInputElementCount(value, max) {
53413
53413
  let count = 0;
53414
53414
  const stack = [value];
@@ -53457,6 +53457,15 @@ var McpServer = class {
53457
53457
  this._promptHandlersInitialized = false;
53458
53458
  this.server = new Server(serverInfo, options);
53459
53459
  this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements);
53460
+ if (options?.capabilities?.tools) {
53461
+ this.setToolRequestHandlers();
53462
+ }
53463
+ if (options?.capabilities?.resources) {
53464
+ this.setResourceRequestHandlers();
53465
+ }
53466
+ if (options?.capabilities?.prompts) {
53467
+ this.setPromptRequestHandlers();
53468
+ }
53460
53469
  }
53461
53470
  /**
53462
53471
  * Access experimental features.
@@ -54264,10 +54273,10 @@ var EMPTY_COMPLETION_RESULT = {
54264
54273
  }
54265
54274
  };
54266
54275
 
54267
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
54276
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
54268
54277
  import process2 from "node:process";
54269
54278
 
54270
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
54279
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
54271
54280
  var STDIO_DEFAULT_MAX_BUFFER_SIZE = 10 * 1024 * 1024;
54272
54281
  var ReadBuffer = class {
54273
54282
  constructor(options) {
@@ -54304,7 +54313,7 @@ function serializeMessage(message) {
54304
54313
  return JSON.stringify(message) + "\n";
54305
54314
  }
54306
54315
 
54307
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
54316
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
54308
54317
  var StdioServerTransport = class {
54309
54318
  constructor(_stdin = process2.stdin, _stdout = process2.stdout, options) {
54310
54319
  this._stdin = _stdin;
@@ -54466,6 +54475,7 @@ var RETRYABLE_ERROR_PATTERNS = [
54466
54475
  /busy/i,
54467
54476
  /changed during listing/i
54468
54477
  ];
54478
+ var TIMED_OUT_PATTERN = /timed? out|\(-1712\)/i;
54469
54479
  function isRetryableError(errorMessage) {
54470
54480
  return RETRYABLE_ERROR_PATTERNS.some((pattern2) => pattern2.test(errorMessage));
54471
54481
  }
@@ -54594,6 +54604,7 @@ function executeAppleScript(script, options = {}) {
54594
54604
  maxRetries
54595
54605
  });
54596
54606
  let lastError = null;
54607
+ let timeoutDiagnostic;
54597
54608
  const startTime = Date.now();
54598
54609
  const deadline = startTime + timeoutMs;
54599
54610
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
@@ -54652,10 +54663,12 @@ function executeAppleScript(script, options = {}) {
54652
54663
  errorMessage,
54653
54664
  rawError: rawError?.substring(0, 500)
54654
54665
  });
54666
+ const attemptTimedOut = isTimeout || TIMED_OUT_PATTERN.test(stripQuoted(errorMessage));
54667
+ if (attemptTimedOut) timeoutDiagnostic ??= errorMessage;
54655
54668
  lastError = {
54656
54669
  success: false,
54657
54670
  output: "",
54658
- error: errorMessage
54671
+ error: timeoutDiagnostic && !attemptTimedOut ? `${timeoutDiagnostic} A retry then failed: ${errorMessage}` : errorMessage
54659
54672
  };
54660
54673
  const canRetry = isTimeout || isRetryableError(errorMessage);
54661
54674
  const hasAttemptsLeft = attempt < maxRetries;
@@ -67196,6 +67209,42 @@ function readNoteStructure(id2, { dbPath: dbPath2 = NOTES_DB_PATH8, includeText
67196
67209
  };
67197
67210
  }
67198
67211
 
67212
+ // src/utils/notePresence.ts
67213
+ var NOTE_ID3 = /^x-coredata:\/\/([0-9A-Fa-f-]+)\/ICNote\/p(\d+)$/;
67214
+ function readNotePresence(id2, dbPath2 = NOTES_DB_PATH8) {
67215
+ const match = NOTE_ID3.exec(id2);
67216
+ if (!match) return null;
67217
+ const [, store, pk] = match;
67218
+ try {
67219
+ const columns = readColumns(dbPath2);
67220
+ const c = (alias, name) => col(columns, alias, name);
67221
+ const sql = `SELECT json_object(
67222
+ 'store', (SELECT Z_UUID FROM Z_METADATA LIMIT 1),
67223
+ 'isNote', n.Z_ENT = ${entity("ICNote")},
67224
+ 'live', ${notTombstonedSql(columns, "n")},
67225
+ 'title', ${c("n", "ZTITLE1")},
67226
+ 'locked', ${c("n", "ZISPASSWORDPROTECTED")},
67227
+ 'encrypted', (SELECT d.ZCRYPTOINITIALIZATIONVECTOR IS NOT NULL FROM ZICNOTEDATA d WHERE d.ZNOTE = n.Z_PK),
67228
+ 'inTrash', CASE WHEN f.Z_PK IS NULL THEN 0 ELSE ${trashFolderSql(columns, "f")} END)
67229
+ FROM ZICCLOUDSYNCINGOBJECT n
67230
+ LEFT JOIN ZICCLOUDSYNCINGOBJECT f ON f.Z_PK = ${c("n", "ZFOLDER")}
67231
+ WHERE n.Z_PK = @pk;`;
67232
+ const [row] = parseJsonLines(
67233
+ runReadOnlySql(dbPath2, sql, { pk: { int: Number(pk) } })
67234
+ );
67235
+ if (!row || typeof row.store !== "string" || row.store.toUpperCase() !== store.toUpperCase())
67236
+ return null;
67237
+ if (row.isNote !== 1 || row.live !== 1) return null;
67238
+ return {
67239
+ title: typeof row.title === "string" ? row.title : null,
67240
+ locked: row.locked === 1 || row.encrypted === 1,
67241
+ inRecentlyDeleted: row.inTrash === 1
67242
+ };
67243
+ } catch {
67244
+ return null;
67245
+ }
67246
+ }
67247
+
67199
67248
  // src/utils/bodyReadFailure.ts
67200
67249
  var LARGE_ATTACHMENT_BYTES = 5 * 1024 * 1024;
67201
67250
  var OUTPUT_OVERFLOW = /Notes\.app returned more than [\d.]+ (?:MB|bytes) of output/;
@@ -67229,6 +67278,11 @@ function describeBodyReadFailure(title, error62, attachments) {
67229
67278
  return `${base}
67230
67279
 
67231
67280
  ${cause2} ${remedy2}`;
67281
+ }
67282
+ if (attachments && attachments.length === 0) {
67283
+ return `${base}
67284
+
67285
+ The note has no attachments, so its size is not the cause: Notes.app was most likely busy (for example, syncing iCloud) and did not answer in time. Retry in a moment, or with a longer timeoutSeconds (up to 120). get-note-structure reads the note from the NoteStore database without Notes.app.`;
67232
67286
  }
67233
67287
  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.";
67234
67288
  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.";
@@ -79607,6 +79661,12 @@ function bodyReadFailureMessage(id2, title, error62) {
79607
79661
  }
79608
79662
  return describeBodyReadFailure(title, error62, attachments);
79609
79663
  }
79664
+ function isExactIdNotFound(error62) {
79665
+ return error62 === NOTE_ID_NOT_FOUND_MESSAGE || error62 !== void 0 && /^Can[’']t get note id\b/i.test(error62);
79666
+ }
79667
+ function storedNoteUnresolvedMessage(id2, title, error62) {
79668
+ return `Failed to read content of note "${title}" (ID "${id2}"): Notes.app did not resolve the ID (${error62}), but the NoteStore database holds this note, so it is not reported as not found. Notes.app may be busy, for example syncing iCloud. Retry in a moment; get-note-structure reads the note from the database without Notes.app.`;
79669
+ }
79610
79670
  var NOT_DELETED_MESSAGE = "Notes.app accepted the delete, but the note is still in its original folder, so it was not moved to Recently Deleted. Nothing was deleted; read the note again before retrying.";
79611
79671
  function deleteUnverifiedMessage(title, id2) {
79612
79672
  return `Notes.app accepted the delete for note "${title}", but its original folder could not be re-read to confirm the note left it. The outcome is uncertain; read exact ID ${id2} before retrying.`;
@@ -80098,19 +80158,36 @@ registerTool(
80098
80158
  },
80099
80159
  withErrorHandling(({ id: id2, title, account }) => {
80100
80160
  if (id2) {
80101
- const { note: note2, error: metadataError } = notesManager.readNoteById(id2);
80102
- if (!note2) {
80103
- const message = `Failed to read metadata of note with ID "${id2}": ${metadataError}`;
80104
- return metadataError === NOTE_ID_NOT_FOUND_MESSAGE ? notFoundResponse(message) : errorResponse(message);
80105
- }
80106
- if (note2.passwordProtected) {
80107
- return errorResponse(
80108
- `Note "${note2.title}" is password-protected and cannot be read. Unlock it in Notes.app first.`
80109
- );
80161
+ const stored = readNotePresence(id2);
80162
+ let noteTitle;
80163
+ if (stored && stored.title !== null) {
80164
+ if (stored.locked) {
80165
+ return errorResponse(
80166
+ `Note "${stored.title}" is password-protected and cannot be read. Unlock it in Notes.app first.`
80167
+ );
80168
+ }
80169
+ noteTitle = stored.title;
80170
+ } else {
80171
+ const { note: note2, error: metadataError } = notesManager.readNoteById(id2);
80172
+ if (!note2) {
80173
+ const message = `Failed to read metadata of note with ID "${id2}": ${metadataError}`;
80174
+ return metadataError === NOTE_ID_NOT_FOUND_MESSAGE ? notFoundResponse(message) : errorResponse(message);
80175
+ }
80176
+ if (note2.passwordProtected) {
80177
+ return errorResponse(
80178
+ `Note "${note2.title}" is password-protected and cannot be read. Unlock it in Notes.app first.`
80179
+ );
80180
+ }
80181
+ noteTitle = note2.title;
80110
80182
  }
80111
80183
  const { body: rawContent2, error: readError2 } = notesManager.readNoteBodyById(id2);
80112
80184
  if (!rawContent2) {
80113
- return errorResponse(bodyReadFailureMessage(id2, note2.title, readError2));
80185
+ if (isExactIdNotFound(readError2)) {
80186
+ if (!stored) return notFoundResponse(bodyReadFailureMessage(id2, noteTitle, readError2));
80187
+ const message = storedNoteUnresolvedMessage(id2, noteTitle, readError2);
80188
+ return errorResponse(message, new CodedError(message, { code: "notes_unavailable" }));
80189
+ }
80190
+ return errorResponse(bodyReadFailureMessage(id2, noteTitle, readError2));
80114
80191
  }
80115
80192
  const rich2 = enrichNoteRead(id2, rawContent2);
80116
80193
  const stripped2 = stripLargeInlineImages(rich2.content);
@@ -80120,7 +80197,7 @@ registerTool(
80120
80197
  return successResponse(warning2 ? content2 + warning2 : content2, {
80121
80198
  id: id2,
80122
80199
  ...noteIdentifiers(id2),
80123
- title: note2.title,
80200
+ title: noteTitle,
80124
80201
  content: content2,
80125
80202
  contentHash: richContentHash(rawContent2, rich2),
80126
80203
  links: rich2.links,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apple-notes-mcp",
3
- "version": "2.15.15",
3
+ "version": "2.15.17",
4
4
  "description": "MCP server for Apple Notes - read, search, create, edit, organize, and export notes on macOS via Claude and other AI assistants",
5
5
  "type": "module",
6
6
  "main": "build/index.js",