Skip to main content

Xanther Memory Engine (XME)

Persistent memory for AI coding assistants.

License: Apache 2.0 Python 3.10+ PyPI


Your AI assistant forgets every decision you've made. It repeats the same failed approaches. It re-explains your stack every session. XME fixes this.

XME gives AI coding assistants persistent memory across sessions. Works with Claude Code, Kiro, Cursor, Codex, and any MCP-compatible tool. No cloud required.

pip install xanther-memory-engine
xme hook install .      # 30 seconds — auto-captures every session
xme start my-project    # memory starts now

Want code intelligence too? Install XME bundled with the Xanther Context Engine (XCE) in one command:

pip install "xanther-xce[all]"        # XCE + XME together
# or run instantly, no install:
uvx --from "xanther-xce[all]" xanther --help

Architecture

graph TB
    subgraph "AI Agent (Claude Code / Kiro / Cursor)"
        AGENT[Agent]
        HOOKS[IDE Hooks<br/>agentStop · promptSubmit]
    end

    subgraph "XME Memory Engine"
        ENGINE[MemoryEngine<br/>xme/engine.py]

        subgraph "Layer 1 — Episodic"
            EP[EpisodicStore<br/>Verbatim session transcripts]
        end

        subgraph "Layer 2 — Facts"
            FG[FactGraphStore<br/>Decisions · Attempts<br/>Preferences · Conventions]
            EXT[FactExtractor<br/>LLM or regex]
            EMB[LocalEmbedder<br/>all-MiniLM-L6-v2]
            EXT --> FG
            EMB --> FG
        end

        subgraph "Layer 3 — Context"
            CTX[ContextStore<br/>Working state per project+user<br/>UPSERT semantics]
        end

        ENGINE --> EP & FG & CTX
    end

    subgraph "Storage"
        OS[(OpenSearch<br/>port 9200<br/>Full-text + k-NN)]
        NEO4J[(Neo4j<br/>port 7687<br/>Fact graph + vectors)]
        SQLITE[(SQLite<br/>.xanther/xme.db<br/>Context + fallback)]
    end

    subgraph "Outputs"
        MCP[MCP Server<br/>11 tools]
        DASH[Dashboard<br/>port 8001]
        EXP[Exports<br/>Obsidian · Wiki · Graphify]
    end

    HOOKS -- buffer files --> ENGINE
    AGENT -- MCP tool calls --> MCP
    EP --> OS & SQLITE
    FG --> NEO4J & SQLITE
    CTX --> SQLITE
    ENGINE --> DASH & EXP
    ENGINE --> MCP

Local Infrastructure

graph LR
    subgraph "Your Machine"
        subgraph "Docker Compose"
            NEO4J[(Neo4j:7687<br/>Fact knowledge graph)]
            OS[(OpenSearch:9200<br/>Episodic search)]
        end

        subgraph "XME Process"
            CLI[xme CLI]
            DASH[xme dashboard<br/>:8001]
            MCP_SRV[MCP Server]
        end

        subgraph "Hook Files"
            BUF[.xanther/turns/<br/>Buffer files<br/>written per turn]
            DB[.xanther/xme.db<br/>SQLite warm store]
        end

        subgraph "IDE"
            KIRO[Kiro / Claude Code]
            MCP_CFG[mcp.json]
        end
    end

    subgraph "External APIs (optional)"
        OR[OpenRouter API<br/>LLM fact extraction]
    end

    KIRO -- agentStop hook --> BUF
    KIRO -- promptSubmit hook --> BUF
    CLI -- drain buffer --> DB
    CLI -- index to --> NEO4J & OS
    MCP_CFG -- spawn --> MCP_SRV
    MCP_SRV -- read --> NEO4J & OS & DB
    KIRO -- MCP tool calls --> MCP_SRV
    CLI -. LLM extraction .-> OR
    DASH -- read --> NEO4J & OS & DB

Session lifecycle

sequenceDiagram
    participant IDE as Kiro / Claude Code
    participant HOOK as Hook Handler<br/>.xanther/hook.py
    participant BUF as Buffer<br/>.xanther/turns/
    participant XME as XME Engine
    participant DB as Neo4j + SQLite

    IDE->>HOOK: promptSubmit (user message)
    HOOK->>BUF: write turn JSON (< 5ms)

    IDE->>HOOK: promptSubmit (next message)
    HOOK->>BUF: write turn JSON

    Note over IDE,DB: ... more turns ...

    IDE->>HOOK: agentStop (response finished)
    HOOK->>BUF: write session_end marker

    Note over BUF,DB: On next xme start or xme_session_end MCP call

    XME->>BUF: drain all buffer files
    XME->>XME: extract facts (LLM or regex)
    XME->>DB: upsert facts with vector dedup
    XME->>DB: save episode to OpenSearch
    XME->>DB: update working context (UPSERT)

    Note over IDE,DB: Next session

    IDE->>XME: xme_session_start
    XME->>DB: load working context
    XME->>DB: load recent facts
    XME->>DB: load last episode summary
    XME-->>IDE: primed context block (inject into prompt)

Three memory layers

