Smriti MCP
Smriti is a Model Context Protocol (MCP) server that provides persistent, graph-based memory for LLM applications. Built on LadybugDB (embedded property graph database), it uses EcphoryRAG-inspired multi-stage retrieval - combining cue extraction, graph traversal, vector similarity, and multi-hop association - to deliver human-like memory recall.
Smriti MCP
Graph-Based AI Memory System with EcphoryRAG Retrieval and Leiden Clustering
Smriti is a Model Context Protocol (MCP) server that provides persistent, graph-based memory for LLM applications. It supports three database backends — LadybugDB (embedded), Neo4j, and FalkorDB — and uses EcphoryRAG-inspired multi-stage retrieval — combining cue extraction, graph traversal, vector similarity, and multi-hop association — to deliver human-like memory recall. Smriti uses the Leiden algorithm for automatic community detection, enabling cluster-aware retrieval that scales beyond thousands of memories.
Features
- Graph-Based Memory — Engrams (memories) linked via Cues and Associations in a property graph
- EcphoryRAG Retrieval — Multi-hop associative recall with cue extraction, vector similarity, and composite scoring
- Leiden Community Detection — Automatic clustering of related memories using the Leiden algorithm with smart-cached resolution tuning, enabling cluster-aware scoring for efficient retrieval at scale
- Multi-Backend Support — LadybugDB (embedded, zero-config), Neo4j (enterprise graph DB), or FalkorDB (Redis-based graph DB)
- Multi-User Isolation — Per-file (LadybugDB), per-tenant property or per-database (Neo4j), or per-tenant property or per-graph (FalkorDB)
- Automatic Consolidation — Exponential decay, pruning of weak memories, strengthening of frequently accessed ones, and periodic Leiden re-clustering
- Flexible Backup — GitHub (system git) or S3 (AWS SDK) sync, plus noop for local-only
- Lazy HNSW Indexing — Vector and FTS indexes created on-demand when dataset exceeds threshold
- OpenAI-Compatible APIs — Works with any OpenAI-compatible LLM and embedding provider
- 3 MCP Tools —
smriti_store,smriti_recall,smriti_manage
Architecture
graph TD
Client["MCP Client<br/>(Cursor / Claude / Windsurf / etc.)"]
Client -->|stdio| Server
subgraph Server["Smriti MCP Server"]
direction TB
subgraph Tools["MCP Tools"]
Store["smriti_store"]
Recall["smriti_recall"]
Manage["smriti_manage"]
end
subgraph Engine["Memory Engine"]
Encoding["Encoding<br/>LLM + Embed + Link"]
Retrieval["Retrieval<br/>Cue Match + Vector + Multi-hop<br/>+ Cluster-Aware Scoring"]
Consolidation["Consolidation<br/>Decay + Prune + Leiden Clustering"]
end
subgraph DB["Graph Database"]
direction LR
Graph["(Engram)──[:EncodedBy]──▶(Cue)<br/>(Engram)──[:AssociatedWith]──▶(Engram)<br/>(Cue)──[:CoOccurs]──▶(Cue)"]
DBType["LadybugDB | Neo4j | FalkorDB"]
end
subgraph Backup["Backup Provider (optional)"]
Git["GitHub (git)"]
S3["S3 (AWS SDK)"]
Noop["Noop"]
end
Store & Recall & Manage --> Engine
Encoding & Retrieval & Consolidation --> DB
DB --> Backup
end
LLM["LLM / Embedding API<br/>(OpenAI-compatible)"]
Engine --> LLM
Recall Pipeline
The default recall mode performs multi-stage retrieval:
- Cue Extraction — LLM extracts entities and keywords from the query
- Cue-Based Graph Traversal — Follows
EncodedByedges to find engrams linked to matching cues - Vector Similarity Search — Cosine similarity against all engram embeddings (HNSW index when available, fallback to brute-force)
- Multi-Hop Expansion — Follows
AssociatedWithedges to discover related memories - Cluster-Aware Composite Scoring — Blends vector similarity (40%), recency (20%), importance (20%), and decay (20%), with hop-depth penalty and soft-bounded cross-cluster penalty (0.5x for hop results outside the seed cluster)
- Access Strengthening — Recalled engrams get their access count and decay factor bumped (reinforcement)
Leiden Clustering
Smriti uses the Leiden algorithm — an improvement over Louvain that guarantees well-connected communities — to automatically detect clusters of related memories in the graph.
How it works:
- Runs automatically during each consolidation cycle
- Builds a weighted undirected graph from
AssociatedWithedges between engrams - Auto-tunes the resolution parameter using community profiling on the first run
- Uses a smart cache: the tuned resolution is reused across runs and only re-tuned when the graph grows by more than 10%
- Assigns a
cluster_idto each engram, stored persistently in the database - New engrams inherit the
cluster_idof their strongest neighbor at encode time
How it improves retrieval:
- The recall pipeline determines a seed cluster (most common cluster among direct-match results)
- Multi-hop results that cross into a different cluster receive a 0.5x score penalty (soft-bounded: they are penalized, not dropped)
- This keeps retrieval focused within the most relevant topic cluster while still allowing cross-topic discovery
Performance characteristics:
- Gracefully skips on small graphs (< 3 nodes or 0 edges)
- Clustering 60 nodes: ~40ms (first run with auto-tune), ~14ms (cached resolution)
- Per-user: each Engine instance maintains its own independent cache
Consolidation Pipeline
Consolidation runs periodically (default: every 3600 seconds) and performs:
- Exponential Decay — Reduces
decay_factorbased on time since last access - Weak Memory Pruning — Removes engrams below minimum decay threshold
- Frequency Strengthening — Boosts decay factor for frequently accessed memories
- Orphaned Cue Cleanup — Removes cues no longer linked to any engram
- Leiden Clustering — Re-clusters the memory graph (smart-cached, skips if graph hasn't changed significantly)
- Index Management — Creates HNSW vector and FTS indexes when engram count exceeds threshold (50)
Requirements
-
Go 1.25+ — For building from source
-
Git 2.x+ — Required for GitHub backup provider (must be in PATH)
-
GCC/Build Tools — Required for CGO (LadybugDB backend)
- macOS:
xcode-select --install - Linux:
sudo apt install build-essential - Windows: Use Docker (recommended) or MinGW
- macOS:
-
liblbug (LadybugDB shared library) — Runtime dependency for LadybugDB backend, downloaded automatically by
go-ladybugduring build. If building manually, grab the latest release from LadybugDB/ladybug:Platform Asset Library macOS liblbug-osx-arm64.tar.gz/liblbug-osx-x86_64.tar.gzliblbug.dylibLinux liblbug-linux-{arch}.tar.gzliblbug.soWindows liblbug-windows-x86_64.zipliblbug.dllThe shared library must be on the system library path at runtime (e.g.,
DYLD_LIBRARY_PATHon macOS,LD_LIBRARY_PATHon Linux, or alongside the binary on Windows). Docker and release binaries bundle this automatically. -
Neo4j 5.x+ — Required only when using
DB_TYPE=neo4j. Must have APOC and GDS plugins for vector search and full-text indexing. -
FalkorDB — Required only when using
DB_TYPE=falkordb. Runs on Redis protocol (default port 6379).
Quick Start
1. Build
# Build
CGO_ENABLED=1 go build -o smriti-mcp .
# Run (minimal config)
export LLM_API_KEY=your-api-key
export ACCESSING_USER=alice
./smriti-mcp
2. MCP Client Integration
Option 1: Native Binary
Cursor (~/.cursor/mcp_settings.json):
{
"mcpServers": {
"smriti": {
"command": "/path/to/smriti-mcp",
"env": {
"LLM_API_KEY": "your-api-key",
"EMBEDDING_API_KEY": "your-embedding-key"
}
}
}
}
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"smriti": {
"command": "/path/to/smriti-mcp",
"args": [],
"env": {
"LLM_API_KEY": "your-api-key",
"EMBEDDING_API_KEY": "your-embedding-key"
}
}
}
}
Windsurf (~/.codeium/windsurf/mcp_config.json):
{
"mcpServers": {
"smriti": {
"command": "/path/to/smriti-mcp",
"env": {
"LLM_API_KEY": "your-api-key",
"EMBEDDING_API_KEY": "your-embedding-key"
}
}
}
}
Option 2: Go Run
Run directly without installing — similar to npx for Node.js:
{
"mcpServers": {
"smriti": {
"command": "go",
"args": ["run", "github.com/tejzpr/smriti-mcp@latest"],
"env": {
"LLM_API_KEY": "your-api-key",
"EMBEDDING_API_KEY": "your-embedding-key"
}
}
}
}
Option 3: Docker Container
Simple mode (single user):
{
"mcpServers": {
"smriti": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "/Users/yourname/.smriti:/home/smriti/.smriti",
"-e", "LLM_API_KEY=your-api-key",
"-e", "EMBEDDING_API_KEY=your-embedding-key",
"tejzpr/smriti-mcp"
]
}
}
}
Multi-user mode:
{
"mcpServers": {
"smriti": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "/Users/yourname/.smriti:/home/smriti/.smriti",
"-e", "LLM_API_KEY=your-api-key",
"-e", "EMBEDDING_API_KEY=your-embedding-key",
"-e", "ACCESSING_USER=yourname",
"tejzpr/smriti-mcp"
]
}
}
}
Note:
- Replace
/Users/yournamewith your actual home directory path- MCP clients do not expand
$HOMEor~in JSON configs — use absolute paths- The
.smritivolume mount persists your memory database- The container runs as non-root user
smriti
Build locally (optional):
docker build -t smriti-mcp .
Then use smriti-mcp instead of tejzpr/smriti-mcp in your config.
Option 4: GitHub Release Binary
Download pre-built binaries from the Releases page. Binaries are available for:
| Platform | Architecture | CGO |
|---|---|---|
| Linux | amd64 | Enabled (native) |
| macOS | arm64 (Apple Silicon) | Enabled (native) |
| Windows | amd64 | Enabled (native) |
Each release includes a checksums-sha256.txt for verification.
Environment Variables
Core
| Variable | Default | Description |
|---|---|---|
ACCESSING_USER | OS username | User identifier (used for DB isolation) |
STORAGE_LOCATION | ~/.smriti | Root storage directory (LadybugDB only) |
DB_TYPE | ladybug | Database backend: ladybug, neo4j, or falkordb |
LLM
| Variable | Default | Description |
|---|---|---|
LLM_BASE_URL | https://api.openai.com/v1 | LLM API endpoint (OpenAI-compatible) |
LLM_API_KEY | (required) | LLM API key |
LLM_MODEL | gpt-4o-mini | LLM model name |
Embedding
| Variable | Default | Description |
|---|---|---|
EMBEDDING_BASE_URL | https://api.openai.com/v1 | Embedding API endpoint |
EMBEDDING_API_KEY | (falls back to LLM_API_KEY) | Embedding API key |
EMBEDDING_MODEL | text-embedding-3-small | Embedding model name |
EMBEDDING_DIMS | 1536 | Embedding vector dimensions |
Backup
| Variable | Default | Description |
|---|---|---|
BACKUP_TYPE | none | none, github, or s3 |
BACKUP_SYNC_INTERVAL | 60 | Seconds between backup syncs (0 = disabled) |
GIT_BASE_URL | (empty) | Git remote base URL (required if github) |
S3_ENDPOINT | (empty) | S3 endpoint (for non-AWS providers) |
S3_REGION | (empty) | S3 region (required if s3) |
S3_ACCESS_KEY | (empty) | S3 access key (required if s3) |
S3_SECRET_KEY | (empty) | S3 secret key (required if s3) |
Neo4j (when DB_TYPE=neo4j)
| Variable | Default | Description |
|---|---|---|
NEO4J_URI | (required) | Bolt URI (e.g. bolt://localhost:7687) |
NEO4J_USERNAME | (required) | Neo4j username |
NEO4J_PASSWORD | (required) | Neo4j password |
NEO4J_DATABASE | neo4j | Database name (overridden by username in database isolation mode) |
NEO4J_ISOLATION | tenant | tenant (property-based, Community Edition) or database (per-DB, Enterprise Edition) |
FalkorDB (when DB_TYPE=falkordb)
| Variable | Default | Description |
|---|---|---|
FALKOR_ADDR | localhost:6379 | FalkorDB Redis address |
FALKOR_PASSWORD | (empty) | FalkorDB password (if auth enabled) |
FALKOR_GRAPH | smriti | Graph name (overridden by {user}_smriti in graph isolation mode) |
FALKOR_ISOLATION | tenant | tenant (property-based) or graph (per-graph isolation) |
Consolidation
| Variable | Default | Description |
|---|---|---|
CONSOLIDATION_INTERVAL | 3600 | Seconds between consolidation runs (0 = disabled) |
MCP Tools
smriti_store
"Remember this" — Store a new memory. Content is automatically analyzed by the LLM, embedded, and woven into the memory graph. New engrams inherit the cluster_id of their most similar existing neighbor.
{
"content": "Kubernetes uses etcd as its backing store for all cluster data",
"importance": 0.8,
"tags": "kubernetes,etcd,infrastructure",
"source": "meeting-notes"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
content | string | yes | Memory content |
importance | number | no | Priority 0.0–1.0 (default: 0.5) |
tags | string | no | Comma-separated tags |
source | string | no | Source/origin label |
smriti_recall
"What do I know about X?" — Retrieve memories using multi-stage EcphoryRAG retrieval with cluster-aware scoring.
{
"query": "container orchestration tools",
"limit": 5,
"mode": "recall"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | no | Natural language query (omit for list mode) |
limit | number | no | Max results (default: 5) |
mode | string | no | recall (deep multi-hop), search (fast vector-only), or list (browse) |
memory_type | string | no | Filter: episodic, semantic, procedural |
Modes explained:
recall(default) — Full pipeline: cue extraction → graph traversal → vector search → multi-hop → cluster-aware composite scoringsearch— Vector-only cosine similarity. Faster but shallower.list— No search. Returns recent memories ordered by last access time.
smriti_manage
"Forget this / sync now" — Administrative operations.
{
"action": "forget",
"memory_id": "abc-123-def"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | yes | forget (delete memory) or sync (push backup) |
memory_id | string | if forget | Engram ID to delete |
Graph Schema
Smriti stores memories in a property graph with the following structure:
Node Tables:
Engram — id, content, summary, memory_type, importance, access_count,
created_at, last_accessed_at, decay_factor, embedding, source,
tags, cluster_id
Cue — id, name, cue_type, embedding
Relationship Tables:
EncodedBy — (Engram) → (Cue)
AssociatedWith — (Engram) → (Engram) [strength, relation_type, created_at]
CoOccurs — (Cue) → (Cue) [strength]
The cluster_id field on Engram nodes is managed by the Leiden algorithm. A value of -1 indicates the engram has not yet been assigned to a cluster (e.g., the graph is too small, or the engram has no associations).
Storage & Isolation
Smriti supports three database backends with different storage and isolation models:
LadybugDB (default)
Each user gets an isolated embedded database file:
~/.smriti/
└── {username}/
└── memory.lbug # LadybugDB property graph database
The STORAGE_LOCATION env var controls the root. The ACCESSING_USER env var selects which user's DB to open. Backup providers sync the user directory to remote storage.
Neo4j
Two isolation modes controlled by NEO4J_ISOLATION:
tenant(default) — All users share one database. Each node gets auserproperty and all queries filter by it. Works on Neo4j Community Edition.database— Each user gets a separate Neo4j database. Requires Neo4j Enterprise Edition.
FalkorDB
Two isolation modes controlled by FALKOR_ISOLATION:
tenant(default) — All users share one graph. Each node gets auserproperty and all queries filter by it.graph— Each user gets a separate graph (named{user}_smriti).
Schema migrations (e.g., adding cluster_id to existing databases) run automatically on startup.
Project Structure
smriti-mcp/
├── main.go # Entry point, server setup, signal handling
├── config/ # Environment variable parsing
├── llm/ # OpenAI-compatible HTTP client (LLM + embeddings)
├── db/ # Database backends (LadybugDB, Neo4j, FalkorDB), schema, indexes, migrations
├── memory/
│ ├── engine.go # Engine struct, consolidation loop
│ ├── types.go # Engram, Cue, Association, SearchResult structs
│ ├── encoding.go # Store pipeline: LLM extraction → embed → link → cluster inherit
│ ├── retrieval.go # Recall pipeline: cue search → vector → multi-hop → cluster scoring
│ ├── search.go # Search modes: list, vector-only, FTS, hybrid
│ ├── consolidation.go # Decay, prune, strengthen, orphan cleanup
│ └── leiden.go # Leiden clustering: graph build, auto-tune, smart cache, batch write
├── backup/ # Backup providers: noop, github (git), s3 (AWS SDK)
├── tools/ # MCP tool definitions: store, recall, manage
└── testutil/ # Shared test helpers
Testing
# Run unit tests
CGO_ENABLED=1 go test ./...
# Verbose with all output
CGO_ENABLED=1 go test -v ./...
# Specific package
CGO_ENABLED=1 go test -v ./memory/...
CGO_ENABLED=1 go test -v ./tools/...
# Leiden clustering tests only
CGO_ENABLED=1 go test -v -run "TestRunLeiden|TestNeedsRetune|TestDetermineSeedCluster" ./memory/
E2E / Integration Tests
E2E tests require real LLM/embedding services and are gated behind the integration build tag:
# LadybugDB E2E (no external DB required)
CGO_ENABLED=1 go test -tags integration -v -run "TestE2E_LadybugDB" ./memory/
# Neo4j E2E (requires running Neo4j instance)
NEO4J_URI="bolt://localhost:7687" NEO4J_USERNAME="neo4j" NEO4J_PASSWORD="yourpass" \
CGO_ENABLED=1 go test -tags integration -v -run "TestE2E_Neo4j" ./memory/
# FalkorDB E2E (requires running FalkorDB instance)
FALKOR_ADDR="localhost:6379" \
CGO_ENABLED=1 go test -tags integration -v -run "TestE2E_FalkorDB" ./memory/
# All E2E tests
CGO_ENABLED=1 go test -tags integration -v -run "TestE2E_" ./memory/
All E2E tests require LLM_BASE_URL, LLM_API_KEY, LLM_MODEL, EMBEDDING_BASE_URL, EMBEDDING_MODEL, and EMBEDDING_API_KEY environment variables.
Contributing
Contributions are welcome! Please ensure:
- All tests pass (
CGO_ENABLED=1 go test ./...) - Code is properly formatted (
go fmt ./...) - New code includes the SPDX license header
See CONTRIBUTORS.md for the contributor list.
License
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0) from v1.0.7 onwards.
Versions prior to v1.0.7 are licensed under the Mozilla Public License 2.0.
İlgili Sunucular
Alpha Vantage MCP Server
sponsorAccess financial market data: realtime & historical stock, ETF, options, forex, crypto, commodities, fundamentals, technical indicators, & more
Thirdweb
Read/write to over 2k blockchains, enabling data querying, contract analysis/deployment, and transaction execution, powered by Thirdweb.
ApostropheCMS
Interact with ApostropheCMS, a Node.js-based content management system, to manage content snippets.
Code Graph RAG MCP
Code Rag with Graph - local only installation
MCP Project Helper
A lightweight, extensible MCP server for running prompt-based tools and file utilities, with support for custom prompts.
LaTeX PDF MCP Server
Converts LaTeX source code into professionally formatted PDF documents.
agentwallet-mcp
Server-side EVM wallet for Ai agents. Send transactions, manage tokens, and interact with smart contracts across multiple chains.
sqlew
ADR (Architecture Decision Record) for AI Agents – An MCP server that enables AI agents to create, query, and maintain architecture decision records in a structured SQL database
MCP LLaMA
An MCP server with weather tools and LLaMA integration.
pipeyard
Curated MCP connector marketplace for industry verticals — Construction, Finance, Healthcare, and Logistics with full docs, curl examples and sandbox testing.
TrustBench
x402 provider rankings + Ed25519-signed payment receipts + signature verification (3 tools).