apple-notes-mcp

apple-notes-mcp

An MCP server for Apple Notes that enables semantic search and full CRUD operations through natural language.

Category
访问服务器

README

apple-notes-mcp

npm version npm downloads License: MIT macOS Bun Claude

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
  • Background Index Jobs - Async full/incremental indexing with progress polling
  • Dual Embedding - Local HuggingFace or OpenRouter API

What's New in 1.8.1

  • Faster list-notes folder filtering - list-notes now queries only the requested folder instead of scanning all notes first
  • Duplicate folder name correctness - Folder filtering now aggregates matching folders across accounts
  • Large vault performance - Folder-scoped listing is significantly faster on larger note libraries

Installation

npm (recommended)

npm install -g @disco_trooper/apple-notes-mcp
apple-notes-mcp

The setup wizard guides you through:

  1. Choosing your embedding provider (local or OpenRouter)
  2. Configuring API keys if needed
  3. Setting up Claude Code integration
  4. Indexing your notes

From source

git clone https://github.com/disco-trooper/apple-notes-mcp.git
cd apple-notes-mcp
bun install
bun run start

Requirements

  • macOS (uses Apple Notes via JXA)
  • Bun runtime
  • Apple Notes app with notes

Quick Start

Run the command after installation:

apple-notes-mcp

The 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-refresh-on-search interval in seconds (disabled when unset) -
SEARCH_REFRESH_TIMEOUT_MS Max time search waits for refresh before using stale index 2000
INDEX_JOB_RETENTION_SECONDS How long completed/failed index jobs remain queryable 3600
EMBEDDING_BATCH_SIZE Batch size for embedding generation 50
DEBUG Enable debug logging false

Search Auto-Refresh Policy

  • search-notes does not force refresh on every request.
  • If INDEX_TTL is unset, auto-refresh is disabled and search uses the current index.
  • If INDEX_TTL is set, refresh runs only after TTL expiration.
  • If refresh fails or takes longer than SEARCH_REFRESH_TIMEOUT_MS, search falls back to stale index results instead of timing out.

To reconfigure:

apple-notes-mcp setup
# or from source:
bun run setup

Embedding 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 preview

list-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)

When folder is provided, the server fetches only matching folders from Apple Notes. This keeps folder-scoped requests fast even when your vault has hundreds of notes.

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 expired
background: false         # optional; defaults to false (synchronous mode)

Use 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.

For large vaults, prefer background indexing:

start-index-job

mode: "full"               # full or incremental

Returns a job snapshot with id, status, and progress. Progress updates in smaller steps across fetch, embed, and persist phases.

get-index-job

job_id: "<job-id>"

Poll until status is completed, failed, or cancelled. You may see cancelling as a transitional status.

list-index-jobs

limit: 10                  # optional, 1-50

cancel-index-job

job_id: "<job-id>"

Requests best-effort cancellation for a running job. Cancellation is cooperative:

  • A long-running step must reach a cancellation checkpoint.
  • Partial work may remain.
  • Start a new job after the current one reaches cancelled.

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 Notes

After create, update, delete, or move, the server auto-syncs vector and chunk indexes in best-effort mode. If sync partly fails, the tool response includes an index sync warning. Run reindex-note or index-notes.

update-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 delete

move-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 safety

batch-move

Move multiple notes to a target folder.

titles: ["Note 1", "Note 2"]  # OR sourceFolder: "Old"
targetFolder: "Archive"       # required

Index Management

purge-index

Clear all indexed data. Use when switching embedding models or to fix corrupted index.

confirm: true   # required for safety

After 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: 20

related-notes

Find notes related to a source note.

title: "My Note"
types: ["tag", "link", "similar"]  # default: all
limit: 10                          # default: 10

export-graph

Export knowledge graph for visualization.

format: "json"     # json or graphml
folder: "Work"     # optional filter

Supported 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.

"iCloud account not available" / Can't get account "iCloud"

This error comes from a different Apple Notes MCP implementation that uses tool search_notes and argument Keywords.

This project uses:

  • tool: search-notes
  • argument: query

If your client calls search_notes with Keywords, point your MCP config to apple-notes-mcp and restart the client.

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:

  1. Close other applications to free memory
  2. Set EMBEDDING_BATCH_SIZE=25 in .env to reduce memory usage
  3. Restart Apple Notes app
  4. Run index-notes again

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 dev

Contributing

PRs welcome! Please:

  • Run bun run check before submitting
  • Add tests for new functionality
  • Update documentation as needed

License

MIT

推荐服务器

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 模型以安全和受控的方式获取实时的网络信息。

官方
精选