Production-ready MCP server for async, cache-backed access to Apple Notes.
macnotes-mcp
macnotes-mcp is a fork of RhetTbull/macnotesapp focused on running Apple Notes as a production-ready MCP server.
It provides:
- Async, cache-backed reads
- Background queued writes to Apple Notes
- macOS LaunchAgent service support
- Easy integration with
mcporterand OpenClaw
Fork Attribution
This project is forked from:
- Upstream:
RhetTbull/macnotesapp - Upstream repo: https://github.com/RhetTbull/macnotesapp
The original Python/CLI Notes automation remains available, and this fork adds MCP-first architecture and service tooling.
Requirements
- macOS (Apple Notes automation is macOS-only)
- Python 3.10-3.13
uv(recommended) for env/dependency management- Apple Notes.app installed and accessible
Optional:
mcporterfor MCP client setup and testing- OpenClaw if you want agent integration
Quick Start
Clone and install:
git clone https://github.com/zorrobyte/macnotes-mcp.git
cd macnotes-mcp
uv sync
Run MCP over stdio:
uv run notes-mcp
Run MCP over local HTTP (streamable-http):
MACNOTES_MCP_TRANSPORT=streamable-http MACNOTES_MCP_HOST=127.0.0.1 MACNOTES_MCP_PORT=8765 uv run notes-mcp-daemon
Run as a macOS Background Service
Install as LaunchAgent:
./scripts/install_service.sh
Uninstall:
./scripts/uninstall_service.sh
Service details:
- Label:
com.zorrobyte.macnotes-mcp - Default endpoint:
http://127.0.0.1:8765/mcp - Logs:
~/Library/Logs/macnotes-mcp/
Check service:
launchctl print "gui/${UID}/com.zorrobyte.macnotes-mcp"
Tail logs:
tail -f ~/Library/Logs/macnotes-mcp/launchd.stderr.log
tail -f ~/Library/Logs/macnotes-mcp/service.log
MCP Client Setup
mcporter + OpenClaw helper
Use the helper script:
./scripts/setup_mcporter.sh
This does two things:
- Registers MCP server
macnotes-mcpin~/.mcporter/mcporter.json - Disables OpenClaw bundled
apple-notesskill to avoid overlap
Custom server name/url:
./scripts/setup_mcporter.sh my-notes http://127.0.0.1:8765/mcp
Manual mcporter setup
mcporter config add macnotes-mcp --url http://127.0.0.1:8765/mcp --transport http --scope home
mcporter call macnotes-mcp.notes_health --json
MCP Tools
The server exposes:
notes_healthnotes_accountsnotes_sync_fullnotes_sync_incrementalnotes_sync_statusnotes_queue_statusnotes_job_statusnotes_job_waitnotes_listnotes_readnotes_createnotes_updatenotes_deletenotes_move
Configuration
Config source priority:
- Environment variables
~/.config/macnotes-mcp/service.toml- Built-in defaults
Example config template:
deploy/config/service.example.toml
Main environment variables:
MACNOTES_MCP_TRANSPORT=stdio|sse|streamable-httpMACNOTES_MCP_HOST(default127.0.0.1)MACNOTES_MCP_PORT(default8000)MACNOTES_MCP_MOUNT_PATH(default/)MACNOTES_MCP_BOOTSTRAP_SYNC(defaulttrue)MACNOTES_MCP_POLL_INTERVAL_SECONDS(default120)MACNOTES_MCP_CACHE_DB_PATH(optional override)MACNOTES_MCP_LOG_LEVEL(defaultINFO)MACNOTES_MCP_LOG_DIR(optional override)MACNOTES_MCP_LOCK_PATH(optional override)
Architecture Summary
- Source of truth: Apple Notes via ScriptingBridge/Apple Events
- Cache: local SQLite for fast reads and search
- Writes: queued background jobs for non-blocking behavior
- Sync: bootstrap full sync + periodic refresh loop
Important:
- Direct writes to Apple Notes private SQLite (
NoteStore.sqlite) are not used. - This avoids corruption/sync issues from private schema assumptions.
Permissions and macOS Notes Automation
On first run, macOS may prompt for Automation permissions (Terminal/Python controlling Notes).
If calls fail:
- Open System Settings -> Privacy & Security -> Automation
- Ensure your invoking app/runtime is allowed to control Notes
- Re-run service or command
Troubleshooting
Health check:
mcporter call macnotes-mcp.notes_health --json
If endpoint is unreachable:
- Verify service is running with
launchctl print ... - Confirm listener port
8765is open - Check
launchd.stderr.logandservice.log
If sync is slow on first run:
- Large Apple Notes libraries can take time for initial bootstrap
- Use
notes_sync_statusto track cache size and sync state
If OpenClaw still uses old notes skill:
openclaw config set skills.entries.apple-notes.enabled false
Legacy CLI (from upstream)
This fork still includes upstream CLI entrypoints:
notesmacnotesappPython API modules
The main focus of this fork is MCP service usage.
Development
Install dev environment:
uv sync
Run tests:
uv run pytest -v -s tests/
Run daemon locally:
uv run notes-mcp-daemon --transport streamable-http --host 127.0.0.1 --port 8765
License
MI
Tools (14)
notes_healthCheck the health status of the notes server.notes_accountsList available Apple Notes accounts.notes_sync_fullPerform a full synchronization of Apple Notes.notes_sync_incrementalPerform an incremental synchronization of Apple Notes.notes_sync_statusGet the current status of the sync process.notes_queue_statusCheck the status of the background write queue.notes_job_statusCheck the status of a specific background job.notes_job_waitWait for a specific background job to complete.notes_listList notes from Apple Notes.notes_readRead the content of a specific note.notes_createCreate a new note in Apple Notes.notes_updateUpdate an existing note.notes_deleteDelete a note.notes_moveMove a note to a different folder.Environment Variables
MACNOTES_MCP_TRANSPORTTransport method: stdio, sse, or streamable-httpMACNOTES_MCP_HOSTHost address for HTTP transportMACNOTES_MCP_PORTPort for HTTP transportMACNOTES_MCP_LOG_LEVELLogging level (default INFO)Configuration
{"mcpServers": {"macnotes-mcp": {"command": "uv", "args": ["run", "notes-mcp"], "env": {"MACNOTES_MCP_TRANSPORT": "stdio"}}}}