This file provides guidance for AI agents (Claude, etc.) when using this MCP server.
This MCP server enables AI assistants to interact with Apple Notes on macOS via AppleScript. All operations are local - no data leaves the user's machine.
- TECHNICAL_NOTES.md - Deep technical research on Apple Notes internals, database structure, protobuf format, and alternative access methods
- TODO.md - Prioritized improvement roadmap with stability fixes and new features
When sending content with backslashes to any tool, you MUST escape them.
The MCP protocol uses JSON for parameters. In JSON, \ is an escape character. To include a literal backslash:
| You want | Send in JSON parameter |
|---|---|
\ |
\\ |
\\ |
\\\\ |
Mobile\ Documents |
Mobile\\ Documents |
If you send a single backslash without escaping:
- The JSON parser interprets
\as an escape sequence - Invalid sequences like
\(backslash-space) cause silent failures - The note creation/update will fail with no clear error
Correct - Shell command with escaped space:
content: "cp ~/Library/Mobile\\ Documents/file.txt ~/dest/"
Correct - Windows path:
content: "Path: C:\\\\Users\\\\Documents"
Incorrect - Will fail:
content: "cp ~/Library/Mobile\ Documents/file.txt ~/dest/"
All note operations support an optional id parameter. Using IDs is more reliable than titles because:
- IDs are unique across all accounts
- Titles can be duplicated
- No issues with special characters
Recommended workflow:
- Use
search-notesorcreate-noteto get the note's ID - Use the ID for subsequent operations (
get-note-content,update-note,delete-note,move-note)
# Search returns IDs
search-notes query="Meeting"
→ "Meeting Notes (Work) [id: x-coredata://ABC/ICNote/p123]"
# Use ID for reliable operations
get-note-content id="x-coredata://ABC/ICNote/p123"
update-note id="x-coredata://ABC/ICNote/p123" newContent="Updated"
delete-note id="x-coredata://ABC/ICNote/p123"
- Always escape backslashes in content (see above)
- Newlines can be sent as
\n(this is a valid JSON escape) - Title handling: The
titleparameter is automatically prepended as<h1>in the note body. Do NOT include the title in thecontentparameter, or it will appear twice. - HTML format: When using
format: "html", do NOT include a<h1>tag incontent— the title is prepended automatically as<h1>. create-notereturns the new note's ID for subsequent operations
Important: When repeatedly updating a note (especially with HTML content), Apple Notes can accumulate whitespace artifacts - specifically <div><br></div> tags that persist between sections even after removing them from your content.
Symptoms:
- Large gaps appear between sections that weren't in your content
- Reading the note back shows multiple blank
<div><br></div>lines - The whitespace persists even when you update with clean content
Cause: Apple Notes' internal HTML processing preserves empty divs from previous edits. Each update can leave behind formatting artifacts.
Solution: If a note has accumulated unwanted whitespace:
- Delete the note with
delete-note - Create a fresh note with
create-note
This is more reliable than trying to fix the whitespace through updates, as the artifacts are baked into the note's internal representation.
- Set
searchContent: trueto search note body, not just titles - Searches are case-insensitive
- Results include note IDs for reliable subsequent operations
- Use
modifiedSince(ISO 8601 date) to filter to recently modified notes — useful for large collections - Use
limitto cap the number of results returned - Use
folderto restrict search to a specific folder
- Returns note titles only, not content
- Use
get-note-contentto retrieve full content - Use
modifiedSince(ISO 8601 date) to filter to recently modified notes - Use
limitto cap the number of notes returned
- Internally copies then deletes the original
- If delete fails, note exists in both locations (still returns success)
- Prefer using
idparameter to avoid issues with duplicate titles
- Requires note ID (not title) — use
search-notesto find the ID first - Reads directly from the NoteStore SQLite database (not via AppleScript)
- Requires Full Disk Access for the MCP host process
- Returns
nullif note has no checklists or database is inaccessible - Works independently of
get-note-content— use both for full picture
- Automatically annotates checklist items with
[x]/[ ]when database is accessible - Falls back to plain list items if Full Disk Access is not granted (no error)
- No action needed — enrichment happens transparently
- Default account is iCloud
- Use
list-accountsto see available accounts - Pass
accountparameter to target specific account - When using
id, account is not needed (IDs are globally unique)
- Use
get-sync-statusto check if sync is in progress search-notes,list-notes, andlist-folderswill warn if sync is active- If you get incomplete results, wait a moment and retry
- Use
list-shared-notesto find notes shared with collaborators update-noteanddelete-notewill warn when modifying shared notes- Changes to shared notes are immediately visible to all collaborators
| Error | Likely Cause |
|---|---|
| "Notes.app not responding" | Notes.app frozen or not running |
| "Note not found" | Title doesn't match exactly (case-sensitive) |
| Silent failure | Backslash not escaped in content |
| "Permission denied" | macOS automation permission needed |
| "iCloud sync in progress" | Wait and retry - results may be incomplete |
| "No checklist items found" | Note has no checklists, or Full Disk Access not granted |
Before creating notes with shell commands or paths containing backslashes, verify you're escaping correctly:
~/path/to/file- No escaping needed (no backslashes)Mobile\ Documents- Needs escaping:Mobile\\ DocumentsC:\Users\- Needs escaping:C:\\Users\\