Skip to main content
Glama
krisxsee

Apple Notes on Steroids

by krisxsee

Apple Notes on Steroids

An MCP server for Apple Notes. Read, search, write and sync notes at full fidelity, including the styles Apple's own import path throws away.

Requirements

macOS with Apple Notes, Node 18 or newer, and up to three permission grants:

Grant

Buys

Needed

Automation

talking to Notes at all

always, prompted on first run

Accessibility

true styles and attachments on write

optional

Full Disk Access

reading Notes' own store: checked state, quotes, link targets, highlights. Also how a note holding attachments is safely updated, since the store says where they sit

optional

The server works with Automation alone, at reduced fidelity, and says so in its answers. The optional two are granted in System Settings, Privacy & Security, to the exact app running the server, so they need re-granting after that app updates.

Related MCP server: Apple Notes MCP

Connect

Any MCP client that runs local stdio servers works: Claude Code, Claude Desktop, Codex CLI, Cursor and the rest. The one constraint is that the server must run on the Mac where Notes lives.

{ "mcpServers": { "apple-notes-on-steroids": { "command": "npx", "args": ["-y", "github:krisxsee/apple-notes-on-steroids-mcp"] } } }

In Claude Code it is also a plugin:

claude plugin marketplace add krisxsee/apple-notes-on-steroids-mcp
claude plugin install apple-notes-on-steroids

In Claude Desktop, no terminal needed: download the .mcpb from the latest release, double-click it, install.

From source: npm install && npm run build, then point the client at dist/index.js. To sync, set APPLE_NOTES_MD_DIR to the folder of .md files, or pass dir per call.

Verify

npm run verify

Creates one note in "MCP Tests" holding every style the server claims to write, reads it back character for character, and never touches a note that existed before.

Tools

Tool

What it does

list_folders

Every folder with path and note count.

list_notes

Notes, newest first. Optional folder, limit.

search_notes

Titles by default; search_body: true also scans bodies, capped at 300 notes.

get_note

One note by id or name. format: "markdown" reads Notes' own store, the only place checked state, quotes, link targets and highlights exist; when the store is out of reach it falls back to the HTML and says so with rich: false. format: "html" gives the raw HTML.

create_note

New note from a Markdown body. attach puts files in it; true_styles applies what the importer cannot.

append_note

Adds to the end. true_styles pastes at the caret instead of rewriting the body.

update_note

Replaces a note's body, keeping its attachments. attach adds more. Destructive for that note.

list_attachments

What a note carries besides text, one entry per mark and in the same order.

get_attachment

One attachment as an image, by index. Drawings come back as Notes' own render.

sync_now

One pass over a folder of Markdown files. See Sync.

sync_status

Dry run of sync_now.

export_note

Writes a note to a new .md file with its media. Creates only.

import_note

Creates a note from a .md file. Creates only.

No delete tool, on purpose.

Formatting

Bodies are Markdown, both ways. Two write paths produce a note: the HTML importer takes everything it can, instantly and silently, and a pasteboard hand-off supplies what it cannot.

Feature

State

Bold, italic, strikethrough, underline

both ways

Inline code

both ways, at the size of the line around it

Links, bare and labelled

both ways

Nested bullet and numbered lists

both ways, four spaces per level

Tables

both ways

Headings

both ways. # is Title, ## Heading, ### Subheading; deeper collapses to Subheading

Code fences

both ways. Notes cannot hold the language tag, but a pull keeps the one the file already has

Block quote

both ways, single level, which is all Notes has

==highlight==

both ways, orange, with inline code in mint so the two never read alike

- [ ], - [x], nested

both ways, checked state included

Horizontal rule

both ways, written as em dashes because Notes has no rule

Images, drawings, scans, any file

read fully; written by pasting the file, since the importer cannot make one

Callouts, footnotes

plain text, no Notes equivalent

Sync

One direction per file, and Notes is the centre. A file's own name says which note it belongs to, and one property says which way it flows.

apple-note-sync

Direction

What happens

push

file → note

the note's body is replaced from the file

pull

file ← note

the file's body is replaced from the note, media included

off

paused

nothing

A pass only touches notes that already exist. A name matching no note, or more than one, is reported and neither side is written. Rename a note and the pair is lost until you rename the file to match.

One direction cannot have a conflict, so there is no conflict resolution. .apple-notes-sync.json is a cache used only to skip work; delete it and the next pass reaches the same place.

Media pulls in beside the .md file that links it, with ordinary Markdown. A push reconciles those links against the note: a link added attaches the file, one removed detaches it. A drawing is never removed, because nothing outside Notes reads its strokes.

export_note and import_note create the other side. Both refuse to overwrite.

Safety

  • No delete tool.

  • Sync never propagates deletions.

  • Notes in "Recently Deleted" are excluded from listings, search and folder resolution, and are never written to.

  • Locked notes: metadata reads, body reads return a placeholder, writes fail with LOCKED.

  • Ambiguous names return candidates rather than a guess.

  • The live check works only on notes it created.

  • The store is opened read-only. Writing goes through Notes itself, always.

Design

Four ideas hold it together. The source map lives in CLAUDE.md.

Nothing is addressed by position. A position is a second model of the note kept beside the note, and it drifts. Text is what both sides can see.

The store is the only witness. A paste changes what a paragraph is and not one character of what it says, so the editor proves nothing.

Losing state must never read as having no state. Empty is a fact about the world; unreadable is a fact about this pass. Conflating them lets one side overwrite the other.

Never destroy what cannot be put back. An image removed still exists as a file. A drawing does not.

Development

npm test

npm run verify covers what only macOS can answer.

A
license - permissive license
-
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.

  • MCP-native open-source Notion alternative: read & write pages, databases and kanban boards.

  • Markdown-first MCP server for Notion API with 8 composite tools and 39 actions.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/krisxsee/apple-notes-on-steroids-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server