Agent skill

Apple Notes

by sweetrb in sweetrb/apple-notes-mcp

A skill your agent uses when the user wants to interact with Apple Notes on macOS - creating, searching, reading, updating, deleting, organizing, or formatting notes and folders.

MITAuto-check: warningsAgent Workflows

Install Apple Notes

The automated check flagged lines worth reading first. See the safety section below.

skills CLI
$ npx skills add sweetrb/apple-notes-mcp --skill apple-notes -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install sweetrb/apple-notes-mcp apple-notes --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/sweetrb/apple-notes-mcp.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/apple-notes .claude/skills/apple-notes && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
apple-notes
GitHub stars
150
Token cost
~13k tokens
SKILL.md length
4,561 words
Files
1
Skills in repo
1
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when the user wants to interact with Apple Notes on macOS - creating, searching, reading, updating, deleting, organizing, or formatting notes and folders.

  • Works in 7 steps: Exact IDs for writes: Search may use… → Default Account: Operations default to… → Content Format: Notes store content as… → …
  • The user wants to interact with Apple Notes on macOS - creating
  • SKILL.md covers When to Use This Skill, Available Tools, Usage Patterns and Formatting Guidance, plus 6 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Apple Notes is an agent skill from sweetrb/apple-notes-mcp. Use this skill when the user wants to interact with Apple Notes on macOS - creating, searching, reading, updating, deleting, organizing, or formatting notes and folders. This skill provides access to Apple Notes through MCP tools and includes safe formatting guidance.

Its SKILL.md is about 13k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Agent Workflows, covering MCP servers. It works with macOS and Model Context Protocol. The repository describes itself as: MCP server for Apple Notes - read, search, create, edit, organize, and export notes on macOS via Claude and other AI assistants. The licence is MIT.

When your agent uses it

  • The user wants to interact with Apple Notes on macOS - creating
  • Formatting notes and folders

Example prompts

  • “/apple-notes”

Workflow steps

7 steps, taken from the first numbered list in SKILL.md.

  1. Exact IDs for writes: Search may use titles, but update, append, delete,
  2. Default Account: Operations default to iCloud. Use the account parameter for other accounts (Gmail, Exchange).
  3. Content Format: Notes store content as HTML. Use format="html" for structured content. Retrieved HTML is normalized by Notes and may not…
  4. Backslash Escaping: When content contains backslashes, escape them as \ in the JSON.
  5. Password-Protected Notes: Cannot be accessed via this skill. Inform the user if they try.
  6. Shared Notes: Use extra care before edits or deletes. Changes to shared notes are visible to collaborators.
  7. macOS Only: This skill only works on macOS systems.

What it can do on your machine

Read from SKILL.md and the folder at commit 3b04478. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Apple Notes loads about 13k tokens when it runs. Until then it costs about 70 tokens; SKILL.md has 4,561 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~70
When it runs · the whole SKILL.md, loaded when a task matches
~13k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: warnings

The automated check found patterns that need a careful read before installing.

  • WarningMentions a credentials file (SSH keys, cloud or package-manager tokens)SKILL.md:369
    hidden paths such as `~/.ssh` and anything in `~/Library` are refused, except

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from sweetrb/apple-notes-mcp at commit 3b04478, republished under its MIT licence (© sweetrb). 4,561 words, ~13,223 tokens.

