Your Claude conversations live in superposition — capture them to local Markdown before the session collapses.
Important
Find this useful? You can support development on Ko-fi ☕ — please mention Schrödinger-Sync so I know what to keep building.
Exports your own claude.ai conversations, project knowledge docs, and memory to local Markdown — for feeding into your own local AI memory system (e.g. MemPalace). Windows-only, single Go binary.
Claude today is three separate products that don't talk to each other: claude.ai Web, Claude Desktop, and Claude Code (VS Code/CLI). Use more than one of them — most power users do — and each surface holds its own account state and conversation history, with nothing bridging them natively.
If you've built a local, persistent memory store on the Claude Code side (a semantic search over your own project history, decisions, past sessions), that gap turns very concrete: Claude Code queries years of accumulated context in a few hundred milliseconds. A claude.ai Web or Desktop session running in parallel on the exact same account has none of it — no shared filesystem, no shared MCP server, no query path into the other surface's memory.
The tax shows up every time something changes on one side and needs to reach the other: writing a summary by hand, opening the other surface, pasting it in, hoping it's read before that session goes stale too. That's not hypothetical friction — it's the literal manual workaround this project replaces. Multiply it by however often a real workflow crosses surfaces, and it's recurring, unpaid busywork — exactly what an AI assistant is supposed to remove, not create.
Schrödinger-Sync closes that gap from the Web/Desktop side: it exports what claude.ai already knows — conversations, project docs, memory — into a local, greppable, version-controlled Markdown store that a memory system like MemPalace can ingest. Point Claude Code at the same store, and continuity across all three surfaces stops depending on a human being the sync layer.
Note
Early Access. The harvest/export core is stable and covered by tests, but the project is still actively evolving — expect breaking changes between minor versions until v3.
Roadmap:
- A native MemPalace ingest handshake so exports feed straight in without a format
detour, verified rather than assumed: a SHA-256 hash of the source content taken
before ingest and compared against a re-hash read back from the (encrypted) store
after — a binary pass/fail, reported as an X/Y scorecard per sync batch, not a "should
be lossless" claim.
Write side shipped (v2.2.0): every exported file's SHA-256 is now recorded in
outDir/.content-hashes.jsonat write time (integrity.go), crash-safe by design (saved per-file, not batched, so an interrupted harvest never loses a hash for a file already on disk). The read-back half is still open — a re-hash from MemPalace's own store, compared against this manifest, reported as the X/Y scorecard — because it needs a matching change on the ingest side (a separate repo); tracked, not forgotten. - A native bridge so a claude.ai Web/Desktop session can query a running local MemPalace instance directly, not just feed it one-way via the ingest handshake above: the machine already running MemPalace exposes it as a remote MCP endpoint over a tunnel (Cloudflare Tunnel / Tailscale Funnel — no port-forwarding, no VPS, home IP never touches DNS). A read-only tool allowlist sits at the gateway (status/search/list only) because claude.ai's server-side read/write lock is a Team/Enterprise feature, not available on an individual plan. This is the direct fix for the gap described in "Why this exists" above — point 1 gets data into MemPalace, this gets it back out to Web/Desktop.
- App-managed encryption at rest for the local data store and
desktop-chats/exports — envelope encryption: a random AES-256 data key wraps the exports (AES-256-GCM), itself wrapped by a non-exportable, TPM-resident key via Windows CNG's Platform Crypto Provider (NCrypt) or a raw TPM 2.0 command channel, with a DPAPI-CurrentUser copy as fallback. BitLocker alone doesn't satisfy strict enterprise reviewers — full-disk encryption only protects a powered-off, stolen drive; once Windows is running, it decrypts transparently for any authenticated process on the machine, which is exactly the multi-user/malware/forensic-live-mount threat model banks, law firms and hospitals actually test for. Library choice, verified against source (2026-07-19), not assumed: no pure-Go library wraps NCrypt/the Platform Crypto Provider directly.microsoft/go-crypto-winnativewas considered and ruled out — itscngpackage (inspected file-by-file) implements only symmetric/asymmetric primitives (AES, RSA, ECDSA, HMAC, …) for FIPS-mode Go builds, zero NCrypt/PCP surface, confirmed by a zero-result code search forNCryptOpenStorageProviderin that repo.golang.org/x/sys/windowsdoesn't ship NCrypt bindings either — only the generic LazyDLL syscall mechanism a hand-rolled NCrypt layer would sit on top of. The lower-effort path with no missing-library problem:google/go-tpm'slegacy/tpm2package, which opens a genuine Windows TPM 2.0 channel viaTbs.dll(its ownopen_windows.gocalls straight intotpmutil/tbs) — raw TPM 2.0 commands instead of the NCrypt/PCP abstraction, but real and working today.go-tpm's newer TPMDirect API is still labeled prototype by its own README (as of 2026-06); stick tolegacy/tpm2. - Resolved, not just a maybe: Ada/SPARK stays a conceptual reference only, never a
rewrite target. SPARK (the formally-verifiable Ada subset) can prove real properties
about the ~50 lines of key-wrap glue code itself — provable zeroization, provable
absence of an unintended information flow — but it cannot prove anything about the TPM
channel on the other side of the FFI call, which is the piece whose correctness
the security claim actually rests on, in any language. Reuse-first also points hard at
Go: zero existing permissively-licensed Ada/SPARK bindings for Windows TBS/NCrypt
exist to build on, versus Go's already-working
google/go-tpmlegacy/tpm2path above. - The DPAPI-decrypted sessionKey currently lives as a plain Go
string(immutable, GC-managed, no guaranteed erasure) betweenreadSessionKey()andsetCookieAction(). Doesn't defend against a memory dump taken by something already running as the same logged-in user — SECURITY.md says so today — but the next hardening step is holding it as[]byteand actively zeroing it after use instead of trusting the GC.
Target audience: built for individuals first (free, AGPLv3, forever) — a commercial licence exists for organisations that need to embed or network-deploy a modified version without AGPLv3's copyleft obligations. The two sharpest buyers: law firms and other professional-secrecy holders (German §203 StGB makes disclosure of client secrets a criminal offence, not just a GDPR fine — §43e BRAO restricts external AI processors accordingly) and healthcare (§393 SGB V effectively requires BSI C5 certification for cloud services touching health data since mid-2025). Behind those two: banks/insurers (BAIT/VAIT/DORA auditability) and KRITIS/NIS2 operators (supply-chain liability reaching named executives). The wedge underneath all of them: "data residency" is not "data sovereignty" — an EU-hosted cloud instance is still subject to the US CLOUD Act, which a fully local, zero-network-egress tool structurally isn't.
Coverage caveat: the "no separate Cowork/Code/Design store" claim below was
verified against the API on 2026-07-02 (platform field only ever CLAUDE_AI/VOICE).
Claude Desktop's UI has visibly grown since (Projects/Artifacts/Scheduled/Send tabs) —
re-run probe against a current account before relying on that claim; if a surface
turns out to live outside chat_conversations, harvesting it is not yet covered.
See CHANGELOG.md for what's new in v2 versus the retired v1 (VS Code extension + Python CLI).
Read SECURITY.md before running this. This tool decrypts a DPAPI-protected credential store — the same primitive class as credential-stealing malware. SECURITY.md explains exactly why it can only ever be used against your own account, and how that's enforced in code, not just promised in prose.
- Conversations — every chat_conversation on your account, full turn history including tool calls/results, converted to per-conversation Markdown.
- Project knowledge docs — every file attached to your claude.ai Projects.
- Memory — the claude.ai memory feature's current content.
There is no separate "Cowork"/"Code"/"Design" store to export from — those surfaces
live inside the same chat_conversations API, distinguished only by a platform field
(CLAUDE_AI / VOICE). One harvest command covers all of it.
- Decrypts your own
sessionKeycookie from Claude Desktop's local, DPAPI-encrypted cookie store (readSessionKey()inmain.go) — requires Desktop to be closed (Chromium holds the file locked while it runs). - Launches a real, visible Chrome, injects that cookie, navigates to claude.ai — Chrome
clears Cloudflare's JS challenge itself and earns a fresh
cf_clearance(cdp.go). - Uses same-origin in-page
fetch()calls against claude.ai's own API to pull conversations, project docs, and memory. - Writes everything to
%LOCALAPPDATA%\SchroedingerSync\desktop-chats\as Markdown — a stable per-user path, not the current working directory (seedefaultOutDir()indaemon.go). Override with an explicitoutDirargument where commands accept one.
- Windows 10/11, x64.
- Claude Desktop installed (the tool reads its local, DPAPI-encrypted cookie store — nothing else counts as a valid source).
- Google Chrome installed (CDP needs a real browser to clear Cloudflare's JS challenge; see "How it works" above).
Grab SchroedingerSyncSetup.exe from the
latest release
and run it. Per-user, no admin rights needed. It installs to
%LOCALAPPDATA%\SchroedingerSync, optionally adds a desktop icon, and
optionally registers itself to start in the tray on logon — all opt-in
checkboxes in the wizard, nothing silent. Uninstalling never touches your
already-harvested data.
Unsigned — SmartScreen will warn. SchroedingerSyncSetup.exe is not
code-signed (no cert, no bought-and-forgotten EV "trust" — that stopped
bypassing SmartScreen in 2024 anyway). Verify what you downloaded against
SHA256SUMS in the same release before running it:
certutil -hashfile <file> SHA256 (Windows) and compare by eye.
From source — for anyone who wants to read the code before running it:
go build -trimpath -ldflags "-s -w" -o schroedinger-sync.exe .
# -trimpath: strips local filesystem paths from the binary (no build-machine info leaks)
# -s -w: strips debug symbols/DWARF (smaller binary; nothing to reverse-engineer for free)
.\schroedinger-sync.exe # auth smoke test (org + first 3 conversation titles)
.\schroedinger-sync.exe harvest # full export: chats + project docs + memory
.\schroedinger-sync.exe probe # dump the raw API schema + scan for new surfaces
.\schroedinger-sync.exe supervise # what install-task registers: syncs only while Desktop/VS Code is open
.\schroedinger-sync.exe watch # headless live-sync daemon, no GUI, runs forever once started
.\schroedinger-sync.exe tray # same daemon, with a system-tray icon — manual/always-on use
All commands require Claude Desktop to be closed — the cookie store is locked while it's running (see SECURITY.md, "It cannot target another user's account").
.\schroedinger-sync.exe install-task # register logon autostart (uses supervise)
.\schroedinger-sync.exe uninstall-task
.\schroedinger-sync.exe supervise [outDir] [intervalMinutes] # what install-task registers
.\schroedinger-sync.exe tray [outDir] [intervalMinutes] # visible tray icon, manual/always-on
.\schroedinger-sync.exe watch [outDir] [intervalMinutes] # headless, always-on — default interval: 30 min
supervise is the autostart mode: it stays resident at logon but only runs sync cycles
while Claude Desktop or VS Code is actually open, and goes idle — no Chrome, no network,
just a cheap process-list poll every 20s — once neither has been seen for a few
consecutive polls. tray/watch are the always-on modes for a manual, foreground run;
tray additionally puts an icon in the notification area with a right-click menu: "Jetzt
synchronisieren" (sync now), "Status anzeigen" (toast with the last cycle's result), "Logs
öffnen" (opens sync.log), "Beenden" (quit). All three share the exact same sync engine
(runCycle in daemon.go).
The engine also checks whether Claude Desktop is currently running before every cycle
(isDesktopRunning() in daemon.go) and skips cleanly if it is — no failed sync
attempts, no popped-up Chrome window while you're actively using Desktop. It only
actually syncs in the windows where Desktop happens to be closed. If you keep Desktop
open most of the time, sync cycles will fire rarely by design — use harvest on demand
for anything time-sensitive.
Project docs and memory are refreshed once every 24h (they change far less often than chats), independent of the chat-sync cycle.
go test -v ./...
Runs the security invariant tests described in SECURITY.md — redaction, the hardcoded headless flag, the claude.ai-only network egress check, and the non-importable-package check.
Claude/Anthropic only, for now. See SECURITY.md "Scope" section.
Dual-licensed.
- Open source — GNU AGPLv3: free forever for individuals and for any use that honours the AGPL's copyleft (including its network/SaaS clause). Run it, read it, modify it, self-host it at no cost. The individual tool will always have a free, open edition.
- Commercial — COMMERCIAL-LICENSE.md: organisations that want to embed or redistribute Schrödinger-Sync inside a closed-source or SaaS product — without taking on the AGPL's obligation to release their own source — can obtain a separate commercial licence.
Copyright © 2026 KeilerHirsch. All external contributions are governed by the Contributor License Agreement, which keeps the relicensing right consolidated so the dual-licence can exist. See CONTRIBUTING.md and SECURITY.md's "Business model" section for the reasoning.
