Persistent vector memory for any MCP-compatible AI client — local, semantic, structured
⚠️ Active Development — APIs and tools may change without prior notice. Use tagged releases (vX.Y.Z) for stability.
Local MCP server compatible with any stdio-based AI client. Provides persistent structured memory, semantic search, version tracking and reindexing using local embeddings and LanceDB.
- Vector DB: LanceDB (local, stored in
./vectorial/) - Embeddings:
nomic-embed-textvia Ollama - Protocol: MCP over stdio
- Runtime: Node.js + TypeScript (
tsx)
src/
├── types/ # Zod schemas + TypeScript types
├── functions/ # Business logic (pure functions)
└── tools/ # Tool registration (glue code)
All tools use the data_* prefix for a unified API.
CRUD entries with semantic embeddings, FTS indexing, automatic version tracking, and priority weights (1-10). Persists across sessions.
Each memory has:
- Embedding (
embeddings): Semantic embedding of the full body text (768-dim via nomic-embed-text) - Full-text search: BM25 index on body for keyword-based search
- Weight (1-10): Prioritizes critical memories in search results
- Weight 8-10: Full body returned in search results
- Weight 5-7: Full body or excerpt depending on mode
- Weight 1-4: Excerpt only
| Type | Purpose |
|---|---|
soul |
Agent identity, values and personality |
user |
User profile: role, expertise, preferences |
feedback |
Learned rules: corrections and confirmed approaches |
project |
Active work, decisions, project state |
reference |
Pointers to external systems, tools, docs |
pending |
Open tasks and follow-ups |
| Table | Source | Description |
|---|---|---|
memories |
./memories/ |
Structured entries with types |
codebase |
./coding/ |
Source code (.ts, .tsx, .js, .jsx) |
docs |
./coding/ |
Documentation (.md, .sql, .json) |
reference |
./reference/ |
User-provided code examples, guides, and learning materials |
chatlogs |
./chatlogs/ |
Conversation history |
Default directories are relative to the project root. Configure via environment variables or use defaults.
If no .env is configured, the following defaults are used:
vectorial/— LanceDB storagememories/— Markdown memory vaultcoding/— Code to index (you need to place your project here or configureCODING_DIR)reference/— User-provided code examples and learning materialschatlogs/— Conversation history
Automatic snapshot saved every time a memory is updated. Query with data_versions(name).
All tools use the data_* prefix for consistency.
| Tool | Description |
|---|---|
data_search |
⭐ Unified search. Use source param: memories, codebase, docs, chatlogs, or all for global search across all 4 sources. Supports mode: critical, condensed, full, lite |
| Tool | Description |
|---|---|
data_create |
Create new memory with auto-embedding. Params: type, name, body, tags, weight |
data_update |
Update memory by ID. Auto re-embeds body. Params: id, body, tags, weight, name |
data_delete |
Delete memory by ID. Params: id |
data_list |
List memories. Params: type (optional), tag (optional filter) |
data_count |
Count memories. Params: type (optional) |
data_get |
Get memory by exact name. Params: name |
| Tool | Description |
|---|---|
data_context |
⭐ RECOMMENDED Session bootstrap. Params: mode (minimal/compact/full) OR task for smart context loading |
data_recent |
Recent memories by date. Params: days, limit |
data_stats |
Statistics: total count, breakdown by type, oldest/newest, avg body length |
data_versions |
Version history of a memory by name. Params: name |
| Tool | Description |
|---|---|
data_files |
List markdown files in vault. Params: type (optional) |
data_sync |
Sync vault files to vector DB. Params: type, dry_run, import_missing |
data_export |
Export memories to markdown files. Params: type, overwrite |
SESSION START (RECOMMENDED):
1. data_context() ← minimal mode, ~50 tokens
OR
1. data_context(mode: "compact") ← ~1.5k tokens with previews
OR (smart)
1. data_context(task: "what I'm doing") ← semantic smart loading
DURING WORK — when you learn something new:
→ data_create(type, name, body, tags, weight)
FETCHING A KNOWN MEMORY:
→ data_get(name: "exact_name") ← O(1), no embedding cost
FETCHING CRITICAL RULES:
→ data_list(tag: "CRITICAL")
SEARCHING:
→ data_search(source: "memories", query: "...")
→ data_search(source: "all", query: "...") ← global search across all sources
HOUSEKEEPING:
→ data_stats() ← check totals
→ data_versions(name: "memory_name") ← view history
cp .env.example .env # fill in your paths
pnpm install
pnpm test # diagnostic: verify all connections and counts
pnpm index:all # initial indexing
pnpm start # start MCP serverpnpm index # code + docs + reference + chatlogs (all sources)
pnpm index:code # source code only
pnpm index:docs # documentation only
pnpm index:reference # user-provided guides and examples
pnpm index:chatlogs # conversation history onlypnpm download # export all memories to markdown
pnpm download:memories # export memories onlyIndexers are incremental — only new or modified files are processed.
To reindex from scratch:
rm -rf ./vectorial/
pnpm index| Variable | Description |
|---|---|
OLLAMA_HOST |
Ollama server URL (default: http://localhost:11434) |
CODING_DIR |
Path to code repository to index (default: ../coding) |
CHATLOG_DIR |
Path to chatlogs folder (default: ../_memory/chatlogs) |
REFERENCE_DIR |
Path to user-provided guides and examples (default: ../_memory/reference) |
LANCEDB_DIR |
Path to LanceDB storage (default: ../_memory/vectorial) |
MEMORIES_DIR |
Path to memories vault (default: ../_memory/memories) |
MEMORIES_WRITE_ENABLED |
Enable writing to vault (default: true) |
IGNORE_PREFIXES |
Comma-separated prefixes to skip during indexing (default: _) |
BATCH_SIZE |
Chunks per batch for embedding and parallel file reads (default: 20) |
See INSTALL.md for setup. Contributions are subject to natuleadan review policies and terms.
Thanks to all contributors:
MIT © Leonardo Jara