Download SKILL.mdSave it as .claude/skills/apple-notes/SKILL.md (or your agent's skills folder).
name
apple-notes
description
Use this skill when the user wants to interact with Apple Notes on macOS - creating, searching, reading, updating, deleting, organizing, or formatting notes and folders. This skill provides access to Apple Notes through MCP tools and includes safe formatting guidance.

Apple Notes Skill

This skill enables you to manage Apple Notes on macOS through natural language. Use it whenever the user mentions notes, wants to save information to Notes, or needs to retrieve, update, or organize their notes.

When to Use This Skill

Use this skill when the user:

  • Wants to create a new note or save information
  • Asks to find, search, or look up notes
  • Wants to read the contents of a note
  • Needs to update or edit an existing note
  • Wants to delete or remove a note
  • Asks to move or organize notes into folders
  • Wants to list their notes or folders
  • Mentions Apple Notes, Notes app, or "my notes"

Available Tools

Note Operations
ToolPurpose
create-noteCreate a new note with title and content
search-notesFind notes by title or content
query-notesFind notes with a boolean expression over text, folders, tags, attachments, checklists, flags, word counts, and dates (reads the database; needs Full Disk Access)
get-note-contentRead the full content of a note
get-note-plaintextRead a note's body as plain text (no HTML)
get-note-markdownRead note content as Markdown
get-note-by-idGet note metadata by ID
get-note-detailsGet metadata (created, modified, account)
get-note-linkGet the shareable notes://showNote?identifier=… deep link for a note
update-noteReplace a note's whole body; refused when the note holds attachments, tables, checklists, or native tags, or formatting HTML cannot carry
append-to-noteAdd content to a note without replacing it (position: "after" / "before", which inserts below the title)
append-nativeAppend plaintext, the native HTML subset, or Markdown to a note that holds native objects, without replacing its body (needs scopeText)
insert-linkAdd one URL to a note as its raw text or as a labeled hyperlink, verified from the stored link
insert-note-linkAppend a real link to another note (by id) with a static label, verified after the write
delete-noteRemove a note (moves to Recently Deleted; refuses a note already there, where delete is permanent); like update-note, append-to-note, and move-note it accepts ifFolderId, ifAncestorFolderId, and forbiddenAncestorFolderIds folder preconditions. For copy-then-retire, pass guardNoteId and expectedGuardContentHash (the verified copy's contentHash) so the original is deleted only while the copy is intact; needs Full Disk Access
batch-delete-notesDelete multiple notes by ID (max 500 per call; refuses notes already in Recently Deleted)
move-noteMove a note to a different folder
batch-move-notesMove multiple notes by ID (max 500 per call)
list-notesList all notes or notes in a folder (excludes Recently Deleted unless includeRecentlyDeleted)
list-special-notesList pinned notes, Quick Notes, Recently Deleted, or locked notes (kind; metadata only, needs Full Disk Access)
set-note-pinnedPin or unpin one exact note (checks expectedPinned and expectedContentHash; never rewrites the body)
list-recent-notesChanges since a cursor, oldest first, for incremental sync: pass since, then keep calling with nextSince until saturated is false (needs Full Disk Access)
show-noteReveal a note in the Notes.app UI by ID
get-selected-notesRead the notes currently selected in Notes.app
export-notes-jsonExport notes as JSON one page at a time (offset/limit/modifiedSince); repeat with page.nextOffset while page.hasMore
export-notes-markdownExport one note or a folder as one Markdown document from the decoded body; optional create-only outputPath and assetsDir for attachment copies; template/templateFile render through a JSON Markdown template such as obsidian front matter (presentation format, not a backup)
export-notes-htmlExport one note or a folder as one standalone HTML file (semantic tables, attachments in body order); outputPath required and create-only; assets embedded (10 MiB each) or in a sidecar directory with embedAssets: false; vectorDrawings: true renders classic drawings as SVG through the public helper (default false keeps Notes' PNG; Paper keeps its PNG; failures fall back to PNG)
list-markdown-templatesList built-in and saved Markdown export templates
show-markdown-templateShow a template's JSON (portable form; expanded for every rule)
validate-markdown-templateCheck a template; returns every problem with a JSON path
save-markdown-templateSave a template to the library by slug name (create-only unless force)
delete-markdown-templateDelete a saved template (built-ins cannot be deleted)

To edit a template visually, the user can run apple-notes-mcp templates edit [name] in a terminal: a local, token-gated web editor with live validation and a preview on sample notes. It is a command-line tool, not an MCP tool, so suggest it rather than trying to start it.

Folder Operations
ToolPurpose
list-foldersList all folders in an account; with Full Disk Access, smart folders are marked smartFolder: true
list-smart-foldersList Smart Folders with their decoded rules; optionally the notes each one shows
get-folder-by-idRead one folder's name, parent, account, and isRoot before a guarded rename or delete
rename-folderRename one folder in place; requires its expected current name and parent
list-folder-treeFolder hierarchy with direct and cumulative note counts per account
create-folderCreate a new folder
delete-folderDelete an empty folder
delete-folder-by-idGuarded delete of one exact empty folder: dry run returns a revision, apply requires it
show-folderReveal a folder in the Notes.app UI by ID
Account Operations
ToolPurpose
list-accountsList configured accounts (iCloud, Gmail, etc.)
get-default-locationRead the default account and folder used for new notes
show-accountReveal an account in the Notes.app UI by ID
Native Tags
ToolPurpose
native-tags-statusCheck that the Native Tags Shortcut is installed before a tag write
list-native-tagsNative tags in one folder, or omit folder for an account-wide inventory with note counts
add-native-tagsAdd real, clickable tags to one exact note (needs expectedContentHash and a distinctive scopeText)
remove-native-tagsRemove named tags from one exact note, keeping its other tags
replace-native-tagSwap one tag for another across a list of freshly read notes; stops at the first uncertain result
Attachments, Checklists, Collaboration, and Diagnostics
ToolPurpose
list-attachmentsList attachments in a note; includePaths adds on-disk assetPaths/previewPath, firstImage returns the lead visual in body order
add-attachmentAttach one local file (home, temp or /Volumes; no hidden paths or ~/Library) to an exact note (filename renames it); a macOS 27 PDF "outcome uncertain": read the note first
create-note-with-attachmentCreate a note and attach one local file in one call; on a failed attach, reuse the named note id with add-attachment
add-attachment-from-pasteboardAttach the copied image, PDF, or one file to an exact note (note checked first, pasteboard frozen, never modified); pasteboard_access_denied: ask before allowPasteAlert: true
save-attachmentSave an attachment to disk
list-paper-attachmentsList Paper and classic drawings in a note, with Notes' rendered image size and any recognized handwriting text
export-paper-imageSave Notes' rendered PNG (or JPEG) of one drawing to a new file
analyze-svgRead-only SVG preflight: can a local SVG become editable strokes, which losses it needs, and a digest of the result
export-attachmentsCopy a note's attachment files (or only its lead visual) into a directory; exportedKind says asset, fallback, or preview
fetch-attachmentFetch attachment bytes as base64
show-attachmentReveal an attachment in the Notes.app UI
get-checklist-stateRead checked/unchecked state for existing checklists
create-checklist-itemAppend one unchecked native checklist item (needs the Background Operations bridge)
get-note-tablesRead a note's native tables as Markdown and JSON rows, in body order
create-tableAppend one native table from rectangular rows (omit rows for an empty 2 × 2 table); verified by reading the cells back
create-checklist-itemsAppend several unchecked native checklist items in order (needs the Background Operations bridge; on ok: false, only landed items are verified)
get-note-metadata[BETA] Read pinned/trash/snippet metadata from the NoteStore DB
get-note-drawingsDecode classic PencilKit drawings to strokes or SVG (needs apple-notes-mcp setup --public-helper once)
transcribe-note-audioTranscribe a note's voice recordings on-device (same helper; pass locale, and attachmentId for long recordings)
get-note-blocksRead a note's paragraph styles, inline formatting, and attachment positions as typed blocks
get-native-objectsRead a note's native object ids, checklist ids and state, native tags, and decoded tables, with the current revision
list-note-paragraphsList a note's paragraphs with style, stored paragraph ID, and a direct link when the ID is unique
get-paragraph-linkGet a link that opens Notes at one paragraph, refused when its ID is shared
create-paragraph-anchorRecord an anchor for one paragraph so it can be found again after edits or ID changes (local registry only)
resolve-paragraph-anchorFind an anchored paragraph again; url only when status is resolved, fails closed on ambiguity
list-paragraph-anchorsList recorded paragraph anchors, all or for one note
get-paragraph-anchorShow one stored paragraph anchor
prune-paragraph-anchorsRemove anchors that no longer resolve (dry run unless dryRun: false)
get-note-structureRead a note's links by kind, tags, attachments (as list-attachments reports them), counts, and view/lock/share/trash state in one call
list-note-linksList links (inline, card, note, section) in a note, folder (with subfolders), account, or the whole library
get-audio-transcriptsRead the transcripts and summaries Notes stored for a note's audio recordings
list-shared-notesList notes shared with collaborators
get-sync-statusCheck whether iCloud sync is active
health-checkQuickly verify Notes.app access
doctorRun detailed setup diagnostics, including the feature matrix
get-capabilitiesCheck native-write operations and the OS-aware feature matrix (features.<name>.available / reason) before calling a tool that depends on them
get-notes-statsSummarize note counts and recent activity
Private Helper (opt-in, read-only, unsupported Apple API)

Off unless the user built it (apple-notes-mcp setup --native-helper) and set APPLE_NOTES_MCP_ENABLE_PRIVATE=1. Call native-helper-status first; use native-note-state only when it reports the feature available. The helper is read-only: write support was deliberately deferred by the maintainer.

ToolPurpose
native-helper-statusReport opt-in, build, and live-probe state with a reason code (read-only)
native-note-stateRead a note's native state and revision change token (read-only)

Usage Patterns

Creating Notes

When the user wants to save information:

User: "Save this meeting summary as a note"
Action: Use create-note with an appropriate title and the content
User: "Create a shopping list note"
Action: Use create-note with title="Shopping List" and formatted content

For structured notes, pass format="html" and use simple Apple Notes-friendly HTML. The server automatically prepends the title as an <h1> in both plaintext and HTML modes, so do not include the same <h1> title in content when creating a note.

Finding Notes

When the user wants to find notes:

User: "Find my notes about the project"
Action: Use search-notes with query="project"
User: "Search for notes containing budget information"
Action: Use search-notes with query="budget" and searchContent=true

With Full Disk Access, a searchContent search reads the Notes database and returns quickly even for a common word; without it, a broad body search can time out, so narrow it with folder or modifiedSince.

When Full Disk Access is available, prefer query-notes for anything beyond a single keyword. It matches title or body in one call, runs in well under a second, and combines conditions:

User: "Which work notes still have open to-dos?"
Action: Use query-notes with query='folder:Work checklist:open'

User: "Find invoices or anything tagged finance since July"
Action: Use query-notes with query='(title:invoice OR tag:finance) modified:>=2026-07-01'

User: "Long notes with a PDF that aren't in Archive"
Action: Use query-notes with query='words:>250 has:pdf -folder:Archive'

Bare words and "quoted phrases" match title or body. Fields are title:, body:, text:, folder:, account:, and tag:; facets are has:link|attachment|checklist|drawing|image|video|audio|pdf|table|scan|url|map|tag (has:url is a link preview card, has:map a map); checklist:open|done; flags pinned, locked, shared, quicknote; and words:, created:, modified: take =, >, >=, <, <= with YYYY-MM-DD local dates. AND is implicit; use OR, NOT or a leading -, and parentheses. Quote an operator word ("and") to search it literally. It scans the 500 most recently modified notes unless scanLimit is raised (max 10000), and the response says when older notes were left out. Recently Deleted is excluded unless includeDeleted is true. Locked notes match on title and metadata only. The returned ids work with every id-based tool.

Both search tools can say where a note matched and how long it is. Results whose text came from the database carry matchedIn (title, body, or both); query-notes always has it for readable notes, and search-notes has it for a database body search. Pass includeWordCount: true to either tool for a wordCount per result (null for locked notes). On a search-notes title search it reads the bodies in one database query and adds matchedIn too, which answers "does this note also mention it in the body?" without opening each note.

User: "Which of my budget notes are long, and do they mention it in the body?"
Action: Use query-notes with query='budget' and includeWordCount=true
Reading Notes

When the user wants to see note contents:

User: "Show me my shopping list"
Action: Search by title if needed, then use get-note-content with the exact ID

For a note's tables, use get-note-tables with the note ID. It returns each table as Markdown and as JSON rows. When tableCellsComplete is false, some cells could not be decoded: they are null in rows and shown as [undecoded cell] in Markdown. Report that to the user rather than filling them in.

Use titles for discovery only. Mutations require the exact note ID; update, append, and delete also require the contentHash returned by get-note-content. This prevents duplicate-title mistakes and stale saves.

For a note with audio recordings, get-audio-transcripts returns the transcript Notes already computed for each recording (it never transcribes). Check each attachment's status: none means Notes stored no transcript, not that the read failed. Ask for includeSegments only when word timings or speakers per word matter, because segments make the response much larger.

Updating Notes

Adding to a note — use append-to-note. It takes the new content plus an optional position ("after" is the default and appends; "before" prepends), separator, and format ("plaintext" / "html"), and does the read-and-splice itself, always round-tripping the body as HTML so existing rich formatting survives. Do not hand-roll read-then-update-note for an addition.

A note that already contains native objects (a table, a checklist, native tags) cannot be spliced, so append-to-note routes it to the native end-append bridge instead. That path additionally needs scopeText (a unique existing phrase from below the title line; a title-only phrase is refused), keeps the default blank-line separator and position: "after", and accepts a fixed HTML subset: `<a> <b> <br> <code> <del> <div> <em> <h1> <h2> <h3> <i> <li>

<ol> <p> <s> <span> <strong> <tt> <u> <ul>`, with `href` on `<a>` and a
`font-size` style on `<span>` as the only attributes. A table, whole or in
part, is refused here — use `create-table` instead. Anything else outside that
subset is refused by name — rewrite the whole body with `update-note` instead.

Adding a web link — use insert-link. Pass url and either mode: "raw" (the URL is its own clickable text) or mode: "hyperlink" with a label. position is "end" (default) or "after-title". It checks the stored link afterwards and reports linkStored and storedUrl. A plain URL typed into append-to-note content stays plain text: Notes does not turn it into a stored link. Rich URL preview cards cannot be created. For a link to another note, use insert-note-link.

User: "Add milk to my shopping list"
Action:
1. Use search-notes if needed to get the note ID
2. Read it with get-note-content and retain contentHash
3. Use append-to-note with its exact ID, expectedContentHash, and content="Milk"

Replacing a note — use update-note. Only reach for it when the body really is being rewritten:

User: "Rewrite my project brief with this new version"
Action:
1. Use search-notes if needed to get the note ID
2. Read it with get-note-content and retain contentHash
3. Use update-note with its exact ID, expectedContentHash, and complete new body

update-note replaces the entire note body. It is not an append operation. If format="html", newTitle is ignored and the first element in newContent becomes the visible title, so start newContent with the title line (for example <h1>Project Brief</h1>). This is the opposite of create-note, which adds the title itself.

If the note has links, update-note needs format: "html", and every link get-note-content returned must still be in newContent with the same text and URL. A write that would drop or change one is refused. Pass allowLinkChanges: true only when the user asked to remove or change a link.

Do not write get-note-content's body back through another tool. For image-heavy notes that body is lossy: inline base64 images over the configured cap (default 256 KB each) come back as [inline image omitted: …] text placeholders.

update-note refuses a note whose body it cannot rewrite without loss: one that holds attachments, tables, checklists, or native tags, or uses formatting that Notes' AppleScript HTML does not carry (superscript, subscript, paragraph alignment, highlight). get-note-content reports that as writable: false with the reason. append-to-note does not refuse such a note. It switches to native end-append, which needs scopeText and the HTML subset above, and keeps the existing objects. Any other change to such a note belongs in Notes.app.

Organizing Notes

When the user wants to organize:

User: "Move my old notes to Archive"
Action: Search for each note, then use move-note with its exact ID and folder="Archive"
User: "Create a Work folder"
Action: Use create-folder with name="Work"

create-folder takes a whole nested path (name="Work/Clients/Omnia") and creates every missing segment, skipping ones that already exist — so it is idempotent and safe to call unconditionally. Do call it first: create-note, create-note-with-attachment, move-note, and batch-move-notes all require the destination folder to already exist (and never a smart folder: those destinations, and a smart folder anywhere in a create-folder path, are refused with reason: "smart_folder_destination", since Notes would send a moved note to Recently Deleted; the guard needs Full Disk Access to detect one), and create-note reports a missing folder with a generic "check that Notes.app is configured and accessible" message that looks like a permissions problem but is not.

Sharing and Revealing Notes
User: "Send me a link to that note"
Action: Use get-note-link with the note ID → notes://showNote?identifier=<uuid>

Hand out that deep link, not the x-coredata:// id — the link opens the note in Notes.app on macOS and iOS and can be pasted into a Reminders task or a message. It needs Full Disk Access for the process that runs the server (under Claude Desktop, the Node binary itself) (it reads the note's identifier from the Notes database; macOS 12–15 has an AppleScript fallback), and password-protected notes cannot be linked.

User: "Open that note for me" / "What note am I looking at?"
Action: show-note by ID to reveal it in Notes.app; get-selected-notes to read the current selection

show-note, show-folder, show-account, and show-attachment activate the Notes.app GUI, so they only do something useful on a Mac with an active desktop session.

Show full SKILL.md (1,854 more words)Show less

Formatting Guidance

Use HTML for predictable rich notes. Apple Notes normalizes HTML internally, but these tags are reliable for most API-created content:

  • Use <div> for body blocks and <div><br></div> for blank spacing.
  • create-note already creates the top <h1> from the title, but <h2>/<h3> in its content do not produce real Heading/Subheading styles — AppleScript's body property renders them as plain bold text (#172). For a new note with real headings, use create-note with format: "markdown" (##/### → Heading/Subheading, flat lists, **bold**/*italic* and inline links; iCloud only, no account). tags are refused with this format: create the note, then use add-native-tags on the returned id. It needs the optional Create Markdown Note Shortcut (macOS 26+); check get-capabilities for create-note-markdown. On an existing note, use append-native with format: "markdown". Both refuse Markdown Notes would rewrite, such as _ emphasis outside a word or backslash escapes; underscores inside a link destination are fine.
  • With format: "markdown", do not repeat the title as a # line; if the first line is exactly # <title>, the server removes it. Without the Shortcut, or in another account, pass markdownRoute: "html": same Markdown subset through AppleScript HTML, no real Heading styles, and - [ ] / - [x] task items become list rows with a visible ☐ / ☑ character (text, not a checkable checklist; say so to the user).
  • To import a Markdown or text file, pass its absolute path as contentPath instead of content (UTF-8, at most 1 MiB, inside home, temp, or /Volumes; hidden paths such as ~/.ssh and anything in ~/Library are refused, except iCloud Drive and ~/Library/CloudStorage).
  • On the default Shortcut route, create-note with format: "markdown" also maps block constructs to native Notes styles (create-note-markdown-blocks in get-capabilities): - [ ]/- [x] → native checklist items with that done state, > text → a block quote, a bare ``` fence (no language) → Monospaced paragraphs, a --- line after a blank line → a divider, and `inline code` → highlighted text (not monospace). Code content is kept literal. append-native still refuses all of these, because its converter flattens them (quotes and code to plain body text, - [ ] to a bullet with literal brackets, --- dropped). markdownRoute: "html" does not map them either: it renders - [ ]/- [x] as ☐ / ☑ glyph rows, keeps --- as literal text, and refuses the rest.
  • Pass title as plain text. The server escapes &, <, and > in it, so an entity such as &amp; in a title shows up literally.
  • Use <ul><li> and <ol><li> for native bullet and numbered lists. Add <div><br></div> after closing </ul> or </ol> so the next section has spacing.
  • Keep each <li> to one line of inline text. Do not put <div>, <p>, headings, or tables inside a list item, and do not send an empty <li>, which shows as a blank bullet or number. A <br> inside an item does not start a new line in Notes; the text after it joins the line. For sub-points, write the parent as its own <div> line and follow it with a separate flat list. HTML from a Markdown converter often wraps list items in <p>, so flatten it before sending. The server's own Markdown converter likewise emits only flat, one-line list items and refuses nested lists.
  • Use <b>, <i>, <u>, and <s> for inline emphasis, and <span style="color: …"> for text color.
  • Use <tt> (or <code>) for commands, code, paths, API keys, and other technical strings.
  • Escape literal &, <, and > in user content as &amp;, &lt;, and &gt;.
  • Avoid nested lists when possible. Apple Notes can flatten or misplace nested list markup.
  • Avoid <sup>, <sub>, and text-align in a note you may rewrite later. Notes applies them, but its AppleScript HTML does not return them, so the note becomes writable: false and update-note refuses it.
  • <blockquote> does not create a Notes block quote. Use the Markdown route's > text instead (see below).
  • For a table, use create-table on an existing note; it builds a native table and verifies its cells. A table is a native object, so afterwards update-note refuses the note and append-to-note switches to native append. Read tables back with get-note-tables.
  • For a clickable link, use <a href="…"> in HTML content or insert-link. A bare URL written as text is stored as plain text, not as a link.
  • Do not use decorative separators between sections (horizontal rules, repeated dashes, or box-drawing characters). They render inconsistently in Notes; use an empty <div><br></div> spacer instead.

Do not use CDATA sections. They can render literally in Apple Notes.

Attachment-Safe Updates

update-note refuses any note containing an attachment (a table counts, since Notes stores it as an embedded object). Do not bypass this control. To add text to such a note, use append-to-note with scopeText, which appends natively and leaves the attachments in place; to add a file, use add-attachment. For any other edit, use Notes.app or create a separate formatted note.

Formatting Limits

Some Notes UI features cannot be created through AppleScript HTML. Several have another route:

  • Interactive checklists: in plaintext or HTML, create a plain list instead; create-note with format: "markdown" and - [ ]/- [x] lines creates real ones, and create-checklist-item / create-checklist-items append unchecked items to an existing note. Use get-checklist-state to read checklist state.
  • Headings and collapsing: HTML <h2>/<h3> become bold text, not heading styles, so they get no collapse control. ##/### through create-note or append-native with format: "markdown" produce real Heading/Subheading styles.
  • Block quotes and highlights: only the Markdown Shortcut route of create-note creates them (> text for a block quote, `inline code` for highlighted text, with no choice of color). Otherwise apply them in Notes.app.
  • Dashed lists: no tool creates them; apply them in Notes.app.

If the user specifically requires those features, create all API-supported content first, then explain which remaining formatting must be applied in Notes.app.

Important Guidelines

  1. Exact IDs for writes: Search may use titles, but update, append, delete, and move require the exact note ID. Update, append, and delete also require the contentHash from the version just read. A note ID may be the x-coredata://… id, the note's Notes UUID (the identifier field list and read tools return with Full Disk Access), or its numeric key (the digits after p). UUIDs and numeric keys need Full Disk Access; store the identifier when a reference must outlive this session.

  2. Default Account: Operations default to iCloud. Use the account parameter for other accounts (Gmail, Exchange).

  3. Content Format: Notes store content as HTML. Use format="html" for structured content. Retrieved HTML is normalized by Notes and may not match the submitted HTML byte-for-byte. verifiedVisibleText proves the words survived, not every rich-formatting detail.

  4. Backslash Escaping: When content contains backslashes, escape them as \\ in the JSON.

  5. Password-Protected Notes: Cannot be accessed via this skill. Inform the user if they try.

  6. Shared Notes: Use extra care before edits or deletes. Changes to shared notes are visible to collaborators.

  7. macOS Only: This skill only works on macOS systems.

Verification

get-note-content returns Apple Notes' stored HTML, which may differ from the original HTML while still rendering correctly. Use get-note-markdown, get-note-content, or a quick reread of the note after create/update to verify the title, line breaks, list spacing, and important content. Do not rewrite normalized HTML just because Notes transformed tags such as headings or monostyled text.

When the stored HTML looks suspicious, get-note-plaintext is the quickest check: it returns the note's plain-text body (what Notes itself shows) with no markup, so you can confirm the title, line breaks, and text survived without reading through normalized HTML.

Plain text cannot confirm structure. It carries no list markers, so it cannot show whether items became bullets or numbers, and a table's cell text is not part of it. With Full Disk Access, use get-note-blocks to check paragraph styles, list types, and indentation, and get-note-tables to check table cells. Stored HTML can also contain entities without a closing semicolon, such as &quot. That is how Notes writes them, not damage to repair.

Error Handling

Every error result carries structuredContent.code (not_found, ambiguous, permission_denied, full_disk_access_missing, shortcut_not_installed, timeout_indeterminate, verification_failed, revision_conflict, validation_error, unsupported, notes_unavailable, operation_failed). Branch on the code rather than the wording. If indeterminate is true, the write may have landed: read the exact note before deciding whether to retry. committed: false means nothing was written.

If your client shows only text, not structuredContent, every result that has it ends with a structuredContent: {…} line holding the same JSON. Take contentHash (for expectedContentHash), ids, and the error code from that line.

  • "Note not found": Use search-notes to find similar titles
  • "Permission denied": User needs to grant automation permission in System Settings > Privacy & Security > Automation. The user can run apple-notes-mcp setup --permissions --open --probe-automation in their terminal to check every grant and open each missing pane
  • Native write times out or reports an uncertain outcome ("Shortcuts timed out waiting for …", "Operation outcome uncertain", "readback was not verified"): do not retry. Read the exact note first — the write may have landed. If it did not, the named bridge Shortcut is likely waiting on a first-run consent prompt that a background run cannot display; ask the user to run that Shortcut once in the foreground in Shortcuts.app and choose Always Allow (once per bridge, after install or upgrade), then retry
  • Slow Notes.app: create-note, update-note, append-to-note, delete-note, and move-note accept timeoutSeconds (1–120) for each automation step of that call. A timed-out write is uncertain; read the exact note before retrying
  • Read times out on a note with a large image: Notes.app returns images inside the body as base64, so a multi-megabyte image can outlast the read timeout, which also blocks delete-note. The error names the large attachments when Full Disk Access is granted. Retry get-note-content (and then delete-note) with a larger timeoutSeconds; if it still fails, have the user remove the image or delete the note in Notes.app
  • "Notes.app accepted the delete, but the note is still in its original folder": nothing was deleted. Read the note again before retrying
  • "Notes.app returned more than … of output": a size limit, not a timeout, so retrying will not help. Note bodies embed inline images as base64; body reads accept up to 512 MB, and other calls follow APPLE_NOTES_MCP_MAX_BUFFER (64 MB default). A note with a large image can still be read and deleted by id
  • "A note may have been created, but its exact ID could not be verified": do not call create-note again, or you may get a duplicate. The message carries the returned ID; read it, or search for the title, before deciding anything. After any create-note timeout, search for the title first for the same reason
  • "The note accepted an update, but exact-ID readback visible text did not match": do not retry. Read the note and compare its text with what you sent
  • "Folder not empty": Cannot delete folders with notes; move notes first
  • Attachment-risk update: update-note rejects the mutation. Append with append-to-note and scopeText, use Notes.app, or create a separate note.
  • Notes accumulate blank lines after repeated updates: Apple Notes' internal HTML processing preserves empty <div><br></div> artifacts from previous edits, and they persist even when you update with clean content. Fix: delete the note with delete-note and create a fresh one with create-note — the artifacts are baked into the note's internal representation, so this is more reliable than trying to fix the whitespace through updates

Examples

Save conversation to notes
User: "Save our conversation about the API design to my notes"
→ create-note with title="API Design Discussion" and summarized content
Daily workflow
User: "What's on my todo list?"
→ search-notes with query="todo" or get-note-content with title="Todo"
Multi-step organization
User: "Archive all my completed project notes"
→ 1. list-notes to find notes
→ 2. create-folder name="Archive" if needed
→ 3. move-note for each relevant note

© sweetrb, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/apple-notes of sweetrb/apple-notes-mcp.

Open the folder on GitHubat commit 3b04478

Compare with similar skills

Apple Notes next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Apple Notes compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Apple Notes this skillsweetrb/apple-notes-mcp150—~13kAutomated safety check: WarnMIT
Binggo MCPluovicter-collab/bilibinggo388—~1.2kAutomated safety check: PassProprietary
Cortex Mem MCPsopaco/cortex-mem313—~2.8kAutomated safety check: PassMIT
Mps Project ManagementJetBrains/MPS1.7k—~2.2kAutomated safety check: PassApache-2.0
Premiere Pro MCPhetpatel-11/Adobe_Premiere_Pro_MCP669—~1.3kAutomated safety check: PassMIT
Gearcoleco Romhackingdrhelius/Gearcoleco142—~3.9kAutomated safety check: PassGPL-3.0

Similar skills

  • Binggo MCP

    luovicter-collab/bilibinggo

    Operates the local Binggo (bilibinggo) Bilibili lottery helper console strictly through binggo MCP tools.

    388 GitHub stars~1.2k tokensUpdated 1 mo ago
    Agent WorkflowsAuto-check passed
  • Cortex Mem MCP

    sopaco/cortex-mem

    Persistent memory enhancement for AI agents. An agent skill from sopaco/cortex-mem.

    313 GitHub stars~2.8k tokensUpdated 2 mo ago
    Agent WorkflowsAuto-check passed
  • Official

    Open an MPS project in a running or freshly started MPS instance when MCP tools fail because no project is open (welcome screen), close an open project with mpsmcpcloseproject, or create a new empty…

    1.7k GitHub stars~2.2k tokensUpdated today
    Agent WorkflowsAuto-check passed
  • Premiere Pro MCP

    hetpatel-11/Adobe_Premiere_Pro_MCP

    Install, verify, troubleshoot, and operate the Adobe Premiere Pro MCP server.

    669 GitHub stars~1.3k tokensUpdated 15 days ago
    Agent WorkflowsAuto-check passed
  • Gearcoleco Romhacking

    drhelius/Gearcoleco

    Hack, modify, and translate ColecoVision and Super Game Module ROMs using the Gearcoleco emulator MCP server.

    142 GitHub stars~3.9k tokensUpdated yesterday
    Agent WorkflowsAuto-check passed
  • Carnet

    jfarcand/mirroir-mcp

    Work the private register (mirroir-carnet) from a session — claim an issue before touching it so peers see who holds it and which session, release or close it when done, file new issues in the one…

    247 GitHub stars~2.8k tokensUpdated 4 days ago
    Agent WorkflowsAuto-check passed

Categories

Questions about Apple Notes

What does Apple Notes do?

A skill your agent uses when the user wants to interact with Apple Notes on macOS - creating, searching, reading, updating, deleting, organizing, or formatting notes and folders. Apple Notes is an agent skill from sweetrb/apple-notes-mcp. Use this skill when the user wants to interact with Apple Notes on macOS - creating, searching, reading, updating, deleting, organizing, or formatting notes and folders.

When should I use Apple Notes?

Apple Notes fits situations like: the user wants to interact with Apple Notes on macOS - creating; formatting notes and folders.

How do I install Apple Notes in Claude Code?

Run `npx skills add sweetrb/apple-notes-mcp --skill apple-notes -a claude-code`. Or copy the skill folder (skills/apple-notes in sweetrb/apple-notes-mcp) into .claude/skills/apple-notes in your project. Claude Code loads it when a task matches its description.

How do I install Apple Notes in Codex?

Run `npx skills add sweetrb/apple-notes-mcp --skill apple-notes -a codex`. Or copy the skill folder (skills/apple-notes in sweetrb/apple-notes-mcp) into .agents/skills/apple-notes in your project. Codex loads it when a task matches its description.

Can I use Apple Notes in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add sweetrb/apple-notes-mcp --skill apple-notes -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/apple-notes, .gemini/skills/apple-notes, .github/skills/apple-notes and .opencode/skills/apple-notes in your project.

What does Apple Notes need to run?

SKILL.md names no scripts, command-line tools or credentials: Apple Notes is instructions for the agent only.

Does Apple Notes access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Apple Notes safe to install?

Our automated static check of SKILL.md flagged 1 warning(s): mentions a credentials file (ssh keys, cloud or package-manager tokens). Read the flagged lines before installing; the check is not a guarantee either way.

What licence does Apple Notes use?

Apple Notes is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Apple Notes use?

About 13k tokens (SKILL.md is roughly 53k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Apple Notes?

Skills that share tags, products or a category with Apple Notes: Binggo MCP (luovicter-collab/bilibinggo, 388 stars), Cortex Mem MCP (sopaco/cortex-mem, 313 stars), Mps Project Management (JetBrains/MPS, 1.7k stars) and Premiere Pro MCP (hetpatel-11/Adobe_Premiere_Pro_MCP, 669 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Apple Notes?

sweetrb (a GitHub user) maintains it in sweetrb/apple-notes-mcp, which has 150 GitHub stars. The repository was last updated on October 9, 2026.

Source: sweetrb/apple-notes-mcp on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.