apple-notes-mcp 2.8.29 → 2.8.31
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 +74 -6
- package/build/index.js +786 -191
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ Install as a Claude Code plugin for automatic configuration and enhanced AI beha
|
|
|
56
56
|
|
|
57
57
|
This method also installs a **skill** that teaches Claude when and how to use Apple Notes effectively.
|
|
58
58
|
|
|
59
|
-
On the first tool call, macOS shows an Automation permission prompt ("Claude" wants access to control "Notes") — click **OK**. Optionally, grant **Full Disk Access** to the app that launches the server to enable the database-backed tools (`get-checklist-state`, `get-note-metadata`, `get-note-link`, checklist annotations in `get-note-markdown`, and full `get-sync-status` detail); see the [Full Disk Access Setup Guide](https://github.com/sweetrb/apple-notes-mcp/blob/main/docs/FULL-DISK-ACCESS.md). The rest of the server is pure AppleScript and works without it.
|
|
59
|
+
On the first tool call, macOS shows an Automation permission prompt ("Claude" wants access to control "Notes") — click **OK**. Optionally, grant **Full Disk Access** to the app that launches the server to enable the database-backed tools (`get-checklist-state`, `get-note-metadata`, `get-audio-transcripts`, `get-note-link`, checklist annotations in `get-note-markdown`, and full `get-sync-status` detail); see the [Full Disk Access Setup Guide](https://github.com/sweetrb/apple-notes-mcp/blob/main/docs/FULL-DISK-ACCESS.md). The rest of the server is pure AppleScript and works without it.
|
|
60
60
|
|
|
61
61
|
Native tag, checklist, table, pin, and rich append operations use two packaged
|
|
62
62
|
Apple Shortcuts. A third, `Apple Notes MCP - Create Markdown Note`, is optional:
|
|
@@ -169,6 +169,7 @@ On first use, macOS will ask for permission to automate Notes.app. Click "OK" to
|
|
|
169
169
|
| **Multi-Account** | Work with iCloud, Gmail, Exchange, or any configured account, including account IDs and default folders |
|
|
170
170
|
| **Batch Operations** | Delete or move multiple notes at once |
|
|
171
171
|
| **Checklist State** | Read checklist done/undone state directly from the Notes database (requires Full Disk Access) |
|
|
172
|
+
| **Audio Transcripts** | Read the transcripts and summaries Notes stored for audio recordings (requires Full Disk Access) |
|
|
172
173
|
| **Export** | Export all notes as JSON or get individual notes as Markdown |
|
|
173
174
|
| **Attachments** | List attachments, save them to disk, or fetch their bytes as base64 |
|
|
174
175
|
| **Notes.app UI State** | Reveal a note in Notes.app or read the current Notes.app selection |
|
|
@@ -253,11 +254,14 @@ Creates a new note in Apple Notes.
|
|
|
253
254
|
| Parameter | Type | Required | Description |
|
|
254
255
|
|-----------|------|----------|-------------|
|
|
255
256
|
| `title` | string | Yes | The title of the note. Automatically prepended as `<h1>` — do NOT include the title in `content` |
|
|
256
|
-
| `content` | string |
|
|
257
|
+
| `content` | string | One of `content`/`contentPath` | The body content of the note (do not repeat the title here) |
|
|
258
|
+
| `contentPath` | string | One of `content`/`contentPath` | Absolute path of a local UTF-8 file to use as the body instead of `content`. Allowed in the same places [`save-attachment`](#save-attachment) may write (home, temp, `/Volumes`); symbolic links, non-regular files, invalid UTF-8 and files over 1 MiB are refused before anything is written. A leading byte-order mark is dropped |
|
|
257
259
|
| `tags` | string[] | No | Returned-only metadata — **NOT written to Notes.app**. Apple Notes tags can't be set via AppleScript, so values passed here are echoed back in the response but do not appear on the created note. Use inline `#hashtags` in `content` instead (Notes.app turns those into real tags). Refused with `format: "markdown"` |
|
|
258
260
|
| `folder` | string | No | Folder to create the note in. Supports nested paths like `"Work/Clients"`. **The folder must already exist** — create it first with [`create-folder`](#create-folder). Defaults to account root |
|
|
259
261
|
| `account` | string | No | Account name (defaults to Notes.app's default account; matched exactly or by a *unique* prefix — an ambiguous prefix is refused). Must be an account Notes.app already has configured — see [`list-accounts`](#list-accounts) |
|
|
260
262
|
| `format` | string | No | Content format: `"plaintext"` (default), `"html"`, or `"markdown"`. In all formats, the title is automatically prepended as the note's title line. In plaintext mode, newlines become `<br>`, tabs become `<br>`, and backslashes are preserved as HTML entities. `"markdown"` produces real Title/Heading/Subheading styles through a Shortcut; see [Markdown notes](#markdown-notes) |
|
|
263
|
+
| `markdownRoute` | string | No | With `format: "markdown"` only: `"shortcut"` (default) or `"html"`. See [Markdown through HTML](#markdown-through-html) |
|
|
264
|
+
| `timeoutSeconds` | number | No | Whole seconds, 1–120, for each Notes.app automation step this call runs; overrides `APPLE_NOTES_MCP_TIMEOUT_MS` for this call only. A timed-out write is uncertain, not failed: read the note by id before any retry. Also accepted by `update-note`, `append-to-note`, `delete-note` and `move-note` |
|
|
261
265
|
|
|
262
266
|
**Example (tagged with inline hashtags):**
|
|
263
267
|
```json
|
|
@@ -344,6 +348,35 @@ title line, with no seed line.
|
|
|
344
348
|
as `create-note-markdown`. The Create Markdown Note Shortcut is optional and
|
|
345
349
|
needed only for this format (macOS 26+); install and approve it as described in
|
|
346
350
|
[`shortcuts/README.md`](shortcuts/README.md).
|
|
351
|
+
- A first line that is exactly `# <title>` (same case and spacing as `title`) is
|
|
352
|
+
removed together with one blank line after it, because the title is supplied
|
|
353
|
+
separately; the response then carries `strippedDuplicateTitle: true`. A
|
|
354
|
+
different first heading stays in the body. This applies to both Markdown
|
|
355
|
+
routes, and Markdown that holds only that heading is refused.
|
|
356
|
+
|
|
357
|
+
##### Markdown through HTML
|
|
358
|
+
|
|
359
|
+
`markdownRoute: "html"` imports the same bounded Markdown subset without the
|
|
360
|
+
Shortcut: the server converts it to HTML and creates the note through AppleScript,
|
|
361
|
+
like `format: "html"`. It works in any account, accepts `tags`, and needs no
|
|
362
|
+
Shortcut, but headings get the plain bold styling described in the known
|
|
363
|
+
limitation above rather than real Heading and Subheading styles.
|
|
364
|
+
|
|
365
|
+
On this route, bullet task items (`- [ ] item`, `- [x] item`) become ordinary
|
|
366
|
+
list rows that start with a visible `☐` or `☑` character, and the response
|
|
367
|
+
reports how many as `taskItemsRendered`. They are text, not native checkable
|
|
368
|
+
checklist items. Use this route as the glyph fallback when the Shortcut is not
|
|
369
|
+
installed or the note is outside iCloud.
|
|
370
|
+
|
|
371
|
+
```json
|
|
372
|
+
{
|
|
373
|
+
"title": "Weekly Review",
|
|
374
|
+
"contentPath": "/Users/me/Documents/weekly-review.md",
|
|
375
|
+
"format": "markdown",
|
|
376
|
+
"markdownRoute": "html",
|
|
377
|
+
"folder": "Work"
|
|
378
|
+
}
|
|
379
|
+
```
|
|
347
380
|
|
|
348
381
|
**Returns:** Confirmation message with note title and ID. Save the ID for subsequent operations like `update-note`, `delete-note`, etc.
|
|
349
382
|
|
|
@@ -736,7 +769,10 @@ was read, deletion is also rejected.
|
|
|
736
769
|
}
|
|
737
770
|
```
|
|
738
771
|
|
|
739
|
-
**Returns:** Confirmation message, or error if note not found.
|
|
772
|
+
**Returns:** Confirmation message, or error if note not found. The delete and a
|
|
773
|
+
check of the note's original folder run in one AppleScript: if Notes.app accepts
|
|
774
|
+
the delete but the note is still listed in that folder, the call reports that
|
|
775
|
+
nothing was deleted instead of claiming success.
|
|
740
776
|
|
|
741
777
|
**⚠️ Safety:** Irreversible from the agent's side — requires explicit user confirmation before calling. Prefer `search-notes` / `list-notes` first to confirm the exact id(s) being deleted.
|
|
742
778
|
|
|
@@ -775,7 +811,7 @@ Appends or prepends content to an existing note without replacing it. Always rea
|
|
|
775
811
|
| `id` | string | Yes | Exact CoreData note ID returned by a read or search |
|
|
776
812
|
| `expectedContentHash` | string | Yes | `contentHash` from the exact note version being extended |
|
|
777
813
|
| `content` | string | Yes | Text to append to the note body |
|
|
778
|
-
| `position` | string | No | `"after"` (default) appends to the end; `"before"`
|
|
814
|
+
| `position` | string | No | `"after"` (default) appends to the end; `"before"` inserts directly below the note's title line, so the title stays first |
|
|
779
815
|
| `separator` | string | No | String placed between existing content and new content (default: two newlines → `<div><br></div>` in HTML) |
|
|
780
816
|
| `format` | string | No | Format of the content being appended: `"plaintext"` (default) or `"html"` |
|
|
781
817
|
|
|
@@ -1274,6 +1310,38 @@ Reads note metadata that AppleScript cannot expose, by querying the NoteStore SQ
|
|
|
1274
1310
|
|
|
1275
1311
|
---
|
|
1276
1312
|
|
|
1313
|
+
#### `get-audio-transcripts`
|
|
1314
|
+
|
|
1315
|
+
Reads the transcript, and the summary when one exists, that Notes already computed for the audio recordings in a note. It does not transcribe anything itself. Notes keeps each recording's transcript as word-level mergeable data on the audio attachment's database row, and this tool decodes it read-only.
|
|
1316
|
+
|
|
1317
|
+
**Requires:** Full Disk Access for the MCP host process (see [Full Disk Access Setup](#full-disk-access)). Password-protected notes are refused.
|
|
1318
|
+
|
|
1319
|
+
| Parameter | Type | Required | Description |
|
|
1320
|
+
|-----------|------|----------|-------------|
|
|
1321
|
+
| `id` | string | Yes | Note ID (use `search-notes` to find it first) |
|
|
1322
|
+
| `includeSegments` | boolean | No | Also return word-level segments: `text`, `start` and `duration` in seconds, and `speaker`. Default `false` |
|
|
1323
|
+
| `maxSegments` | number | No | Cap on segments per attachment when `includeSegments` is set (default 2000, at most 20000) |
|
|
1324
|
+
|
|
1325
|
+
**Example:**
|
|
1326
|
+
```json
|
|
1327
|
+
{
|
|
1328
|
+
"id": "x-coredata://ABC123/ICNote/p456",
|
|
1329
|
+
"includeSegments": true,
|
|
1330
|
+
"maxSegments": 500
|
|
1331
|
+
}
|
|
1332
|
+
```
|
|
1333
|
+
|
|
1334
|
+
**Returns:** `structuredContent.attachments` holds one entry per top-level audio attachment, in the order the recordings appear in the note. Each entry has:
|
|
1335
|
+
|
|
1336
|
+
- `attachmentId` (usable with `save-attachment`), `identifier`, `typeUti`, and `durationSeconds` when known
|
|
1337
|
+
- `status`: `ok` (a transcript is stored), `none` (no transcript is stored, for example a recording Notes has not transcribed, or an audio file attached from elsewhere), or `undecodable` with a `reason`
|
|
1338
|
+
- `text` (the words joined into readable text), `wordCount`, `fragmentCount`, `speakers`, `summary` and `topLineSummary` when stored, and `needsTranscription` when the database records it
|
|
1339
|
+
- `segments`, only when `includeSegments` is set, with `segmentsTruncated` when the cap cut them short
|
|
1340
|
+
|
|
1341
|
+
A recording extended with more takes has several fragments. Their transcripts are joined in stored order, separated by a blank line, and each segment carries a `fragment` index. Recordings with more than one fragment have been verified against synthetic fixtures only. A response that would exceed `APPLE_NOTES_MCP_EXPORT_MAX_BYTES` (default 8 MB) drops segments first and then shortens `text`, marking `truncated`, `segmentsTruncated` and `textTruncated`. When the note body cannot be parsed, attachments come back in database order with `bodyOrder: false`.
|
|
1342
|
+
|
|
1343
|
+
---
|
|
1344
|
+
|
|
1277
1345
|
#### `add-attachment`
|
|
1278
1346
|
|
|
1279
1347
|
Adds one nonempty local file of at most 64 MiB to an exact note using `id`, the
|
|
@@ -1660,7 +1728,7 @@ All configuration is optional — the server works out of the box. Override beha
|
|
|
1660
1728
|
| `APPLE_NOTES_MCP_MAX_ATTACHMENT_BYTES` | `26214400` (25 MB) | Max size of an attachment that [`fetch-attachment`](#fetch-attachment) will base64-encode inline. Larger attachments are rejected with an error pointing at [`save-attachment`](#save-attachment) (which streams to disk and has no such limit). Raise it to fetch bigger attachments inline; lower it to cap memory. |
|
|
1661
1729
|
| `APPLE_NOTES_MCP_MAX_INLINE_IMAGE_BYTES` | `262144` (256 KB) | Per-image cap on the base64 payload kept inline in a [`get-note-content`](#get-note-content) response. Inline images over the cap are replaced with placeholders (with a warning appended) so an image-heavy note cannot exceed the MCP client's message limit and drop the connection; export the real files with [`save-attachment`](#save-attachment) or [`fetch-attachment`](#fetch-attachment). Raise it to keep bigger images inline. |
|
|
1662
1730
|
| `APPLE_NOTES_MCP_CONFIG_FILE` | `~/Library/Application Support/apple-notes-mcp/config.json` | Path to the JSON config file (see below). |
|
|
1663
|
-
| `APPLE_NOTES_MCP_TIMEOUT_MS` | `30000` (30 s) | Total AppleScript operation timeout, including retry attempts and delays. Raise it if full-library operations (large searches, exports) time out on a big Notes library. Per-call `timeoutMs` options still win. |
|
|
1731
|
+
| `APPLE_NOTES_MCP_TIMEOUT_MS` | `30000` (30 s) | Total AppleScript operation timeout, including retry attempts and delays. Raise it if full-library operations (large searches, exports) time out on a big Notes library. Per-call `timeoutMs` options still win, and a write tool's `timeoutSeconds` argument overrides it for that call. |
|
|
1664
1732
|
| `APPLE_NOTES_MCP_EXPORT_MAX_BYTES` | `8388608` (8 MB) | Largest response `export-notes-json` sends; a page closes early to stay under it. The default sits below the 10 MB per-message limit of MCP SDK stdio clients, which drop the connection on anything larger. Raise it only if your MCP client accepts bigger messages. |
|
|
1665
1733
|
| `APPLE_NOTES_MCP_BLOCKS_MAX_BYTES` | `4194304` (4 MB) | Largest block payload one [`get-note-blocks`](#get-note-blocks) page returns; the page closes early to stay under it, and a single oversized paragraph comes back with `textOmitted: true`. |
|
|
1666
1734
|
| `APPLE_NOTES_MCP_MAX_RETRIES` | `2` | Maximum attempts for a read-only AppleScript call that fails with a **transient** error (Notes.app busy / not responding / lost connection). `2` means one retry; set `1` to fail fast with no retries. Retries share the single `APPLE_NOTES_MCP_TIMEOUT_MS` budget rather than each getting a fresh one, and a retry is skipped when under a second of that budget remains — so this is a ceiling, not a guarantee. In particular a call that exhausts the budget with a **timeout** has no time left to retry by construction. Mutating operations run once because a timeout can occur after Notes.app applied the change. Non-transient errors (e.g. "note not found") never retry. |
|
|
@@ -1691,7 +1759,7 @@ MCP stores no secrets, but as a general rule keep only non-secret config here.
|
|
|
1691
1759
|
|
|
1692
1760
|
## Full Disk Access
|
|
1693
1761
|
|
|
1694
|
-
Several tools read directly from the Apple Notes SQLite database, which lives in a macOS-protected directory. Those tools require **Full Disk Access** for the process running the MCP server: `get-checklist-state`, `get-note-metadata`, `get-note-blocks`, `get-note-link`, the checklist annotations in `get-note-markdown`, and the database half of `get-sync-status`.
|
|
1762
|
+
Several tools read directly from the Apple Notes SQLite database, which lives in a macOS-protected directory. Those tools require **Full Disk Access** for the process running the MCP server: `get-checklist-state`, `get-note-metadata`, `get-note-blocks`, `get-audio-transcripts`, `get-note-link`, the checklist annotations in `get-note-markdown`, and the database half of `get-sync-status`.
|
|
1695
1763
|
|
|
1696
1764
|
> 📘 **For the full why-and-how walkthrough (which app to grant, verifying with `doctor`, graceful degradation), see the [Full Disk Access Setup Guide](https://github.com/sweetrb/apple-notes-mcp/blob/main/docs/FULL-DISK-ACCESS.md).** The summary below is the quick version.
|
|
1697
1765
|
|