apple-notes-mcp 2.8.21 → 2.8.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1232,6 +1232,38 @@ in the foreground.
1232
1232
  Appends one real unchecked Notes checklist item and verifies its native identity
1233
1233
  and text.
1234
1234
 
1235
+ #### `create-checklist-items`
1236
+
1237
+ Appends several real unchecked checklist items, 1 to 20, in the order given.
1238
+ It takes the same `id`, `expectedContentHash` and `scopeText` as
1239
+ `create-checklist-item`, plus `items`, an array of one-line texts. Each item is
1240
+ one run of the same verified bridge, so the call takes a few seconds per item
1241
+ (a full batch of 20 can run about a minute; if your client times out first,
1242
+ read the note before retrying rather than resending the whole batch) and is
1243
+ gated with `create-checklist-item` in `get-capabilities`.
1244
+
1245
+ After every run the server checks that exactly one new unchecked item with that
1246
+ text and a new native identity appeared, that every item appended earlier in the
1247
+ call kept its identity and text, and that nothing else in the note changed. The
1248
+ verified revision feeds the next run. A final check confirms the new items are
1249
+ the note's last checklist items in the requested order.
1250
+
1251
+ ```json
1252
+ {
1253
+ "id": "x-coredata://ABC123/ICNote/p456",
1254
+ "expectedContentHash": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
1255
+ "scopeText": "Packing list for the trip",
1256
+ "items": ["Passport", "Charger", "Rain jacket"]
1257
+ }
1258
+ ```
1259
+
1260
+ **Returns:** `items`, each with its `index`, native `id` and `text`, plus
1261
+ `orderVerified` and the new `contentHash`. The first uncertain result stops the
1262
+ call without a retry and returns `ok: false` with `landed` (the verified items),
1263
+ `stoppedAt` (the item's index, text, `outcome` of `"not-written"` or
1264
+ `"uncertain"`, and the error), and `notAttempted`. After an uncertain stop, read
1265
+ the note before retrying, and retry only the items that are not present.
1266
+
1235
1267
  #### `create-table`
1236
1268
 
1237
1269
  Appends a native table from rectangular string rows and verifies every decoded
package/build/index.js CHANGED
@@ -44221,6 +44221,72 @@ var common = {
44221
44221
  )
44222
44222
  };
44223
44223
  var htmlEscape = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
44224
+ var MAX_CHECKLIST_BATCH = 20;
44225
+ var byPosition = (items = []) => [...items].sort((a, b) => a.start - b.start);
44226
+ function appendChecklistItems(args, deps, readRich) {
44227
+ const existing = new Set(byPosition(readRich(args.id).checklistItems).map((item) => item.id));
44228
+ const landed = [];
44229
+ let contentHash = args.expectedContentHash;
44230
+ for (const [index, text] of args.items.entries()) {
44231
+ let wrote = false;
44232
+ try {
44233
+ const result = mutateBackground(
44234
+ { ...args, expectedContentHash: contentHash },
44235
+ "create-checklist-item",
44236
+ { text },
44237
+ (before, after) => {
44238
+ wrote = true;
44239
+ assertPreserved(before, after, { append: true });
44240
+ const added = after.checklist.slice(before.checklist.length);
44241
+ if (added.length !== 1 || added[0].text !== text || added[0].done)
44242
+ throw new Error("Native checklist item not verified");
44243
+ },
44244
+ deps
44245
+ );
44246
+ const items = byPosition(readRich(args.id).checklistItems);
44247
+ const fresh = items.filter(
44248
+ (item) => !existing.has(item.id) && !landed.some((done) => done.id === item.id)
44249
+ );
44250
+ if (fresh.length !== 1 || fresh[0].text !== text || fresh[0].done)
44251
+ throw new Error("Native checklist identity not verified");
44252
+ for (const done of landed) {
44253
+ const current = items.find((item) => item.id === done.id);
44254
+ if (!current || current.text !== done.text || current.done)
44255
+ throw new Error("An earlier appended item changed identity or text");
44256
+ }
44257
+ landed.push({ index, id: fresh[0].id, text });
44258
+ contentHash = result.contentHash;
44259
+ } catch (error2) {
44260
+ return {
44261
+ ok: false,
44262
+ id: args.id,
44263
+ landed,
44264
+ stoppedAt: {
44265
+ index,
44266
+ text,
44267
+ outcome: wrote ? "uncertain" : "not-written",
44268
+ error: error2 instanceof Error ? error2.message : String(error2)
44269
+ },
44270
+ notAttempted: args.items.slice(index + 1),
44271
+ contentHash,
44272
+ message: `Stopped at item ${index + 1} of ${args.items.length}; ${landed.length} item(s) landed and were verified. Read the exact note before retrying, and retry only items that are not present.`
44273
+ };
44274
+ }
44275
+ }
44276
+ const finalItems = byPosition(readRich(args.id).checklistItems);
44277
+ const tail = finalItems.slice(finalItems.length - landed.length);
44278
+ const orderVerified = tail.length === landed.length && tail.every((item, i) => item.id === landed[i].id && item.text === landed[i].text);
44279
+ return {
44280
+ ok: orderVerified,
44281
+ id: args.id,
44282
+ contentHash,
44283
+ items: landed,
44284
+ orderVerified,
44285
+ ...orderVerified ? {} : {
44286
+ message: "Every item landed and was verified, but they are not the note's last checklist items in the requested order. Read the note before editing it further."
44287
+ }
44288
+ };
44289
+ }
44224
44290
  function registerNativeOperations(server2, manager) {
44225
44291
  function tool(name, description, input, handler, readOnly = false) {
44226
44292
  server2.registerTool(
@@ -44346,6 +44412,20 @@ function registerNativeOperations(server2, manager) {
44346
44412
  return { ...result, items: readRichNote(args.id).checklistItems };
44347
44413
  }
44348
44414
  );
44415
+ tool(
44416
+ "create-checklist-items",
44417
+ "Use when: appending several real unchecked Notes checklist items to one note, in order.\nReturns: each landed item's native identity and text, the final order check, and the new revision; on a stop, which items landed, the item whose outcome is uncertain, and the items not attempted.\nDo not use when: one item is enough (create-checklist-item) or plain text is sufficient.\nSafety: runs the verified single-item bridge once per item, chaining each verified revision into the next; checks after every item that exactly one new unchecked item with that text and a new identity appeared and that earlier items kept theirs, and stops at the first uncertain result without retrying. Each item takes a few seconds, so a full batch can run about a minute; if the call times out on the client side, read the note before retrying and send only items that are not present.",
44418
+ {
44419
+ ...common,
44420
+ items: external_exports.array(
44421
+ external_exports.string().min(1).max(1e4).refine((s) => !/[\r\n\0]/u.test(s), "One line per checklist item")
44422
+ ).min(1).max(MAX_CHECKLIST_BATCH).describe(`Item texts in the order they should appear (1-${MAX_CHECKLIST_BATCH})`)
44423
+ },
44424
+ (args) => {
44425
+ requireValidated("create-checklist-item");
44426
+ return appendChecklistItems(args, backgroundDependencies(manager), readRichNote);
44427
+ }
44428
+ );
44349
44429
  tool(
44350
44430
  "create-table",
44351
44431
  "Use when: appending one native Notes table from a rectangular array of strings.\nReturns: the native table identity and decoded cells after readback.\nDo not use when: a text table is acceptable or the rows are not rectangular.\nSafety: never substitutes text; preserves existing rich content and reports failure unless the native table is verified.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apple-notes-mcp",
3
- "version": "2.8.21",
3
+ "version": "2.8.22",
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",