upnote-mcp

upnote-mcp

Enables AI agents to read and write UpNote notes locally via SQLite and URL schemes, supporting search, creation, editing, and organization.

Category
Visit Server

README

upnote-mcp

A local Model Context Protocol server for UpNote. It lets Claude Code, Cursor, and other AI agents read and write your UpNote library.

UpNote has no public cloud API, so this server works with the two integration surfaces UpNote exposes locally:

  • Reads come from UpNote's local SQLite database (read-only).
  • Note/notebook creation uses UpNote's official upnote:// URL scheme (app-native).
  • Edits, moves, deletes, restores, and tagging are written directly into the SQLite database (guarded by backups and a "quit the app first" preflight), because UpNote provides no edit/delete endpoint.

Features

Read tools:

  • search_notes - full-text-ish search over title/body, scoped optionally to a notebook or tag
  • get_note - a note's content (markdown / html / text) plus metadata, notebooks, and tags
  • list_notebooks - the notebook tree with per-notebook note counts
  • list_notes - by filter: recent, notebook, tag, bookmarked, pinned, trashed, templates
  • list_tags - all tags with note counts
  • get_note_attachments / read_attachment - attachment metadata and bytes
  • get_stats - library counts and the resolved DB path

Write tools:

  • create_note, create_notebook - via the upnote:// URL scheme (works while the app is running)
  • update_note, move_note, delete_note, restore_note, tag_note, untag_note - direct SQLite writes (app should be quit)
  • open_in_upnote - open a note or run a search in the app

How it works

flowchart LR
  agent["Claude Code / Cursor"] -->|stdio MCP| server["upnote-mcp"]
  server -->|read-only| readdb[("upnote.sqlite3")]
  server -->|"create (default)"| scheme["upnote:// URL scheme"]
  scheme --> app["UpNote app"]
  server -->|"edit / move / delete (app quit)"| writer["backup + preflight + tx"]
  writer --> writedb[("upnote.sqlite3")]
  app --> writedb

When a row is changed directly, the server sets synced = 0, bumps revision, and updates updatedAt. UpNote re-pushes those rows to its sync backend the next time it launches.

Safety model

Editing a live, syncing database is inherently risky. This server defends your data:

  • Reads use a read-only connection and never lock or modify anything.
  • Before any direct write it takes a timestamped backup of upnote.sqlite3 (plus -wal/-shm) into a MCP Backups/ folder.
  • Direct writes are refused while UpNote is running (it caches rows in memory and could overwrite your change). Quit UpNote first, or set UPNOTE_ALLOW_WHILE_RUNNING=1 to override (not recommended).
  • Each mutation runs in a single transaction and checkpoints the WAL afterward.
  • Destructive tools accept dry_run=true to preview without writing.

Recommended workflow for edits/deletes: quit UpNote, run the changes, then reopen UpNote to let it sync. Creating notes via the default URL scheme is safe while the app is open.

Requirements

  • UpNote desktop app installed (macOS verified; Windows/Linux best-effort).
  • uv installed.
  • Python 3.10+.

Install

git clone https://github.com/bug-breeder/upnote-mcp.git
cd upnote-mcp
uv sync

Run it directly (stdio):

uv run upnote-mcp

Configuration

All paths are auto-detected per platform and can be overridden with environment variables.

Variable Purpose Default (macOS)
UPNOTE_DB Path to upnote.sqlite3 <data dir>/upnote.sqlite3
UPNOTE_DATA_DIR UpNote data directory ~/Library/Containers/com.getupnote.desktop/Data/Library/Application Support/UpNote
UPNOTE_IMAGES_DIR Attachment blob directory <data dir>/images
UPNOTE_BACKUPS_DIR Where pre-write backups go <data dir>/MCP Backups
UPNOTE_WRITE_MODE Create backend: url (default) or sqlite url
UPNOTE_ALLOW_WHILE_RUNNING Permit direct writes while UpNote runs unset (off)

Default data directories: macOS uses the container path above; Windows uses %APPDATA%/UpNote; Linux uses ~/.config/UpNote.

Client setup

Replace the path below with your local clone if different: /Users/alanguyen/Code/Personal/upnote-mcp.

Cursor

Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (per project):

{
  "mcpServers": {
    "upnote": {
      "command": "uv",
      "args": ["run", "--directory", "/Users/alanguyen/Code/Personal/upnote-mcp", "upnote-mcp"]
    }
  }
}

Claude Code

claude mcp add upnote -- uv run --directory /Users/alanguyen/Code/Personal/upnote-mcp upnote-mcp

Or add it to .mcp.json with the same command/args shown above.

uvx alternative

If you prefer uvx, use "command": "uvx" with "args": ["--from", "/Users/alanguyen/Code/Personal/upnote-mcp", "upnote-mcp"].

Limitations and caveats

  • The URL scheme is fire-and-forget: create_note/create_notebook do not return the id of what they create. Set UPNOTE_WRITE_MODE=sqlite to create via SQLite and receive the new note id (requires the app to be quit).
  • UpNote must be quit for edits/moves/deletes to be reliable.
  • Direct writes set synced = 0 so UpNote re-syncs on next launch; the first time you use the write tools, verify a test edit appears correctly in the app before trusting it with important notes.
  • Search is substring-based (LIKE) over title and plain text, not a ranked full-text index.

Development

uv sync
uv run pytest

Tests run against a throwaway SQLite database in a temp directory and never touch your real UpNote data.

License

MIT

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured