apple-notes-mcp 2.7.5 → 2.8.0
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 +43 -65
- package/build/index.js +336 -432
- package/docs/NODE-RUNTIME-AND-TCC-PERMISSIONS.md +32 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -284,8 +284,10 @@ Retrieves the full content of a specific note.
|
|
|
284
284
|
}
|
|
285
285
|
```
|
|
286
286
|
|
|
287
|
-
**Returns:** The HTML content of the note,
|
|
288
|
-
`
|
|
287
|
+
**Returns:** The HTML content of the note, its exact `id`, and a
|
|
288
|
+
`contentHash`. Pass that hash back as `expectedContentHash` for a later update,
|
|
289
|
+
append, or delete; the write is rejected if the note changed after this read.
|
|
290
|
+
The `structuredContent` also includes `hashtags` — any inline `#hashtag` tags parsed
|
|
289
291
|
from the body. Apple Notes tags are inline hashtags, not a scriptable property;
|
|
290
292
|
see [docs/APPLESCRIPT-LIMITATIONS.md](https://github.com/sweetrb/apple-notes-mcp/blob/main/docs/APPLESCRIPT-LIMITATIONS.md#tags--hashtags-29). Smart Folders are not scriptable.
|
|
291
293
|
|
|
@@ -294,10 +296,9 @@ base64 images larger than `APPLE_NOTES_MCP_MAX_INLINE_IMAGE_BYTES` (default
|
|
|
294
296
|
256 KB) are replaced with `[inline image omitted: …]` text placeholders so an
|
|
295
297
|
image-heavy note cannot blow the MCP message limit. `structuredContent` reports
|
|
296
298
|
this as `strippedImages` (count) and `truncated` (boolean). When either is set,
|
|
297
|
-
passing this body to
|
|
298
|
-
with
|
|
299
|
-
|
|
300
|
-
first.
|
|
299
|
+
passing this body to an unguarded full-body writer would replace the real images
|
|
300
|
+
with placeholder text. This server refuses update and append operations on
|
|
301
|
+
attachment-bearing notes; edit them in Notes.app.
|
|
301
302
|
|
|
302
303
|
---
|
|
303
304
|
|
|
@@ -379,56 +380,42 @@ Updates an existing note's content and/or title.
|
|
|
379
380
|
|
|
380
381
|
| Parameter | Type | Required | Description |
|
|
381
382
|
|-----------|------|----------|-------------|
|
|
382
|
-
| `id` | string |
|
|
383
|
-
| `
|
|
383
|
+
| `id` | string | Yes | Exact CoreData note ID returned by a read or search |
|
|
384
|
+
| `expectedContentHash` | string | Yes | `contentHash` from the exact note version being replaced |
|
|
384
385
|
| `newTitle` | string | No | New title (if changing the title; ignored when `format` is `"html"`) |
|
|
385
386
|
| `newContent` | string | Yes | New content for the note body |
|
|
386
|
-
| `account` | string | No | Account containing the note (defaults to Notes.app's default account; exact or unique-prefix match, ignored if `id` is provided) |
|
|
387
387
|
| `format` | string | No | Content format: `"plaintext"` (default) or `"html"`. When `"html"`, content replaces the entire note body as raw HTML and `newTitle` is ignored (the first HTML element serves as the title) |
|
|
388
388
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
**Returns:** Confirmation with the note's visible title and, for ID-based updates, its ID. For HTML updates, the title comes from the first rendered line of `newContent`, matching Notes.app. The response also warns if the note is shared.
|
|
389
|
+
Title-only updates are rejected because Apple Notes titles are not unique.
|
|
392
390
|
|
|
393
391
|
**Example - Using ID (recommended):**
|
|
394
392
|
```json
|
|
395
393
|
{
|
|
396
394
|
"id": "x-coredata://ABC123/ICNote/p456",
|
|
395
|
+
"expectedContentHash": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
|
397
396
|
"newContent": "Updated content here"
|
|
398
397
|
}
|
|
399
398
|
```
|
|
400
399
|
|
|
401
|
-
**Example - Update content only:**
|
|
402
|
-
```json
|
|
403
|
-
{
|
|
404
|
-
"title": "Shopping List",
|
|
405
|
-
"newContent": "- Milk\n- Eggs\n- Bread\n- Butter"
|
|
406
|
-
}
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
**Example - Update title and content:**
|
|
410
|
-
```json
|
|
411
|
-
{
|
|
412
|
-
"title": "Draft",
|
|
413
|
-
"newTitle": "Final Version",
|
|
414
|
-
"newContent": "This is the completed document."
|
|
415
|
-
}
|
|
416
|
-
```
|
|
417
|
-
|
|
418
400
|
**Example - Update with HTML formatting:**
|
|
419
401
|
```json
|
|
420
402
|
{
|
|
421
403
|
"id": "x-coredata://ABC123/ICNote/p456",
|
|
404
|
+
"expectedContentHash": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
|
422
405
|
"newContent": "<p>New findings with <b>bold</b> emphasis.</p><pre><code>console.log('hello');</code></pre>",
|
|
423
406
|
"format": "html"
|
|
424
407
|
}
|
|
425
408
|
```
|
|
426
409
|
|
|
427
|
-
**Returns:** Confirmation
|
|
410
|
+
**Returns:** Confirmation with the exact ID, post-save `contentHash`, and
|
|
411
|
+
`verifiedVisibleText: true`, or an error if the note changed before saving.
|
|
412
|
+
Apple Notes normalizes HTML, so this proves the visible text after saving, not
|
|
413
|
+
byte-identical rich formatting.
|
|
428
414
|
|
|
429
415
|
**Note:** `newContent` **replaces the entire note body** — it is not appended. To add to a note, prefer [`append-to-note`](#append-to-note), which does the read-and-concatenate for you and always round-trips the body as HTML. If you do read-modify-write by hand, note that `get-note-content` replaces oversized inline images with text placeholders (see [`get-note-content`](#get-note-content)) — writing that body back bakes the placeholders in.
|
|
430
416
|
|
|
431
|
-
**Attachments:**
|
|
417
|
+
**Attachments:** `update-note` refuses to replace any note that contains an
|
|
418
|
+
attachment. Edit those notes in Notes.app or create a separate note instead.
|
|
432
419
|
|
|
433
420
|
---
|
|
434
421
|
|
|
@@ -438,23 +425,17 @@ Deletes a note (moves to Recently Deleted in Notes.app).
|
|
|
438
425
|
|
|
439
426
|
| Parameter | Type | Required | Description |
|
|
440
427
|
|-----------|------|----------|-------------|
|
|
441
|
-
| `id` | string |
|
|
442
|
-
| `
|
|
443
|
-
| `account` | string | No | Account containing the note (defaults to Notes.app's default account; exact or unique-prefix match, ignored if `id` is provided) |
|
|
428
|
+
| `id` | string | Yes | Exact CoreData note ID returned by a read or search |
|
|
429
|
+
| `expectedContentHash` | string | Yes | `contentHash` from the exact note version being deleted |
|
|
444
430
|
|
|
445
|
-
|
|
431
|
+
Title-only deletion is rejected. If the note changed after the supplied hash
|
|
432
|
+
was read, deletion is also rejected.
|
|
446
433
|
|
|
447
434
|
**Example - Using ID (recommended):**
|
|
448
435
|
```json
|
|
449
436
|
{
|
|
450
|
-
"id": "x-coredata://ABC123/ICNote/p456"
|
|
451
|
-
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
**Example - Using title:**
|
|
455
|
-
```json
|
|
456
|
-
{
|
|
457
|
-
"title": "Old Draft"
|
|
437
|
+
"id": "x-coredata://ABC123/ICNote/p456",
|
|
438
|
+
"expectedContentHash": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
458
439
|
}
|
|
459
440
|
```
|
|
460
441
|
|
|
@@ -470,12 +451,10 @@ Moves a note to a different folder. The note is relocated in place via Notes.app
|
|
|
470
451
|
|
|
471
452
|
| Parameter | Type | Required | Description |
|
|
472
453
|
|-----------|------|----------|-------------|
|
|
473
|
-
| `id` | string |
|
|
474
|
-
| `title` | string | No | Title of the note to move (use `id` instead when available) |
|
|
454
|
+
| `id` | string | Yes | Exact CoreData note ID returned by a read or search |
|
|
475
455
|
| `folder` | string | Yes | Destination folder name or nested path (e.g., `"Work/Clients"`) |
|
|
476
|
-
| `account` | string | No | Account containing the note (defaults to Notes.app's default account; exact or unique-prefix match, ignored if `id` is provided) |
|
|
477
456
|
|
|
478
|
-
|
|
457
|
+
Title-only moves are rejected.
|
|
479
458
|
|
|
480
459
|
**Example - Using ID (recommended):**
|
|
481
460
|
```json
|
|
@@ -485,15 +464,8 @@ Moves a note to a different folder. The note is relocated in place via Notes.app
|
|
|
485
464
|
}
|
|
486
465
|
```
|
|
487
466
|
|
|
488
|
-
**
|
|
489
|
-
|
|
490
|
-
{
|
|
491
|
-
"title": "Completed Task",
|
|
492
|
-
"folder": "Archive"
|
|
493
|
-
}
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
**Returns:** Confirmation message, or error if note or folder not found.
|
|
467
|
+
**Returns:** Confirmation only after the same note ID is read back and its
|
|
468
|
+
actual destination folder ID matches the requested folder.
|
|
497
469
|
|
|
498
470
|
---
|
|
499
471
|
|
|
@@ -503,20 +475,20 @@ Appends or prepends content to an existing note without replacing it. Always rea
|
|
|
503
475
|
|
|
504
476
|
| Parameter | Type | Required | Description |
|
|
505
477
|
|-----------|------|----------|-------------|
|
|
506
|
-
| `id` | string |
|
|
507
|
-
| `
|
|
478
|
+
| `id` | string | Yes | Exact CoreData note ID returned by a read or search |
|
|
479
|
+
| `expectedContentHash` | string | Yes | `contentHash` from the exact note version being extended |
|
|
508
480
|
| `content` | string | Yes | Text to append to the note body |
|
|
509
481
|
| `position` | string | No | `"after"` (default) appends to the end; `"before"` prepends to the start |
|
|
510
482
|
| `separator` | string | No | String placed between existing content and new content (default: two newlines → `<div><br></div>` in HTML) |
|
|
511
483
|
| `format` | string | No | Format of the content being appended: `"plaintext"` (default) or `"html"` |
|
|
512
|
-
| `account` | string | No | Account containing the note (defaults to Notes.app's default account; exact or unique-prefix match, ignored if `id` is provided) |
|
|
513
484
|
|
|
514
|
-
|
|
485
|
+
Title-only appends are rejected.
|
|
515
486
|
|
|
516
487
|
**Example - Append plaintext:**
|
|
517
488
|
```json
|
|
518
489
|
{
|
|
519
490
|
"id": "x-coredata://ABC123/ICNote/p456",
|
|
491
|
+
"expectedContentHash": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
|
520
492
|
"content": "New item added today"
|
|
521
493
|
}
|
|
522
494
|
```
|
|
@@ -525,15 +497,20 @@ Appends or prepends content to an existing note without replacing it. Always rea
|
|
|
525
497
|
```json
|
|
526
498
|
{
|
|
527
499
|
"id": "x-coredata://ABC123/ICNote/p456",
|
|
500
|
+
"expectedContentHash": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
|
528
501
|
"content": "<div><b>Status:</b> done</div>",
|
|
529
502
|
"format": "html",
|
|
530
503
|
"position": "before"
|
|
531
504
|
}
|
|
532
505
|
```
|
|
533
506
|
|
|
534
|
-
**Returns:** Confirmation with
|
|
507
|
+
**Returns:** Confirmation with the exact ID, post-save `contentHash`, and
|
|
508
|
+
`verifiedVisibleText: true`. Apple Notes normalizes HTML, so this proves the
|
|
509
|
+
visible text after saving, not byte-identical rich formatting. Warns when the
|
|
510
|
+
note is shared with collaborators.
|
|
535
511
|
|
|
536
|
-
|
|
512
|
+
**Safety:** The append is rejected if the note changed since it was read or if
|
|
513
|
+
the note contains an attachment.
|
|
537
514
|
|
|
538
515
|
---
|
|
539
516
|
|
|
@@ -740,7 +717,7 @@ Deletes multiple notes at once by ID.
|
|
|
740
717
|
|
|
741
718
|
| Parameter | Type | Required | Description |
|
|
742
719
|
|-----------|------|----------|-------------|
|
|
743
|
-
| `
|
|
720
|
+
| `notes` | object[] | Yes | Array of `{id, expectedContentHash}` snapshots to delete (max 500 per request) |
|
|
744
721
|
|
|
745
722
|
**Returns:** Summary of successes and failures.
|
|
746
723
|
|
|
@@ -758,7 +735,8 @@ Moves multiple notes to a folder.
|
|
|
758
735
|
| `folder` | string | Yes | Destination folder name or nested path (e.g., `"Work/Clients"`). Must already exist — create it with [`create-folder`](#create-folder) |
|
|
759
736
|
| `account` | string | No | Account containing the folder |
|
|
760
737
|
|
|
761
|
-
**Returns:** Summary of successes and failures.
|
|
738
|
+
**Returns:** Summary of successes and failures. Each success is reported only
|
|
739
|
+
after the note's actual container folder ID matches the destination folder ID.
|
|
762
740
|
|
|
763
741
|
---
|
|
764
742
|
|
|
@@ -1003,7 +981,7 @@ AI: [calls create-folder with name="Archive"]
|
|
|
1003
981
|
"Created folder 'Archive'"
|
|
1004
982
|
|
|
1005
983
|
User: "Move my old meeting notes to Archive"
|
|
1006
|
-
AI: [calls move-note with
|
|
984
|
+
AI: [searches for the note, then calls move-note with its exact id and folder="Archive"]
|
|
1007
985
|
"Moved 'Old Meeting Notes' to 'Archive'"
|
|
1008
986
|
|
|
1009
987
|
User: "What folders do I have?"
|