$ show MemPalace/mempalace
MemPalace is a local-first, persistent memory system for AI agents. It stores and retrieves structured 'drawers' (memory chunks) organized into wings, rooms, and closets, with hybrid vector+BM25 search, a temporal knowledge graph, and agent coordination via a logstream. The system provides a CLI, an MCP server (both full and lightweight), and shell hooks for integration with Claude Code, Cursor, Codex, Antigravity, and DeepSeek Harness. It supports multiple storage backends (ChromaDB, SQLite exact, pgvector, Qdrant, Milvus, and a Rust native backend) and offers privacy-first operation with no mandatory API keys or internet connectivity. Architecturally, MemPalace is a modular Python package with optional Rust acceleration (PyO3). The core is split into several packages: `mempalace.cli` (fragment-exec-based CLI), `mempalace.mcp_server` (MCP tool server), `mempalace.palace` (palace operations and locks), `mempalace.searcher` (hybrid ranking and filters), and `mempalace.backends` (pluggable storage). The knowledge graph is SQLite-backed with temporal validity windows. A write-ahead log provides an audit trail. The system uses a hybrid logical clock (HLC) for causal ordering and a source adapter system for pluggable ingest. Although primarily an application, the project includes extensive benchmarking and model evaluation suites, giving it a mild hybrid character.
The LLM identified 7 files worth highlighting for reuse:
Implements a length-prefixed SHA-256 hashing scheme (`_delimited_sha256`) for generating drawer and triple IDs. Prevents boundary collisions (e.g., 'a1'+'23' vs 'a'+'123') by encoding each part with its length. The module is self-contained, has no internal imports beyond hashlib, and can be extracted and reused in any project requiring deterministic, collision-resistant IDs from concatenated parts.
Defines `BaseBackend` and `BaseCollection` abstract classes with capability tokens (`supports_*` flags) and a registry pattern. Provides a clean contract for vector storage backends (add, upsert, query, delete) with explicit read-only, filtering, and embedding support. The abstraction is decoupled from any concrete implementation and can be reused to build custom backends for other projects.
Implements a temporal knowledge graph with entity-relationship triples, confidence scores, validity intervals, supersession, and invalidation. Uses SQLite with a clean schema, supports `as_of` queries for point-in-time fact retrieval, and provides timeline pagination. The design is generic enough to be extracted for any application needing temporal fact storage with versioning.
A write-ahead audit log that records all mutating operations (add, update, delete) with intent and outcome. Automatically redacts sensitive fields (e.g., embeddings, full content) to avoid leaking privacy data into the log. Designed to never crash the caller and to be idempotent. The pattern is reusable for any system requiring a durable, privacy-conscious audit trail.
Implements connection strength dynamics based on Hebbian potentiation and Ebbinghaus exponential decay, with the Cepeda spacing effect. Pure math (no I/O) with configurable constants for stability growth. Can be extracted and reused in any system needing adaptive memory strength or reinforcement learning with time-based decay.
Core hybrid ranking engine that combines Okapi-BM25 scores with vector cosine similarity using configurable weights (default 0.6/0.4). Includes corpus-relative IDF, stop-word filtering (per-locale), tie-breaking by authored_at, and fallback to BM25-only when vector index is unavailable. The module is self-contained and can be reused in any search application needing a lightweight hybrid ranker.
Provides lock-safe SQLite probe connections for ChromaDB collections. Uses `immutable=1` connections and retains probe connections on POSIX to avoid dropping sibling POSIX locks. Handles the subtle interaction between Python sqlite3 and ChromaDB's internal locking, preventing corruption from concurrent readers. A reusable pattern for any system that needs to query SQLite databases held by another process.