apple-notes-mcp 2.6.14 → 2.6.16

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 (2) hide show
  1. package/build/index.js +103 -73
  2. package/package.json +1 -1
package/build/index.js CHANGED
@@ -32119,7 +32119,7 @@ function object(shape, params) {
32119
32119
  return new ZodMiniObject(def);
32120
32120
  }
32121
32121
 
32122
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
32122
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
32123
32123
  function isZ4Schema(s) {
32124
32124
  const schema = s;
32125
32125
  return !!schema._zod;
@@ -32203,17 +32203,33 @@ function normalizeObjectSchema(schema) {
32203
32203
  }
32204
32204
  return void 0;
32205
32205
  }
32206
+ function getDotPath(path4) {
32207
+ if (path4.length === 0) {
32208
+ return "object root";
32209
+ }
32210
+ return path4.reduce((acc, seg, index) => {
32211
+ if (index === 0) {
32212
+ return String(seg);
32213
+ }
32214
+ if (typeof seg === "number") {
32215
+ return `${acc}[${seg}]`;
32216
+ }
32217
+ return `${acc}.${seg}`;
32218
+ }, "");
32219
+ }
32206
32220
  function getParseErrorMessage(error2) {
32207
32221
  if (error2 && typeof error2 === "object") {
32222
+ if ("issues" in error2 && Array.isArray(error2.issues) && error2.issues.length > 0) {
32223
+ return error2.issues.map((i) => {
32224
+ if (!i.path?.length) {
32225
+ return i.message;
32226
+ }
32227
+ return `${i.message} at ${getDotPath(i.path)}`;
32228
+ }).join("\n");
32229
+ }
32208
32230
  if ("message" in error2 && typeof error2.message === "string") {
32209
32231
  return error2.message;
32210
32232
  }
32211
- if ("issues" in error2 && Array.isArray(error2.issues) && error2.issues.length > 0) {
32212
- const firstIssue = error2.issues[0];
32213
- if (firstIssue && typeof firstIssue === "object" && "message" in firstIssue) {
32214
- return String(firstIssue.message);
32215
- }
32216
- }
32217
32233
  try {
32218
32234
  return JSON.stringify(error2);
32219
32235
  } catch {
@@ -32958,7 +32974,7 @@ function preprocess(fn, schema) {
32958
32974
  // node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/classic/external.js
32959
32975
  config(en_default2());
32960
32976
 
32961
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
32977
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
32962
32978
  var LATEST_PROTOCOL_VERSION = "2025-11-25";
32963
32979
  var SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"];
32964
32980
  var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
@@ -34489,7 +34505,7 @@ var UrlElicitationRequiredError = class extends McpError {
34489
34505
  }
34490
34506
  };
34491
34507
 
34492
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
34508
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
34493
34509
  function isTerminal(status) {
34494
34510
  return status === "completed" || status === "failed" || status === "cancelled";
34495
34511
  }
@@ -35778,7 +35794,7 @@ var zodToJsonSchema = (schema, options) => {
35778
35794
  return combined;
35779
35795
  };
35780
35796
 
35781
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
35797
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
35782
35798
  function mapMiniTarget(t) {
35783
35799
  if (!t)
35784
35800
  return "draft-7";
@@ -35820,7 +35836,7 @@ function parseWithCompat(schema, data) {
35820
35836
  return result.data;
35821
35837
  }
35822
35838
 
35823
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
35839
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
35824
35840
  var DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
35825
35841
  var Protocol = class {
35826
35842
  constructor(_options) {
@@ -36774,7 +36790,7 @@ function mergeCapabilities(base, additional) {
36774
36790
  return result;
36775
36791
  }
36776
36792
 
36777
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
36793
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
36778
36794
  var import_ajv = __toESM(require_ajv(), 1);
36779
36795
  var import_ajv_formats = __toESM(require_dist(), 1);
36780
36796
  function createDefaultAjvInstance() {
@@ -36842,7 +36858,7 @@ var AjvJsonSchemaValidator = class {
36842
36858
  }
36843
36859
  };
36844
36860
 
36845
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
36861
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
36846
36862
  var ExperimentalServerTasks = class {
36847
36863
  constructor(_server) {
36848
36864
  this._server = _server;
@@ -37055,7 +37071,7 @@ var ExperimentalServerTasks = class {
37055
37071
  }
37056
37072
  };
37057
37073
 
37058
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
37074
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
37059
37075
  function assertToolsCallTaskCapability(requests, method, entityName) {
37060
37076
  if (!requests) {
37061
37077
  throw new Error(`${entityName} does not support task creation (required for ${method})`);
@@ -37090,7 +37106,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
37090
37106
  }
37091
37107
  }
37092
37108
 
37093
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
37109
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
37094
37110
  var Server = class extends Protocol {
37095
37111
  /**
37096
37112
  * Initializes this server with the given name and version information.
@@ -37156,16 +37172,7 @@ var Server = class extends Protocol {
37156
37172
  if (!methodSchema) {
37157
37173
  throw new Error("Schema is missing a method literal");
37158
37174
  }
37159
- let methodValue;
37160
- if (isZ4Schema(methodSchema)) {
37161
- const v4Schema = methodSchema;
37162
- const v4Def = v4Schema._zod?.def;
37163
- methodValue = v4Def?.value ?? v4Schema.value;
37164
- } else {
37165
- const v3Schema = methodSchema;
37166
- const legacyDef = v3Schema._def;
37167
- methodValue = legacyDef?.value ?? v3Schema.value;
37168
- }
37175
+ const methodValue = getLiteralValue(methodSchema);
37169
37176
  if (typeof methodValue !== "string") {
37170
37177
  throw new Error("Schema method literal must be a string");
37171
37178
  }
@@ -37470,7 +37477,7 @@ var Server = class extends Protocol {
37470
37477
  }
37471
37478
  };
37472
37479
 
37473
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
37480
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
37474
37481
  var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
37475
37482
  function isCompletable(schema) {
37476
37483
  return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
@@ -37484,7 +37491,7 @@ var McpZodTypeKind;
37484
37491
  McpZodTypeKind2["Completable"] = "McpCompletable";
37485
37492
  })(McpZodTypeKind || (McpZodTypeKind = {}));
37486
37493
 
37487
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/uriTemplate.js
37494
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/uriTemplate.js
37488
37495
  var MAX_TEMPLATE_LENGTH = 1e6;
37489
37496
  var MAX_VARIABLE_LENGTH = 1e6;
37490
37497
  var MAX_TEMPLATE_EXPRESSIONS = 1e4;
@@ -37706,7 +37713,7 @@ var UriTemplate = class _UriTemplate {
37706
37713
  }
37707
37714
  };
37708
37715
 
37709
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
37716
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
37710
37717
  var TOOL_NAME_REGEX = /^[A-Za-z0-9._-]{1,128}$/;
37711
37718
  function validateToolName(name) {
37712
37719
  const warnings = [];
@@ -37764,7 +37771,7 @@ function validateAndWarnToolName(name) {
37764
37771
  return result.isValid;
37765
37772
  }
37766
37773
 
37767
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
37774
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
37768
37775
  var ExperimentalMcpServerTasks = class {
37769
37776
  constructor(_mcpServer) {
37770
37777
  this._mcpServer = _mcpServer;
@@ -37779,7 +37786,7 @@ var ExperimentalMcpServerTasks = class {
37779
37786
  }
37780
37787
  };
37781
37788
 
37782
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
37789
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
37783
37790
  var McpServer = class {
37784
37791
  constructor(serverInfo, options) {
37785
37792
  this._registeredResources = {};
@@ -38595,12 +38602,21 @@ var EMPTY_COMPLETION_RESULT = {
38595
38602
  }
38596
38603
  };
38597
38604
 
38598
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
38605
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
38599
38606
  import process2 from "node:process";
38600
38607
 
38601
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
38608
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
38609
+ var STDIO_DEFAULT_MAX_BUFFER_SIZE = 10 * 1024 * 1024;
38602
38610
  var ReadBuffer = class {
38611
+ constructor(options) {
38612
+ this._maxBufferSize = options?.maxBufferSize ?? STDIO_DEFAULT_MAX_BUFFER_SIZE;
38613
+ }
38603
38614
  append(chunk) {
38615
+ const newSize = (this._buffer?.length ?? 0) + chunk.length;
38616
+ if (newSize > this._maxBufferSize) {
38617
+ this.clear();
38618
+ throw new Error(`ReadBuffer exceeded maximum size of ${this._maxBufferSize} bytes`);
38619
+ }
38604
38620
  this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
38605
38621
  }
38606
38622
  readMessage() {
@@ -38626,20 +38642,26 @@ function serializeMessage(message) {
38626
38642
  return JSON.stringify(message) + "\n";
38627
38643
  }
38628
38644
 
38629
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
38645
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
38630
38646
  var StdioServerTransport = class {
38631
- constructor(_stdin = process2.stdin, _stdout = process2.stdout) {
38647
+ constructor(_stdin = process2.stdin, _stdout = process2.stdout, options) {
38632
38648
  this._stdin = _stdin;
38633
38649
  this._stdout = _stdout;
38634
- this._readBuffer = new ReadBuffer();
38635
38650
  this._started = false;
38636
38651
  this._ondata = (chunk) => {
38637
- this._readBuffer.append(chunk);
38638
- this.processReadBuffer();
38652
+ try {
38653
+ this._readBuffer.append(chunk);
38654
+ this.processReadBuffer();
38655
+ } catch (error2) {
38656
+ this.onerror?.(error2);
38657
+ this.close().catch(() => {
38658
+ });
38659
+ }
38639
38660
  };
38640
38661
  this._onerror = (error2) => {
38641
38662
  this.onerror?.(error2);
38642
38663
  };
38664
+ this._readBuffer = new ReadBuffer({ maxBufferSize: options?.maxBufferSize });
38643
38665
  }
38644
38666
  /**
38645
38667
  * Starts listening for messages on stdin.
@@ -42146,7 +42168,15 @@ var folderNameSchema = {
42146
42168
  name: external_exports.string().min(1, "Folder name is required").max(MAX.FOLDER),
42147
42169
  account: external_exports.string().max(MAX.ACCOUNT).optional().describe("Account name (defaults to iCloud)")
42148
42170
  };
42149
- server.registerTool(
42171
+ function registerTool(name, config2, cb) {
42172
+ const { outputSchema, ...rest } = config2;
42173
+ return server.registerTool(
42174
+ name,
42175
+ outputSchema ? { ...rest, outputSchema: external_exports.object(outputSchema).passthrough() } : rest,
42176
+ cb
42177
+ );
42178
+ }
42179
+ registerTool(
42150
42180
  "create-note",
42151
42181
  {
42152
42182
  description: "Use when: the user wants to create a brand-new Apple Note.\nReturns: the new note's title and id \u2014 reuse the id for follow-up reads/edits.\nDo not use when: editing an existing note (use update-note).\nNote: the title is prepended as an <h1>; true Apple Notes checklists cannot be created via AppleScript (see the content field). A 'folder' must already exist \u2014 create-folder first (it is idempotent), since this tool does not create it.",
@@ -42192,7 +42222,7 @@ server.registerTool(
42192
42222
  });
42193
42223
  }, "Error creating note")
42194
42224
  );
42195
- server.registerTool(
42225
+ registerTool(
42196
42226
  "search-notes",
42197
42227
  {
42198
42228
  description: "Use when: finding notes by a keyword in the title (or body with searchContent=true) and you need their ids.\nReturns: matching notes with title, folder, and id.\nDo not use when: you already have a note id (use get-note-content) or want every note (use list-notes).\nPrefer this first to obtain ids for subsequent read/update/delete/move calls.",
@@ -42265,7 +42295,7 @@ ${noteList}${truncationNote}${syncNote}`,
42265
42295
  );
42266
42296
  }, "Error searching notes")
42267
42297
  );
42268
- server.registerTool(
42298
+ registerTool(
42269
42299
  "get-note-content",
42270
42300
  {
42271
42301
  description: "Use when: reading the full body text of one known note, by id (preferred) or title.\nReturns: the note's content plus parsed hashtags, and strippedImages/truncated when the body was capped.\nDo not use when: you only need metadata (get-note-details) or Markdown with checklist state (get-note-markdown).\nNote: password-protected notes must be unlocked in Notes.app first.\nSafety: inline images larger than APPLE_NOTES_MCP_MAX_INLINE_IMAGE_BYTES (default 256 KB) are replaced with '[inline image omitted: ...]' text placeholders, so the returned body is lossy whenever truncated is true \u2014 do NOT write it back with update-note or the real images are replaced by that text. Use append-to-note to add content, or export the images with save-attachment / fetch-attachment first.",
@@ -42340,7 +42370,7 @@ server.registerTool(
42340
42370
  });
42341
42371
  }, "Error retrieving note content")
42342
42372
  );
42343
- server.registerTool(
42373
+ registerTool(
42344
42374
  "get-note-plaintext",
42345
42375
  {
42346
42376
  description: "Use when: reading one note's body as plain text with no HTML, by id (preferred) or title.\nReturns: the note's plaintext exactly as Notes exposes it.\nDo not use when: you need the HTML body (get-note-content) or Markdown with checklist state (get-note-markdown).\nNote: this reads the note's native plaintext property, so it skips the HTML-to-text conversion; password-protected notes must be unlocked in Notes.app first.",
@@ -42390,7 +42420,7 @@ server.registerTool(
42390
42420
  return successResponse(plaintext, { title, plaintext });
42391
42421
  }, "Error retrieving note plaintext")
42392
42422
  );
42393
- server.registerTool(
42423
+ registerTool(
42394
42424
  "get-note-by-id",
42395
42425
  {
42396
42426
  description: "Use when: you have a note id and need its metadata only.\nReturns: id, title, created, modified, shared, passwordProtected.\nDo not use when: you need the body text (get-note-content) or only have a title (get-note-details).",
@@ -42422,7 +42452,7 @@ server.registerTool(
42422
42452
  return successResponse(JSON.stringify(metadata, null, 2), metadata);
42423
42453
  }, "Error retrieving note")
42424
42454
  );
42425
- server.registerTool(
42455
+ registerTool(
42426
42456
  "get-note-details",
42427
42457
  {
42428
42458
  description: "Use when: you have a note title (not an id) and need its metadata.\nReturns: id, title, created, modified, shared, passwordProtected, account.\nDo not use when: you have an id (get-note-by-id) or need the body text (get-note-content).\nUse the returned id for reliable follow-up operations.",
@@ -42454,7 +42484,7 @@ server.registerTool(
42454
42484
  return successResponse(JSON.stringify(metadata, null, 2), metadata);
42455
42485
  }, "Error retrieving note details")
42456
42486
  );
42457
- server.registerTool(
42487
+ registerTool(
42458
42488
  "show-note",
42459
42489
  {
42460
42490
  description: "Use when: the user wants to reveal a known note in Notes.app by id.\nReturns: confirmation that Notes.app accepted the show command.\nDo not use when: you only need note content (get-note-content) or metadata (get-note-by-id).\nNote: this opens or focuses the Notes UI.",
@@ -42475,7 +42505,7 @@ server.registerTool(
42475
42505
  return successResponse(`Shown note with ID "${id}" in Notes.app`, { id, separately });
42476
42506
  }, "Error showing note")
42477
42507
  );
42478
- server.registerTool(
42508
+ registerTool(
42479
42509
  "get-note-link",
42480
42510
  {
42481
42511
  description: "Use when: you need the notes:// deep-link URL for a note so it can be stored in a Reminders task, shared, or opened directly.\nReturns: a notes://showNote?identifier=<uuid> URL that opens the note in Notes.app on iOS and macOS.\nDo not use when: you only need the note's CoreData id (get-note-by-id) or want to reveal the note on screen (show-note).\nNote: the primary path reads the note's identifier from the Notes database, so it needs Full Disk Access for the app that launches this server; macOS 12-15 can fall back to the AppleScript 'note link' property, which macOS 26+ no longer exposes. Password-protected notes cannot be linked.",
@@ -42530,7 +42560,7 @@ server.registerTool(
42530
42560
  return successResponse(`Note link: ${url}`, { title, url });
42531
42561
  }, "Error getting note link")
42532
42562
  );
42533
- server.registerTool(
42563
+ registerTool(
42534
42564
  "show-folder",
42535
42565
  {
42536
42566
  description: "Use when: the user wants to reveal a known folder in Notes.app by id.\nReturns: confirmation that Notes.app accepted the show command.\nDo not use when: you only need the folder list (list-folders).\nNote: this opens or focuses the Notes UI. Get the id from list-folders.",
@@ -42551,7 +42581,7 @@ server.registerTool(
42551
42581
  return successResponse(`Shown folder with ID "${id}" in Notes.app`, { id, separately });
42552
42582
  }, "Error showing folder")
42553
42583
  );
42554
- server.registerTool(
42584
+ registerTool(
42555
42585
  "show-account",
42556
42586
  {
42557
42587
  description: "Use when: the user wants to reveal a known account in Notes.app by id.\nReturns: confirmation that Notes.app accepted the show command.\nDo not use when: you only need the account list (list-accounts).\nNote: this opens or focuses the Notes UI. Get the id from list-accounts.",
@@ -42572,7 +42602,7 @@ server.registerTool(
42572
42602
  return successResponse(`Shown account with ID "${id}" in Notes.app`, { id, separately });
42573
42603
  }, "Error showing account")
42574
42604
  );
42575
- server.registerTool(
42605
+ registerTool(
42576
42606
  "update-note",
42577
42607
  {
42578
42608
  description: "Use when: changing the title and/or replacing the body of an existing note, by id (preferred) or title.\nReturns: confirmation; warns when the note is shared.\nDo not use when: creating a new note (create-note).\nSafety: newContent REPLACES the entire body \u2014 it does not append. Read the note first if you need to preserve existing text, and run list-attachments first when the note may hold files, images, scans, PDFs, or audio, since a full-body replace can drop embedded attachments. Edits to shared notes are immediately visible to all collaborators.",
@@ -42648,7 +42678,7 @@ server.registerTool(
42648
42678
  });
42649
42679
  }, "Error updating note")
42650
42680
  );
42651
- server.registerTool(
42681
+ registerTool(
42652
42682
  "append-to-note",
42653
42683
  {
42654
42684
  description: "Use when: adding content to an existing note without replacing it, by id (preferred) or title.\nReturns: confirmation with the note id and title.\nDo not use when: creating a new note (create-note) or replacing the entire body (update-note).\nSafety: reads the existing body first, concatenates, then writes back. Run list-attachments first if the note may hold embedded files \u2014 a full-body rewrite can drop attachments.",
@@ -42763,7 +42793,7 @@ server.registerTool(
42763
42793
  "Error appending to note"
42764
42794
  )
42765
42795
  );
42766
- server.registerTool(
42796
+ registerTool(
42767
42797
  "delete-note",
42768
42798
  {
42769
42799
  description: "Use when: permanently deleting a single note, by id (preferred) or title.\nReturns: confirmation; warns when the note was shared.\nDo not use when: deleting many notes (batch-delete-notes) or just relocating one (move-note).\nSafety: requires explicit user confirmation before deleting. Prefer search-notes/list-notes first to show the affected note id and title. Deleting a shared note removes collaborator access.",
@@ -42818,7 +42848,7 @@ server.registerTool(
42818
42848
  });
42819
42849
  }, "Error deleting note")
42820
42850
  );
42821
- server.registerTool(
42851
+ registerTool(
42822
42852
  "move-note",
42823
42853
  {
42824
42854
  description: "Use when: moving one note to a different folder, by id (preferred) or title.\nReturns: confirmation of the note and destination folder.\nDo not use when: moving many notes (batch-move-notes).\nNote: the note is relocated in place via Notes.app's native move, preserving its id, creation date, and all attachments. The destination folder must already exist (create-folder).",
@@ -42876,7 +42906,7 @@ server.registerTool(
42876
42906
  });
42877
42907
  }, "Error moving note")
42878
42908
  );
42879
- server.registerTool(
42909
+ registerTool(
42880
42910
  "list-notes",
42881
42911
  {
42882
42912
  description: "Use when: enumerating notes in an account or folder; supports modifiedSince and limit for large collections.\nReturns: note titles only (no content or ids).\nDo not use when: you need content (get-note-content) or ids for follow-up edits (use search-notes).\nNote: warns if iCloud sync is active and results may be partial.",
@@ -42930,7 +42960,7 @@ ${noteList}${syncNote}`,
42930
42960
  );
42931
42961
  }, "Error listing notes")
42932
42962
  );
42933
- server.registerTool(
42963
+ registerTool(
42934
42964
  "get-selected-notes",
42935
42965
  {
42936
42966
  description: "Use when: the user asks what note(s) are currently selected in Notes.app.\nReturns: selected note metadata with ids for follow-up operations.\nDo not use when: searching all notes (search-notes) or listing a folder (list-notes).\nNote: reads Notes.app UI selection; it may be empty if Notes is closed or no note is selected.",
@@ -42953,7 +42983,7 @@ server.registerTool(
42953
42983
  ${noteList}`, { notes, count: notes.length });
42954
42984
  }, "Error getting selected notes")
42955
42985
  );
42956
- server.registerTool(
42986
+ registerTool(
42957
42987
  "list-folders",
42958
42988
  {
42959
42989
  description: "Use when: listing all folders, with full nested paths, for an account.\nReturns: folder names/paths.\nDo not use when: listing notes (list-notes).\nNote: warns if iCloud sync is active.",
@@ -42993,7 +43023,7 @@ ${folderList}${syncNote}`, {
42993
43023
  });
42994
43024
  }, "Error listing folders")
42995
43025
  );
42996
- server.registerTool(
43026
+ registerTool(
42997
43027
  "create-folder",
42998
43028
  {
42999
43029
  description: "Use when: creating a folder, including nested paths like 'Work/Clients' (intermediate folders are created, existing ones skipped).\nReturns: confirmation.\nDo not use when: creating a note (create-note).",
@@ -43019,7 +43049,7 @@ server.registerTool(
43019
43049
  });
43020
43050
  }, "Error creating folder")
43021
43051
  );
43022
- server.registerTool(
43052
+ registerTool(
43023
43053
  "delete-folder",
43024
43054
  {
43025
43055
  description: "Use when: deleting an existing folder by name or nested path.\nReturns: confirmation.\nDo not use when: deleting a note (delete-note).\nSafety: requires explicit user confirmation. Deletion fails if the folder still contains notes \u2014 list or move those notes first.",
@@ -43039,7 +43069,7 @@ server.registerTool(
43039
43069
  return successResponse(`Folder deleted: "${name}"`, { ok: true, folder: name });
43040
43070
  }, "Error deleting folder")
43041
43071
  );
43042
- server.registerTool(
43072
+ registerTool(
43043
43073
  "list-accounts",
43044
43074
  {
43045
43075
  description: "Use when: discovering which Notes accounts exist (iCloud, Gmail, Exchange, etc.) before targeting one.\nReturns: account names.\nDo not use when: you already know the account, or are working by note id (ids are account-independent).",
@@ -43066,7 +43096,7 @@ ${accountList}`, {
43066
43096
  });
43067
43097
  }, "Error listing accounts")
43068
43098
  );
43069
- server.registerTool(
43099
+ registerTool(
43070
43100
  "get-default-location",
43071
43101
  {
43072
43102
  description: "Use when: discovering where Notes.app will create new notes by default.\nReturns: default account and default folder metadata.\nDo not use when: you already have an explicit account/folder target.",
@@ -43083,7 +43113,7 @@ Default folder: ${location.folder.name} [id: ${location.folder.id}]`;
43083
43113
  return successResponse(message, { ...location });
43084
43114
  }, "Error getting default Notes location")
43085
43115
  );
43086
- server.registerTool(
43116
+ registerTool(
43087
43117
  "list-shared-notes",
43088
43118
  {
43089
43119
  description: "Use when: finding notes shared with collaborators.\nReturns: shared notes with title, account, and id.\nDo not use when: searching all notes (search-notes).\nNote: edits or deletes to these notes affect all collaborators.",
@@ -43114,7 +43144,7 @@ ${noteList}
43114
43144
  );
43115
43145
  }, "Error listing shared notes")
43116
43146
  );
43117
- server.registerTool(
43147
+ registerTool(
43118
43148
  "get-sync-status",
43119
43149
  {
43120
43150
  description: "Use when: checking whether iCloud sync is in progress before trusting read results.\nReturns: sync active/idle, pending upload count, and seconds since last change.\nDo not use when: you need note data \u2014 this is a read-only diagnostics tool.",
@@ -43153,7 +43183,7 @@ server.registerTool(
43153
43183
  return successResponse(lines.join("\n"), { ...status });
43154
43184
  }, "Error checking sync status")
43155
43185
  );
43156
- server.registerTool(
43186
+ registerTool(
43157
43187
  "health-check",
43158
43188
  {
43159
43189
  description: "Use when: a quick check that Notes.app is reachable and (optionally) Full Disk Access is granted for checklist features.\nReturns: pass/fail per check.\nDo not use when: you need detailed, actionable setup diagnostics (use doctor).\nRead-only.",
@@ -43184,7 +43214,7 @@ ${fdaLine}`, {
43184
43214
  });
43185
43215
  }, "Error running health check")
43186
43216
  );
43187
- server.registerTool(
43217
+ registerTool(
43188
43218
  "doctor",
43189
43219
  {
43190
43220
  description: "Use when: diagnosing setup problems (Notes.app automation permission, account state, Full Disk Access) with actionable guidance.\nReturns: a detailed report plus structured fields.\nDo not use when: you just need a quick pass/fail (health-check).\nRead-only.",
@@ -43199,7 +43229,7 @@ server.registerTool(
43199
43229
  return successResponse(formatDoctorReport(report), { ...report });
43200
43230
  }, "Error running doctor")
43201
43231
  );
43202
- server.registerTool(
43232
+ registerTool(
43203
43233
  "get-notes-stats",
43204
43234
  {
43205
43235
  description: "Use when: summarizing the library \u2014 total notes, per-account/folder counts, and recent activity.\nReturns: aggregate statistics; flags partial coverage when some scopes were unreadable.\nDo not use when: you need individual notes (list-notes/search-notes).\nRead-only.",
@@ -43244,7 +43274,7 @@ server.registerTool(
43244
43274
  return successResponse(lines.join("\n"), { ...stats });
43245
43275
  }, "Error getting notes statistics")
43246
43276
  );
43247
- server.registerTool(
43277
+ registerTool(
43248
43278
  "list-attachments",
43249
43279
  {
43250
43280
  description: "Use when: listing the attachments of one note, by id (preferred) or title.\nReturns: each attachment's name, content type, and id (use with save-attachment/fetch-attachment).\nDo not use when: you want the attachment bytes (fetch-attachment) or a file on disk (save-attachment).",
@@ -43299,7 +43329,7 @@ ${attachmentList}`,
43299
43329
  );
43300
43330
  }, "Error listing attachments")
43301
43331
  );
43302
- server.registerTool(
43332
+ registerTool(
43303
43333
  "batch-delete-notes",
43304
43334
  {
43305
43335
  description: "Use when: permanently deleting multiple notes by id in one call.\nReturns: per-id success/failure counts.\nDo not use when: deleting a single note (delete-note).\nSafety: requires explicit user confirmation; this is destructive and not undoable. Prefer search-notes/list-notes first to confirm the exact ids being deleted.",
@@ -43335,7 +43365,7 @@ server.registerTool(
43335
43365
  }) : errorResponse(lines.join("\n"));
43336
43366
  }, "Error performing batch delete")
43337
43367
  );
43338
- server.registerTool(
43368
+ registerTool(
43339
43369
  "batch-move-notes",
43340
43370
  {
43341
43371
  description: "Use when: moving multiple notes by id into one destination folder.\nReturns: per-id success/failure counts.\nDo not use when: moving a single note (move-note).\nNote: the destination folder must already exist (create-folder).",
@@ -43377,7 +43407,7 @@ server.registerTool(
43377
43407
  }) : errorResponse(lines.join("\n"));
43378
43408
  }, "Error performing batch move")
43379
43409
  );
43380
- server.registerTool(
43410
+ registerTool(
43381
43411
  "save-attachment",
43382
43412
  {
43383
43413
  description: "Use when: writing one note attachment to a file on disk.\nReturns: the saved path.\nDo not use when: you want the bytes in-memory as base64 (fetch-attachment).\nSafety: writes a file; savePath must be absolute and under the home directory, a temp dir, or /Volumes. Get the ids from list-attachments first.",
@@ -43404,7 +43434,7 @@ server.registerTool(
43404
43434
  });
43405
43435
  }, "Error saving attachment")
43406
43436
  );
43407
- server.registerTool(
43437
+ registerTool(
43408
43438
  "fetch-attachment",
43409
43439
  {
43410
43440
  description: "Use when: retrieving one note attachment's bytes inline as base64 (no file written).\nReturns: name, content type, byte count, and base64 data.\nDo not use when: you want it saved to disk (save-attachment).\nNote: get the ids from list-attachments first.",
@@ -43430,7 +43460,7 @@ server.registerTool(
43430
43460
  );
43431
43461
  }, "Error fetching attachment")
43432
43462
  );
43433
- server.registerTool(
43463
+ registerTool(
43434
43464
  "show-attachment",
43435
43465
  {
43436
43466
  description: "Use when: the user wants to reveal one note attachment in Notes.app.\nReturns: confirmation that Notes.app revealed the attachment.\nDo not use when: you want the bytes (fetch-attachment) or a file on disk (save-attachment).\nNote: this opens or focuses the Notes UI. Get the ids from list-attachments first.",
@@ -43457,7 +43487,7 @@ server.registerTool(
43457
43487
  });
43458
43488
  }, "Error showing attachment")
43459
43489
  );
43460
- server.registerTool(
43490
+ registerTool(
43461
43491
  "export-notes-json",
43462
43492
  {
43463
43493
  description: "Use when: exporting the entire notes library as structured JSON for backup or bulk processing.\nReturns: a summary plus the full JSON of all notes, folders, and accounts.\nDo not use when: you need a single note (get-note-content) \u2014 this reads everything and can be large.\nRead-only.",
@@ -43489,7 +43519,7 @@ Full JSON export:`
43489
43519
  };
43490
43520
  }, "Error exporting notes")
43491
43521
  );
43492
- server.registerTool(
43522
+ registerTool(
43493
43523
  "get-note-markdown",
43494
43524
  {
43495
43525
  description: "Use when: reading a note as Markdown, with checklist items annotated [x]/[ ] when Full Disk Access is granted.\nReturns: the note's Markdown.\nDo not use when: you need the raw HTML/plaintext body (get-note-content) or only metadata (get-note-details).\nNote: falls back to plain lists (no checkmarks) without Full Disk Access.",
@@ -43522,7 +43552,7 @@ server.registerTool(
43522
43552
  return successResponse(markdown, { markdown });
43523
43553
  }, "Error getting note as markdown")
43524
43554
  );
43525
- server.registerTool(
43555
+ registerTool(
43526
43556
  "get-checklist-state",
43527
43557
  {
43528
43558
  description: "Use when: reading the checked/unchecked state of a note's checklist items, by id.\nReturns: each item's text and done state plus checked/total counts.\nDo not use when: you only have a title (get the id via search-notes first) or want the full body text (get-note-content).\nNote: requires Full Disk Access; reads the NoteStore database directly.",
@@ -43558,7 +43588,7 @@ ${summary}`,
43558
43588
  );
43559
43589
  }, "Error reading checklist state")
43560
43590
  );
43561
- server.registerTool(
43591
+ registerTool(
43562
43592
  "get-note-metadata",
43563
43593
  {
43564
43594
  description: "[BETA] Use when: reading note metadata AppleScript cannot expose \u2014 pinned state, checklist flags, trash/recovery state, preview snippet, password hint \u2014 by id.\nReturns: a metadata object; fields vary by macOS version and are omitted when unavailable.\nDo not use when: you need the body (get-note-content) or per-item checklist state (get-checklist-state).\nNote: reads the NoteStore SQLite database read-only and requires Full Disk Access. BETA \u2014 the database schema changes between macOS releases, so some fields may be absent. Works on trashed notes that AppleScript can no longer resolve.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apple-notes-mcp",
3
- "version": "2.6.14",
3
+ "version": "2.6.16",
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",