README file from
GithubATProto Sync
Sync your Obsidian vault to your own ATProto PDS — the same account you use for Bluesky, Blacksky, Eurosky, or a self-hosted server. End-to-end encrypted by default.
- Your storage, your account. Notes live in your PDS repo as
app.notesky.*records. No third-party sync server, nothing to trust but your own host. - End-to-end encrypted. Every note and attachment is encrypted on-device (XChaCha20-Poly1305, per-item keys wrapped by an Argon2id passphrase-derived master key). Filenames and titles are encrypted too — at rest, your PDS sees only ciphertext.
- Multi-device. Desktop and mobile converge through three-way sync with
character-level merging (the same algorithm Obsidian Sync uses). True
conflicts never lose data: the losing version is kept locally in
Sync Conflicts/. - Publish per note. Toggle a note public and it becomes a plaintext record (with its embedded images) that anyone — or any app — can read from your PDS. Toggle it back and it re-encrypts with a fresh key. A public web viewer for these records is planned at notesky.app.
Setup
- Install and enable the plugin.
- The setup wizard opens: sign in with Bluesky (OAuth) or with an app password, then choose your encryption passphrase. You can switch methods later under Settings → Account → Sign-in method.
- That's it — the status bar shows sync state. Later devices enter the same passphrase.
Passphrase warning: if you lose the passphrase, encrypted notes on the server cannot be recovered by anyone — including us.
Permissions and privacy
- File listing: as a sync plugin, it enumerates vault file paths to know
what to sync (respecting your ignore patterns;
.obsidian/never syncs). - Clipboard: written only when you tap "Copy link instead" during mobile sign-in; never read.
- Browser storage: sync state and settings live in IndexedDB; the OAuth library additionally persists its session material in browser storage.
- Network: your PDS, plus public directory endpoints
(
public.api.bsky.app,plc.directory) to resolve your handle. No analytics, no third-party servers.
Notes on limits
- Files larger than your PDS blob limit (5 MB on the reference PDS) stay local-only; they're listed under Settings → Skipped files.
.obsidian/configuration does not sync.
Command-line sync (without Obsidian)
packages/cli provides atpsync, a CLI and background daemon that
keeps a plain vault folder in sync using the same engine, encryption and record layout as the
plugin. It reacts to remote changes in real time through your PDS's event stream, and works
with any editor or coding agent (CLI with --json, or atpsync mcp). App-password auth;
config in ~/.config/atpsync/.
Development
pnpm install
pnpm test # all packages (core, obsidian, cli)
pnpm run build # produces main.js at the repo root
The repo is a pnpm workspace: packages/core (sync engine, crypto, reconciler — no Obsidian dependency, fully unit-tested), packages/obsidian (the plugin), and packages/cli (the atpsync command-line tool). See docs/ for the design documents and the manual testing guide (including a local Docker PDS setup).