Upnote Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Upnote Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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:
upnote:// URL scheme (app-native).Read tools:
search_notes - full-text-ish search over title/body, scoped optionally to a notebook or tagget_note - a note's content (markdown / html / text) plus metadata, notebooks, and tagslist_notebooks - the notebook tree with per-notebook note countslist_notes - by filter: recent, notebook, tag, bookmarked, pinned, trashed, templateslist_tags - all tags with note countsget_note_attachments / read_attachment - attachment metadata and bytesget_stats - library counts and the resolved DB pathWrite 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)append_note - append content to the end of a note without rewriting its existing body (safe for rich/image-heavy notes)merge_notes - fold one note into another (append its body under an ## <source title> divider, migrate its images so nothing is orphaned, then trash the source)open_in_upnote - open a note or run a search in the appflowchart 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 --> writedbWhen 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.
Editing a live, syncing database is inherently risky. This server defends your data:
upnote.sqlite3 (plus -wal/-shm) into a MCP Backups/ folder.UPNOTE_ALLOW_WHILE_RUNNING=1 to override (not recommended).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.
A capture-then-triage loop keeps the library tidy:
📥 Inbox notebook — type them in UpNote, or have the agent create_note them. No structure required.📥 Inbox, then proposes, per note, one of: move to the right notebook, merge into an existing note, or create a new note — and shows the plan for you to review.move_note / merge_notes / append_note. A timestamped backup is taken first; merged sources go to Trash (recoverable) and their images are migrated so nothing is orphaned.merge_notes and append_note make this safe: the destination note's existing content (including images) is preserved verbatim and the new material is appended under a labelled ## divider.
git clone https://github.com/bug-breeder/upnote-mcp.git
cd upnote-mcp
uv syncRun it directly (stdio):
uv run upnote-mcpAll 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.
Replace the path below with your local clone if different: /Users/alanguyen/Code/Personal/upnote-mcp.
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 mcp add upnote -- uv run --directory /Users/alanguyen/Code/Personal/upnote-mcp upnote-mcpOr add it to .mcp.json with the same command/args shown above.
If you prefer uvx, use "command": "uvx" with "args": ["--from", "/Users/alanguyen/Code/Personal/upnote-mcp", "upnote-mcp"].
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).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.LIKE) over title and plain text, not a ranked full-text index.uv sync
uv run pytestTests run against a throwaway SQLite database in a temp directory and never touch your real UpNote data.
MIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.