An MCP (Model Context Protocol) server that reads handwritten notes from GoodNotes on macOS. It exposes your handwritten notebooks as structured data that AI assistants like Claude can read, search, and process.
GoodNotes stores all data in local SQLite databases on macOS:
projection.sqlite— document metadata (names, folders, page ordering)fts.sqlite— full-text search index with OCR'd handwriting (multiple recognition candidates per word)
This MCP server reads those databases (read-only) and exposes 6 tools:
| Tool | Description |
|---|---|
list_notebooks |
List all notebooks with IDs, page counts, dates |
read_notebook |
Read OCR text from a notebook (supports page ranges) |
read_page |
Read OCR text from a single page |
search_notes |
Full-text search across all handwritten notes |
get_unprocessed |
Find new/changed pages since last processing |
mark_processed |
Mark pages as processed (for pipeline workflows) |
GoodNotes OCR produces multiple word candidates. The server returns them separated by |:
Temple|Tomple|temple Voice|Voica recognition
Your AI assistant picks the best word using semantic context — much more accurate than taking the top candidate alone.
- macOS (GoodNotes stores its databases locally)
- GoodNotes installed and synced
- Python 3.11+
- uv (recommended) or pip
git clone https://github.com/withsivram/goodnotes-mcp.git
cd goodnotes-mcp
uv venv && uv pip install -e .Add to your Claude Code MCP settings:
{
"mcpServers": {
"goodnotes": {
"type": "stdio",
"command": "/path/to/goodnotes-mcp/.venv/bin/python",
"args": ["/path/to/goodnotes-mcp/server.py"]
}
}
}Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"goodnotes": {
"command": "/path/to/goodnotes-mcp/.venv/bin/python",
"args": ["/path/to/goodnotes-mcp/server.py"]
}
}
}| Variable | Default | Description |
|---|---|---|
GOODNOTES_DB_DIR |
~/Library/Containers/com.goodnotesapp.x/Data/Library/Databases |
Path to GoodNotes SQLite databases |
GOODNOTES_TRACKING_FILE |
~/.goodnotes-mcp/processed.json |
Path to processing state file |
Once configured, your AI assistant can:
- List your notebooks: "What notebooks do I have in GoodNotes?"
- Read notes: "Read my latest notebook"
- Search: "Search my handwritten notes for 'meeting action items'"
- Process pipeline: Use
get_unprocessed+mark_processedto build automated workflows (e.g., handwriting → structured Obsidian notes)
The server is designed as a minimal data pipe — all intelligence (OCR resolution, categorization, structuring) happens in the AI assistant. A typical workflow:
get_unprocessed→ find new pagesread_notebook→ get raw OCR with word candidates- AI resolves
Temple|Tomple|temple→ "Temple" using context - AI categorizes and structures into markdown
- Write to Obsidian (or any markdown-based system)
mark_processed→ track what's been handled
iPad (GoodNotes) → iCloud Sync → macOS SQLite DBs → MCP Server → AI Assistant
The server is intentionally minimal (~390 lines, zero external dependencies beyond mcp). All intelligence lives in the AI layer, making the server easy to maintain and extend.
MIT License — see LICENSE.