apple-notes-mcp 2.8.48 → 2.9.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 CHANGED
@@ -829,8 +829,11 @@ nothing was deleted instead of claiming success.
829
829
  A note that is already in Recently Deleted is refused, because deleting it there
830
830
  removes it permanently. The folder is read live from Notes.app in the same
831
831
  AppleScript; the Recently Deleted folder is recognised by its database id (with
832
- Full Disk Access) or by its English name. To remove such a note for good, do it
833
- in Notes.app.
832
+ Full Disk Access) or by its English name. The check fails closed: a note whose
833
+ folder Notes.app reports as something other than a folder (as it does for a note
834
+ trashed earlier in the same Notes session) is refused the same way, and a note
835
+ whose folder cannot be read at all is refused with a message to retry. To remove
836
+ such a note for good, do it in Notes.app.
834
837
 
835
838
  **⚠️ 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.
836
839
 
@@ -1846,7 +1849,9 @@ It also reports `runtimeOS` (`platform`, `macOSVersion` from `sw_vers`,
1846
1849
  `applescriptCore`, `fullDiskAccessReads`, `shortcutsBridges`,
1847
1850
  `backgroundOperationsBridge`, `nativeTagsBridge`, `markdownNoteBridge`, and the
1848
1851
  placeholders `checklistToggle`, `smartFolders`, `paragraphLinks`, and
1849
- `audioTranscription`, which need a native helper this server does not ship.
1852
+ `audioTranscription`, which need a native *write* helper this server does not
1853
+ ship (requirement `native_write_helper`). The opt-in private helper below is
1854
+ read-only, so enabling it does not change them: they stay `not_implemented`.
1850
1855
  Each entry carries `available`, `osSupported`, `minimumMacOSVersion`,
1851
1856
  `requirements`, `missing`, `unverified`, `tools`, and a machine-readable
1852
1857
  `reason` that is `null` when available and otherwise the first that applies:
@@ -1952,6 +1957,55 @@ not changed.
1952
1957
  Retrieves another note's real deep link and appends it with a static label while
1953
1958
  preserving the target note's native objects.
1954
1959
 
1960
+ ### Private helper (opt-in, unsupported Apple API)
1961
+
1962
+ An optional, **read-only** native helper reads note state through Notes' own
1963
+ data model (Apple's private NotesShared framework) instead of AppleScript or
1964
+ Shortcuts. It is **off by default** and nothing in the rest of the server
1965
+ depends on it. It cannot write: every store it opens is opened read-only, and
1966
+ write support was deliberately deferred by the maintainer until a second
1967
+ writer beside a running Notes.app, CRDT replica identity, and the iCloud
1968
+ upload lag are understood.
1969
+ Private API can break on any macOS update; see
1970
+ [TECHNICAL_NOTES.md](TECHNICAL_NOTES.md#private-helper-notesshared) for the
1971
+ API surface, risks, and safety contract.
1972
+
1973
+ To use it:
1974
+
1975
+ 1. Build it on your Mac from the packaged source (needs the Command Line
1976
+ Tools, `xcode-select --install`). No prebuilt binary ships with the package.
1977
+
1978
+ ```bash
1979
+ apple-notes-mcp setup --native-helper # build, ad-hoc sign, install
1980
+ apple-notes-mcp setup --native-helper --check # report only
1981
+ ```
1982
+
1983
+ 2. Set `APPLE_NOTES_MCP_ENABLE_PRIVATE=1` in the server's environment (or in
1984
+ the [config file](#configuration-file-when-the-host-strips-env)).
1985
+ 3. Give the app that launches the server Full Disk Access, the same grant the
1986
+ database reads already need.
1987
+
1988
+ The server checks the helper's recorded source and binary SHA-256 before every
1989
+ call and refuses a missing, stale, or modified helper with a machine-readable
1990
+ `code`. Rerun setup after upgrading apple-notes-mcp.
1991
+
1992
+ #### `native-helper-status`
1993
+
1994
+ Reports whether the helper is enabled, built, and current, and runs its live
1995
+ probe: macOS and Notes versions, whether NotesShared loads, whether every
1996
+ required class, selector, and model property exists, and whether the Notes
1997
+ store opens. Each feature reports `available` plus a `reason` code
1998
+ (`disabled`, `helper_not_installed`, `helper_stale`, `helper_modified`,
1999
+ `private_api_unavailable`, `store_unavailable`, …). Read-only; the response
2000
+ carries `readOnly: true`.
2001
+
2002
+ #### `native-note-state`
2003
+
2004
+ Reads one note's native state by Notes UUID (`identifier`) or x-coredata `id`:
2005
+ title, modification date, folder identifier, lock/trash/shared/editable
2006
+ flags, iCloud version counters, and a `revision` change token (compare two
2007
+ reads to detect a change). Opens the store with Core Data's read-only option.
2008
+
1955
2009
  ## Usage Patterns
1956
2010
 
1957
2011
  ### Basic Workflow
@@ -2092,6 +2146,10 @@ All configuration is optional — the server works out of the box. Override beha
2092
2146
  | `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`. |
2093
2147
  | `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. |
2094
2148
  | `APPLE_NOTES_MCP_RETRY_DELAY_MS` | `1000` (1 s) | Base delay before the first retry; subsequent retries back off exponentially (1s, 2s, 4s, ...). |
2149
+ | `APPLE_NOTES_MCP_ENABLE_PRIVATE` | unset | Set to `1` to allow the opt-in [private helper](#private-helper-opt-in-unsupported-apple-api). Any other value keeps it off. |
2150
+ | `APPLE_NOTES_MCP_PRIVATE_HELPER_DIR` | `~/Library/Application Support/apple-notes-mcp/private-helper` | Where `setup --native-helper` installs the helper and its checksum manifest. |
2151
+ | `APPLE_NOTES_MCP_PRIVATE_HELPER_TIMEOUT_MS` | `20000` (20 s) | Per-call helper timeout. A timed-out write is indeterminate. |
2152
+ | `APPLE_NOTES_MCP_PRIVATE_STORE` | unset | Testing only: points the helper at a **copy** of `NoteStore.sqlite`. The helper refuses a path that resolves to the live store. |
2095
2153
  | `DEBUG` / `VERBOSE` | unset | Set either to enable verbose diagnostic logging to stderr. |
2096
2154
 
2097
2155
  ### Configuration file (when the host strips `env`)