upnote-mcp
Enables AI agents to read and write UpNote notes locally via SQLite and URL schemes, supporting search, creation, editing, and organization.
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 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 path
Write tools:
create_note,create_notebook- via theupnote://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 aMCP 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=1to override (not recommended). - Each mutation runs in a single transaction and checkpoints the WAL afterward.
- Destructive tools accept
dry_run=trueto 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_notebookdo not return the id of what they create. SetUPNOTE_WRITE_MODE=sqliteto 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 = 0so 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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。