flowchart LR
    subgraph "Layer 1 — Episodic"
        direction TB
        E1[Full session transcripts<br/>verbatim]
        E2[Searchable by:<br/>full-text · semantic · date · user]
        E3[Backend: OpenSearch<br/>Fallback: SQLite FTS5]
        E1 --> E2 --> E3
    end

    subgraph "Layer 2 — Facts"
        direction TB
        F1[Extracted knowledge nodes]
        F2[Types:<br/>Decision · Attempt<br/>Preference · Convention · Entity]
        F3[UPSERT dedup<br/>cosine similarity > 0.85]
        F4[Backend: Neo4j graph<br/>+ vector index]
        F1 --> F2 --> F3 --> F4
    end

    subgraph "Layer 3 — Context"
        direction TB
        C1[Live working state<br/>per project + user]
        C2[Fields:<br/>current_task · next_steps<br/>recent_decisions · blockers]
        C3[UPSERT only — always current<br/>Backend: SQLite]
        C1 --> C2 --> C3
    end

    EP[Episodic\nStore] --> L1(Layer 1)
    FG[Fact\nGraph] --> L2(Layer 2)
    CTX[Context\nStore] --> L3(Layer 3)

    style L1 fill:#dbeafe
    style L2 fill:#dcfce7
    style L3 fill:#fef9c3

Quickstart

pip install xanther-memory-engine
xme hook install .
xme start my-project

With full infrastructure (Neo4j + OpenSearch):

cp .env.example .env        # set NEO4J_PASSWORD
docker-compose up -d
xme start my-project

Zero infrastructure (SQLite only, no Docker):

XME_FALLBACK_MODE=true xme start my-project

What gets captured automatically

After xme hook install .:

  • Every prompt is buffered to .xanther/turns/ (< 5ms, no blocking)
  • On agentStop: buffer drains → facts extracted → context updated
  • Next session: agent gets a primed context block injected automatically
**Current task**: Refactor auth module
**Last session**: Moved JWT to dedicated auth service — success
**Recent decisions**:
  - [VALIDATED] Use FastAPI — async support required
  - [VALIDATED] PostgreSQL — ACID compliance
**Known failed approaches**:
  - Redis distributed lock — timeout under high load
**Next steps**: Deploy auth service to staging

MCP tools (11)

Tool Description
xme_session_start Start session, get primed context block
xme_session_end End session: persist episode, extract facts, update context
xme_add Add content — Mem0-style UPSERT with deduplication
xme_search Search across all 3 layers simultaneously
xme_get_context Get working context for prompt injection
xme_facts Query fact graph (filter by type, user, keyword)
xme_episodes Full-text + semantic search over past sessions
xme_remember Explicitly store a typed fact
xme_forget Soft-delete a memory node
xme_export Export to Obsidian vault / wiki / Graphify JSON
xme_context_update Partial UPSERT of working context fields

Add to MCP config:

{
  "mcpServers": {
    "xme": {
      "command": "xme",
      "args": ["serve"],
      "env": {
        "NEO4J_PASSWORD": "your-password"
      }
    }
  }
}

Deduplication

Facts are stored once, not repeated across sessions:

flowchart TD
    A[New content added] --> B[Embed with\nall-MiniLM-L6-v2]
    B --> C{Similar fact exists?\ncosine > 0.85}
    C -- Yes --> D[Merge into existing fact\nupdate content + metadata]
    C -- No --> E[Create new fact node]
    D --> F[Update Neo4j + SQLite]
    E --> F

Comparison

Mem0 Zep MemPalace XME
Episodic memory
Fact graph partial
Working context UPSERT
Multi-user scoping
Deduplication
Local-first / open source
MCP tools ✅ (11)
Obsidian export
Dashboard UI
Code graph integration ✅ via XCE

CLI

xme start <project>              # init + show stats
xme add <project> <user> <text>  # add content to memory
xme search <project> <query>     # search all layers
xme facts <project>              # list facts
xme stats <project>              # memory health metrics
xme export <project>             # export (obsidian/wiki/graphify)
xme dashboard                    # launch web UI (port 8001)
xme hook install [path]          # install Kiro + Claude Code hooks
xme hook uninstall [path]        # remove hooks

Configuration

# LLM for better fact extraction (optional — regex works without it)
OPENROUTER_API_KEY=sk-or-...
XME_LLM_MODEL=openai/gpt-4o-mini

# Neo4j — fact graph (recommended, free tier at console.neo4j.io)
NEO4J_URI=bolt://localhost:7687
NEO4J_PASSWORD=your-password

# OpenSearch — episodic search (optional, falls back to SQLite FTS5)
XME_OPENSEARCH_URL=http://localhost:9200

# Zero-infrastructure mode
XME_FALLBACK_MODE=false   # set true for SQLite-only, no Docker needed

See .env.example for the complete reference.


Related

Xanther Context Engine (XCE) — code graph intelligence. When installed alongside XME, decisions link directly to the code they affect.

pip install "xanther-context-engine[memory]"  # XCE + XME together

License

Apache 2.0. See LICENSE.

Download files

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

Source Distribution

xanther_xme-0.1.1.tar.gz (100.9 kB view details)

Uploaded Source

Built Distribution

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

xanther_xme-0.1.1-py3-none-any.whl (56.8 kB view details)

Uploaded Python 3

File details

Details for the file xanther_xme-0.1.1.tar.gz.

File metadata

  • Download URL: xanther_xme-0.1.1.tar.gz
  • Upload date:
  • Size: 100.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for xanther_xme-0.1.1.tar.gz
Algorithm Hash digest
SHA256 1625290c0cd909524c19741a957a38ba201d76ead7f1b432627a0e698d81841a
MD5 0b5fd50668c514e5ff37ae8d047e7f08
BLAKE2b-256 19323787ff096b76ff02c1d0863b3e397b0bcf27985ffd3a239a2d6bf65aa0ae

See more details on using hashes here.

File details

Details for the file xanther_xme-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: xanther_xme-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 56.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for xanther_xme-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e0379bb1e00a65ba1f88f93857a9dd95381898317a87836c0f7e885756c452fb
MD5 58b3d8a589600cc843b180f99f1f5306
BLAKE2b-256 d3834c37f8474a0034759df1c4f284bf6dd5f8968e0a8f4b76594cdd9ee4fb87

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page