Skip to main content

Local-first, MCP-native unified memory vault — your AI memory as files you own, shared across every model.

Project description

EleSync — a neon circuit elephant

🐘 EleSync

Tired of re-explaining yourself to every AI? I bet you are, that's why we created EleSync, a One command setup memory vault, nicely encrypted, accessible to continue your conversations without repeating yourself to every model.

🔰 You're not a developer? Perfect — EleSync is designed for regular people first. Read the plain-English setup guide — covers everything from first install to USB vault, step by step. ~10 minutes, no coding knowledge needed.

EleSync demo

PyPI CI License: MIT MCP Buy Me A Coffee

You use Claude, ChatGPT, and Gemini. Each one knows a different slice of you, and none of them share. EleSync is one private vault on your own computer that every AI plugs into — so anything one AI learns about you is instantly available in all of them.

No accounts. No cloud. No subscriptions. Your memories are plain text files on your own disk — readable in any text editor, synced however you already sync files.

Tell ChatGPT something  →  it lands in your vault  →  Claude already knows it.

Two commands and you're done:

pip install "elesync[mcp]"   # install
ele onboard                  # connect to Claude Desktop — that's it

Want it fully automatic? Install the watch extra once — after that, just export from any AI and Claude already knows:

pip install "elesync[watch]"
ele watch --autostart        # runs in the background from now on

Stable at v1.3 — a 179-test suite, CI across Python 3.10–3.14 (including a dev-extras job covering encryption and real-model semantic recall) plus ruff lint/format and mypy type-checking, and a public surface (CLI commands, MCP tools, vault layout, export format) you can build on without breakage inside 1.x. See the CHANGELOG for the full history.


The one-sentence idea

EleSync is an MCP server sitting on top of a local-first file store.

Because MCP is now supported natively by OpenAI, Google and Anthropic, a single server makes one vault you own readable and writable by all of them — live and bidirectionally.

Who it's for

EleSync is for people who use AI — not engineers building agents.

"AI memory" is having a moment, but most of it is developer infrastructure: memory layers and SDKs you wire into agents you're coding (mem0, Letta, Zep), or autonomous-agent products that manage their own memory (Manus). Powerful — for builders.

EleSync is the everyday-user end of that spectrum:

  • No code, no agent to build, no cloud account. Install it, run ele onboard, done.
  • It plugs into the apps you already talk to — Claude, ChatGPT, Gemini — instead of asking you to adopt a new one.
  • The memory is yours: plain markdown files on your disk, not rows in someone else's database.

If you've ever had to re-explain yourself to a fresh chat, EleSync is for you. If you're wiring a memory store into a fleet of autonomous agents, one of the developer tools above is the better fit.

Why this, when Anuma / Memory Forge exist?

The "unified memory layer" concept is validated (Anuma crossed ~60k users). The gap they leave open is the wedge here:

Anuma Memory Forge EleSync (this)
Open / inspectable ✗ closed app partial ✓ your files, your code
MCP server ✗ none ✓ core feature
Keep using Claude/ChatGPT/Gemini apps ✗ must switch in n/a ✓ they connect to you
Live read + write back within app ✗ static file
Infrastructure crypto/wallet browser only ✓ zero — files + SQLite

"Eco-friendly and easy" = no server, no database to run, no blockchain/wallet. Markdown + SQLite.

