Skip to main content
Glama
odiak

livesync-workers

by odiak

livesync-workers

A Self-hosted LiveSync-compatible backend for Obsidian, with full-text and semantic search and an MCP server, running entirely on Cloudflare Workers.

Sync your vault from Obsidian the way you would to CouchDB, then let AI assistants (Claude, Cursor, Claude Code, …) read and search your notes through MCP.

Deploy to Cloudflare

This is an independent project. It is not affiliated with the Self-hosted LiveSync plugin or its author. It implements the subset of the CouchDB API that the plugin uses, not CouchDB in general.

Built for Kuro. Available to everyone.

What you get

  • LiveSync endpoint (/livesync): the CouchDB-compatible API the plugin talks to. Your vault lives in a SQLite-backed Durable Object; no CouchDB server to run.

  • Search indexes, kept up to date as notes sync:

    • full-text (exact match; character bigrams for Japanese/CJK, words for ASCII) stored in R2,

    • semantic (Workers AI embeddings + Vectorize).

  • MCP endpoint (/mcp) with OAuth, exposing 11 tools: listDirectory, listNotes, listRecentNotes, readNote, readDailyNote, searchNotes, grepNotes, vaultStatus (read), appendToDailyNote, appendToNote (append), writeNote (write, with conflict detection).

  • A small status page at / with your connection details.

Notes written through MCP are regular LiveSync revisions, so they show up in Obsidian on the next sync.

The server also sends MCP instructions telling assistants to read AGENTS.md at the vault root first, if it exists. Put your vault's layout and the rules you want agents to follow (where daily notes live, how to mark AI-written text, …) in that note and every connected assistant will see them before touching the vault.

Related MCP server: Obsidian MCP Server

Deploy

Option A: Deploy to Cloudflare button

  1. Click the button above. Cloudflare clones this repository into your GitHub/GitLab account and connects it to Workers Builds. Tick Create private Git repository if you would rather not publish your copy (it contains no secrets either way).

  2. For the Vectorize index, enter 768 dimensions and cosine metric (the embedding model requires them). Keep the other resources as proposed.

  3. Fill in the secrets. The fields start empty; the form shows what each one is for.

    • LIVESYNC_PASSWORD: what the Obsidian plugin will log in with (the username is the LIVESYNC_USERNAME variable, obsidian by default).

    • ADMIN_PASSWORD: for the admin login on the status page and when authorizing MCP clients.

    • SESSION_SECRET: any long random string, e.g. openssl rand -hex 32.

  4. Deploy. Durable Objects, KV, R2, Workers AI and Vectorize are created for you.

  5. Open your Worker's URL. The page shows the LiveSync URI, database name and MCP URL, and warns if a secret is still missing.

Later pushes to your copy of the repository redeploy automatically. Note that the copy is not a fork: it does not receive updates from this repository by itself. See docs/upgrading.md for pulling them in (it is a plain git merge; only wrangler.jsonc tends to conflict).

Option B: wrangler

git clone https://github.com/odiak/livesync-workers.git
cd livesync-workers
npm install
npm run setup            # creates the Vectorize index and R2 bucket
npx wrangler secret put LIVESYNC_PASSWORD
npx wrangler secret put ADMIN_PASSWORD
npx wrangler secret put SESSION_SECRET
npm run build && npm run deploy

build and deploy are separate scripts on purpose: Workers Builds runs build and then either deploy (production) or wrangler preview (preview builds).

The KV namespace for OAuth is provisioned automatically on the first deploy.

Requirements and cost

A Cloudflare account with Workers enabled. The Worker uses Durable Objects (SQLite), R2, KV, Vectorize and Workers AI; all have free tiers, but R2 needs a payment method on the account and usage beyond the free tiers is billed by Cloudflare. Embeddings are computed once per changed note.

Connect Obsidian

In Self-hosted LiveSync's setup:

Setting

Value

Remote Type

CouchDB

URI

https://<your-worker>.workers.dev/livesync

Database name

vault (the LIVESYNC_DATABASE var)

Username / Password

