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. 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 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-User Support — Separate LadybugDB per user, scales to thousands of isolated memory stores
- 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["LadybugDB (Property Graph)"]
Graph["(Engram)──[:EncodedBy]──▶(Cue)<br/>(Engram)──[:AssociatedWith]──▶(Engram)<br/>(Cue)──[:CoOccurs]──▶(Cue)"]
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)
- macOS:
xcode-select --install - Linux:
sudo apt install build-essential - Windows: Use Docker (recommended) or MinGW
- macOS:
-
liblbug (LadybugDB shared library) — Runtime dependency, downloaded automatically by
go-ladybugduring build. If building manually, grab the latest release from LadybugDB/ladybug:Platform Asset Library macOS liblbug-osx-universal.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.
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 (separate DB per user) |
STORAGE_LOCATION | ~/.smriti | Root storage directory |
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) |
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
Each user gets an isolated LadybugDB 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.
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/ # LadybugDB Store wrapper, 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 all 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/
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 Mozilla Public License 2.0.
Serveurs connexes
Scout Monitoring MCP
sponsorPut performance and error data directly in the hands of your AI assistant.
Alpha Vantage MCP Server
sponsorAccess financial market data: realtime & historical stock, ETF, options, forex, crypto, commodities, fundamentals, technical indicators, & more
Apifox MCP Pro
An enhanced Apifox MCP service providing comprehensive API management capabilities for Claude Desktop and Cursor.
agent smith
Auto-generate AGENTS.md from your codebase
MCP Image Extractor
Extracts images from files, URLs, or base64 strings and converts them to base64 for LLM analysis.
Android Preference Editor
Edit Android preferences using adb and Node.js.
Symphony of One
An MCP server for orchestrating multiple Claude instances to collaborate in a shared workspace with real-time communication.
Cargo MCP
Interact with Rust projects using Cargo commands like build, test, and run.
Aptos NPM MCP
A MCP server for interacting with Aptos NPM packages.
MCP Server
A backend service providing tools, resources, and prompts for AI models using the Model Context Protocol (MCP).
TechDebtMCP
MCP server for analyzing and managing technical debt in codebases via the Model Context Protocol
MCP Android Agent
Automate Android devices using the uiautomator2 library, requiring adb and a connected device.