Skip to content

About

Local-first notes app that opens your Obsidian vault as-is, with end-to-end encrypted sync and an MCP server.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

markdown-viewer: notes that open your Obsidian vault as-is

Tauri, Rust, React, TypeScript, Vite, Cloudflare



A local-first notes app that opens your Obsidian vault without breaking anything,
and syncs it end-to-end encrypted across devices, with no file size limit.

Features · Screenshots · Getting started · Sync · Architecture


Seamless editing: Markdown syntax shows on the line under the cursor and fades away everywhere else

Seamless editing: the syntax shows on the line you are on and fades everywhere else. The file stays plain Markdown.


Note

The interface is in Brazilian Portuguese. Everything in the screenshots comes from a fictional sample vault that ships with the app (?demo).

Features

📂 Your vault, untouched The vault stays a regular folder in the same layout Obsidian uses. If this app disappears tomorrow, Obsidian still opens it all.
✍️ Seamless editor CodeMirror 6 with live rendering: callouts, tasks, tables, Mermaid, footnotes, ==highlights==, embeds and transclusion.
🔗 Obsidian-grade links [[note]], [[note#heading]], [[note#^block]] and aliases resolve exactly like Obsidian. Renaming a file updates every link.
🗂️ Bases Reads .base files and renders their table and card views, with filters, formulas, grouping and sorting.
🌐 HTML as a first-class note HTML files run in an isolated frame, and their localStorage is redirected to a file in the vault, so trackers sync too.
🔒 End-to-end encrypted sync Content-defined chunks, XChaCha20-Poly1305, three-way merge for text. The server never sees names, paths or content.
🤖 MCP server Lets Claude search, read, query Bases and rename inside the vault, using the same index as the app.
📄 PDF, code and images pdf.js reader with search, syntax-highlighted code, image viewer. Everything else opens in the system app.

Screenshots

A note with properties, callouts and wiki links in the dark theme

Tasks, a Mermaid diagram and a code block A Base rendered as book cards
Mermaid, tasks and code Bases · a .base file as cards
An HTML habit tracker running inside the app The same note in the light theme
HTML trackers · state saved in the vault Light theme

Getting started

You need Node.js 22+ and, for the desktop app, the Tauri prerequisites (Rust 1.77+).

npm install

npm run dev           # the interface in the browser, at http://localhost:5273
npm run dev:desktop   # the desktop app (Tauri)

Tip

Open http://localhost:5273/?demo to try it with the in-memory sample vault, no folder needed.

All scripts
Command What it does
npm run dev Vite dev server for the interface
npm run dev:desktop Desktop app with hot reload
npm run build:desktop Desktop installers for the current platform
npm run verify Lint (oxlint), typecheck, tests (Vitest) and build
npm run vault:check Lists links, embeds and aliases that do not resolve
npm run base:check Runs every .base in a vault and prints the rows

Sync

The sync runs on Cloudflare's free tier and you deploy your own copy.

Piece Role
Worker Routes each call to the vault's Durable Object
Durable Object (one/vault) Authenticates devices, keeps the log in SQLite, orders commits, notifies by WebSocket
R2 Stores the encrypted chunks (10 GB free, no egress fees)
How it works
  • Chunks. Every file is split into content-defined chunks of about 4 MB, so there is no size limit, a small edit to a huge PDF uploads only the chunk that changed, and transfers resume where they stopped.
  • Encryption. libsodium on every device: XChaCha20-Poly1305 for content, Argon2id to derive keys from the vault password. One random master key per vault, stored on the server only when wrapped. Chunk ids are an HMAC of the content, so the server learns nothing from them.
  • Conflicts. Text gets a line-by-line three-way merge against the last common version. Only overlapping edits produce a conflict copy next to the file. Binaries keep the newest version and the other one stays in history.
  • No accounts. Each device gets a token when it is paired, by QR code or by the vault password, and can be revoked from any other device.
cd services/sync
npx wrangler login
npm run deploy

See services/sync for the setup code and the secrets the Worker expects. Then point the app at it: copy apps/desktop/.env.example to apps/desktop/.env.local and set VITE_SYNC_SERVER to your Worker's URL.

MCP server

packages/mcp reads the vault straight from disk, with the same index as the app, and does not need the app to be open.

Tool What it does
search Search notes and HTML, with #tag, path:, "phrase", -not
get_note Properties, aliases, tags, headings, links, backlinks, content
resolve_link Where a [[link]] points, the Obsidian way
backlinks Who links to a file
query_base Runs a .base and returns its rows
list_tags Tags with counts
list_properties Properties with counts, or the values of one
rename Renames or moves and updates every link, never overwrites
npm run build -w @markdown-viewer/mcp
claude mcp add vault -- node packages/mcp/dist/server.mjs "/path/to/your/vault"

Architecture

An npm workspaces monorepo. The sync engine and the index are plain TypeScript, with no dependency on Tauri, so each app only provides the file, key storage and network layers.

flowchart LR
  subgraph app [apps/desktop]
    UI[React + CodeMirror] --> T[Tauri / Rust]
  end
  UI --> core[packages/core<br>Markdown dialect, index, links, Bases]
  UI --> sync[packages/sync<br>chunking, merge, queue]
  sync --> crypto[packages/crypto<br>libsodium]
  sync -- WebSocket + HTTPS --> svc[services/sync<br>Worker, Durable Object, R2]
  mcp[packages/mcp] --> core
Loading
Project layout
apps/desktop      Tauri app: React interface, CodeMirror editor, viewers
packages/core     Obsidian Markdown dialect, file systems, index, link resolution, Bases
packages/sync     Sync engine: chunking, three-way merge, queue, protocol
packages/crypto   Keys and encryption on top of libsodium
packages/mcp      MCP server for the vault
services/sync     Cloudflare Worker and Durable Object
docs/             Spec, design system and release process

Layer Technology
Desktop Tauri 2 (Rust), auto-updates through GitHub Releases
Interface React 19, TypeScript, CodeMirror 6, Lucide icons, Mermaid
Viewers pdf.js, sandboxed iframes for HTML
Sync Cloudflare Workers, Durable Objects (SQLite), R2, libsodium
Quality Vitest, oxlint, Prettier

Roadmap

  • Monorepo and in-app feedback
  • Obsidian-compatible vault on desktop
  • HTML, PDF, code and Bases
  • MCP server for the vault
  • End-to-end encrypted sync between Mac and Windows
  • Comments for Claude inside notes
  • Android reader (Expo)
  • Web app

The full plan lives in docs/spec.md (in Portuguese).

License

MIT


Built by Matheus Ervilha to replace Obsidian Sync with something he owns.

About

Local-first notes app that opens your Obsidian vault as-is, with end-to-end encrypted sync and an MCP server.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages