npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@disco_trooper/apple-notes-mcp

v1.7.0

Published

MCP server for Apple Notes with semantic search and CRUD operations

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

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

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.

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

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.

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