the LIVESYNC_USERNAME variable (obsidian by default) / your LIVESYNC_PASSWORD secret

End-to-End Encryption

off

E2EE must stay off: the server has to read note contents to index them and serve them over MCP. The status page at / shows these values (sign in with the admin password to see the username).

Or skip the typing: after signing in on the status page, click Generate Setup URI. It produces an encrypted obsidian://setuplivesync?settings=… link plus a passphrase; choose Use Setup URI in the plugin's setup wizard and paste both. The URI is built in your browser (the server only supplies the connection details) and every click creates a new pair.

Connect an MCP client

Point the client at https://<your-worker>.workers.dev/mcp (Streamable HTTP). It will open a browser window; sign in with ADMIN_PASSWORD and choose which scopes to grant:

Scope

Default

Tools

vault:read

always

listDirectory, listNotes, listRecentNotes, readNote, readDailyNote, searchNotes, grepNotes, vaultStatus

vault:append

off

appendToDailyNote, appendToNote

vault:write

off

writeNote

Clients that cannot do OAuth can send Authorization: Bearer <MCP_STATIC_TOKEN> instead once you add that secret (wrangler secret put MCP_STATIC_TOKEN, or in the dashboard under Settings → Variables and Secrets). The token grants vault:read only; add vault:append and/or vault:write through the MCP_STATIC_TOKEN_SCOPES variable. Tools apply the same scope checks as for OAuth grants.

Configuration

Variables (in wrangler.jsonc vars, editable in the dashboard; keep_vars is on, so variables added in the dashboard survive deploys):

Variable

Default

Meaning

LIVESYNC_DATABASE

vault

CouchDB database name the plugin connects to

LIVESYNC_USERNAME

obsidian

Username the plugin logs in with

VAULT_EXCLUDED_FOLDERS

(not set)

Comma-separated folders left out of the search indexes (still readable), e.g. Templates,Archive

MCP_STATIC_TOKEN_SCOPES

(not set)

Extra scopes for the static token, e.g. vault:append,vault:write

The "not set" ones are optional and deliberately absent from wrangler.jsonc, because every vars entry becomes a required field in the Deploy form. Add them in the dashboard (Settings → Variables and Secrets) or to vars when you need them.

Secrets: LIVESYNC_PASSWORD, ADMIN_PASSWORD, SESSION_SECRET, and optionally MCP_STATIC_TOKEN (not in .dev.vars.example, since every entry there becomes a required field in the Deploy form). Empty values and change-me… placeholders count as unset; the status page tells you which ones are missing.

/livesync accepts requests from any origin (authentication is HTTP Basic, so there is nothing for a cross-site page to hijack). Daily notes: appendToDailyNote takes the date from the client; without one it falls back to today in UTC.

How it works

Obsidian ──LiveSync (CouchDB API)──▶ Worker ──▶ VaultDO (Durable Object, SQLite)
                                                   │ alarm: index changed notes
                                                   ├──▶ Vectorize (Workers AI embeddings)
                                                   └──▶ R2 (full-text index generations)
MCP client ──OAuth──▶ Worker ──▶ VaultMCP (McpAgent) ──▶ vault client ──▶ VaultDO / Vectorize / R2
  • Longpoll and continuous _changes feeds are waited on in the Worker over a hibernatable WebSocket, so the Durable Object sleeps between writes.

  • The full-text index is rebuilt in full (debounced 5 minutes after the last change) as immutable generations in R2.

  • Vectors live in a Vectorize namespace per vault.

Using it as a library

The livesync-workers npm package (in packages/livesync-workers) is what this Worker is built on. A multi-tenant host implements VaultHost (credential verification and per-vault policy) and subclasses LiveSyncVaultDO; see docs/embedding.md.

Development

npm install       # also builds the library into packages/livesync-workers/dist (prepare)
npm run build     # rebuild the library after editing packages/livesync-workers/src
npm test          # library unit tests
npm run typecheck
npm run dev       # wrangler dev (needs a Cloudflare login for AI/Vectorize)

License

MIT

Related MCP Connectors

Related MCP Servers