Apple Notes MCP

Apple Notes MCP

Enables AI assistants to search and edit Apple Notes on macOS using semantic search, with safe write operations and full local indexing.

Category
访问服务器

README

<div align="center">

Apple Notes MCP

Let Claude, Cursor, or Codex search and edit your Apple Notes — by meaning, entirely on your Mac.

<img width="1460" height="395" alt="Screenshot 2026-08-12 at 11 03 56 PM" src="https://github.com/user-attachments/assets/637a0952-e1db-4426-b50d-0d9713ba0e94" /> <img width="738" height="293" alt="Screenshot 2026-08-12 at 11 04 46 PM" src="https://github.com/user-attachments/assets/52cc9f4e-c5da-44ef-98c5-198235afee2d" />

License: MIT MCP

</div>

You  ▸ What did I decide about the pricing model back in spring?

Claude ▸ [search-notes] "Pricing v3" (Apr 14) — you settled on usage-based
         with a floor, after rejecting per-seat in "Pricing v2".

You didn't name the note. There's no folder called "pricing." No API key was used, and nothing left your laptop.


Features

Search finds notes you can't remember the words for

Every note is embedded on-device with all-MiniLM-L6-v2 into LanceDB, alongside a full-text index. A query runs both and fuses the two rankings with Reciprocal Rank Fusion.

Why both: keyword search fails when you remember the idea but not the phrasing. Vector search fails on exact strings — an error code, an invoice number, a person's name. Fusing them ranks a note that scores mid-range on both above one that spikes on only one, so you don't have to guess which kind of query you're making.

Writes that can't quietly destroy a note

Six write tools, with three guarantees:

Guarantee Why it matters
Every mutation snapshots the old body to disk first, and returns the path An agent editing your notes is unreviewed by definition. You get an undo file even when the edit was wrong.
Ambiguous titles refuse to write — two notes sharing a title is an error, not a coin flip Silently overwriting the wrong note is unrecoverable in a way an error message isn't.
append-note is a separate tool from update-note "Add this to my todos" must never replace the todo list. Separating them makes the destructive option an explicit choice.

Reading an untrusted note can't execute code

The obvious way to drive Apple Notes is to interpolate a title into a script:

const title = "${title}"   // ← arbitrary code execution

A title containing " closes that literal, and the rest runs as JavaScript for Automation — shell commands, file reads, exfiltration. Note titles are not trusted input: they arrive from shared notes, mail-to-Notes, imports, and sync from other devices.

This server removes the vulnerability class instead of escaping around it. The JXA scripts are static files shipped in the package, titles and bodies are passed as argv and read inside run(argv), and subprocess always runs with an argument list and shell=False. No user-controlled text ever enters any program source. Full review in SECURITY.md.

Fully local

No API keys, no account, no telemetry. The only network request in the tool's life is a one-time ~90 MB model download — after that it works on a plane.

Built to survive macOS updates

Notes are read through Apple's automation API, not by parsing the private NoteStore.sqlite. Direct sqlite reads are faster, but Apple reshapes that schema between releases and stores bodies as gzipped protobuf. Via the automation API, macOS's own permission prompt is the consent gate and an OS update doesn't silently corrupt your index.

Folder scoping everywhere

get-note, update-note, append-note, backup-note, and move-note all take an optional folder. Pass it and same-titled notes in other folders or iCloud accounts stop shadowing your target.


Requirements

macOS (Apple Notes and osascript are macOS-only) · Python 3.10+ · ~500 MB disk for the model and its torch dependency.

Setup

1. Install

uv tool install applenotes-mcp

<details> <summary>No <code>uv</code>? Or prefer pip?</summary>

brew install uv && uv tool install applenotes-mcp     # recommended, isolated

# or pip, inside a virtualenv
python3 -m venv ~/.venvs/notes && ~/.venvs/notes/bin/pip install applenotes-mcp

</details>

[!IMPORTANT] The package is applenotes-mcp — no hyphen after "apple". The name apple-notes-mcp on PyPI is a different, unrelated project, so uvx apple-notes-mcp fetches the wrong thing.

2. Register it with your client

Every client runs the same command, uvx applenotes-mcp. Find your row:

Client How
Claude Code claude mcp add apple-notes -- uvx applenotes-mcp
Claude Code — plugin (recommended) see below — registers the server and teaches Claude to use it
Cursor ~/.cursor/mcp.json (global) or .cursor/mcp.json (per project)
Codex CLI ~/.codex/config.toml
Claude Desktop Settings → Developer → Edit Config
VS Code / Copilot .vscode/mcp.json
Zed settings.json, under context_servers
Windsurf ~/.codeium/windsurf/mcp_config.json

Cursor, Claude Desktop, and Windsurf take this exact JSON:

{
  "mcpServers": {
    "apple-notes": { "command": "uvx", "args": ["applenotes-mcp"] }
  }
}

