Skip to main content
Glama
Apple Notes MCP
by duanefields

Apple Notes MCP

An MCP server for Apple Notes on macOS. It reads Notes' own SQLite store directly and writes through Notes.app over AppleScript.

It runs over stdio for local use and over HTTP for remote use, so a phone or tablet can reach the same notes the laptop does. That is the point of the project: the desktop-only Notes integrations work well, but the desktop is often the wrong place — the note you need to check or add to is usually needed while you are away from it.

Why read the database

Every other Apple Notes integration drives AppleScript for reads as well as writes, which costs roughly 200ms per note. Reading the store instead means fetching and decoding all 1,163 notes on the reference machine takes 24ms — about four orders of magnitude cheaper for a full-archive query.

That is not a micro-optimization. It is the difference between searching note titles and searching what the notes actually say. It is also the only way to read checklist state, pin state, or a note's full text at all: AppleScript exposes none of them.

Related MCP server: apple-notes-mcp

Tools

Read — from the database, and they work whether or not Notes.app is running.

Tool

list_folders

The folder tree with paths and note counts. Where folder_ids come from.

list_notes

Note summaries, pinned first. Paginated.

get_note

One note in full, body rendered as Markdown.

search_notes

Searches titles and full note bodies, across the whole archive.

Write — through Notes.app, so it must be running.

Tool

create_note

Markdown in; the first line becomes the title.

update_note

Replaces the whole body. Guarded — see below.

append_to_note

Adds to the end. Guarded — see below.

move_note

Move to another folder.

delete_note

To Recently Deleted, recoverable for 30 days.

create_folder

Optionally nested.

delete_folder

Refuses a folder that still holds notes unless told otherwise.

What Apple's scripting interface cannot do

These are limits of the Notes scripting interface, not choices made here. Each was tested against the real app rather than assumed; docs/scope.md has the evidence.

  • Checklists cannot be created. Five HTML spellings were tried and every one came back as an ordinary bullet, so - [ ] becomes a plain bullet. Reading checklist state works fine — that comes from the database.

  • Headings become bold. <h1>, <h2> and <h3> all arrive as plain bold text; Notes' own Title and Heading styles are not reachable from a script.

  • Editing replaces the entire note. There is no partial edit, so attachments and checklists cannot survive one. update_note and append_to_note refuse rather than destroy them; the operator can override it deliberately.

  • A note's title is its first line. set name of note appears to work and only changes the title in the list view, leaving the body's first line alone, so the two disagree from then on. There is no separate title to set.

Requirements

  • macOS, with Notes signed in

  • Python 3.12+ and uv

  • Full Disk Access for the Python interpreter, to read the Notes store

  • Permission to control Notes, which macOS prompts for on the first write

Development

uv sync --extra test
uv run pytest

The test suite is offline and runs against a synthetic database built from Apple's schema. It never opens the real one, so it works on a machine that has never taken a note.

Deployment

docs/deployment-macos.md covers running it as a LaunchAgent behind a tunnel, including the privacy prompt that will otherwise hang the service on first start.

License

MIT

Available Tools

11 tools
append_to_noteA

Add text to the end of a note, keeping what is already there.

The existing note is read from the database and re-sent with the new text on the end, because Notes has no append operation -- so this is a whole-note rewrite underneath, and it refuses on attachments and checklists for the same reason update_note does.

Inputs: text (required), note_id (required), replace_attachments.

create_folderB

Create a folder, optionally nested inside another.

Inputs: name (required), parent_id.

create_noteA

Create a note. The first line of body becomes its title.

body is Markdown. Bullets, numbered lists, bold, italic, strikethrough, links and code blocks all render. Two things do not, because Notes does not expose them to scripts: "# Heading" becomes bold text, and "- [ ]" becomes a plain bullet rather than a checkbox.

Inputs: body (required), folder_id.

delete_folderA

Move a folder, and every note in it, to Recently Deleted.

Refuses a folder that still has notes unless delete_notes_inside is set, because the notes go with it and nothing in the call site says how many there are.

Inputs: folder_id (required), delete_notes_inside.

delete_noteA

Move a note to Recently Deleted.

Not a purge. Notes keeps it for 30 days and the operator can restore it from the app, which is the only way back -- this server cannot undo it.

Inputs: note_id (required).

get_noteA

Read one note in full, with its body as Markdown.

Checklists come back as "- [x]" / "- [ ]" with their real ticked state, and attachments as "[attachment: type]" placeholders -- the files themselves are not read, so this says an image is there, not what is in it.

Inputs: note_id (required).

list_foldersA

List every Apple Notes folder, with its full path and how many notes it holds.

This is where folder_ids come from. Folders nest, and two can share a name, so path ("Work/Clients") is what tells them apart for a human while folder_id is what the other tools take.

Returns everything rather than a page: the whole point is to see the shape of the archive, and a folder list is small.

Inputs: no named parameters.

list_notesA

List notes as summaries, pinned first, without fetching their bodies.

Each entry carries the note_id that get_note and the write tools need, plus the folder it lives in and when it changed. Use get_note to read one.

Inputs: sort, limit, offset, folder_id, +1 more.

move_noteC

Move a note to a different folder.

Inputs: note_id (required), folder_id (required).

search_notesA

Search note titles and full note bodies, case-insensitively.

The entire archive is searched, not a recent window, so a total of 0 means the text is genuinely not in any note. Body matches come back with an excerpt around the hit; each result says whether it matched on title or body.

Inputs: query (required), limit, offset, folder_id.

update_noteA

Replace a note's entire body. The first line of body becomes its title.

This is a whole-note replacement, not an edit -- Apple's scripting interface offers no way to change part of a note. Anything not in body is gone. Read the note with get_note first unless you are deliberately starting over.

Refuses when the note holds attachments or checklists, because neither can be rebuilt from Markdown.

Inputs: body (required), note_id (required), replace_attachments.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 11 tools

    Disambiguation5/5

    Each tool maps to a distinct action-resource pair: listing folders, listing/reading/searching notes, creating/updating/appending/moving/deleting notes, and creating/deleting folders. The subtle difference between update_note (full replacement) and append_to_note (add to end) is clearly explained, so agents can reliably select the right tool.

    Naming Consistency5/5

    All tools follow a consistent verb_noun snake_case pattern: list_folders, get_note, search_notes, create_note, update_note, append_to_note, move_note, delete_note, create_folder, delete_folder. No mixed conventions or vague verbs.

    Tool Count5/5

    With 11 tools covering both notes and folders, the count is well-scoped. Each tool serves a clear, non-redundant purpose, and the set feels complete without being bloated.

    Completeness4/5

    The tool surface covers the full note lifecycle (create, read, update, append, move, delete) and folder lifecycle (create, list, delete). Minor gaps exist—like no rename folder tool or attachment handling—but these are platform limitations rather than design oversights, and core workflows have no dead ends.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers