@disco_trooper/apple-notes-mcp
v1.7.0
Published
MCP server for Apple Notes with semantic search and CRUD operations
Maintainers
Readme
apple-notes-mcp
MCP server for Apple Notes with semantic search and CRUD operations. Claude searches, reads, creates, updates, and manages your Apple Notes through natural language.
Features
- Chunk-Based Search - Long notes split into chunks for accurate matching
- Query Caching - 60x faster repeated searches
- Knowledge Graph - Tags, links, and related notes discovery
- Hybrid Search - Vector + keyword search with Reciprocal Rank Fusion
- Semantic Search - Find notes by meaning, not keywords
- Full CRUD - Create, read, update, delete, and move notes
- Incremental Indexing - Re-embed only changed notes
- Dual Embedding - Local HuggingFace or OpenRouter API
What's New in 1.7
- Hybrid Fallback Indexing - Recovers from failures by falling back: single call → folder batch → note-by-note
- Streaming Batches - Processes embeddings in batches to reduce peak memory
- Skipped Notes Reporting - Shows which notes failed (locked, syncing, corrupted)
Installation
npm (recommended)
npm install -g @disco_trooper/apple-notes-mcp
apple-notes-mcpThe setup wizard guides you through:
- Choosing your embedding provider (local or OpenRouter)
- Configuring API keys if needed
- Setting up Claude Code integration
- Indexing your notes
From source
git clone https://github.com/disco-trooper/apple-notes-mcp.git
cd apple-notes-mcp
bun install
bun run startRequirements
- macOS (uses Apple Notes via JXA)
- Bun runtime
- Apple Notes app with notes
Quick Start
Run the command after installation:
apple-notes-mcpThe setup wizard starts automatically on first run. Restart Claude Code after setup to use the MCP tools.
Configuration
Configuration stored in ~/.apple-notes-mcp/.env:
| Variable | Description | Default |
|----------|-------------|---------|
| OPENROUTER_API_KEY | OpenRouter API key (enables cloud embeddings) | - |
| EMBEDDING_MODEL | Model name (local or OpenRouter) | Xenova/multilingual-e5-small |
| EMBEDDING_DIMS | Embedding dimensions | 4096 |
| READONLY_MODE | Block all write operations | false |
| INDEX_TTL | Auto-reindex interval in seconds | - |
| EMBEDDING_BATCH_SIZE | Batch size for embedding generation | 50 |
| DEBUG | Enable debug logging | false |
To reconfigure:
apple-notes-mcp setup
# or from source:
bun run setupEmbedding Providers
Local (default): Uses HuggingFace Transformers with Xenova/multilingual-e5-small. Free, runs locally, ~200MB download.
OpenRouter: Uses cloud API. Fast, requires no local resources, needs API key from openrouter.ai.
See docs/models.md for model comparison.
Tools
Search & Discovery
search-notes
Hybrid vector + fulltext search.
query: "meeting notes from last week"
folder: "Work" # optional, filter by folder
limit: 10 # default: 20
mode: "hybrid" # hybrid, keyword, or semantic
include_content: false # include full content vs previewlist-notes
List notes with sorting and filtering. Without parameters, shows index statistics.
sort_by: "modified" # created, modified, or title (default: modified)
order: "desc" # asc or desc (default: desc)
limit: 10 # max notes to return (1-100)
folder: "Work" # filter by folder (case-insensitive)Examples:
- Get 5 newest notes:
{ sort_by: "created", order: "desc", limit: 5 } - Recently modified:
{ sort_by: "modified", limit: 10 } - Alphabetical in folder:
{ sort_by: "title", order: "asc", folder: "Projects" }
list-folders
List all Apple Notes folders.
get-note
Get note content by title.
title: "My Note" # or "Work/My Note" for disambiguation
include_html: false # include raw HTML (default: false)get-tables
Extract structured table data from a note.
title: "My Note"Returns:
{
"tableCount": 2,
"tables": [{
"index": 0,
"rows": [["Header1", "Header2"], ["Val1", "Val2"]],
"formatting": [[{"bold": true}, {"bold": true}], ...]
}]
}Indexing
index-notes
Index notes for semantic search.
mode: "incremental" # incremental (default) or full
force: false # force reindex even if TTL hasn't expiredUse mode: "full" to create the chunk index for better long-note search. First full index takes longer as it generates chunks, but subsequent searches run fast.
reindex-note
Re-index a single note after manual edits.
title: "My Note"CRUD Operations
create-note
Create a note in Apple Notes.
title: "New Note"
content: "# Heading\n\nMarkdown content..."
folder: "Work" # optional, defaults to Notesupdate-note
Update an existing note.
title: "My Note"
content: "Updated markdown content..."
reindex: true # re-embed after update (default: true)delete-note
Delete a note (requires confirmation).
title: "My Note"
confirm: true # must be true to deletemove-note
Move a note to another folder.
title: "My Note"
folder: "Archive"batch-delete
Delete multiple notes at once.
titles: ["Note 1", "Note 2"] # OR folder: "Old Project"
confirm: true # required for safetybatch-move
Move multiple notes to a target folder.
titles: ["Note 1", "Note 2"] # OR sourceFolder: "Old"
targetFolder: "Archive" # requiredIndex Management
purge-index
Clear all indexed data. Use when switching embedding models or to fix corrupted index.
confirm: true # required for safetyAfter purging, run index-notes to rebuild.
Knowledge Graph
list-tags
List all tags with occurrence counts.
search-by-tag
Find notes with a specific tag.
tag: "project"
folder: "Work" # optional
limit: 20 # default: 20related-notes
Find notes related to a source note.
title: "My Note"
types: ["tag", "link", "similar"] # default: all
limit: 10 # default: 10export-graph
Export knowledge graph for visualization.
format: "json" # json or graphml
folder: "Work" # optional filterSupported Formats:
json- For custom visualization (D3.js, web apps)graphml- For professional tools (Gephi, yEd, Cytoscape)
Claude Code Setup
Automatic (recommended)
The setup wizard automatically adds apple-notes-mcp to Claude Code. Run apple-notes-mcp after installation.
Manual
Add to ~/.claude.json:
For npm installation:
{
"mcpServers": {
"apple-notes": {
"command": "apple-notes-mcp",
"args": [],
"env": {}
}
}
}For source installation:
{
"mcpServers": {
"apple-notes": {
"command": "bun",
"args": ["run", "/path/to/apple-notes-mcp/src/index.ts"],
"env": {}
}
}
}Usage Examples
After setup, use natural language with Claude:
- "Search my notes for project ideas"
- "Create a note called 'Meeting Notes' in the Work folder"
- "What's in my note about vacation plans?"
- "Move the 'Old Project' note to Archive"
- "Index my notes" (after adding notes in Apple Notes)
Troubleshooting
"Note not found"
Use full path format Folder/Note Title when multiple notes share the same name.
Slow first search
Local embeddings download the model on first use (~200MB). Subsequent searches run fast.
"READONLY_MODE is enabled"
Set READONLY_MODE=false in .env to enable write operations.
Notes missing from search
Run index-notes to update the search index. Use mode: full if incremental misses changes.
JXA errors
Ensure Apple Notes runs and contains notes. Grant automation permissions when prompted.
"JSON Parse error: Unexpected identifier undefined"
This usually means the indexing process ran out of memory. Try:
- Close other applications to free memory
- Set
EMBEDDING_BATCH_SIZE=25in.envto reduce memory usage - Restart Apple Notes app
- Run
index-notesagain
Skipped notes during indexing
Some notes may be skipped if they are:
- Locked - Unlock them in Apple Notes if you want them indexed
- Syncing - Wait for iCloud sync to complete, then reindex
- Corrupted - Try copying content to a new note and deleting the old one
The indexer will report which notes were skipped and continue with the rest.
Development
# Type check
bun run check
# Run tests
bun run test
# Run with coverage
bun run test:coverage
# Run with debug logging
DEBUG=true bun run start
# Watch mode
bun run devContributing
PRs welcome! Please:
- Run
bun run checkbefore submitting - Add tests for new functionality
- Update documentation as needed
License
MIT
