Metadata-Version: 2.4
Name: elesync
Version: 0.1.3
Summary: Local-first, MCP-native unified memory vault — your AI memory as files you own, shared across every model.
Author: Alphanymous
License: MIT
Project-URL: Homepage, https://github.com/darknodebros/EleSync
Project-URL: Repository, https://github.com/darknodebros/EleSync
Project-URL: Issues, https://github.com/darknodebros/EleSync/issues
Keywords: mcp,ai-memory,local-first,claude,chatgpt,gemini,grok,deepseek,memory,elesync
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: mcp
Requires-Dist: mcp[cli]>=1.2.0; extra == "mcp"
Provides-Extra: semantic
Requires-Dist: fastembed>=0.3.0; extra == "semantic"
Provides-Extra: encryption
Requires-Dist: pynacl>=1.5; extra == "encryption"
Provides-Extra: dev
Requires-Dist: mcp[cli]>=1.2.0; extra == "dev"
Requires-Dist: fastembed>=0.3.0; extra == "dev"
Requires-Dist: pynacl>=1.5; extra == "dev"
Dynamic: license-file

# 🐘 EleSync

### Your AI memory, as files you own. One vault. Every model.

[![PyPI](https://img.shields.io/pypi/v/elesync.svg)](https://pypi.org/project/elesync/)
[![CI](https://github.com/darknodebros/EleSync/actions/workflows/ci.yml/badge.svg)](https://github.com/darknodebros/EleSync/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![MCP](https://img.shields.io/badge/MCP-native-8A2BE2.svg)](https://modelcontextprotocol.io)


You use Claude, ChatGPT, and Gemini. Each one knows a different slice of you, and none
of them share. **EleSync** is one local-first vault on your own disk that every AI
plugs into over the [Model Context Protocol](https://modelcontextprotocol.io) — so context
you build in one AI is instantly available in all of them. Local-first. MCP-native. Yours.

> No pasting context around. No static "memory chips." No switching apps. The AIs you
> already use connect to a vault *you* control.

```
Teach ChatGPT a fact  →  it lands in your vault  →  Claude already knows it.
```

**The whole setup — paste this and you're done:**

```bash
pip install "elesync[mcp]"   #  install
ele onboard                  #  connect it to your AI app — that's it
```

**No accounts. No servers. No database. No cloud. No config files.** Your memories are plain
markdown files on your own disk — that's the entire footprint. Nothing to sign up for, nothing
to run, nothing to maintain.

This is a working seed (MVP), not a toy: the core has a passing 60-test suite and a CLI
you can run today.

---

## 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 crypto. 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
```

- **`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`).
- **`elesync/cli.py`** — `import`, `search`, `add`, `stats`, `reindex`, `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

Install from [PyPI](https://pypi.org/project/elesync/) in one line. Works on **macOS, Windows, and Linux**; needs **Python 3.10+**. To use it as a live connector you also need a desktop AI app that speaks MCP — e.g. **[Claude Desktop](https://claude.ai/download)**.

**1 · Install EleSync**

```bash
pip install "elesync[mcp]"
```
> No Python yet? Get it from **[python.org/downloads](https://www.python.org/downloads/)** (on **Windows, tick "Add Python to PATH"**). If `pip` isn't found, use `py -m pip …` (Windows) or `python3 -m pip …` (macOS/Linux). The `[mcp]` part adds the connector SDK.

Confirm it worked:
```bash
ele --version          # → EleSync 0.1.3
```

**2 · Connect it to Claude — one command**

```bash
ele onboard
```
This creates your vault (default: `~/EleSyncVault`) and writes the EleSync entry into your Claude Desktop config **automatically** — it finds the right file on macOS/Windows/Linux and backs up any existing config first. Then **fully quit and reopen Claude Desktop**.

**3 · Verify**

```bash
ele doctor             # checks Python, vault, search, MCP SDK, and the Claude wiring
```
Then ask Claude: *"What do you remember about me?"* — that's your live confirmation. 🎉

<details>
<summary>Install from source instead (for contributors / latest <code>master</code>)</summary>

```bash
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.
</details>

<details>
<summary>Prefer to wire Claude by hand?</summary>

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

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

## 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](https://manus.im)**, 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

```bash
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 only for chat assistants that expose a **memory export** (ChatGPT, Claude, Gemini, Grok, DeepSeek). 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:

```bash
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 export vault-backup.json   # back up / move your whole vault
ele reindex                    # rebuild the search index from notes/*.md
```

> 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:

```bash
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:

```bash
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):

```bash
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.

## Troubleshooting

**First move for anything weird:** run `ele doctor` — it checks your Python version, the vault, search, the MCP SDK, and the Claude wiring, and tells you exactly what's wrong.

<details>
<summary><code>ele: command not found</code> (or <code>'ele' is not recognized</code>)</summary>

The install put the `ele` launcher in a folder that isn't on your PATH (pip usually prints a "Scripts installed in '…' which is not on PATH" warning).

- **Quickest workaround** — run it as a module instead: `python -m elesync.cli --version` (works for every command: `python -m elesync.cli onboard`, etc.).
- **Proper fix** — add the folder pip mentioned to your PATH, *or* use a virtual environment (recommended), which puts `ele` on PATH automatically while active:
  ```bash
  python -m venv .venv
  # macOS/Linux:           source .venv/bin/activate
  # Windows (PowerShell):  .venv\Scripts\Activate.ps1
  pip install -e ".[mcp]"
  ```
</details>

<details>
<summary><code>pip: command not found</code></summary>

Use Python's bundled pip: **Windows** → `py -m pip …`; **macOS/Linux** → `python3 -m pip …`.
</details>

<details>
<summary>Wrong / too-old Python, or several Pythons installed</summary>

EleSync needs **3.10+**. Check with `ele doctor` (or `python --version`). On Windows you can pick a specific version: `py -3.12 -m pip install -e ".[mcp]"`.
</details>

<details>
<summary>Claude doesn't seem to know anything / EleSync isn't showing up</summary>

1. **Fully quit** Claude Desktop — *quit the app* (Cmd/Ctrl+Q, or quit from the menu-bar/tray icon), not just close the window — then reopen it. MCP servers are only picked up at launch.
2. Run `ele doctor` — confirm the line "Claude Desktop config wired" says **PASS** (it shows which file). If it says WARN, run `ele onboard`.
3. Make sure the MCP SDK is installed: `pip install "mcp[cli]"`.
</details>

<details>
<summary><code>ModuleNotFoundError: No module named 'mcp'</code> when serving</summary>

The MCP SDK isn't installed (it's optional and only needed to *serve*). Install it: `pip install "mcp[cli]"` — or reinstall EleSync with the extra: `pip install -e ".[mcp]"`.
</details>

<details>
<summary>Semantic search isn't matching on meaning</summary>

Semantic recall is an optional extra. Install it and embed your memories:
```bash
pip install "elesync[semantic]"
ele embed                 # first run downloads a small model (one time)
ele --semantic search "…"
```
</details>

Still stuck? Open an issue with the output of `ele doctor` and we'll help.

## Tests

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

## Where the export files come from (2026 reality)

All three majors shipped memory export in March 2026 (GDPR Article 20 + competition), but
the formats are uneven and there's no clean memory API — so the adapters normalize the mess:
- **ChatGPT** — JSON of stored facts/preferences
- **Claude** — structured memory export from claude.ai
- **Gemini** — via Google Takeout (ZIP)
- **Grok** — xAI memory/personalization export (`{"grok_memories": [...]}`)
- **DeepSeek** — memory export (`{"deepseek_memories": [...]}`)
- **Perplexity** — memory export (`{"perplexity_memories": [...]}`)
- **Copilot** — Microsoft Copilot memory export (`{"copilot_memories": [...]}`)

EU/EEA availability of the in-app import tools is 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** — per-client memory scopes (let Claude see writing style without
   exposing legal/health context), the way Anuma gates by category.
5. **Provenance & conflict resolution** — when two AIs assert contradictory facts, surface
   it instead of silently picking one.
6. **More adapters** — Grok, DeepSeek, Perplexity, and Copilot have landed. (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 source is a ~40-line file in `normalize.py`.

## License

MIT — see [LICENSE](LICENSE) for details.