Architecture

  ChatGPT export ─┐
  Claude export  ─┤   adapters/normalize.py      ┌─ notes/*.md   (source of truth, Obsidian-compatible)
  Gemini export  ─┼─►  → MemoryItem (schema) ──►  │
  manual notes   ─┘                               └─ index.db    (SQLite + FTS5 full-text search)
                                                         │
                                                         ▼
                                              mcp_server.py  (the connector)
                                                         │
                       ┌─────────────────────────────────┼─────────────────────────────────┐
                   Claude Desktop                     ChatGPT                            Gemini / any MCP client
                   recall / remember / forget / memory_status / list_scopes
  • elesync/models.py — the normalized MemoryItem schema every source maps into.
  • elesync/store.py — local-first store: markdown files + SQLite FTS index, with content-hash dedup (re-importing is idempotent).
  • elesync/normalize.py — tolerant ingest adapters that sniff each provider's export shape.
  • elesync/mcp_server.py — exposes the vault over MCP (recall, remember, forget, memory_status, find_conflicts, list_scopes).
  • elesync/cli.pyimport, search, add, stats, reindex, sync, conflicts, scope, scopes, embed, export, encrypt, decrypt, serve.
  • elesync/embeddings.py — optional semantic recall: vectors stored alongside the SQLite index, brute-force cosine, hybrid keyword+vector ranking. Degrades to keyword-only.
  • elesync/crypto.py — optional encryption at rest: argon2id key + libsodium per-file AEAD; the index is a rebuildable cache. Plaintext stays the default.

Install

Works on macOS, Windows, and Linux. Needs Python 3.10+ and Claude Desktop.

Not a developer? The plain-English setup guide walks through every step, including where to get your memory export files from ChatGPT, Claude, and Gemini.

1 · Install

pip install "elesync[mcp]"

No Python yet? Download from python.org/downloads — on Windows tick "Add Python to PATH" during install. If pip isn't found: use py -m pip … (Windows) or python3 -m pip … (Mac/Linux).

ele --version          # → EleSync 1.3.0

2 · Import your memories from ChatGPT / Claude / Gemini

ele import ~/Downloads/chatgpt_memory.json   --source chatgpt
ele import ~/Downloads/claude_export.json    --source claude
ele import ~/Downloads/gemini_memory.json    --source gemini

Re-importing is always safe — duplicates are skipped automatically.

3 · Connect to Claude Desktop — one command

ele onboard

Finds the Claude config file automatically on macOS/Windows/Linux, backs it up, and wires EleSync in. Then fully quit and reopen Claude Desktop (not just close the window — quit the whole app).

4 · Verify

ele doctor

Then ask Claude: "What do you remember about me?" — that's your live confirmation. 🎉

Install from source instead (for contributors / latest master)
git clone https://github.com/darknodebros/EleSync.git
cd EleSync
pip install -e ".[mcp]"

No git? Use the green Code → Download ZIP button on the repo page, unzip, and run the pip install from inside the folder.

Prefer to wire Claude by hand?

ele onboard --print-only prints the exact block to paste into your Claude Desktop config file:

{
  "mcpServers": {
    "elesync": {
      "command": "python",
      "args": ["-m", "elesync.mcp_server"],
      "env": { "ELESYNC_DIR": "/path/to/your/EleSyncVault" }
    }
  }
}

Use it with other AI apps (any MCP client)

EleSync is a standard MCP server, so the same vault works with any app that can act as an MCP client — not just Claude Desktop. Tools like Manus, Cursor, and other MCP-capable apps can connect and recall / remember against your vault live — no adapter, no export/import.

The how-to is the same everywhere: point the client at EleSync's MCP server. Print the config block with

ele onboard --print-only

then add that mcpServers entry wherever the app keeps its MCP config (in Manus: Settings → Connectors; in Cursor: its MCP settings), with ELESYNC_DIR pointing at your vault. Done — that app now reads and writes the one vault every other AI shares.

Note: the ele import adapters are for chat assistants that expose a memory export. Three platforms offer verified exports today (ChatGPT, Claude, Gemini); four more have adapters ready for when exports become available (Grok, DeepSeek, Perplexity, Copilot). Agent tools like Manus don't offer one — and don't need it: they connect as a live MCP client instead.

Everyday use

Import what your AIs already exported, then search across all of them at once:

ele import ~/Downloads/chatgpt_memory.json --source chatgpt
ele import ~/Downloads/claude_export.json   --source claude

ele search "project notes"
ele add "Prefers direct, no-fluff answers" --type preference
ele stats

ele summary                    # see everything your vault knows about you
ele summary --short            # quick overview — counts + top facts
ele export vault-backup.json   # back up / move your whole vault
ele reindex                    # rebuild the search index from notes/*.md
ele forget <id>                # delete a memory by full id or 8-char prefix

# Auto-import: watches ~/Downloads and imports exports as they arrive
pip install "elesync[watch]"
ele watch                      # Ctrl+C to stop
ele watch --autostart          # register as a login item (runs from boot)

The file paths above are just examples — point them at wherever your export files are. EleSync keeps its vault at ~/EleSyncVault; to use a different folder set ELESYNC_DIR (macOS/Linux: export ELESYNC_DIR=~/my-vault · Windows PowerShell: $env:ELESYNC_DIR="C:\path\to\my-vault").

Now Claude can recall your full cross-AI context at the start of any chat and remember new durable facts back into the same vault that ChatGPT and Gemini read from.

Semantic recall (optional)

By default, search is keyword-based (SQLite FTS) — no dependencies, no model. Install the optional extra to also match on meaning, so recall finds the right memory even when the wording differs:

pip install "elesync[semantic]"     # adds a small local ONNX model (no PyTorch, no cloud)
ele embed                            # embed existing memories (first run downloads the model)
ele --semantic search "where do they live"   # → surfaces "Based in Westbrook"

Vectors are stored as float32 blobs in the same SQLite index — no new datastore — and ranking fuses keyword + vector hits (Reciprocal Rank Fusion), so exact matches stay strong while semantically-close memories surface too. Set ELESYNC_SEMANTIC=1 to make it the default (the MCP server picks this up too). Without the extra, everything works exactly as before.

Encryption at rest (optional)

Plaintext markdown is the default (so the vault stays Obsidian-readable). If you'd rather your notes be unreadable on disk — a stolen laptop, a leaked backup, a synced folder — encrypt the vault with a passphrase:

pip install "elesync[encryption]"
ele encrypt          # encrypts notes/*.md → *.md.enc, drops the plaintext index

Each note is encrypted with XSalsa20-Poly1305 (libsodium); your passphrase is stretched to a key with argon2id (the key is never written to disk — only the salt + params live in vault.json).

Use it while it stays encrypted. You don't have to decrypt the whole vault to use it — just supply the passphrase and EleSync unlocks it live, building the search index only in memory (nothing plaintext ever touches the disk):

ELESYNC_PASSPHRASE= ele search "project notes"   # or it'll prompt you
ele add "Prefers concise answers" --type preference   # writes a new *.md.enc, still encrypted at rest
ele decrypt                                        # permanently revert to plaintext when you want

The MCP server does the same: set ELESYNC_PASSPHRASE in its config and it serves the encrypted vault live (key held in memory for the session). ele decrypt is only for permanently turning encryption back off.

Threat model — be clear-eyed. This protects data at rest (stolen disk, leaked backup, synced folder). It does not protect a running process, or a host where your passphrase is in memory or in an env var. Lose the passphrase and the data is unrecoverable.

Scoped sharing (optional)

One vault, but not every AI needs to see every memory. Your writing style is fine for any assistant; your legal or health notes are not. Scopes let a single vault present a different slice of itself to each client — the everyday-user version of what Anuma gates by category, with zero new infrastructure.

The model is one rule: a memory with no scope is general — visible to everyone, exactly as today — and a memory with a scope is visible only to a client granted that scope. Scoping is opt-in restriction, so every memory you already have is unaffected.

# tag memories into compartments (or scope an existing one in place)
ele add "Lawsuit vs Acme; settle at 10k" --type fact --scopes legal
ele scope 1dc24751 writing,coding        # re-scope by id/prefix (never forks identity)
ele scopes                               # list compartments with counts

# audit exactly what a given client would see, before you trust it
ele --as general,writing scopes           # which compartments are visible — legal/health absent
ele --as general,writing search Acme      # the legal "Acme" memory above won't surface

Each client carries a grant as an env var — the same local-first pattern as ELESYNC_DIR: ELESYNC_SCOPES=general,writing lets that client see general + writing and nothing else, and ELESYNC_WRITE_SCOPE=writing files everything it remembers into the writing compartment. Unset means unrestricted (the full vault), so existing setups are unchanged. ele onboard wires it for you:

# Claude Desktop: writing + general only
ele onboard --scopes general,writing --write-scope writing

# a second, legal-scoped connection in the SAME client (distinct --name)
ele onboard --scopes general,legal --write-scope legal --name elesync-legal

Every read path is grant-aware — recall, find_conflicts, memory_status and even forget filter by the client's scope, so a scoped client can't read or infer the existence of anything outside its compartment (counts and conflict output never leak hidden memories). An AI can discover its own compartments with the list_scopes MCP tool.

Be clear-eyed about the boundary. Scopes are organisational hygiene, not a cryptographic wall: the boundary is the per-client config you control, and a client you point at the vault with no ELESYNC_SCOPES set sees everything, by design. For data that must be unreadable even to a process that opens the vault, use encryption at rest — the two compose (an encrypted vault still scopes).

Spotting contradictions (provenance)

When two AIs record facts that disagree — "Based in Westbrook" (from Claude) vs "Based in Portland" (from ChatGPT) — EleSync surfaces the conflict with provenance instead of silently treating both as true:

ele conflicts
# Found 1 possible conflict(s) — review and `forget` the wrong one:
# 1. Same topic, different values:
#    - [claude, 2026-03-12] Based in Westbrook  (id=ff85b854)
#    - [chatgpt, 2026-05-01] Based in Portland   (id=efbecb07)

recall flags it inline too (so a connected AI notices and can ask you), and there's a find_conflicts MCP tool. Detection is a deliberately simple, local heuristic — it flags facts that look like they're about the same thing but differ — so treat results as candidates to review, not verdicts. EleSync only ever surfaces; you resolve with ele forget <id>.

Portable USB vault (carry your memory anywhere)

Plug in a USB drive, run one command, and your encrypted AI memory goes with you everywhere. On any machine with Python, python RUN_ME.py installs EleSync and connects it to Claude — no prior knowledge needed.

pip install "elesync[mcp,encryption]"

# One-time setup on your USB drive
ele usb install /Volumes/MyUSB          # macOS
ele usb install E:\\                    # Windows
ele usb install /media/myusb            # Linux
# Enter a passphrase when prompted — this encrypts everything on the drive

# Later: import your AI memories onto the drive
ele --vault /Volumes/MyUSB/EleSyncVault import chatgpt_memory.json --source chatgpt
ele --vault /Volumes/MyUSB/EleSyncVault import claude_export.json  --source claude
ele --vault /Volumes/MyUSB/EleSyncVault import gemini_memory.json  --source gemini

# Connect to Claude Desktop (on any machine)
ele usb attach /Volumes/MyUSB           # prompts for passphrase, wires Claude Desktop
# → Fully quit and reopen Claude Desktop

# Before unplugging
ele usb detach /Volumes/MyUSB           # removes Claude Desktop entry
ele usb eject  /Volumes/MyUSB           # safe-eject

# Other commands
ele usb list                            # see all removable drives
ele usb status /Volumes/MyUSB          # check vault health & memory count

On a new machine — plug in the drive and run:

python /Volumes/MyUSB/RUN_ME.py

That's it. RUN_ME.py is a self-contained script the drive carries with it: it installs EleSync via pip (if needed) and wires the USB vault into Claude Desktop — no prior knowledge of pip or MCP required.

Security model — USB vaults are always encrypted (unlike the main vault where encryption is opt-in). Your passphrase is the only thing that unlocks the vault; a lost or stolen drive exposed nothing without it. The same XSalsa20-Poly1305 + argon2id encryption used by ele encrypt is applied automatically at install time.

The USB vault is a standard EleSync vault at <drive>/EleSyncVault. You can run any normal ele command against it by passing --vault <drive>/EleSyncVault. Nothing is synced automatically between the USB vault and your main vault — use ele export + ele import to move memories between them.

Local web UI

No terminal needed once EleSync is installed — ele web opens a clean browser-based vault explorer:

ele web                 # opens http://127.0.0.1:7477 in your browser
ele web --port 8080     # custom port
ele web --no-browser    # start server without auto-opening browser

What you get:

Tab What it does
Dashboard Total memories, AI source breakdown, FTS / embedding status
Browse Paginated list with live filter, source & type dropdowns
Search Instant full-text search across all memories
Add Memory Manually add a memory (content, source, type, tags)
Import Drag-and-drop a ChatGPT / Claude / Gemini / Grok export JSON

Click any memory to open a slide-in editor — update content, type, tags, or delete it.

Zero extra dependencies — pure Python stdlib http.server. Works with encrypted vaults (prompts for passphrase at startup). Binds to 127.0.0.1 only.


Sync across devices

Your vault is just a folder (notes/*.md + a small vault.json), so sync it however you already sync files — git, iCloud, Syncthing, Dropbox, Drive. No server, no account.

Two things to know:

  • Don't sync index.db — it's a local, rebuildable cache. ele sync drops a .gitignore in your vault so git skips it automatically; for other tools, just exclude index.db.
  • After pulling changes on another device, run ele sync. It rebuilds the index from the notes and tells you what changed (e.g. "2 added, 1 changed, 0 removed"). Plain ele reindex does the rebuild silently if you don't care about the diff.
# device B, after a git pull / iCloud sync
ele sync        # → "1 added, 0 changed, 0 removed. Vault holds 42."

Encrypted vaults sync safely through even an untrusted service — the notes are *.md.enc ciphertext at rest, so the sync provider only ever sees encrypted blobs.

Troubleshooting

Run this first — it checks everything and tells you in plain words what needs fixing:

ele doctor
🔴 Claude says it doesn't know anything

You almost certainly closed the window instead of quitting the app. MCP connections are only loaded when Claude starts.

  • Mac: press Cmd + Q to quit, then reopen
  • Windows: right-click the Claude icon near the clock → Quit, then reopen

If that doesn't fix it: run ele doctor and check that "Claude Desktop config wired" says PASS. If it says WARN, run ele onboard again.

🔴 ele: command not found (or 'ele' is not recognized)

The ele shortcut wasn't added to your PATH. Use the full form instead — it works for every command:

python -m elesync.cli --version
python -m elesync.cli onboard
python -m elesync.cli import ~/Downloads/chatgpt_memory.json --source chatgpt

Or add the scripts folder pip printed to your PATH, then restart the command box.

🔴 pip: command not found
  • Windows: use py -m pip install "elesync[mcp]"
  • Mac / Linux: use python3 -m pip install "elesync[mcp]"
🔴 Python too old or not found

EleSync needs Python 3.10 or newer. Check: python --version (or python3 --version). Download the latest from python.org/downloads. On Windows, tick "Add Python to PATH" during install.

🔴 ModuleNotFoundError: No module named 'mcp'

Run: pip install "mcp[cli]" then restart Claude.

🔴 Semantic search not matching on meaning

Semantic recall is optional. Enable it once:

pip install "elesync[semantic]"
ele embed

Then search with ele --semantic search "your query".

Still stuck? Open an issue at github.com/darknodebros/EleSync/issues and paste the output of ele doctor. We'll help.

Tests

python -m unittest discover -s tests -v   # 179 tests, stdlib only — no MCP SDK required

Where the export files come from (2026 reality)

EleSync ships 3 verified sources (real, user-accessible memory exports today) and 4 experimental adapters (code is ready, but the platforms don't yet offer a native memory export — bring-your-own-format only).

Verified — real exports you can get right now:

  • ChatGPT — Settings → Data controls → Export memory (JSON of stored facts/preferences)
  • Claude — claude.ai → Settings → Export data → memory export (structured JSON)
  • Gemini — Google Takeout → select "Gemini" → download ZIP, extract the memory JSON

Experimental — adapters built, export not yet publicly available:

  • Grok — adapter expects {"grok_memories": [...]}; xAI has not shipped a user-accessible memory export
  • DeepSeek — adapter expects {"deepseek_memories": [...]}; no native export available
  • Perplexity — adapter expects {"perplexity_memories": [...]}; no native export available
  • Copilot — adapter expects {"copilot_memories": [...]}; Microsoft has not shipped a memory export

These four platforms do not currently provide user-accessible memory exports. The adapters are ready for when they do. Contributions welcome once formats are confirmed.

EU/EEA availability of the in-app import tools may be restricted; importing your own export file into your own vault sidesteps that entirely.

Roadmap (the honest next 20%)

  1. Semantic recall — ✅ landed (optional [semantic] extra: local ONNX embeddings, hybrid keyword+vector ranking — see above). Next: semantic dedup (near-duplicate detection), and pgvector/sqlite-vec if a vault ever outgrows brute-force cosine.
  2. Encryption at rest — ✅ landed, both phases (see above): opt-in ele encrypt/decrypt (libsodium + argon2id), and live "locked mode" — supply the passphrase and the vault is queryable/writable with an in-memory index, so the CLI and MCP server use it without ever decrypting to disk.
  3. Sync — it's just files: git, iCloud, Syncthing, or Drive. No server to build. After syncing the notes to another machine, ele reindex rebuilds the search index from the markdown so the vault and its index agree again.
  4. Scoped sharing — ✅ landed (see above): per-client memory scopes via ELESYNC_SCOPES, so one vault shows Claude your writing style while keeping legal/health context in a compartment it can't see — ele scope/ele scopes/ele --as, a list_scopes MCP tool, and ele onboard --scopes. Next: an optional per-scope passphrase so a compartment is encrypted and access-gated, not just gated.
  5. Provenance & conflict resolution — ✅ landed (ele conflicts + find_conflicts MCP tool, and recall flags clashes inline — see above). Next: smarter detection (embedding-based, or an optional LLM pass) beyond the current lexical heuristic.
  6. More adapters — 3 verified (ChatGPT, Claude, Gemini) + 4 experimental (Grok, DeepSeek, Perplexity, Copilot) — adapters are ready, waiting on the platforms to ship user-accessible exports. (Manus was researched and ruled out — it's an autonomous agent with no memory export; it connects as a live MCP client instead.) Each new verified source is a ~40-line file in normalize.py.

License

MIT — see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

elesync-1.3.1.tar.gz (97.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

elesync-1.3.1-py3-none-any.whl (73.8 kB view details)

Uploaded Python 3

File details

Details for the file elesync-1.3.1.tar.gz.

File metadata

  • Download URL: elesync-1.3.1.tar.gz
  • Upload date:
  • Size: 97.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for elesync-1.3.1.tar.gz
Algorithm Hash digest
SHA256 377f822f07617f0415e75dd9a7cda213d9fe7e883b9c6eaf6d4e0a791ea8c869
MD5 4aaa1c44d088ee7a4feaeaa82fb01f5e
BLAKE2b-256 c5ea7c9efc3f84fedf38a1bc7174082fed06637e658717ffc7a701e4e671331d

See more details on using hashes here.

Provenance

The following attestation bundles were made for elesync-1.3.1.tar.gz:

Publisher: release.yml on darknodebros/EleSync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file elesync-1.3.1-py3-none-any.whl.

File metadata

  • Download URL: elesync-1.3.1-py3-none-any.whl
  • Upload date:
  • Size: 73.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for elesync-1.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7b897b6dfab229c58f4d168ea53fae090adcab10276d78282fc9397dfe29a514
MD5 9fc5af19995eaae905a7ea8fddbe55f5
BLAKE2b-256 9eb67e0ca4c6098896287c984e1c6e918b5b8ed90c058497424e1f0783a89ed2

See more details on using hashes here.

Provenance

The following attestation bundles were made for elesync-1.3.1-py3-none-any.whl:

Publisher: release.yml on darknodebros/EleSync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page