local-apple-data
# local-apple-data
Local-first Apple data access for Codex and other MCP clients.
This project provides a privacy-gated CLI and MCP server for locally synced:
- Mail.app mail, including iCloud and Gmail accounts synced locally through Mail.app
- Messages chats synced locally through Messages.app
- Inferred Hide My Email aliases observed in local Mail address metadata
- Voice Memos synced locally through Voice Memos.app
- Safari bookmarks, Reading List items, and bookmark folders synced locally through Safari/iCloud
- Apple Shortcuts shortcut, folder, and exact selected-folder shortcut metadata
through the local `shortcuts` CLI
- Apple Books library metadata and selected-book annotations synced through Books/iCloud
- Apple Podcasts show and episode metadata synced through Podcasts/iCloud
- Apple Music track and playlist metadata synced through Music/Apple Music
- Apple TV item, playlist, and selected-playlist item metadata synced through TV/iCloud
- Apple Freeform board, folder, selected-folder board, and selected-folder child-folder metadata synced through Freeform/iCloud
- Apple Notes note, folder, and exact selected-folder item metadata
- Apple Calendar
- Apple Reminders
- Apple Contacts
- Apple Photos asset, regular-album, exact selected-album asset metadata, and regular-album management
- iCloud Drive local files and folders
- A bounded home-directory Filesystem rooted at the operator home directory
The current release is local-only and read-mostly. Its plan/apply surfaces cover approved exact operations in Reminders, iCloud Drive, Calendar, Contacts excluding note mutation, Notes (including rich-text body create/replace and exact empty child-folder move), Mail, Photos, Messages, the bounded home-directory Filesystem, and one exact identifier-bound Shortcuts run. Every apply requires its matching approval token and explicit confirmation; the exact operation inventory and per-operation limits are maintained in `docs/MUTATION_GATES.md`.
Contacts note plan/apply contracts are designed and synthetic-testable, but they are not a usable live mutation surface: this local signed helper lacks Apple's restricted Contacts-notes entitlement, so every note operation fails closed with `contacts_note_unavailable` before mutation. Contact free-form labels are implemented up to 255 characters; control characters and oversize labels are refused.
The plugin does not use the Gmail connector, Gmail API, IMAP credentials, OAuth, app passwords, iCloud.com, browser sessions, keychain credentials, private iCloud web APIs, or any network mail service.
## Current Status
The MCP server, local skill/plugin packaging, exact-handle retrieval, the approved apply paths summarized above, and synthetic runtime verification are implemented. That includes the bounded home-directory Filesystem and exact identifier-bound Shortcuts run gate; “approved Contacts” here excludes the live-unavailable Contacts note operations described above.
Real-machine smoke stays schema-only unless a user intentionally requests a specific metadata search, selects an exact returned handle for detail/content/export, or explicitly approves an operation generated from a matching plan.
Implemented now:
- Repo guidance and privacy model
- `local-apple-data health --json` with redacted broad-surface readiness summaries, schema-only Mail/Messages/Voice Memos/Books/Podcasts/Freeform/Notes/Reminders checks, Safari bookmarks and iCloud Drive root checks, Shortcuts CLI and Music.app/TV.app automation availability, and non-prompting access requirements for framework-backed surfaces
- `local-apple-data doctor --json` with redacted non-mutating remediation guidance
- `local-apple-data mail search/get` metadata commands, with optional exact `--mailbox-handle <mail:mailbox:v1:...>` filtering for one selected mailbox
- `local-apple-data mail mailbox-messages --json --handle <mail:mailbox:v1:...> --after <date-or-timestamp> [--before <date-or-timestamp>]` for date-bounded metadata-only messages in one selected mailbox
- Metadata-only `content_status` hints in Mail search results so agents can prefer locally retrievable messages before exact content calls
- `local-apple-data mail body-search --json --query <text> --after <date-or-timestamp> [--before <date-or-timestamp>]` for date-bounded local Mail body discovery with capped redacted snippets and no full-body output
- `local-apple-data mail attachment-search --json --query <filename-or-mime-or-content> --after <date-or-timestamp> [--before <date-or-timestamp>] [--include-content] [--include-ocr]` for date-bounded Mail attachment filename/MIME metadata discovery plus opt-in text/PDF/OCR redacted snippets, exact attachment handles, and no bytes
- `local-apple-data mail advanced-search --json --query <text> --scope subject|from|to|cc|bcc|body|attachment_filename --after <date-or-timestamp> [--before <date-or-timestamp>]` for date-bounded subject/header/body/attachment metadata discovery with masked headers and capped snippets
- `local-apple-data mail fts-build --json --after <date-or-timestamp> [--before <date-or-timestamp>] --confirm-index [--cursor <cursor>] [--include-attachments] [--include-ocr]` for opt-in private local Mail FTS indexing; this writes a durable local content cache but returns only counts, `next_cursor`, and an opaque index ref, not the cache path. Use `--reset` only on the first build page; continuation cursors must run without reset.
- `local-apple-data mail fts-search --json --query <text> --after <date-or-timestamp> [--before <date-or-timestamp>] [--scope subject|from|to|cc|bcc|body|attachment_filename|attachment_content]` for date-bounded read-only search of the opt-in Mail FTS index with capped redacted snippets, live-row/date/content-state revalidation, and no full body, bytes, or cache path output
- `local-apple-data mail content --json --handle <mail:message:v2:...> --max-chars 4000 [--offset <n>]` for exact-handle local Mail plain-text content with paging metadata
- `local-apple-data mail unsubscribe-metadata --json --handle <mail:message:v2:...> [--include-body-links]` and MCP `mail_get_unsubscribe_metadata(handle, include_body_links=false)` for exact-message, read-only `List-Unsubscribe`/`List-Unsubscribe-Post`/`List-Help` detail. Output contains only ordered allowlisted http(s)/mailto endpoints plus opaque account/mailbox refs; only HTTPS paired with the exact RFC 8058 post header is classified as `one_click`. The explicit body-link opt-in returns at most five conservatively matched anchor URLs as `body_link`, always `manual_required`; it returns no body, anchor labels, or unrelated links.
- `local-apple-data mail mailboxes --json --query <text>` and `local-apple-data mail mailbox --json --handle <mail:mailbox:v1:...>` for bounded Mail move target selection by opaque mailbox handle and opaque account refs
- `local-apple-data mail senders --json --query <text>` and `local-apple-data mail sender --json --handle <mail:sender:v1:...>` for bounded configured Mail sender metadata selection with masked email previews only; search matches returned-safe masked fields only
- `local-apple-data mail signatures --json --query <text>` and `local-apple-data mail signature --json --handle <mail:signature:v1:...>` for bounded Mail signature metadata without signature bodies
- `local-apple-data mail template-create/templates/template/template-delete` for plugin-local Mail template management, plus `local-apple-data mail plan-search-triage` for capped FTS-result triage planning into exact selected message handles
- `local-apple-data mail attachments --json --handle <mail:message:v2:...>` for exact selected-message attachment metadata with opaque `mail:attachment:v1:` handles
- `local-apple-data mail export-attachment --json --message-handle <mail:message:v2:...> --handle <mail:attachment:v1:...> --output-dir <dir>` for exact local Mail attachment export without inline bytes or source message paths
- `local-apple-data mail plan --json --operation create-draft --to <address> --subject <subject> --body-text <text> [--sender-handle <mail:sender:v1:...>] [--attachment-path <local-file>]` for non-mutating future draft-create previews with optional exact sender selection, bounded caller-selected local file attachments, file identity plus content SHA-256 approval binding, idempotency where safe, and approval metadata
- `local-apple-data mail apply --json --operation create-draft --to <address> --subject <subject> --body-text <text> [--sender-handle <mail:sender:v1:...>] [--attachment-path <local-file>] --approval-token <token> --confirm-apply` for the approved Mail create-draft path, with optional exact sender selection and bounded caller-selected local file attachments, private validated attachment-copy automation handoff, selected-sender/attachment automation read-back, and local Drafts read-back verification when the Drafts store exposes the saved draft
- `local-apple-data mail plan --json --operation send-message --to <address> --subject <subject> --body-text <text> [--sender-handle <mail:sender:v1:...>] [--attachment-path <local-file>]` for non-mutating future outbound-send previews with optional exact sender selection, optional bounded caller-selected local file attachments, irreversible-send metadata, non-retry-safe status, and approval metadata
- `local-apple-data mail apply --json --operation send-message --to <address> --subject <subject> --body-text <text> [--sender-handle <mail:sender:v1:...>] [--attachment-path <local-file>] --approval-token <token> --confirm-apply` for the approved Mail send-message path, with optional exact sender selection, optional bounded caller-selected local file attachments, private validated attachment-copy automation handoff, selected-sender and Mail-derived attachment-count confirmation before send, local Sent-copy read-back when available, no draft save, and no body/path/byte/full-sender echo in apply output
- `local-apple-data mail plan --json --operation reply-message --message-handle <mail:message:v2:...> --body-text <text> [--sender-handle <mail:sender:v1:...>] [--attachment-path <local-file>]` for non-mutating exact-message sender-only reply previews with optional exact sender selection, optional bounded caller-selected local file attachments, current source-message state binding, and irreversible-send metadata
- `local-apple-data mail apply --json --operation reply-message --message-handle <mail:message:v2:...> --body-text <text> [--sender-handle <mail:sender:v1:...>] [--attachment-path <local-file>] --approval-token <token> --confirm-apply` for the approved Mail sender-only reply path, scoped by Mail account, mailbox, and RFC Message-ID, with optional exact sender selection, optional bounded caller-selected local file attachments, stale-state refusal, no direct-recipient override, local Sent-copy read-back when available, and no body/path/byte/full-sender echo in apply output
- `local-apple-data mail plan --json --operation reply-all-message --message-handle <mail:message:v2:...> --body-text <text> [--sender-handle <mail:sender:v1:...>] [--attachment-path <local-file>]` for non-mutating exact-message reply-all previews with optional exact sender selection, optional bounded caller-selected local file attachments, current source-message state binding, and irreversible-send metadata
- `local-apple-data mail apply --json --operation reply-all-message --message-handle <mail:message:v2:...> --body-text <text> [--sender-handle <mail:sender:v1:...>] [--attachment-path <local-file>] --approval-token <token> --confirm-apply` for the approved Mail exact-message reply-all path, scoped by Mail account, mailbox, and RFC Message-ID, with optional exact sender selection, optional bounded caller-selected local file attachments, stale-state refusal, no direct-recipient override, local Sent-copy read-back when available, and no body/path/byte/full-sender echo in apply output
- `local-apple-data mail plan --json --operation forward-message --message-handle <mail:message:v2:...> --to <address> --body-text <text> [--sender-handle <mail:sender:v1:...>] [--attachment-path <local-file>] [--include-source-attachments]` for non-mutating exact-message forward previews with optional exact sender selection, optional bounded caller-selected local file attachments, current source-message state binding, default source attachment/non-body-part refusal, opt-in source attachment-like part preservation, irreversible-send metadata, and approval metadata
- `local-apple-data mail apply --json --operation forward-message --message-handle <mail:message:v2:...> --to <address> --body-text <text> [--sender-handle <mail:sender:v1:...>] [--attachment-path <local-file>] [--include-source-attachments] --approval-token <token> --confirm-apply` for the approved Mail exact-message forward path, scoped by Mail account, nested mailbox path, and RFC Message-ID, with optional exact sender selection, optional bounded caller-selected local file attachments, optional source attachment-like part preservation, stale-state refusal, selected-sender and pre-send Mail attachment-count verification, local Sent-copy read-back when available, and no body/source-content/path/byte/full-sender echo in apply output
- `local-apple-data mail plan --json --operation mark-read|mark-unread|flag-message|unflag-message|archive-message|move-message|trash-message --message-handle <mail:message:v2:...> [--message-handle <mail:message:v2:...> ...] [--target-mailbox-handle <mail:mailbox:v1:...>]` for non-mutating exact-message or capped exact bulk read/flag/archive/move/trash triage previews with current-state binding, idempotency, and approval metadata
- `local-apple-data mail apply --json --operation mark-read|mark-unread|flag-message|unflag-message|archive-message|move-message|trash-message --message-handle <mail:message:v2:...> [--message-handle <mail:message:v2:...> ...] [--target-mailbox-handle <mail:mailbox:v1:...>] --approval-token <token> --confirm-apply` for the approved Mail read/flag/archive/move/trash triage path, scoped by Mail account, mailbox, exact target mailbox, and RFC Message-ID, with same-account Archive/Trash resolution, exact target-mailbox resolution including cross-account exact targets, capped exact bulk preflight, stale-state refusal, no permanent deletion, partial reporting, and local read-back verification
- `local-apple-data mail plan-mailbox/apply-mailbox` for exact sender-selected synthetic top-level `LAD-TEST-*` mailbox create/rename and source-gated empty synthetic mailbox delete
- `local-apple-data mail plan-cleanup/apply-cleanup` for source-gated exact synthetic `LAD-TEST-*` permanent-delete planning/apply and synthetic-only empty Trash/Junk planning/apply with Mail-idle, exact target-state binding, and absence proof
- `local-apple-data messages search/get` commands for local Messages chat display-name metadata and exact bounded transcripts, including modern local `attributedBody` plaintext fallback when `message.text` is empty
- `local-apple-data messages participants --json --handle <messages:chat:v1:...>` and `local-apple-data messages participant --json --chat-handle <messages:chat:v1:...> --handle <messages:participant:v1:...>` for exact selected-chat participant metadata; list output returns opaque participant handles without phone/email previews, and full participant identifiers are exact participant-handle detail only
- `local-apple-data messages attachments --json --handle <messages:chat:v1:...>` for exact selected-chat attachment metadata with opaque `messages:attachment:v1:` handles
- `local-apple-data messages export-attachment --json --chat-handle <messages:chat:v1:...> --handle <messages:attachment:v1:...> --output-dir <dir>` for exact local Messages attachment export without inline bytes or source media paths
- `local-apple-data messages plan --json --operation send-text --handle <messages:chat:v1:...> --body-text <text>` for non-mutating future send-text previews with chat-state, body-hash, idempotency, and approval metadata
- `local-apple-data messages apply --json --operation send-text --handle <messages:chat:v1:...> --body-text <text> --approval-token <token> --confirm-apply` for the approved Messages send-text path, with Messages.app automation, stale chat-state refusal, ghost-row detection, and local read-back verification without echoing the sent body in apply output
- `local-apple-data messages plan --json --operation send-file --handle <messages:chat:v1:...> --file-path <path>` for non-mutating future exact-chat file-send previews with file metadata, file-identity binding, idempotency, and approval metadata without returning local file paths or bytes
- `local-apple-data messages apply --json --operation send-file --handle <messages:chat:v1:...> --file-path <path> --approval-token <token> --confirm-apply` for the approved Messages send-file path, with Messages.app automation, stale chat/file-state refusal, ghost-row detection, and local attachment read-back verification without returning file bytes or local paths
- `local-apple-data hide-my-email search/get` commands for inferred Hide My Email aliases observed in local Mail address metadata
- `local-apple-data voice-memos search/get/export` commands for local Voice Memos title/filename metadata, exact existing embedded transcripts, and exact-handle `.m4a` export to a caller-selected output directory
- `local-apple-data safari search/get/folders/folder/folder-items` commands for local Safari bookmarks, Reading List title/URL metadata, bookmark-folder metadata, exact selected URL detail, and exact selected-folder direct child metadata by opaque handle
- `local-apple-data shortcuts search/get/folder-items` commands for local
Apple Shortcuts shortcut/folder name metadata and exact selected-folder
shortcut metadata by opaque handle, without opening, signing, exporting, or
returning shortcut bodies
- `local-apple-data shortcuts plan/apply --json --operation run --handle <shortcuts:item:v1:...>` for one exact identifier-bound shortcut run through the approval-token/explicit-confirmation gate, argv-only invocation, and a hard execution timeout. Success proves only that the named shortcut was invoked; arbitrary shortcut side effects are not read back.
- `local-apple-data books search/get/annotations` commands for local Apple Books title/author/genre metadata and exact selected-book annotation text by opaque handle, without extracting book/chapter text or returning raw asset IDs, annotation UUIDs, or local file paths
- `local-apple-data podcasts search/get/episodes/episode` commands for local Apple Podcasts show metadata, selected-show episode metadata, and exact selected-episode bounded descriptions by opaque handle, without returning transcripts, audio bytes, feed/enclosure URLs, raw identifiers, or local download paths
- `local-apple-data music search/get/playlists/playlist/playlist-tracks` commands for local Apple Music track, playlist, and exact selected playlist-track metadata by opaque handle, without returning audio bytes, lyrics, file paths, raw identifiers, play history, ratings, or broad playlist track dumps
- `local-apple-data tv search/get/playlists/playlist/playlist-items` commands for local Apple TV item, playlist, and exact selected-playlist item metadata by opaque handle, without returning video bytes, file paths, artwork, descriptions, playback state, watched state, ratings, raw identifiers, or broad playlist item dumps
- `local-apple-data freeform boards/get/folders/folder/folder-boards/child-folders` commands for local Apple Freeform recent-board, folder-title, exact selected-folder board, and exact selected-folder child-folder metadata by opaque handle, without returning board BLOBs, decoded board items, asset bytes, previews, collaboration payloads, raw identifiers, or board content
- `local-apple-data notes search/get` metadata commands and `local-apple-data notes folders/folder/folder-items/folder-tree` exact folder metadata/direct-item/tree commands
- `local-apple-data notes content --json --handle <notes:note:v2:...> --max-chars 4000 --offset 0` for exact-handle local Notes content (plain text by default; add `--content-format html` for the bounded rich-text HTML body plus its extracted visible text), with `next_offset` pagination for long imported notes
- `local-apple-data notes attachments --json --handle <notes:note:v2:...>` for exact selected-note attachment metadata with opaque `notes:attachment:v1:` handles
- `local-apple-data notes export-attachment --json --handle <notes:attachment:v1:...> --output-dir <dir>` for exact local Notes attachment export without inline bytes or source media paths
- `local-apple-data notes plan --json --operation create --title <title> --body-text <text>` for non-mutating future note-create previews with idempotency and approval metadata
- `local-apple-data notes apply --json --operation create --title <title> --body-text <text> [--folder-handle <notes:folder:v1:...>] --approval-token <token> --confirm-apply` for the approved Notes create-note path in the default folder or one exact selected folder, with Notes.app automation and exact-content read-back verification
- `local-apple-data notes plan --json --operation create-folder --folder-handle <notes:folder:v1:...> --title <folder-title>` for non-mutating future exact child-folder create previews under one selected normal parent folder
- `local-apple-data notes apply --json --operation create-folder --folder-handle <notes:folder:v1:...> --title <folder-title> --approval-token <token> --confirm-apply` for the approved Notes exact child-folder create path, with Notes.app automation, same-parent idempotency, metadata-only read-back, and selected-parent proof
- `local-apple-data notes plan --json --operation delete-folder --folder-handle <notes:folder:v1:...> --expected-current-sha256 <folder-title-sha256>` for non-mutating future exact empty child-folder delete previews
- `local-apple-data notes apply --json --operation delete-folder --folder-handle <notes:folder:v1:...> --expected-current-sha256 <folder-title-sha256> --approval-token <token> --confirm-apply` for the approved Notes exact empty child-folder delete path, with title-hash drift checks, empty-folder rechecks, scoped Notes.app automation, and absence proof
- `local-apple-data notes plan --json --operation append-text --handle <notes:note:v2:...> --expected-current-sha256 <sha256> --body-text <text>` for non-mutating future note append previews with expected-current-content binding
- `local-apple-data notes apply --json --operation append-text --handle <notes:note:v2:...> --expected-current-sha256 <sha256> --body-text <text> --approval-token <token> --confirm-apply` for the approved Notes append-text path, with drift refusal and exact-content read-back verification
- `local-apple-data notes plan --json --operation replace-text --handle <notes:note:v2:...> --expected-current-sha256 <sha256> --body-text <text>` for non-mutating future note plaintext replacement previews with expected-current-content binding
- `local-apple-data notes apply --json --operation replace-text --handle <notes:note:v2:...> --expected-current-sha256 <sha256> --body-text <text> --approval-token <token> --confirm-apply` for the approved Notes replace-text path, with drift refusal, locked/shared-note refusal, and exact-content read-back verification
- `local-apple-data notes plan --json --operation move-to-folder --handle <notes:note:v2:...> --folder-handle <notes:folder:v1:...> --expected-current-sha256 <sha256>` for non-mutating exact-note/exact-folder move previews with same-account and current-content binding
- `local-apple-data notes apply --json --operation move-to-folder --handle <notes:note:v2:...> --folder-handle <notes:folder:v1:...> --expected-current-sha256 <sha256> --approval-token <token> --confirm-apply` for the approved Notes move-to-folder path, with drift refusal, same-account normal-folder proof, Notes.app scoped move automation, and folder read-back verification
- `local-apple-data notes plan --json --operation delete --handle <notes:note:v2:...> --expected-current-sha256 <sha256>` for non-mutating future note delete previews with expected-current-content binding
- `local-apple-data notes apply --json --operation delete --handle <notes:note:v2:...> --expected-current-sha256 <sha256> --approval-token <token> --confirm-apply` for the approved Notes exact-note delete path, with drift refusal, locked/shared-note refusal, and absence read-back verification
- `local-apple-data icloud-drive search/root/get` metadata commands for local iCloud Drive items by filename or the configured root
- `local-apple-data icloud-drive list --json --handle <icloud:file:v1:...> [--limit 20]` for exact selected-folder direct child metadata listing without content or raw paths
- `local-apple-data icloud-drive tree --json --handle <icloud:file:v1:...> [--depth 2] [--limit 50]` for bounded recursive metadata listing under one exact selected folder without content, raw paths, symlink traversal, or package traversal
- `local-apple-data icloud-drive content --json --handle <icloud:file:v1:...> --max-chars 4000` for exact-handle local iCloud Drive text-file content
- `local-apple-data icloud-drive export --json --handle <icloud:file:v1:...> --output-dir <dir> [--filename <name>]` for exact-handle local iCloud Drive regular-file export with selected source identity binding and without inline bytes, source paths, or arbitrary symlink output ancestors
- `local-apple-data icloud-drive plan --json --operation create-text --parent-handle <icloud:file:v1:...> --filename <name.md> --content-text <text>` for non-mutating future text-file create previews with idempotency and approval metadata
- `local-apple-data icloud-drive apply --json --operation create-text --parent-handle <icloud:file:v1:...> --filename <name.md> --content-text <text> --approval-token <token> --confirm-apply` for the approved iCloud Drive create-text path, with exclusive create and read-back verification
- `local-apple-data icloud-drive plan --json --operation create-folder --parent-handle <icloud:file:v1:...> --folder-name <folder-name>` for non-mutating future folder-create previews with idempotency and approval metadata
- `local-apple-data icloud-drive apply --json --operation create-folder --parent-handle <icloud:file:v1:...> --folder-name <folder-name> --approval-token <token> --confirm-apply` for the approved iCloud Drive create-folder path, with no-follow parent validation, exclusive mkdir, metadata-only read-back, and existing-directory idempotency
- `local-apple-data icloud-drive plan --json --operation rename-folder --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> --folder-name <new-folder-name>` for non-mutating exact folder rename previews with directory metadata binding, non-empty support, and no overwrite
- `local-apple-data icloud-drive apply --json --operation rename-folder --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> --folder-name <new-folder-name> --approval-token <token> --confirm-apply` for the approved iCloud Drive exact folder rename path, with no-follow source validation, metadata drift refusal, no-overwrite target rename, non-empty child preservation, and metadata-only read-back
- `local-apple-data icloud-drive plan --json --operation trash-folder --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256>` for non-mutating exact folder Trash previews with directory metadata binding and no content or parent input
- `local-apple-data icloud-drive apply --json --operation trash-folder --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> --approval-token <token> --confirm-apply` for the approved iCloud Drive exact folder Trash path, including non-empty directories, with no-follow source validation, metadata drift refusal, recoverable Trash move, original absence proof, child preservation, and metadata-only read-back
- `local-apple-data icloud-drive plan --json --operation delete-folder --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256>` for non-mutating exact selected-folder permanent-delete previews with directory metadata binding, private bounded tree binding, and no content, parent, or filename input
- `local-apple-data icloud-drive apply --json --operation delete-folder --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> --approval-token <token> --confirm-apply` for the approved iCloud Drive exact selected-folder permanent-delete path, with no-follow source validation, private bounded tree binding, hidden/symlink/package/tree-size refusal, metadata/tree drift refusal, hidden staging identity proof, bounded permanent staged-tree removal, original absence proof, and metadata-only read-back
- `local-apple-data icloud-drive plan --json --operation delete-text --handle <icloud:file:v1:...> --expected-current-sha256 <content-sha256>` for non-mutating exact text-file permanent-delete previews with current SHA-256 and exact file identity approval binding
- `local-apple-data icloud-drive apply --json --operation delete-text --handle <icloud:file:v1:...> --expected-current-sha256 <content-sha256> --approval-token <token> --confirm-apply` for the approved iCloud Drive exact text-file permanent-delete path, with root-aware plan recomputation, exact file identity approval binding, stale token replay refusal for recreated same-path/same-content files, current-content drift refusal, random-only hidden staging identity proof, permanent unlink, original absence proof, and no content/hash/path return
- `local-apple-data icloud-drive plan --json --operation move-folder --handle <icloud:file:v1:...> --parent-handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> [--folder-name <new-folder-name>]` for non-mutating exact folder move previews with directory metadata binding, exact target parent binding, non-empty support, and no content input
- `local-apple-data icloud-drive apply --json --operation move-folder --handle <icloud:file:v1:...> --parent-handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> [--folder-name <new-folder-name>] --approval-token <token> --confirm-apply` for the approved iCloud Drive exact folder move path, with no-follow source and target-parent validation, metadata drift refusal, descendant-parent refusal, no-overwrite target proof, source/target presence proof, non-empty child preservation, and metadata-only read-back
- `local-apple-data icloud-drive plan --json --operation copy-folder --handle <icloud:file:v1:...> --parent-handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> [--folder-name <new-folder-name>]` for non-mutating exact selected-folder copy previews with directory metadata binding, exact target parent binding, private bounded source-tree binding, and no content input
- `local-apple-data icloud-drive apply --json --operation copy-folder --handle <icloud:file:v1:...> --parent-handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> [--folder-name <new-folder-name>] --approval-token <token> --confirm-apply` for the approved iCloud Drive exact selected-folder copy path, with no-follow source and target-parent validation, bounded non-empty tree support, hidden/symlink/package refusal, metadata/tree drift refusal, no-overwrite target proof, source preservation proof, target presence proof, and metadata-only read-back
- `local-apple-data icloud-drive plan --json --operation append-text --handle <icloud:file:v1:...> --expected-current-sha256 <sha256> --content-text <text>` for non-mutating future text append previews with expected-current-content binding
- `local-apple-data icloud-drive apply --json --operation append-text --handle <icloud:file:v1:...> --expected-current-sha256 <sha256> --content-text <text> --approval-token <token> --confirm-apply` for the approved iCloud Drive append-text path, with drift refusal and read-back hash verification
- `local-apple-data icloud-drive plan --json --operation replace-text --handle <icloud:file:v1:...> --expected-current-sha256 <sha256> --content-text <text>` for non-mutating full-text replacement previews with expected-current-content binding
- `local-apple-data icloud-drive apply --json --operation replace-text --handle <icloud:file:v1:...> --expected-current-sha256 <sha256> --content-text <text> --approval-token <token> --confirm-apply` for the approved iCloud Drive replace-text path, with drift refusal, atomic same-directory replacement, and read-back hash verification
- `local-apple-data icloud-drive plan --json --operation trash-text --handle <icloud:file:v1:...> --expected-current-sha256 <sha256>` for non-mutating recoverable Trash previews with expected-current-content binding
- `local-apple-data icloud-drive apply --json --operation trash-text --handle <icloud:file:v1:...> --expected-current-sha256 <sha256> --approval-token <token> --confirm-apply` for the approved iCloud Drive trash-text path, with drift refusal, post-swap SHA verification, recoverable Trash move, no raw Trash path return, and original-handle absence proof
- `local-apple-data icloud-drive plan --json --operation rename-text --handle <icloud:file:v1:...> --expected-current-sha256 <sha256> --filename <new-name.md>` for non-mutating exact-file rename previews with expected-current-content binding and no overwrite
- `local-apple-data icloud-drive apply --json --operation rename-text --handle <icloud:file:v1:...> --expected-current-sha256 <sha256> --filename <new-name.md> --approval-token <token> --confirm-apply` for the approved iCloud Drive rename-text path, with no-overwrite target reservation, no-follow swap, post-swap SHA/identity proof, rollback on verifiable drift before target proof, no rollback after verified target proof, and source-handle absence proof
- `local-apple-data icloud-drive plan --json --operation copy-text --handle <icloud:file:v1:...> --expected-current-sha256 <sha256> [--parent-handle <icloud:file:v1:...>] --filename <copy-name.md>` for non-mutating exact-file copy previews with no source mutation and no overwrite
- `local-apple-data icloud-drive apply --json --operation copy-text --handle <icloud:file:v1:...> --expected-current-sha256 <sha256> [--parent-handle <icloud:file:v1:...>] --filename <copy-name.md> --approval-token <token> --confirm-apply` for the approved iCloud Drive copy-text path, with exclusive create, target read-back hash proof, post-copy source SHA recheck, and source-presence proof
- `local-apple-data icloud-drive plan --json --operation move-text --handle <icloud:file:v1:...> --parent-handle <icloud:file:v1:...> --expected-current-sha256 <sha256> [--filename <new-name.md>]` for non-mutating exact-file move previews with exact destination folder selection and no overwrite
- `local-apple-data icloud-drive apply --json --operation move-text --handle <icloud:file:v1:...> --parent-handle <icloud:file:v1:...> --expected-current-sha256 <sha256> [--filename <new-name.md>] --approval-token <token> --confirm-apply` for the approved iCloud Drive move-text path, with no-overwrite target reservation, no-follow swap, post-swap SHA/identity proof, rollback on verifiable drift before target proof, no rollback after verified target proof, and source-handle absence proof
- `local-apple-data icloud-drive plan --json --operation rename-file --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> --filename <new-name.bin>` for non-mutating exact regular-file rename previews with expected metadata binding, no content/hash return, and no overwrite
- `local-apple-data icloud-drive apply --json --operation rename-file --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> --filename <new-name.bin> --approval-token <token> --confirm-apply` for the approved iCloud Drive regular-file rename path, with non-text non-package regular-file validation, no-overwrite target reservation, no-follow swap, metadata-only read-back, and source-handle absence proof
- `local-apple-data icloud-drive plan --json --operation copy-file --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> [--parent-handle <icloud:file:v1:...>] --filename <copy-name.bin>` for non-mutating exact regular-file copy previews with expected metadata binding, no content/hash return, no source mutation, and no overwrite
- `local-apple-data icloud-drive apply --json --operation copy-file --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> [--parent-handle <icloud:file:v1:...>] --filename <copy-name.bin> --approval-token <token> --confirm-apply` for the approved iCloud Drive regular-file copy path, with exclusive create, target identity/size proof, source metadata recheck, metadata-only read-back, and source-presence proof
- `local-apple-data icloud-drive plan --json --operation move-file --handle <icloud:file:v1:...> --parent-handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> [--filename <new-name.bin>]` for non-mutating exact regular-file move previews with exact destination folder selection, expected metadata binding, no content/hash return, and no overwrite
- `local-apple-data icloud-drive apply --json --operation move-file --handle <icloud:file:v1:...> --parent-handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> [--filename <new-name.bin>] --approval-token <token> --confirm-apply` for the approved iCloud Drive regular-file move path, with non-text non-package regular-file validation, no-overwrite target reservation, no-follow swap, metadata-only read-back, and source-handle absence proof
- `local-apple-data icloud-drive plan --json --operation import-file --parent-handle <icloud:file:v1:...> --source-file <path> [--filename <new-name.bin>]` for non-mutating exact regular-file import previews with private source identity/content binding and no source path/hash return
- `local-apple-data icloud-drive apply --json --operation import-file --parent-handle <icloud:file:v1:...> --source-file <path> [--filename <new-name.bin>] --approval-token <token> --confirm-apply` for the approved iCloud Drive regular-file import path, with non-text non-package source validation outside iCloud Drive, no-overwrite target proof, metadata-only read-back, and source preservation proof
- `local-apple-data icloud-drive plan --json --operation replace-file --handle <icloud:file:v1:...> --source-file <path> --expected-current-sha256 <metadata-sha256>` for non-mutating exact regular-file replace previews with private source identity/content binding, extension match, and no source path/hash return
- `local-apple-data icloud-drive apply --json --operation replace-file --handle <icloud:file:v1:...> --source-file <path> --expected-current-sha256 <metadata-sha256> --approval-token <token> --confirm-apply` for the approved iCloud Drive regular-file replace path, with target metadata drift refusal, source preservation proof, byte replacement proof, metadata-only target read-back, and no content/hash/path return
- `local-apple-data icloud-drive plan --json --operation trash-file --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256>` for non-mutating exact regular-file Trash previews with expected metadata binding and no content/hash/path return
- `local-apple-data icloud-drive apply --json --operation trash-file --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> --approval-token <token> --confirm-apply` for the approved iCloud Drive regular-file Trash path, with non-text non-package regular-file validation, recoverable Trash move, original absence proof, metadata-only read-back, and no raw Trash path return
- `local-apple-data icloud-drive plan --json --operation delete-file --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256>` for non-mutating exact regular-file permanent-delete previews with expected metadata binding and no content/hash/path return
- `local-apple-data icloud-drive apply --json --operation delete-file --handle <icloud:file:v1:...> --expected-current-sha256 <metadata-sha256> --approval-token <token> --confirm-apply` for the approved iCloud Drive regular-file permanent-delete path, with non-text non-package regular-file validation, hidden staging identity proof, permanent unlink, original absence proof, metadata-only read-back, and no raw staging or Trash path return
- `local-apple-data calendar search/get` commands for local Calendar events by title through EventKit
- `local-apple-data calendar participants --json --handle <calendar:event:v1:...>` and `local-apple-data calendar participant --json --event-handle <calendar:event:v1:...> --participant-handle <calendar:participant:v1:...>` for exact Calendar participant metadata and selected participant detail; list output returns opaque participant handles, role/status/type/current-user flags, and presence flags only, while exact detail may return bounded participant name/URL
- `local-apple-data calendar request-access --json` to trigger the one-time macOS
Calendar full-access prompt for the stable local EventKit helper app; normal
Calendar reads do not prompt and fail closed if full access is absent
- `local-apple-data calendar calendars --json --query <calendar title> [--include-default]` and `local-apple-data calendar calendar --json --handle <calendar:calendar:v1:...>` for exact Calendar target metadata without raw EventKit identifiers
- `local-apple-data calendar events --json --handle <calendar:calendar:v1:...> --start <YYYY-MM-DD-or-ISO> --end <YYYY-MM-DD-or-ISO> [--limit 20]` for capped event metadata from one exact selected Calendar target; output returns opaque event handles and presence/count flags only, not notes, location text, attendee names/URLs, event URL values, raw EventKit identifiers, or raw alarm detail
- `local-apple-data calendar plan-calendar/apply-calendar` for synthetic `LAD-TEST-*` Calendar calendar create/rename/delete by exact source or target `calendar:calendar:v1:` handle, with safe-hash binding, duplicate-title refusal, bounded empty-calendar safety-window proof for rename/delete, event-only delete refusal for calendars that may contain reminders, EventKit read-back, and delete absence proof.
- `local-apple-data calendar plan --json --operation create --title <title> [--calendar-title <calendar> | --calendar-handle <calendar:calendar:v1:...> | --use-default-calendar] --start-date <ISO> --end-date <ISO> [--time-zone <IANA>] [--availability busy|free|tentative|unavailable] [--event-url <allow-listed-url>] [--structured-location <json>] [--all-day] [--alarm-offsets-minutes -10,0 | --alarm-absolute-dates <ISO>] [--recurrence-frequency daily|weekly|monthly|yearly (--recurrence-count <2-52> | --recurrence-end-date <ISO-with-timezone> | --recurrence-unbounded) [--recurrence-interval <1-4>]]` for non-mutating future timed or explicit all-day event create previews with idempotency and approval metadata; `--use-default-calendar` is plan-only and resolves the current default calendar to an exact `calendar_handle`, `--time-zone` is timed-event only, availability is support-mask validated during apply, event URL scheme must be `http`, `https`, `mailto`, or `tel` with hash-only read-back, structured location is one bounded title plus optional paired coordinates/radius, relative/absolute alarm modes are mutually exclusive, and recurrence is simple count-, end-date-, or explicit-unbounded
- `local-apple-data calendar apply --json --operation create --title <title> [--calendar-title <calendar> | --calendar-handle <calendar:calendar:v1:...>] --start-date <ISO> --end-date <ISO> [--time-zone <IANA>] [--availability busy|free|tentative|unavailable] [--event-url <allow-listed-url>] [--structured-location <json>] [--all-day] [--alarm-offsets-minutes -10,0 | --alarm-absolute-dates <ISO>] [--recurrence-frequency daily|weekly|monthly|yearly (--recurrence-count <2-52> | --recurrence-end-date <ISO-with-timezone> | --recurrence-unbounded) [--recurrence-interval <1-4>]] --approval-token <token> --confirm-apply` for the approved Calendar create-event path, with EventKit apply, read-back verification, hash-only URL proof when an event URL is requested, structured-location read-back proof when requested, and recurrence count/end-date/unbounded read-back proof when requested
- `local-apple-data calendar plan --json --operation update --handle <calendar:event:v1:...> [--target-calendar-handle <calendar:calendar:v1:...>] --expected-title <current> --expected-calendar-title <calendar> --expected-start-date <ISO> --expected-end-date <ISO> [--expected-time-zone <IANA>] [--expected-availability busy|free|tentative|unavailable|not_supported] [--expected-structured-location <json>] [--expected-event-url-present --expected-event-url-sha256 <sha256>] [--expected-alarm-offsets-minutes -10,0 | --expected-alarm-absolute-dates <ISO>] --title <new> --start-date <ISO> --end-date <ISO> [--time-zone <IANA>] [--availability busy|free|tentative|unavailable] [--event-url <allow-listed-url> | --clear-event-url] [--structured-location <json> | --clear-structured-location] [--alarm-offsets-minutes -10,0 | --alarm-absolute-dates <ISO>] [--recurrence-frequency daily|weekly|monthly|yearly (--recurrence-count <2-52> | --recurrence-end-date <ISO-with-timezone> | --recurrence-unbounded) [--recurrence-interval <1-4>]]` for non-mutating exact-event update or calendar-move previews with expected-state binding; changing availability requires `--expected-availability`, changing structured location can bind `--expected-structured-location`, clearing structured location requires `--expected-structured-location` plus empty proposed location, changing or clearing an existing URL requires URL presence/hash binding, and recurrence update is limited to adding one simple count-, end-date-, or explicit-unbounded recurrence to a currently non-recurring event
- `local-apple-data calendar apply --json --operation update --handle <calendar:event:v1:...> [--target-calendar-handle <calendar:calendar:v1:...>] --expected-title <current> --expected-calendar-title <calendar> --expected-start-date <ISO> --expected-end-date <ISO> [--expected-time-zone <IANA>] [--expected-availability busy|free|tentative|unavailable|not_supported] [--expected-structured-location <json>] [--expected-event-url-present --expected-event-url-sha256 <sha256>] [--expected-alarm-offsets-minutes -10,0 | --expected-alarm-absolute-dates <ISO>] --title <new> --start-date <ISO> --end-date <ISO> [--time-zone <IANA>] [--availability busy|free|tentative|unavailable] [--event-url <allow-listed-url> | --clear-event-url] [--structured-location <json> | --clear-structured-location] [--alarm-offsets-minutes -10,0 | --alarm-absolute-dates <ISO>] [--recurrence-frequency daily|weekly|monthly|yearly (--recurrence-count <2-52> | --recurrence-end-date <ISO-with-timezone> | --recurrence-unbounded) [--recurrence-interval <1-4>]] --approval-token <token> --confirm-apply` for the approved Calendar exact-event update/move path, with stale-state refusal, support-mask validation, URL hash read-back verification or URL absence proof when requested, structured-location read-back proof or absence proof when requested, recurrence read-back verification when requested, and read-back verification
- Calendar recurrence selector flags for create/update plan/apply are yearly/monthly/weekly scoped: `--recurrence-weekdays` with weekly recurrence, monthly recurrence, or yearly week-of-year recurrence; `--recurrence-month-days` or `--recurrence-month-weekdays` only with monthly recurrence and never together; `--recurrence-year-months`, `--recurrence-year-days`, and `--recurrence-year-weeks` are yearly-only top-level selectors; `--recurrence-year-month-days` and `--recurrence-year-month-weekdays` are yearly-only subselectors that require `--recurrence-year-months`, are never mixed with each other, and are forbidden with `--recurrence-year-days` or `--recurrence-year-weeks`.
- `local-apple-data contacts search/get` commands for local Contacts by name or organization through Contacts.framework
- `local-apple-data contacts request-access --json` to trigger the one-time
macOS Contacts prompt for the stable signed Contacts helper app; normal
Contacts reads and writes do not prompt and fail closed without authorization
- `local-apple-data contacts groups --json --query <group>` and `local-apple-data contacts group --json --handle <contacts:group:v1:...>` for Contacts group metadata and `group_safe_sha256` without raw member identifiers
- `local-apple-data contacts group-members --json --handle <contacts:group:v1:...> [--limit 20]` for capped selected-group member metadata with opaque contact handles and no raw member IDs or contact detail values
- `local-apple-data contacts containers --json --query <container>` and `local-apple-data contacts container --json --handle <contacts:container:v1:...>` for Contacts container metadata and `container_safe_sha256` without raw container identifiers
- `local-apple-data contacts container-members --json --handle <contacts:container:v1:...> [--limit 20]` for capped selected-container member metadata with opaque contact handles and no raw contact IDs or contact detail values
- `local-apple-data contacts count --json` for read-only live Contacts counts without returning contact details
- `local-apple-data contacts export --json --output-dir <dir> [--filename-prefix contacts]` for a read-only JSON plus vCard Contacts backup with count-match verification and no contact-data echo in the tool response. Contact notes are omitted when Apple's restricted Contacts-notes entitlement is unavailable; if vCard serialization then cannot be verified, the JSON archive is retained but the overall archive fails closed as unverified.
- `local-apple-data contacts plan --json --operation create --contact-type person --given-name <name> --family-name <name> [--container-handle <contacts:container:v1:...> --expected-container-sha256 <container_safe_sha256>]` for non-mutating future contact-create previews with idempotency and approval metadata
- `local-apple-data contacts apply --json --operation create --contact-type person --given-name <name> --family-name <name> [--container-handle <contacts:container:v1:...> --expected-container-sha256 <container_safe_sha256>] --approval-token <token> --confirm-apply` for the approved Contacts create-contact path, with Contacts.framework apply and read-back verification
- `local-apple-data contacts plan --json --operation update --handle <contacts:contact:v1:...> --expected-current-sha256 <update_safe_sha256> --given-name <name> [--email work=name@example.invalid] [--postal-addresses-json '[...]'] [--birthday-json '{"month":1,"day":2}'] [--image-path <file>] [--clear-image]` for non-mutating exact-contact scalar/method/rich-field/image update previews with current-state binding. Omitted arrays are preserved; provided arrays replace; empty arrays clear.
- `local-apple-data contacts apply --json --operation update --handle <contacts:contact:v1:...> --expected-current-sha256 <update_safe_sha256> ... --approval-token <token> --confirm-apply` for the approved exact-contact scalar/method/rich-field/image update path, with Contacts.framework read-back verification
- `local-apple-data contacts plan --json --operation append-note|set-note|clear-note|merge-note --handle <contacts:contact:v1:...> --expected-current-sha256 <note_safe_sha256> [--note-text <text>]` is the approved non-mutating exact-contact note gate, but it currently fails closed with `contacts_note_unavailable` because the local signed helper cannot obtain Apple's restricted provisioning-profile Contacts-notes entitlement
- The matching Contacts note apply command remains approval-token and explicit-confirmation gated but is currently unavailable for the same entitlement reason; it never mutates before returning `contacts_note_unavailable`
- `local-apple-data contacts plan --json --operation add-group-member|remove-group-member --handle <contacts:contact:v1:...> --expected-current-sha256 <update_safe_sha256> --group-handle <contacts:group:v1:...> --expected-group-sha256 <group_safe_sha256>` for non-mutating exact group membership previews
- `local-apple-data contacts apply --json --operation add-group-member|remove-group-member --handle <contacts:contact:v1:...> --expected-current-sha256 <update_safe_sha256> --group-handle <contacts:group:v1:...> --expected-group-sha256 <group_safe_sha256> --approval-token <token> --confirm-apply` for approved exact group membership updates with metadata-only group read-back
- `local-apple-data contacts plan --json --operation create-group --group-name <name> [--container-handle <contacts:container:v1:...> --expected-container-sha256 <container_safe_sha256>]` and matching `contacts apply --operation create-group ... --approval-token <token> --confirm-apply` for exact group creation with metadata-only group read-back
- `local-apple-data contacts plan --json --operation rename-group --group-handle <contacts:group:v1:...> --expected-group-sha256 <group_safe_sha256> --group-name <name>` and matching `contacts apply --operation rename-group ... --approval-token <token> --confirm-apply` for exact group rename
- `local-apple-data contacts plan --json --operation delete-group --group-handle <contacts:group:v1:...> --expected-group-sha256 <group_safe_sha256>` and matching `contacts apply --operation delete-group ... --approval-token <token> --confirm-apply` for exact group delete with absence proof and `contacts_deleted:false`
- `local-apple-data contacts plan --json --operation batch --batch-items-json '[...]'` and matching `contacts apply --operation batch --batch-items-json '[...]' --approval-token <token> --confirm-apply` for capped exact batches over approved existing-contact operations
- `local-apple-data contacts plan --json --operation delete --handle <contacts:contact:v1:...> --expected-current-sha256 <delete_safe_sha256>` for non-mutating exact-contact delete previews with full-detail current-state binding
- `local-apple-data contacts apply --json --operation delete --handle <contacts:contact:v1:...> --expected-current-sha256 <delete_safe_sha256> --approval-token <token> --confirm-apply` for the approved exact-contact delete path, with Contacts.framework deletion and absence read-back proof
- `local-apple-data photos search/get/export` commands for local Photos asset metadata by original filename, exact asset/resource metadata, and exact-handle asset export to a caller-selected output directory through PhotoKit
- `local-apple-data photos albums/album/album-assets` commands for bounded regular-album title metadata, exact regular-album metadata, and exact selected-album child asset metadata by opaque album handle
- `local-apple-data photos request-access --json` to trigger the one-time macOS
Photos access prompt for the local PhotoKit helper path; normal Photos reads
and writes do not prompt and fail closed if Photos access is absent. If macOS
returns `photos_access_request_timeout`, approve
`Local Apple Data Photos Helper` manually under Privacy & Security > Photos.
- `local-apple-data photos plan --json --operation import --source-file <path>` for non-mutating future image/video import previews with source-file hash binding and approval metadata
- `local-apple-data photos apply --json --operation import --source-file <path> --approval-token <token> --confirm-apply` for the approved Photos import path, with PhotoKit apply and created-asset read-back verification
- `local-apple-data photos plan --json --operation update-flags --handle <photos:asset:v1:...> --favorite true --expected-favorite false --expected-hidden false` and matching `photos apply --operation update-flags ... --approval-token <token> --confirm-apply` for exact asset favorite/hidden updates with expected-state binding and PhotoKit read-back verification
- `local-apple-data photos plan --json --operation delete --handle <photos:asset:v1:...>` and matching `photos apply --operation delete ... --approval-token <token> --confirm-apply` for exact selected-asset delete with expected-state binding and PhotoKit absence proof; it does not empty Recently Deleted or permanently purge Photos assets
- `local-apple-data photos plan/apply --json --operation create-album --album-title '<album title>'`, `rename-album --album-handle <photos:album:v1:...> --new-album-title '<album title>'`, and `delete-album --album-handle <photos:album:v1:...>` for exact regular-album create/rename/delete with full Photos Library authorization with duplicate-title refusal, exact state binding for rename/delete, empty-album proof for delete, PhotoKit apply, title read-back for create/rename, absence proof for delete, and no raw album identifiers
- `local-apple-data reminders search/due` metadata commands
- `local-apple-data reminders eventkit-search` for local Reminders title metadata through EventKit
- `local-apple-data reminders request-access --json` to trigger the one-time macOS
Reminders full-access prompt for the stable local EventKit helper app; normal
Reminders reads do not prompt and fail closed if full access is absent
- `local-apple-data reminders lists --json --query <list title text>`, `local-apple-data reminders list --json --handle <reminders:list:eventkit:v1:...>`, and `local-apple-data reminders list-items --json --handle <reminders:list:eventkit:v1:...>` for exact Reminders target-list metadata and selected-list reminder metadata by opaque list handle; `local-apple-data reminders lists --json` without `--query` (MCP `reminders_list_lists`) enumerates all Reminders lists as capped metadata. List metadata includes `is_shared` (null when EventKit sharing detection is unavailable) plus `sharee_count` when EventKit exposes a positive count — count only, never sharee identities — so agents can see that a list is shared with other people before writing to it. Moving a reminder out of a shared list is refused by EventKit and reported as `shared_list_move_unsupported` with a create-on-target plus guarded-delete fallback recommendation
- `local-apple-data reminders content --json --handle <reminders:reminder:eventkit:v1:...> --max-chars 4000` for exact-handle local Reminder notes
- `local-apple-data reminders plan --json --operation create|complete|uncomplete|update-due-date|update-title|update-notes|update-priority|update-url|clear-url|set-absolute-display-alarm|set-relative-display-alarm|clear-display-alarm|move-to-list|delete ...` for non-mutating future-change previews with idempotency and approval metadata
- `local-apple-data reminders apply --json --operation create|complete|uncomplete|update-due-date|update-title|update-notes|update-priority|update-url|clear-url|set-absolute-display-alarm|set-relative-display-alarm|clear-display-alarm|move-to-list|delete ... --approval-token <token> --confirm-apply` for the approved Reminders create/complete/uncomplete/due-date/title/notes/priority/exact URL update/clear/exact absolute/relative/mixed display-alarm set/clear/start-date set/clear/recurrence create/update/clear/exact same-source list-move/delete path, with exact-handle expected-state checks, hash-only URL read-back or absence proof for URL changes, exact absolute-date or relative-offset read-back or alarm absence proof for display-alarm changes, exact expected-current-list and same-source target-list handle checks plus `target_list_verified:true` identity proof for list-move, notes-hash drift refusal for notes updates and delete, EventKit apply, and read-back verification or delete absence proof
- `local-apple-data reminders plan-list --json --operation create-list|rename-list|delete-list|delete-list-with-migration ...` and matching `reminders apply-list ... --approval-token <token> --confirm-apply` for exact list create/rename/empty-delete/same-source migrate-delete, with exact source/target list-handle binding, empty-list proof for rename/delete, bounded migration count proof for migrate-delete, EventKit apply, and source/title, empty-list, migration, target-count, or absence read-back verification
- Highest-version Mail store discovery without exposing raw local store paths in normal output
- `local-apple-data-mcp` stdio MCP server with read-only tools plus 14 public apply-capable MCP tools: `reminders_apply_change`, `reminders_apply_list_change`, `icloud_drive_apply_change`, `calendar_apply_change`, `calendar_apply_calendar_change`, `contacts_apply_change`, `notes_apply_change`, `mail_apply_change`, `mail_apply_mailbox_change`, `mail_apply_cleanup`, `photos_apply_change`, `messages_apply_change`, `filesystem_apply_change`, and `shortcuts_apply_run`. Tools whose static apply surface can delete, move an item to Trash, send external mail, or invoke a Shortcut are annotated destructive.
- MCP runner script that avoids package builds during normal plugin startup
- Codex skill under `skills/local-apple-data/`
- Local plugin manifest under `.codex-plugin/plugin.json`
- Bundled MCP config under `.mcp.json`
- Redacted command event logging
- Opaque signed handles for exact Mail/Messages/Voice Memos/Safari/Shortcuts/Books/Podcasts/Music/TV/Notes/Notes-folder/Calendar/Contacts/Contacts-group/Contacts-container/Photos/Reminders/iCloud Drive/Filesystem metadata fetches, including `fs:file:v1:` for bounded home-directory selection
- Exact Mail content retrieval through the same opaque `mail:message:v2:` handles
- Exact Messages chat transcript retrieval through opaque `messages:chat:v1:` handles, using local text plus bounded `attributedBody` plaintext fallback when available
- Exact Messages participant metadata through opaque `messages:chat:v1:` and `messages:participant:v1:` handles; participant lists do not expose phone/email previews
- Exact Messages attachment metadata/export through opaque `messages:chat:v1:` and `messages:attachment:v1:` handles
- Exact inferred Hide My Email alias detail through opaque `hide_my_email:alias:v1:` handles
- Exact Voice Memos transcript retrieval through opaque `voice_memos:recording:v1:` handles when Apple-generated local transcript data is embedded in the selected `.m4a`
- Exact Voice Memos audio export through opaque `voice_memos:recording:v1:` handles to a caller-selected output directory without returning audio bytes inline
- Exact Safari bookmark and Reading List URL detail retrieval through opaque `safari:item:v1:` handles plus exact selected-folder metadata and direct child listing through opaque `safari:folder:v1:` handles, without returning full URLs in search or folder-list results
- Exact Shortcuts shortcut/folder metadata retrieval and selected-folder
shortcut metadata listing through opaque `shortcuts:item:v1:` handles without
returning raw identifiers or shortcut bodies
- Exact Apple Books metadata and selected-book annotation retrieval through opaque `books:book:v1:` handles without returning raw Books identifiers, local paths, or book/chapter text
- Exact Apple Podcasts show metadata, selected-show episode metadata, and selected-episode bounded descriptions through opaque `podcasts:show:v1:` and `podcasts:episode:v1:` handles without returning transcripts, audio bytes, feed/enclosure URLs, raw identifiers, or local download paths
- Exact Apple Music track, playlist, and selected-playlist track metadata through opaque `music:track:v1:` and `music:playlist:v1:` handles without returning audio bytes, lyrics, file paths, raw identifiers, play history, ratings, or broad playlist track dumps
- Exact Apple TV item, playlist, and selected-playlist item metadata through opaque `tv:item:v1:` and `tv:playlist:v1:` handles without returning video bytes, file paths, artwork, descriptions, playback state, watched state, ratings, raw identifiers, or broad playlist item dumps
- Exact iCloud Drive root metadata selection, selected-folder direct child metadata listing, bounded recursive folder-tree metadata listing, text-file retrieval, and regular-file export through opaque `icloud:file:v1:` handles
- Exact Calendar event detail retrieval through opaque `calendar:event:v1:` handles and exact selected participant detail through `calendar:participant:v1:` handles
- Exact Contact detail retrieval through opaque `contacts:contact:v1:` handles
- Exact Photos asset metadata/resource detail retrieval through opaque `photos:asset:v1:` handles
- Exact Photos asset export through opaque `photos:asset:v1:` handles to a caller-selected output directory without returning image/video bytes inline
- Exact Reminder note retrieval through opaque `reminders:reminder:eventkit:v1:` handles and exact Reminders list metadata through opaque `reminders:list:eventkit:v1:` handles
- Broad-query rejection for empty, wildcard-only, and one-character searches
- Runtime verification script under `scripts/verify_runtime.py`
- Cross-client sync verifier under `scripts/verify_cross_agent_sync.py`, including optional Cursor `mcp.json` validation
- macOS CI workflow under `.github/workflows/ci.yml`
- Contributor guide under `CONTRIBUTING.md` and GitHub issue/PR templates with privacy and mutation-gate checklists
- Repo-local redaction scanner under `scripts/redaction_scan.py`
- Release-readiness auditor under `scripts/audit_release_readiness.py`, including clean-git-worktree, redaction, public leakage, gate drift, public-checkout, public GitHub visibility, live remote-advertised HEAD, and source release candidate gates
- Mutation-gate auditor under `scripts/audit_mutation_gates.py` so write-like CLI/MCP surfaces cannot appear without explicit gates
- Write-design gate auditor under `scripts/audit_write_design_gates.py` so every write-like surface remains machine-checkable against the canonical 14-tool public MCP apply inventory and its operation-specific design gates in `docs/MUTATION_GATES.md`
- Machine-readable public Messages scripting-surface audit under `scripts/audit_messages_public_surface.py`, which keeps risky Messages CRUD blocked unless the public SDEF changes and a separate design gate is approved
- Surface-contract auditor under `scripts/audit_surface_contract.py` so MCP tools, CLI commands, health surfaces, access requirements, and the capability matrix stay aligned
- MCP client config renderer for generic stdio, Claude Code, Cursor, and OpenClaw under `scripts/render_mcp_client_config.py`
- Public release tree builder under `scripts/build_public_release_tree.py`
- Public git checkout preparer under `scripts/prepare_public_git_checkout.py`, including optional initial local commit creation
- Path-redacted release receipt generator under `scripts/generate_release_receipt.py`; receipts include source git traceability and file output is intentionally limited to paths outside the source checkout
- Synthetic unit and CLI tests
- Local git repo on branch `main`
Deferred:
- Any mutating tools other than the approved Reminders create/complete/uncomplete/due-date/title/notes/priority-update/exact URL update/clear/exact absolute/relative/mixed display-alarm set/clear/start-date set/clear/recurrence create/update/clear/exact same-source list-move/delete apply and exact list create/rename/empty-delete/same-source migrate-delete apply surface, iCloud Drive create-folder/create-folder-path/rename-folder/trash-folder/delete-folder/move-folder/copy-folder/create/append-text/replace-text/trash-text/delete-text/rename-text/copy-text/move-text/rename-file/copy-file/move-file/import-file/replace-file/trash-file/delete-file apply surface, Calendar event create/update/delete apply surface including date-only all-day inference, exact availability create/update, exact allow-listed event URL create/update and exact event URL clearing with hash-only read-back proof, simple count-, end-date-, or explicit-unbounded daily/weekly/monthly/yearly recurrence create and add-to-non-recurring-event update with weekly weekday, monthly weekday, monthly day-of-month, monthly nth-weekday, and yearly month/month-day/month-nth-weekday/day-of-year/week-of-year plus explicit weekday selection for week-of-year and selector-backed set-position filtering, selected-occurrence recurring-event title/plain-location/notes/timed reschedule/availability/event URL set/clear/structured-location set/clear/display-alarm set/clear/action-alarm set/clear/all-day set/clear/date-only reschedule/target-calendar move update, selected-occurrence recurring-event delete, future-event recurring span delete, whole-series recurring-event delete, first-visible and mid-series recurrence clearing, mid-series recurrence replacement, future-series recurring-event title/plain-location/notes/timed reschedule/availability/event URL set/clear/structured-location set/clear/display-alarm set/clear/action-alarm set/clear/all-day set/clear/date-only reschedule/target-calendar move update, and structured event location create/update/clear, apply from approved explicit default-calendar create plans only through the resolved exact calendar handle, and Calendar synthetic `LAD-TEST-*` calendar create/rename/delete apply surface, Contacts create-contact/exact scalar/method/rich-field/image update/exact group membership/exact group create/rename/delete/exact batch/delete apply surface, Notes default/exact-folder note create, exact child-folder create, exact-folder rename, exact empty child-folder delete, exact empty child-folder move, append-text, replace-text, rich-text body create, rich-text body replace, move-to-folder, and exact-note delete apply surface, Mail create-draft/send-message/reply-message/reply-all-message/forward-message/mark-read/mark-unread/flag-message/unflag-message/archive-message/move-message/trash-message apply surface, Mail synthetic `LAD-TEST-*` mailbox create/rename apply surface, source-gated synthetic mailbox delete and cleanup apply surface only when public Mail.app deletion plus exact target-state binding, mailbox-scoped absence proof, and Mail-idle guards succeed, Photos import, exact asset favorite/hidden update, exact asset delete, exact regular-album membership add/remove, and exact regular-album create/rename/delete apply with full Photos Library authorization surface, Messages send-text/send-file apply surface, home-directory Filesystem apply surface, and exact identifier-bound Shortcuts run apply surface. Contacts note gates remain designed and synthetic-testable but live-unavailable: they fail closed with `contacts_note_unavailable` before mutation.
- Mail send outside the approved send-message gate, Mail reply outside the approved exact-message sender-only or reply-all gates, Mail forward outside the approved exact-message forward gate, Mail source attachment/non-body-part forwarding outside the explicit `include_source_attachments` forward gate, Mail cross-account move outside the approved exact target-mailbox gate, Mail permanent delete outside the synthetic `LAD-TEST-*` Trash/Junk cleanup gate, Mail mailbox mutation outside the synthetic empty `LAD-TEST-*` mailbox gate, Mail account mutation, Mail archive outside the approved exact-message same-account Archive gate, Mail move outside the approved exact-message target-mailbox gate, Mail read/flag/archive/move/trash triage mutation outside the approved exact-message or capped exact bulk mark-read/mark-unread/flag-message/unflag-message/archive-message/move-message gate, Mail query-result triage outside the capped preview-to-exact-plan gate, Mail attachment mutation outside the approved draft/send/reply/reply-all/forward local-file attachment gates, broad Mail attachment export, Calendar update outside the approved exact-event title/time/location/structured-location/notes/all-day/relative-or-absolute display/audio/email/geofence alarm/time-zone/availability/event-URL/simple add-recurrence/first-visible or mid-series recurrence-clear-or-replace/selected-occurrence title/plain-location/notes/timed reschedule/availability/event URL set/clear/structured-location set/clear/display-alarm set/clear/action-alarm set/clear/all-day set/clear/date-only reschedule/target-calendar move gate, Calendar delete outside the approved exact-event absence-proof gate, Calendar recurrence outside simple count-, end-date-, or explicit-unbounded daily/weekly/monthly/yearly create, add-to-non-recurring-event update with weekly weekday, monthly weekday, monthly day-of-month, monthly nth-weekday, and yearly month/month-day/month-nth-weekday/day-of-year/week-of-year plus explicit weekday selection for week-of-year and selector-backed set-position filtering, selected-occurrence title/plain-location/notes/timed reschedule/availability/event URL set/clear/structured-location set/clear/display-alarm set/clear/action-alarm set/clear/all-day set/clear/date-only reschedule/target-calendar move update, future-series title/plain-location/notes/timed reschedule/availability/event URL set/clear/structured-location set/clear/display-alarm set/clear/action-alarm set/clear/all-day set/clear/date-only reschedule/target-calendar move update, selected-occurrence delete, future-event recurring span delete, whole-series recurring-event delete, or first-visible or mid-series recurrence clearing, mid-series recurrence replacement, or custom recurrence shapes beyond approved selector-backed EventKit rules, attendee/invitation/organizer mutation, silent default-calendar guessing or default-calendar mutation, timed-event time-zone guessing, availability outside explicit busy/free/tentative/unavailable support-mask validation, non-allow-listed event URL schemes, procedure alarms, or alarm mutation outside exact relative/absolute display-or-audio-or-email-or-geofence-alarm gates, Contacts raw identifier input, broad contact dumps in chat, direct database writes, duplicate merge automation, free-form labels over 255 characters or labels containing control characters, and complete Contacts management, Notes update outside the approved exact-note append/replace/move-to-folder gates, Notes delete outside the approved exact-note delete gate, Notes move outside the approved exact-note/exact-folder move-to-folder gate, Notes folder/account targeting outside exact note create, exact child-folder create, exact-folder rename, exact empty child-folder delete, exact empty child-folder move, and move-to-folder gates, Notes root/recursive folder delete, root/non-empty/recursive/cross-account folder move, root/default-account folder creation, Notes rich-text mutation outside approved `create_html`/`replace_html` gates or attachment mutation, Notes broad attachment export, locked/shared-note mutation, Recently Deleted management, Photos permanent delete/Recently Deleted empty, smart/shared/synced album targeting, bulk album membership, content edits, or metadata mutation outside exact favorite/hidden update, exact asset delete, exact regular-album membership add/remove, and exact regular-album create/rename/delete with full Photos Library authorization, Photos network iCloud fetch, Messages direct-recipient send/new-chat/SMS-fallback selection/edit/delete/reaction/tapback/other mutation outside the approved exact-chat send-text/send-file gates, broad Messages attachment export, Messages attachment mutation outside the approved exact-chat send-file gate, Voice Memos mutation or attachments, Safari history/open-tabs/passwords/private-browsing data/bookmark mutation, Shortcuts runs outside the approved exact-handle plan/apply gate, Shortcuts open/view/sign/export/body/action-graph/import/create/update/delete/duplicate mutation, Books book/chapter/PDF/EPUB text extraction, broad annotation dumps/search, raw Books paths/identifiers, or mutation, Podcasts transcript/audio/feed/enclosure URL extraction, broad episode-description dumps/search, raw Podcasts identifiers/paths, iCloud media fetch, Podcasts.app automation, or mutation, Music audio/lyrics/file-path export, play history, ratings/favorites, broad playlist track dumps, playback/queue control, library import/delete, raw Music database parsing, Music.app mutation, TV video/file-path/artwork/description export, playback or watched state, ratings/favorites, broad playlist item dumps, playback/queue control, library import/delete, raw TV library parsing, TV.app mutation, iCloud media fetch, Reminders bulk/account management and sharing/cross-source list management, non-empty list delete outside the bounded same-source migrate-delete gate, and list management outside exact same-source list-move plus exact list create/rename/empty-delete/same-source migrate-delete, attachments, URL mutation outside the exact URL update/clear gate, raw URL return, rich-content mutation, or delete outside the approved exact-handle gate, Reminders title/notes/priority/URL mutation outside the approved exact-handle update gates, Reminders list move outside the approved exact reminder plus exact same-source target-list gate, and Reminders list create/rename/delete outside the exact source/target handle, empty-delete, and bounded same-source migrate-delete gates, iCloud Drive content replacement outside the exact replace-text or replace-file gates, iCloud Drive folder creation outside the exact create-folder or bounded create-folder-path gates, iCloud Drive folder rename outside the exact folder rename gate, iCloud Drive folder move outside the exact folder move gate, iCloud Drive folder copy outside the exact selected-folder copy gate, iCloud Drive folder delete outside the exact selected-folder delete gate, iCloud Drive trash/delete outside the exact trash-text, exact folder trash, exact regular-file trash, or exact delete-file gates, iCloud Drive rename/copy/move outside the exact text-file or regular-file gates, iCloud Drive file permanent delete outside the exact delete-text or delete-file gates, unbounded-recursive-delete/unbounded-folder-copy/binary/document content generation or editing, regular-file mutation outside exact import-file, exact replace-file, exact trash-file, exact delete-file, or metadata-only rename/copy/move gates, authoritative Hide My Email inventory, Hide My Email creation/deactivation/deletion, private iCloud web/API access, browser/keychain credential access, generated Voice Memos transcription, unbounded broad content search, broad Messages text search, broad Voice Memos transcript search, unsupported/binary iCloud Drive content extraction, and durable content caches outside the approved opt-in private Mail FTS index
The exact-handle Mail content retrieval gate is summarized in the safety model and capability matrix.
The public capability matrix is documented in `docs/CAPABILITY_MATRIX.md`.
The write/mutation approval gates are documented in `docs/MUTATION_GATES.md`.
The future write-tool roadmap is documented in `docs/WRITE_TOOL_ROADMAP.md`.
The first Reminders write design gate is documented in `docs/V1_11_REMINDERS_WRITE_DESIGN.md`.
The Reminders exact same-source list-move write design gate is documented in `docs/V1_65_REMINDERS_LIST_MOVE_WRITE_DESIGN.md`.
The Reminders exact URL update/clear write design gate is documented in `docs/V1_136_REMINDERS_URL_WRITE_DESIGN.md`.
The Reminders exact absolute display-alarm set/clear write design gate is documented in `docs/V1_137_REMINDERS_ABSOLUTE_DISPLAY_ALARM_WRITE_DESIGN.md`.
The Reminders exact relative display-alarm set and broadened pure display-alarm clear write design gate is documented in `docs/V1_138_REMINDERS_RELATIVE_DISPLAY_ALARM_WRITE_DESIGN.md`.
The Reminders exact mixed absolute-plus-relative display-alarm set/clear write design gate is documented in `docs/V1_176_REMINDERS_MIXED_DISPLAY_ALARM_WRITE_DESIGN.md`.
The first iCloud Drive write design gate is documented in `docs/V1_12_ICLOUD_DRIVE_WRITE_DESIGN.md`.
The first Calendar write design gate is documented in `docs/V1_13_CALENDAR_WRITE_DESIGN.md`.
The Calendar simple recurrence create write design gate is documented in `docs/V1_89_CALENDAR_RECURRENCE_WRITE_DESIGN.md`.
The Calendar explicit default-calendar create planning gate is documented in `docs/V1_91_CALENDAR_DEFAULT_CALENDAR_CREATE_WRITE_DESIGN.md`.
The Calendar exact availability create/update gate is documented in `docs/V1_92_CALENDAR_AVAILABILITY_WRITE_DESIGN.md`.
The Calendar add-to-non-recurring-event recurrence update gate is documented in `docs/V1_93_CALENDAR_RECURRENCE_UPDATE_WRITE_DESIGN.md`.
The Calendar selected recurring occurrence delete gate is documented in `docs/V1_96_CALENDAR_RECURRING_OCCURRENCE_DELETE_WRITE_DESIGN.md`; the future-event recurring span delete gate is documented in `docs/V1_97_CALENDAR_RECURRING_FUTURE_DELETE_WRITE_DESIGN.md`; the whole-series recurring-event delete gate is documented in `docs/V1_98_CALENDAR_RECURRING_SERIES_DELETE_WRITE_DESIGN.md`; the weekly weekday recurrence gate is documented in `docs/V1_99_CALENDAR_WEEKLY_WEEKDAY_RECURRENCE_WRITE_DESIGN.md`; the first-visible and mid-series recurrence clearing gate is documented in `docs/V1_100_CALENDAR_RECURRENCE_CLEAR_WRITE_DESIGN.md`; the monthly day-of-month recurrence gate is documented in `docs/V1_101_CALENDAR_MONTHDAY_RECURRENCE_WRITE_DESIGN.md`; the structured event location gate is documented in `docs/V1_102_CALENDAR_STRUCTURED_LOCATION_WRITE_DESIGN.md`; selected recurring occurrence scalar update through all-day set/clear/date-only reschedule is documented in `docs/V1_114_CALENDAR_SELECTED_OCCURRENCE_UPDATE_WRITE_DESIGN.md`, `docs/V1_115_CALENDAR_SELECTED_OCCURRENCE_RESCHEDULE_WRITE_DESIGN.md`, `docs/V1_116_CALENDAR_SELECTED_OCCURRENCE_AVAILABILITY_WRITE_DESIGN.md`, `docs/V1_117_CALENDAR_SELECTED_OCCURRENCE_EVENT_URL_WRITE_DESIGN.md`, `docs/V1_118_CALENDAR_SELECTED_OCCURRENCE_STRUCTURED_LOCATION_WRITE_DESIGN.md`, `docs/V1_119_CALENDAR_SELECTED_OCCURRENCE_DISPLAY_ALARM_WRITE_DESIGN.md`, `docs/V1_120_CALENDAR_SELECTED_OCCURRENCE_ACTION_ALARM_WRITE_DESIGN.md`, and `docs/V1_121_CALENDAR_SELECTED_OCCURRENCE_ALL_DAY_WRITE_DESIGN.md`. The Calendar mid-series recurrence replacement gate is documented in `docs/V1_126_CALENDAR_RECURRENCE_REPLACEMENT_WRITE_DESIGN.md`; the future-series recurring-event title/plain-location/notes update gate is documented in `docs/V1_167_CALENDAR_FUTURE_SERIES_SCALAR_UPDATE_WRITE_DESIGN.md`; the future-series recurring-event timed reschedule gate is documented in `docs/V1_168_CALENDAR_FUTURE_SERIES_RESCHEDULE_WRITE_DESIGN.md`; the future-series recurring-event availability update gate is documented in `docs/V1_169_CALENDAR_FUTURE_SERIES_AVAILABILITY_WRITE_DESIGN.md`; the future-series recurring-event event URL set/clear gate is documented in `docs/V1_170_CALENDAR_FUTURE_SERIES_EVENT_URL_WRITE_DESIGN.md`; the future-series recurring-event structured-location set/clear gate is documented in `docs/V1_171_CALENDAR_FUTURE_SERIES_STRUCTURED_LOCATION_WRITE_DESIGN.md`; the future-series recurring-event display-alarm set/clear gate is documented in `docs/V1_172_CALENDAR_FUTURE_SERIES_DISPLAY_ALARM_WRITE_DESIGN.md`; the future-series recurring-event action-alarm set/clear gate is documented in `docs/V1_173_CALENDAR_FUTURE_SERIES_ACTION_ALARM_WRITE_DESIGN.md`; the future-series recurring-event all-day set/clear/date-only reschedule gate is documented in `docs/V1_174_CALENDAR_FUTURE_SERIES_ALL_DAY_WRITE_DESIGN.md`.
The Calendar selector-backed set-position recurrence gate is documented in `docs/V1_123_CALENDAR_SET_POSITIONS_RECURRENCE_WRITE_DESIGN.md`.
The Calendar synthetic calendar management gate is documented in `docs/V1_124_CALENDAR_CALENDAR_MANAGEMENT_WRITE_DESIGN.md`.
The first Contacts write design gate is documented in `docs/V1_14_CONTACTS_WRITE_DESIGN.md`.
The Contacts exact scalar update write design gate is documented in `docs/V1_48_CONTACTS_UPDATE_WRITE_DESIGN.md`; the Contacts exact email/phone/URL method-array replacement gate is documented in `docs/V1_69_CONTACTS_METHOD_UPDATE_WRITE_DESIGN.md`.
The Contacts exact delete write design gate is documented in `docs/V1_49_CONTACTS_DELETE_WRITE_DESIGN.md`.
The first Notes write design gate is documented in `docs/V1_15_NOTES_WRITE_DESIGN.md`.
The Notes exact-folder create write design gate is documented in `docs/V1_39_NOTES_FOLDER_CREATE_WRITE_DESIGN.md`.
The Notes exact child-folder create write design gate is documented in `docs/V1_57_NOTES_FOLDER_CREATE_WRITE_DESIGN.md`.
The Notes exact-folder rename write design gate is documented in `docs/V1_58_NOTES_FOLDER_RENAME_WRITE_DESIGN.md`.
The Notes exact empty child-folder delete write design gate is documented in `docs/V1_59_NOTES_FOLDER_DELETE_WRITE_DESIGN.md`.
The Notes exact empty child-folder move write design gate is documented in `docs/V1_158_NOTES_FOLDER_MOVE_WRITE_DESIGN.md`.
The Notes exact-delete write design gate is documented in `docs/V1_42_NOTES_DELETE_WRITE_DESIGN.md`.
The first Mail draft write design gate is documented in `docs/V1_16_MAIL_DRAFT_WRITE_DESIGN.md`; optional exact sender selection for Mail create-draft is documented in `docs/V1_74_MAIL_SENDER_DRAFT_WRITE_DESIGN.md`; exact sender selection for Mail send/reply/reply-all/forward is documented in `docs/V1_82_MAIL_OUTBOUND_SENDER_SELECTION_WRITE_DESIGN.md`; optional local file attachments for Mail create-draft are documented in `docs/V1_75_MAIL_DRAFT_ATTACHMENT_WRITE_DESIGN.md`.
The Mail send-message write design gate is documented in `docs/V1_43_MAIL_SEND_WRITE_DESIGN.md`.
The Mail reply-message write design gate is documented in `docs/V1_44_MAIL_REPLY_WRITE_DESIGN.md`.
The Mail reply-all-message write design gate is documented in `docs/V1_73_MAIL_REPLY_ALL_WRITE_DESIGN.md`.
The Mail forward-message write design gate is documented in `docs/V1_50_MAIL_FORWARD_WRITE_DESIGN.md`.
The Mail exact-message target-mailbox move write design gate is documented in `docs/V1_46_MAIL_MOVE_WRITE_DESIGN.md`; the cross-account exact target extension is documented in `docs/V1_66_MAIL_CROSS_ACCOUNT_MOVE_WRITE_DESIGN.md`.
The Mail synthetic `LAD-TEST-*` mailbox management and synthetic-only cleanup design gate is documented in `docs/V1_84_MAIL_SYNTHETIC_MAILBOX_CLEANUP_WRITE_DESIGN.md`.
The first Photos import write design gate is documented in `docs/V1_17_PHOTOS_IMPORT_WRITE_DESIGN.md`; exact favorite/hidden update is documented in `docs/V1_134_PHOTOS_UPDATE_FLAGS_WRITE_DESIGN.md`; exact selected-asset delete is documented in `docs/V1_149_PHOTOS_DELETE_WRITE_DESIGN.md`; exact regular-album membership add/remove is documented in `docs/V1_151_PHOTOS_ALBUM_MEMBERSHIP_WRITE_DESIGN.md`; exact selected-album asset listing is documented in `docs/V1_152_PHOTOS_ALBUM_ASSET_LISTING.md`; exact regular-album create/rename/delete with full Photos Library authorization is documented in `docs/V1_154_PHOTOS_REGULAR_ALBUM_MANAGEMENT_WRITE_DESIGN.md`.
The Mail exact-message Trash write design gate is documented in `docs/V1_41_MAIL_TRASH_WRITE_DESIGN.md`.
The first iCloud Drive append-text write design gate is documented in `docs/V1_18_ICLOUD_DRIVE_APPEND_WRITE_DESIGN.md`.
The iCloud Drive replace-text write design gate is documented in `docs/V1_51_ICLOUD_DRIVE_REPLACE_WRITE_DESIGN.md`.
The iCloud Drive create-folder write design gate is documented in `docs/V1_52_ICLOUD_DRIVE_FOLDER_CREATE_WRITE_DESIGN.md`.
The iCloud Drive trash-text write design gate is documented in `docs/V1_53_ICLOUD_DRIVE_TRASH_WRITE_DESIGN.md`.
The iCloud Drive rename/copy/move text-file write design gate is documented in `docs/V1_54_ICLOUD_DRIVE_RENAME_COPY_MOVE_WRITE_DESIGN.md`.
The iCloud Drive exact folder Trash write design gate is documented in `docs/V1_61_ICLOUD_DRIVE_FOLDER_TRASH_WRITE_DESIGN.md`; non-empty folder broadening is documented in `docs/V1_146_ICLOUD_DRIVE_NON_EMPTY_FOLDER_TRASH_WRITE_DESIGN.md`.
The iCloud Drive exact folder move write design gate is documented in `docs/V1_62_ICLOUD_DRIVE_FOLDER_MOVE_WRITE_DESIGN.md`; non-empty folder rename/move broadening is documented in `docs/V1_145_ICLOUD_DRIVE_NON_EMPTY_FOLDER_RENAME_MOVE_WRITE_DESIGN.md`.
The iCloud Drive exact folder copy write design gate is documented in `docs/V1_63_ICLOUD_DRIVE_FOLDER_COPY_WRITE_DESIGN.md` and broadened for bounded non-empty selected-folder trees in `docs/V1_147_ICLOUD_DRIVE_NON_EMPTY_FOLDER_COPY_WRITE_DESIGN.md`.
The iCloud Drive exact selected-folder permanent delete write design gate is documented in `docs/V1_67_ICLOUD_DRIVE_FOLDER_DELETE_WRITE_DESIGN.md`.
The iCloud Drive exact text-file permanent delete write design gate is documented in `docs/V1_68_ICLOUD_DRIVE_DELETE_TEXT_WRITE_DESIGN.md`.
The iCloud Drive exact regular-file export read design gate is documented in `docs/V1_85_ICLOUD_DRIVE_FILE_EXPORT.md`.
The first Notes append-text write design gate is documented in `docs/V1_19_NOTES_APPEND_WRITE_DESIGN.md`.
The first Notes attachment export design gate is documented in `docs/V1_20_NOTES_ATTACHMENT_EXPORT.md`.
The first Mail attachment export design gate is documented in `docs/V1_21_MAIL_ATTACHMENT_EXPORT.md`.
The first Messages attachment export design gate is documented in `docs/V1_22_MESSAGES_ATTACHMENT_EXPORT.md`.
The Messages attributed-body fallback design gate is documented in `docs/V1_23_MESSAGES_ATTRIBUTED_BODY.md`.
The Messages participant metadata read gate is documented in `docs/V1_64_MESSAGES_PARTICIPANTS_METADATA.md`.
The first Messages send-text write design gate is documented in `docs/V1_24_MESSAGES_SEND_TEXT_WRITE_DESIGN.md`.
The first Messages send-file write design gate is documented in `docs/V1_38_MESSAGES_SEND_FILE_WRITE_DESIGN.md`.
The Messages risky-mutation source-review blocker gate and public SDEF audit are documented in `docs/V1_47_MESSAGES_RISKY_MUTATION_SOURCE_REVIEW.md`.
The Safari bookmarks and Reading List read gate is documented in `docs/V1_25_SAFARI_BOOKMARKS.md`.
The Shortcuts metadata/selected-folder shortcut metadata read gate is documented in `docs/V1_26_SHORTCUTS_METADATA.md`.
The Apple Books metadata and selected annotations read gate is documented in `docs/V1_27_BOOKS_METADATA.md`.
The Apple Podcasts metadata read gate is documented in `docs/V1_28_PODCASTS_METADATA.md`.
The Apple Music metadata read gate is documented in `docs/V1_29_MUSIC_METADATA.md`.
The Apple TV metadata read gate is documented in `docs/V1_30_TV_METADATA.md`.
The publication checklist is documented in `docs/PUBLISHING.md`.
The public install guide is documented in `docs/INSTALL.md`.
Synthetic sample outputs are documented in `docs/SAMPLE_OUTPUTS.md`.
macOS support notes are documented in `docs/MACOS_SUPPORT.md`.
Security reporting is documented in `SECURITY.md`.
Contribution rules are documented in `CONTRIBUTING.md`.
Release notes are documented in `CHANGELOG.md`.
Public release file boundaries are documented in `docs/PUBLIC_RELEASE_MANIFEST.md`.
## Quick Checks
```bash
uv run pytest
uv run python -m compileall src tests scripts
uv run python scripts/redaction_scan.py .
uv run python scripts/public_release_scan.py
uv run python scripts/audit_mutation_gates.py
uv run python scripts/audit_write_design_gates.py
uv run python scripts/audit_messages_public_surface.py --json
uv run python scripts/audit_surface_contract.py
uv run python scripts/audit_release_readiness.py --json
uv run python scripts/generate_release_receipt.py --json
uv run python scripts/render_mcp_client_config.py --client claude-code
uv run python scripts/render_mcp_client_config.py --client cursor
uv run python scripts/render_mcp_client_config.py --client openclaw --server-only --compact
uv run python scripts/build_public_release_tree.py --dest /tmp/local-apple-data-public --force
uv run python scripts/prepare_public_git_checkout.py --dest /tmp/local-apple-data-public-git --force --init-git --commit
uv run python scripts/verify_runtime.py
uv run local-apple-data health --json
uv run local-apple-data mail search --json --query '<subject text>'
uv run local-apple-data mail content --json --handle '<mail:message:v2:...>' --max-chars 4000
uv run local-apple-data mail attachments --json --handle '<mail:message:v2:...>'
uv run local-apple-data mail export-attachment --json --message-handle '<mail:message:v2:...>' --handle '<mail:attachment:v1:...>' --output-dir /tmp/local-apple-data-exports
uv run local-apple-data messages search --json --query '<chat display name text>'
uv run local-apple-data messages get --json --handle '<messages:chat:v1:...>' --max-messages 25 --max-chars 4000
uv run local-apple-data messages participants --json --handle '<messages:chat:v1:...>'
uv run local-apple-data messages participant --json --chat-handle '<messages:chat:v1:...>' --handle '<messages:participant:v1:...>'
uv run local-apple-data messages attachments --json --handle '<messages:chat:v1:...>'
uv run local-apple-data messages export-attachment --json --chat-handle '<messages:chat:v1:...>' --handle '<messages:attachment:v1:...>' --output-dir /tmp/local-apple-data-exports
uv run local-apple-data hide-my-email search --json --query '<specific alias substring>'
uv run local-apple-data hide-my-email get --json --handle '<hide_my_email:alias:v1:...>'
uv run local-apple-data voice-memos search --json --query '<recording title text>'
uv run local-apple-data voice-memos get --json --handle '<voice_memos:recording:v1:...>' --max-chars 4000
uv run local-apple-data voice-memos export --json --handle '<voice_memos:recording:v1:...>' --output-dir /tmp/local-apple-data-exports
uv run local-apple-data safari search --json --query '<bookmark title or URL text>'
uv run local-apple-data safari get --json --handle '<safari:item:v1:...>'
uv run local-apple-data shortcuts search --json --query '<shortcut or folder name text>'
uv run local-apple-data shortcuts get --json --handle '<shortcuts:item:v1:...>'
uv run local-apple-data shortcuts folder-items --json --handle '<shortcuts:item:v1:...>' --limit 5
uv run local-apple-data books search --json --query '<book title or author text>'
uv run local-apple-data books get --json --handle '<books:book:v1:...>'
uv run local-apple-data books annotations --json --handle '<books:book:v1:...>' --max-chars 4000
uv run local-apple-data podcasts search --json --query '<podcast show title or author text>'
uv run local-apple-data podcasts get --json --handle '<podcasts:show:v1:...>'
uv run local-apple-data podcasts episodes --json --handle '<podcasts:show:v1:...>'
uv run local-apple-data podcasts episode --json --handle '<podcasts:episode:v1:...>' --max-chars 4000
uv run local-apple-data music search --json --query '<track title or artist text>'
uv run local-apple-data music get --json --handle '<music:track:v1:...>'
uv run local-apple-data music playlists --json --query '<playlist name text>'
uv run local-apple-data music playlist --json --handle '<music:playlist:v1:...>'
uv run local-apple-data music playlist-tracks --json --handle '<music:playlist:v1:...>'
uv run local-apple-data tv search --json --query '<item title or show text>'
uv run local-apple-data tv get --json --handle '<tv:item:v1:...>'
uv run local-apple-data tv playlists --json --query '<playlist name text>'
uv run local-apple-data tv playlist --json --handle '<tv:playlist:v1:...>'
uv run local-apple-data tv playlist-items --json --handle '<tv:playlist:v1:...>'
uv run local-apple-data freeform boards --json --limit 5
uv run local-apple-data freeform get --json --handle '<freeform:board:v1:...>'
uv run local-apple-data freeform folders --json --query '<folder title text>' --limit 5
uv run local-apple-data freeform folder --json --handle '<freeform:folder:v1:...>'
uv run local-apple-data freeform folder-boards --json --handle '<freeform:folder:v1:...>'
uv run local-apple-data freeform child-folders --json --handle '<freeform:folder:v1:...>'
uv run local-apple-data notes search --json --query '<title or snippet text>'
uv run local-apple-data notes folders --json --query '<folder title text>'
uv run local-apple-data notes folder --json --handle '<notes:folder:v1:...>'
uv run local-apple-data notes folder-items --json --handle '<notes:folder:v1:...>' --limit 5
uv run local-apple-data notes folder-tree --json --handle '<notes:folder:v1:...>' --depth 2 --limit 10
uv run local-apple-data notes content --json --handle '<notes:note:v2:...>' --max-chars 4000 --offset 0
uv run local-apple-data notes content --json --handle '<notes:note:v2:...>' --content-format html
uv run local-apple-data notes attachments --json --handle '<notes:note:v2:...>'
uv run local-apple-data notes export-attachment --json --handle '<notes:attachment:v1:...>' --output-dir /tmp/local-apple-data-exports
uv run local-apple-data notes plan --json --operation create --title '<note title>' --body-text '<plain text>'
uv run local-apple-data notes apply --json --operation create --title '<note title>' --body-text '<plain text>' --approval-token '<notes-apply:v1:...>' --confirm-apply
uv run local-apple-data notes plan --json --operation create --title '<note title>' --folder-handle '<notes:folder:v1:...>' --body-text '<plain text>'
uv run local-apple-data notes apply --json --operation create --title '<note title>' --folder-handle '<notes:folder:v1:...>' --body-text '<plain text>' --approval-token '<notes-apply:v1:...>' --confirm-apply
uv run local-apple-data notes plan --json --operation create-html --title '<note title>' --body-html '<h1>title</h1><p>rich body</p>'
uv run local-apple-data notes apply --json --operation create-html --title '<note title>' --body-html '<h1>title</h1><p>rich body</p>' --approval-token '<notes-apply:v1:...>' --confirm-apply
uv run local-apple-data notes plan --json --operation replace-html --handle '<notes:note:v2:...>' --expected-current-sha256 '<extracted-text-sha256-from-content>' --body-html '<h1>title</h1><p>replaced rich body</p>'
uv run local-apple-data notes apply --json --operation replace-html --handle '<notes:note:v2:...>' --expected-current-sha256 '<extracted-text-sha256-from-content>' --body-html '<h1>title</h1><p>replaced rich body</p>' --approval-token '<notes-apply:v1:...>' --confirm-apply
uv run local-apple-data notes plan --json --operation append-text --handle '<notes:note:v2:...>' --expected-current-sha256 '<sha256-from-content>' --body-text '<text>'
uv run local-apple-data notes apply --json --operation append-text --handle '<notes:note:v2:...>' --expected-current-sha256 '<sha256-from-content>' --body-text '<text>' --approval-token '<notes-apply:v1:...>' --confirm-apply
uv run local-apple-data notes plan --json --operation delete --handle '<notes:note:v2:...>' --expected-current-sha256 '<sha256-from-content>'
uv run local-apple-data notes apply --json --operation delete --handle '<notes:note:v2:...>' --expected-current-sha256 '<sha256-from-content>' --approval-token '<notes-apply:v1:...>' --confirm-apply
uv run local-apple-data icloud-drive search --json --query '<filename text>'
uv run local-apple-data icloud-drive root --json
uv run local-apple-data icloud-drive content --json --handle '<icloud:file:v1:...>' --max-chars 4000
uv run local-apple-data icloud-drive export --json --handle '<icloud:file:v1:...>' --output-dir /tmp/local-apple-data-exports
uv run local-apple-data icloud-drive plan --json --operation create-folder --parent-handle '<icloud:file:v1:...>' --folder-name '<folder-name>'
uv run local-apple-data icloud-drive apply --json --operation create-folder --parent-handle '<icloud:file:v1:...>' --folder-name '<folder-name>' --approval-token '<icloud-drive-apply:v1:...>' --confirm-apply
uv run local-apple-data icloud-drive plan --json --operation create-folder-path --parent-handle '<icloud:file:v1:...>' --folder-component '<folder-name>' --folder-component '<child-folder-name>'
uv run local-apple-data icloud-drive apply --json --operation create-folder-path --parent-handle '<icloud:file:v1:...>' --folder-component '<folder-name>' --folder-component '<child-folder-name>' --approval-token '<icloud-drive-apply:v1:...>' --confirm-apply
uv run local-apple-data icloud-drive plan --json --operation rename-folder --handle '<icloud:file:v1:...>' --expected-current-sha256 '<metadata-sha256-from-folder-metadata>' --folder-name '<new-folder-name>'
uv run local-apple-data icloud-drive apply --json --operation rename-folder --handle '<icloud:file:v1:...>' --expected-current-sha256 '<metadata-sha256-from-folder-metadata>' --folder-name '<new-folder-name>' --approval-token '<icloud-drive-apply:v1:...>' --confirm-apply
uv run local-apple-data icloud-drive plan --json --operation create-text --parent-handle '<icloud:file:v1:...>' --filename '<new-file.md>' --content-text '<text>'
uv run local-apple-data icloud-drive apply --json --operation create-text --parent-handle '<icloud:file:v1:...>' --filename '<new-file.md>' --content-text '<text>' --approval-token '<icloud-drive-apply:v1:...>' --confirm-apply
uv run local-apple-data icloud-drive plan --json --operation append-text --handle '<icloud:file:v1:...>' --expected-current-sha256 '<sha256-from-content>' --content-text '<text>'
uv run local-apple-data icloud-drive apply --json --operation append-text --handle '<icloud:file:v1:...>' --expected-current-sha256 '<sha256-from-content>' --content-text '<text>' --approval-token '<icloud-drive-apply:v1:...>' --confirm-apply
uv run local-apple-data icloud-drive plan --json --operation replace-text --handle '<icloud:file:v1:...>' --expected-current-sha256 '<sha256-from-content>' --content-text '<text>'
uv run local-apple-data icloud-drive apply --json --operation replace-text --handle '<icloud:file:v1:...>' --expected-current-sha256 '<sha256-from-content>' --content-text '<text>' --approval-token '<icloud-drive-apply:v1:...>' --confirm-apply
uv run local-apple-data icloud-drive plan --json --operation rename-text --handle '<icloud:file:v1:...>' --expected-current-sha256 '<sha256-from-content>' --filename '<new-name.md>'
uv run local-apple-data icloud-drive apply --json --operation rename-text --handle '<icloud:file:v1:...>' --expected-current-sha256 '<sha256-from-content>' --filename '<new-name.md>' --approval-token '<icloud-drive-apply:v1:...>' --confirm-apply
uv run local-apple-data icloud-drive plan --json --operation copy-text --handle '<icloud:file:v1:...>' --expected-current-sha256 '<sha256-from-content>' --filename '<copy-name.md>'
uv run local-apple-data icloud-drive apply --json --operation copy-text --handle '<icloud:file:v1:...>' --expected-current-sha256 '<sha256-from-content>' --filename '<copy-name.md>' --approval-token '<icloud-drive-apply:v1:...>' --confirm-apply
uv run local-apple-data icloud-drive plan --json --operation move-text --handle '<icloud:file:v1:...>' --parent-handle '<icloud:file:v1:...>' --expected-current-sha256 '<sha256-from-content>'
uv run local-apple-data icloud-drive apply --json --operation move-text --handle '<icloud:file:v1:...>' --parent-handle '<icloud:file:v1:...>' --expected-current-sha256 '<sha256-from-content>' --approval-token '<icloud-drive-apply:v1:...>' --confirm-apply
uv run local-apple-data calendar search --json --query '<event title text>'
uv run local-apple-data calendar get --json --handle '<calendar:event:v1:...>' --max-chars 4000
uv run local-apple-data calendar request-access --json
uv run local-apple-data calendar calendars --json --query '<calendar title text>' --include-default
uv run local-apple-data calendar calendar --json --handle '<calendar:calendar:v1:...>'
uv run local-apple-data calendar plan --json --operation create --title '<event title>' --calendar-title '<target calendar>' --start-date '<ISO timestamp>' --end-date '<ISO timestamp>'
uv run local-apple-data calendar plan --json --operation create --title '<event title>' --calendar-handle '<calendar:calendar:v1:...>' --start-date '<ISO timestamp>' --end-date '<ISO timestamp>'
uv run local-apple-data calendar plan --json --operation create --title '<event title>' --use-default-calendar --start-date '<ISO timestamp>' --end-date '<ISO timestamp>'
uv run local-apple-data calendar plan --json --operation create --title '<event title>' --calendar-handle '<calendar:calendar:v1:...>' --start-date '<ISO timestamp>' --end-date '<ISO timestamp>' --recurrence-frequency weekly --recurrence-count 6 --recurrence-interval 1
uv run local-apple-data calendar apply --json --operation create --title '<event title>' --calendar-title '<target calendar>' --start-date '<ISO timestamp>' --end-date '<ISO timestamp>' --approval-token '<calendar-apply:v1:...>' --confirm-apply
uv run local-apple-data calendar apply --json --operation update --handle '<calendar:event:v1:...>' --target-calendar-handle '<calendar:calendar:v1:...>' --expected-title '<current title>' --expected-calendar-title '<current calendar>' --expected-start-date '<ISO timestamp>' --expected-end-date '<ISO timestamp>' --expected-time-zone '<IANA time zone>' --title '<new title>' --start-date '<ISO timestamp>' --end-date '<ISO timestamp>' --time-zone '<IANA time zone>' --approval-token '<calendar-apply:v1:...>' --confirm-apply
uv run local-apple-data calendar plan --json --operation delete --handle '<calendar:event:v1:...>' --expected-title '<current title>' --expected-calendar-title '<current calendar>' --expected-start-date '<ISO timestamp>' --expected-end-date '<ISO timestamp>' --expected-location '<current location>' --expected-notes '<current notes>'
uv run local-apple-data calendar apply --json --operation delete --handle '<calendar:event:v1:...>' --expected-title '<current title>' --expected-calendar-title '<current calendar>' --expected-start-date '<ISO timestamp>' --expected-end-date '<ISO timestamp>' --expected-location '<current location>' --expected-notes '<current notes>' --approval-token '<calendar-apply:v1:...>' --confirm-apply
uv run local-apple-data calendar plan-calendar --json --operation create-calendar --source-calendar-handle '<calendar:calendar:v1:...>' --calendar-title 'LAD-TEST-<name>'
uv run local-apple-data calendar apply-calendar --json --operation create-calendar --source-calendar-handle '<calendar:calendar:v1:...>' --calendar-title 'LAD-TEST-<name>' --approval-token '<calendar-apply:v1:...>' --confirm-apply
uv run local-apple-data contacts search --json --query '<name or organization text>'
uv run local-apple-data contacts get --json --handle '<contacts:contact:v1:...>'
uv run local-apple-data contacts plan --json --operation create --contact-type person --given-name '<given>' --family-name '<family>' --email 'work=<email>'
uv run local-apple-data contacts apply --json --operation create --contact-type person --given-name '<given>' --family-name '<family>' --email 'work=<email>' --approval-token '<contacts-apply:v1:...>' --confirm-apply
uv run local-apple-data photos search --json --query '<original filename text>'
uv run local-apple-data photos request-access --json
uv run local-apple-data photos albums --json --query '<album title text>'
uv run local-apple-data photos album-assets --json --handle '<photos:album:v1:...>'
uv run local-apple-data photos get --json --handle '<photos:asset:v1:...>'
uv run local-apple-data photos export --json --handle '<photos:asset:v1:...>' --output-dir /tmp/local-apple-data-exports
uv run local-apple-data photos plan --json --operation import --source-file /path/to/local-image.jpg
uv run local-apple-data photos apply --json --operation import --source-file /path/to/local-image.jpg --approval-token '<photos-apply:v1:...>' --confirm-apply
uv run local-apple-data photos plan --json --operation update-flags --handle '<photos:asset:v1:...>' --favorite true --expected-favorite false --expected-hidden false
uv run local-apple-data photos apply --json --operation update-flags --handle '<photos:asset:v1:...>' --favorite true --expected-favorite false --expected-hidden false --approval-token '<photos-apply:v1:...>' --confirm-apply
uv run local-apple-data reminders due --json --days 14
uv run local-apple-data reminders eventkit-search --json --query '<reminder title text>'
uv run local-apple-data reminders request-access --json
uv run local-apple-data reminders lists --json
uv run local-apple-data reminders content --json --handle '<reminders:reminder:eventkit:v1:...>' --max-chars 4000
uv run local-apple-data reminders plan --json --operation create --title '<new reminder title>' --list-name '<target list name>' --due-date '<YYYY-MM-DD>'
uv run local-apple-data reminders apply --json --operation create --title '<new reminder title>' --list-name '<target list name>' --due-date '<YYYY-MM-DD>' --approval-token '<reminders-apply:v1:...>' --confirm-apply
uv run local-apple-data reminders plan-list --json --operation create-list --source-list-handle '<reminders:list:eventkit:v1:...>' --list-title 'Project New'
uv run local-apple-data reminders apply-list --json --operation create-list --source-list-handle '<reminders:list:eventkit:v1:...>' --list-title 'Project New' --approval-token '<reminders-apply:v1:...>' --confirm-apply
```
`scripts/audit_release_readiness.py` treats a dirty git worktree as a release
blocker. Commit or remove source changes before using a release receipt as a
clean handoff.
When writing a durable receipt file, use `/tmp` or another artifact directory
outside the source checkout. `scripts/generate_release_receipt.py --output`
rejects project-local paths so receipt generation cannot dirty a release
candidate.
Run the plugin and skill validator scripts too when those local validator helpers are installed in the current Codex skills cache.
The installed-plugin consistency check for a configured local operator setup is:
```bash
cd /absolute/path/to/local-apple-data && uv run python scripts/verify_cross_agent_sync.py
```
If a Cursor project or global MCP config should be treated as mandatory, verify it explicitly:
```bash
uv run python scripts/verify_cross_agent_sync.py --require-cursor
uv run python scripts/verify_cross_agent_sync.py --cursor-config .cursor/mcp.json --require-cursor
```
The health command reports redacted local readiness only. Search commands may print local metadata such as subjects, Messages chat display names, masked inferred Hide My Email alias previews, Voice Memo titles, Safari bookmark titles/domains, Shortcuts names, Books titles/authors/genres, Podcasts show titles/authors/categories/providers, Music track/artist/album/playlist names, TV item/show/artist/genre/playlist names, Freeform folder metadata and board counts, note titles/snippets, Notes folder titles, calendar event titles, contact names/organizations, Photos filenames, iCloud Drive filenames, and reminder titles, so run them only for an intentional user-requested workflow. The Mail, Messages, inferred Hide My Email, Voice Memos, Safari, Shortcuts, Books, Podcasts, Music, TV, Freeform, Notes, Calendar, Contacts, Photos, Reminders, and iCloud Drive content/detail/folder-list/tree/export commands may print bounded local text, exact selected alias or URL detail, Books selected-book annotations, Podcasts selected-episode descriptions, Music selected-track/playlist/selected-playlist track metadata, TV selected-item/playlist/selected-playlist item metadata, Freeform selected-board/folder/selected-folder board/child-folder metadata, Notes selected-folder direct note/child-folder metadata and bounded child-folder tree metadata, asset/resource metadata, or caller-selected export paths and should be run only with an exact handle selected from metadata output.
Search handles are opaque and are generated from a local secret under the plugin state directory. They are not reusable credentials and are not logged. Mail search results include a best-effort metadata-only `content_status` hint of `available`, `unavailable`, or `unknown`; the hint checks local content-file availability without reading message bodies. Mail body, attachment, and advanced discovery require date bounds, cap returned results/snippets, redact email addresses in snippets, return masked header metadata, and still require exact handles for full content or attachment export. Hide My Email results are inferred from local Mail address metadata and set `authoritative_inventory:false`; they are not an iCloud account inventory or management API. Safari item search returns titles and URL metadata such as domain/scheme/query presence, not full URLs; Safari folder search/listing returns folder and direct child metadata only by exact `safari:folder:v1:` handle. Shortcuts search returns shortcut/folder names; folder-items returns contained shortcut names plus opaque handles only, not raw identifiers or shortcut bodies. Books search returns title/author/genre metadata and annotation counts only, not annotation text, book text, raw identifiers, or local paths. Podcasts search returns show metadata only; episode descriptions require exact episode handles and transcripts, audio bytes, feed/enclosure URLs, raw identifiers, and local download paths are not returned. Music search returns track/artist/album/genre and playlist metadata only; exact selected playlist-track listing is capped, and audio bytes, lyrics, file paths, raw identifiers, play history, ratings, and broad playlist track dumps are not returned. TV search returns item/show/artist/genre and playlist metadata only; exact selected playlist-item listing is capped, and video bytes, file paths, artwork, descriptions, playback state, watched state, ratings, and broad playlist item dumps are not returned. Freeform board/folder retrieval and selected-folder listings reject raw board rows, raw folder rows, raw identifiers, board BLOBs, decoded content, and asset export. Photos album-assets returns capped child asset metadata only for one exact `photos:album:v1:` handle, without resources, bytes, thumbnails, paths, or raw PhotoKit identifiers. Notes folder search returns folder-title metadata and `notes:folder:v1:` handles only, not raw folder IDs or account identifiers. Notes folder-items returns capped direct child folder metadata plus direct note metadata only for one exact folder handle, not note bodies, snippets, raw folder IDs, or account identifiers. Notes folder-tree returns capped descendant folder metadata only for one exact folder handle, not notes, note bodies, snippets, attachment bytes, paths, raw folder IDs, or account identifiers. Mail, Messages, inferred Hide My Email, Voice Memos, Safari, Shortcuts, Books, Podcasts, Music, TV, Freeform, Notes, Calendar, Contacts, Photos, Reminders, and iCloud Drive retrieval reject raw row IDs, older handle formats, mailbox refs, direct paths, raw framework identifiers, raw Hide My Email identifiers, raw Safari folder identifiers, raw Shortcuts identifiers, raw Books identifiers, raw Podcasts identifiers, raw Music identifiers, raw TV identifiers, raw Freeform identifiers, raw Notes folder identifiers, and arbitrary inputs.
## Safety Model
See `docs/PRIVACY_MODEL.md`.
See also `docs/THREAT_MODEL.md` and `docs/TESTING.md`.
For the capability matrix, see `docs/CAPABILITY_MATRIX.md`.
For future write gates, see `docs/MUTATION_GATES.md`.
For the future write roadmap, see `docs/WRITE_TOOL_ROADMAP.md`.
For the first Reminders write design gate, see `docs/V1_11_REMINDERS_WRITE_DESIGN.md`.
For public release readiness, see `docs/PUBLISHING.md`.
For installation, see `docs/INSTALL.md`.
For synthetic examples, see `docs/SAMPLE_OUTPUTS.md`.
For macOS support, see `docs/MACOS_SUPPORT.md`.
For security reporting, see `SECURITY.md`.
For public release file boundaries, see `docs/PUBLIC_RELEASE_MANIFEST.md`.
For exact Mail content behavior, see `docs/PRIVACY_MODEL.md` and `docs/CAPABILITY_MATRIX.md`.
For public MCP client setup, see `docs/INSTALL.md` and `docs/CODEX_PLUGIN.md`.
## Codex Plugin
See `docs/CODEX_PLUGIN.md`.
## License
MIT. See `LICENSE`.
TDQS
Scored across 30 tools
Tools are grouped by domain with distinct operations (search, get, export). Each tool targets a specific resource and action, e.g., notes_get_content vs notes_get_metadata, or reminders_due vs reminders_search. Overlaps are minimal and clarified by descriptions.
Most tools follow a consistent <domain>_<verb>_<object> snake_case pattern. However, some deviations exist: 'reminders_due' lacks a verb, and 'reminders_eventkit_search' includes an extra specifier. Overall pattern is clear but not perfectly uniform.
30 tools cover many Apple data domains (calendar, contacts, mail, etc.). While each domain has a reasonable number (2-3 tools), the total count is high. It is justified for the broad scope but feels heavy.
For each domain, the set provides search, get metadata, and get content (or export). Diagnostics are included. Missing mutation/delete operations are intentional (read-only). Minor gaps include no bulk operations or filter criteria beyond title, but core workflows are covered.