Codex uses TOML:

[mcp_servers.apple-notes]
command = "uvx"
args = ["applenotes-mcp"]

VS Code nests under servers, Zed under context_servers. Ready-to-paste files for every client are in integrations/.

Claude Code plugin

One step for the server plus an apple-notes skill:

/plugin marketplace add ashishakkumar/apple-notes-mcp
/plugin install apple-notes-mcp

3. Teach your agent to use it well

Optional, but the highest-leverage step. Step 2 connects the tools; this explains when to reach for them — search before asking which note, why append-note beats update-note, what to do with an ambiguous title. Without it, agents tend to ask you for a note title instead of just searching.

Client File Put it in
Claude Code skills/apple-notes/SKILL.md ships with the plugin, or copy to ~/.claude/skills/apple-notes/
Cursor integrations/cursor/apple-notes.mdc .cursor/rules/
Codex & everything else integrations/AGENTS.md append to your AGENTS.md

4. Grant permission and index

  1. Ask your assistant: "Index my Apple Notes."
  2. macOS prompts for permission to control Notes. Approve it — nothing works until you do. (Later: System Settings → Privacy & Security → Automation.)
  3. The first run downloads the model once, then embeds every note. Seconds for a few hundred notes, a couple of minutes for thousands.
  4. Ask something real: "What did I write about the Q3 budget?"

Re-run index-notes after adding or editing notes — the index is a snapshot, not a live view.

<details> <summary>Verify the connection</summary>

claude mcp list    # Claude Code

# any client — does the server start and speak MCP?
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"t","version":"0"}}}' \
  | uvx applenotes-mcp

A JSON reply naming apple-notes means the server is fine, and any remaining problem is client config.

</details>


Tools

Read

Tool Does
search-notes Hybrid semantic + full-text search. The one you'll use most.
get-note One note in full, by exact title. Optional folder.
list-folders Every folder name.
list-folder-notes Titles inside one folder.
list-notes How many notes are indexed.
index-notes Rebuild the index from scratch.

Write — each snapshots the old body to ~/.local/share/apple-notes-mcp/backups/ first.

Tool Does
append-note Add HTML to the end of a note. Prefer this over update-note.
update-note Replace a note's body wholesale.
create-note New note in the default folder.
create-note-in-folder New note in a named folder. Fails if it doesn't exist.
move-note Move a note to another folder.
backup-note Snapshot on demand, before a risky multi-step edit.

Bodies are HTML on a single line, capped at 2 MB.

What to know before indexing

  • Indexing reads every note in full. That's the point, but be deliberate.
  • The index is unencrypted at ~/.mcp-apple-notes/data, protected only by file permissions and FileVault. Treat it as sensitive as your notes.
  • Prompt injection is inherent to RAG. A note can contain text aimed at the assistant reading it. No MCP server can neutralize that.
Path Contents
~/.mcp-apple-notes/data LanceDB vector + full-text index
~/.local/share/apple-notes-mcp/backups/ Pre-mutation snapshots (APPLE_NOTES_MCP_BACKUP_DIR to relocate)

Purge everything: rm -rf ~/.mcp-apple-notes ~/.local/share/apple-notes-mcp

Troubleshooting

Symptom Fix
osascript errors, or indexing finds 0 notes Automation permission missing. System Settings → Privacy & Security → Automation → your client → enable Notes.
Not authorised to send Apple events Same. Quit and reopen the client after granting.
First search hangs for a minute One-time model download. Instant afterwards.
Search misses a note you just wrote Re-run index-notes.
command not found: applenotes-mcp ~/.local/bin not on PATH, or you used the hyphenated name.
Won't start on Linux or Windows It can't — Apple Notes is macOS-only.

Bonus: conversation-tag for Ghostty

plugin/ is an optional macOS + Ghostty extra: it tags each terminal tab with a pixel-art sprite and title pulled from today's Apple Notes todo list, so six parallel Claude sessions stop looking identical. Built on this server, installed via its own install.sh (it writes a GPU shader, which the plugin system can't do). See plugin/README.md.

Development

git clone https://github.com/ashishakkumar/apple-notes-mcp && cd apple-notes-mcp
uv venv
uv pip install --group test        # pytest + light runtime deps
uv pip install -e . --no-deps      # skips torch; the tests stub the embedder
uv run pytest

The suite stubs _run_jxa, the single boundary to macOS, so it runs on any platform and covers injection safety, UTF-8 byte caps, ambiguity refusal, backup-before-mutate ordering, path traversal in backup filenames, and RRF fusion. CI additionally exercises mcp 1.x and 2.x and completes a real stdio handshake.

Credits

Python port of mcp-apple-notes by Rafal Wilinski, rewritten to close the injection issues in the original and add write tools, backups, and folder scoping.

MIT — see LICENSE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选