apple-notes-mcp 2.8.21 → 2.8.23

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 +100 -0
  2. package/build/index.js +1030 -92
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -160,6 +160,7 @@ On first use, macOS will ask for permission to automate Notes.app. Click "OK" to
160
160
  |---------|-------------|
161
161
  | **Create Notes** | Create notes with titles, content, and optional folder/account targeting |
162
162
  | **Search Notes** | Find notes by title or search within note content |
163
+ | **Query Language** | `query-notes` combines text, folder, account, tag, attachment, checklist, flag, word-count, and date conditions with AND/OR/NOT, read from the Notes database (requires Full Disk Access) |
163
164
  | **Read Notes** | Retrieve note content and metadata |
164
165
  | **Update Notes** | Modify existing notes (title and/or content) |
165
166
  | **Delete Notes** | Remove notes (moves to Recently Deleted) |
@@ -347,6 +348,73 @@ Searches for notes by title or content.
347
348
 
348
349
  ---
349
350
 
351
+ #### `query-notes`
352
+
353
+ Finds notes with a boolean query expression evaluated against the NoteStore
354
+ database, read-only. Because it does not go through AppleScript, a query over
355
+ several hundred notes typically returns in well under a second, and one call
356
+ can match titles and bodies together.
357
+
358
+ **Requires:** Full Disk Access for the MCP host process (see [Full Disk Access Setup](#full-disk-access)). Without it, use `search-notes`.
359
+
360
+ | Parameter | Type | Required | Description |
361
+ |-----------|------|----------|-------------|
362
+ | `query` | string | Yes | Query expression (syntax below), at most 2000 characters |
363
+ | `limit` | number | No | Maximum notes to return. Defaults to 50, maximum 500. The response reports the total match count. |
364
+ | `scanLimit` | number | No | How many of the most recently modified notes to examine. Defaults to 500, maximum 5000. The response says when older notes were left unscanned. |
365
+ | `includeDeleted` | boolean | No | Also scan notes in Recently Deleted, notes pending deletion, and folderless notes. Defaults to `false`. |
366
+
367
+ **Syntax:**
368
+
369
+ | Form | Matches |
370
+ |------|---------|
371
+ | `budget`, `"quarterly budget"` | Title or body contains the word or phrase (case-insensitive substring) |
372
+ | `title:x`, `body:x`, `text:x` | Title only, body only (text after the first line), or either |
373
+ | `folder:Work`, `folder:"Work/Clients"` | The note's own folder, by name or full path, case-insensitive (notes in subfolders are not included); a literal `/` in a name can be written `\/` as in `list-folders` |
374
+ | `account:iCloud` | Account name, case-insensitive |
375
+ | `tag:finance` | Native Notes tag (with or without `#`); textual hashtags are ordinary words |
376
+ | `has:link`, `has:attachment`, `has:checklist`, `has:drawing`, `has:image`, `has:video`, `has:audio`, `has:pdf`, `has:table`, `has:scan`, `has:tag` | The note body contains that kind of object |
377
+ | `checklist:open`, `checklist:done` | At least one unchecked item; or items present and all checked |
378
+ | `pinned`, `locked`, `shared` (or `is:pinned` …) | Note flags; `shared` includes notes in a shared folder |
379
+ | `words:>250` | Word count, with `=`, `>`, `>=`, `<`, `<=` |
380
+ | `created:>=2026-07-01`, `modified:<2026-09-01` | Dates as `YYYY-MM-DD` in local time, with the same operators; `=` means that whole day |
381
+ | `a b`, `a AND b`, `a OR b`, `NOT a`, `-a`, `( … )` | AND is implicit and binds tighter than OR |
382
+
383
+ Operators are case-insensitive. Quote an operator or flag word to search it
384
+ literally, for example `"and"` or `"pinned"`. Queries are capped at 256 tokens
385
+ and 64 levels of nesting. An unknown field such as `titel:x` is an error rather
386
+ than a silent text search; quote it to search the literal text.
387
+
388
+ Password-protected notes match on title and metadata only. Their bodies are
389
+ encrypted, so body predicates never match them, and `-body:x` therefore does.
390
+ Their snippets are always empty.
391
+
392
+ **Example - Open to-dos in a folder:**
393
+ ```json
394
+ {
395
+ "query": "folder:\"Work Projects\" has:checklist -checklist:done"
396
+ }
397
+ ```
398
+
399
+ **Example - Invoices or finance-tagged notes since July, scanning more history:**
400
+ ```json
401
+ {
402
+ "query": "(title:invoice OR tag:finance) modified:>=2026-07-01",
403
+ "scanLimit": 2000,
404
+ "limit": 20
405
+ }
406
+ ```
407
+
408
+ **Returns:** Matching notes, most recently modified first, each with `id`,
409
+ `title`, `folder`, `account`, `modified`, `created`, and a `snippet` centred on
410
+ the first matched phrase. The ids are the same `x-coredata://…/ICNote/p…` form
411
+ every other tool accepts. `structuredContent` also reports `matched` (total
412
+ matches), `scanned`, `eligible`, `scanTruncated`, `truncated`, and `unreadable`
413
+ (bodies that could not be decoded). A malformed query returns an error naming
414
+ the problem and its position.
415
+
416
+ ---
417
+
350
418
  #### `get-note-content`
351
419
 
352
420
  Retrieves the full content of a specific note.
@@ -1232,6 +1300,38 @@ in the foreground.
1232
1300
  Appends one real unchecked Notes checklist item and verifies its native identity
1233
1301
  and text.
1234
1302
 
1303
+ #### `create-checklist-items`
1304
+
1305
+ Appends several real unchecked checklist items, 1 to 20, in the order given.
1306
+ It takes the same `id`, `expectedContentHash` and `scopeText` as
1307
+ `create-checklist-item`, plus `items`, an array of one-line texts. Each item is
1308
+ one run of the same verified bridge, so the call takes a few seconds per item
1309
+ (a full batch of 20 can run about a minute; if your client times out first,
1310
+ read the note before retrying rather than resending the whole batch) and is
1311
+ gated with `create-checklist-item` in `get-capabilities`.
1312
+
1313
+ After every run the server checks that exactly one new unchecked item with that
1314
+ text and a new native identity appeared, that every item appended earlier in the
1315
+ call kept its identity and text, and that nothing else in the note changed. The
1316
+ verified revision feeds the next run. A final check confirms the new items are
1317
+ the note's last checklist items in the requested order.
1318
+
1319
+ ```json
1320
+ {
1321
+ "id": "x-coredata://ABC123/ICNote/p456",
1322
+ "expectedContentHash": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
1323
+ "scopeText": "Packing list for the trip",
1324
+ "items": ["Passport", "Charger", "Rain jacket"]
1325
+ }
1326
+ ```
1327
+
1328
+ **Returns:** `items`, each with its `index`, native `id` and `text`, plus
1329
+ `orderVerified` and the new `contentHash`. The first uncertain result stops the
1330
+ call without a retry and returns `ok: false` with `landed` (the verified items),
1331
+ `stoppedAt` (the item's index, text, `outcome` of `"not-written"` or
1332
+ `"uncertain"`, and the error), and `notAttempted`. After an uncertain stop, read
1333
+ the note before retrying, and retry only the items that are not present.
1334
+
1235
1335
  #### `create-table`
1236
1336
 
1237
1337
  Appends a native table from rectangular string rows and verifies every decoded