trackmcp
Back to directory
tejzpr

Smriti-MCP

View on GitHub

Smriti is a Model Context Protocol (MCP) server that provides persistent, graph-based memory for LLM applications. Supports LadybugDB, Neo4j, and FalkorDB backends with EcphoryRAG-inspired multi-stage retrieval, combining cue extraction, graph traversal, vector similarity, and multi-hop association - for human-like memory recall.

7 stars GoOthers Updated Jul 15, 2026

Documentation

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

mermaid
graph TD
    Client["MCP Client(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["EncodingLLM + Embed + Link"]
            Retrieval["RetrievalCue Match + Vector + Multi-hop+ Cluster-Aware Scoring"]
            Consolidation["ConsolidationDecay + Prune + Leiden Clustering"]
        end

        subgraph DB["Graph Database"]
            direction LR
            Graph["(Engram)──[:EncodedBy]──▶(Cue)(Engram)──[:AssociatedWith]──▶(Engram)(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(OpenAI-compatible)"]
    Engine --> LLM

Recall Pipeline

The default `recall` mode performs multi-stage retrieval:

1. Cue Extraction — LLM extracts entities and keywords from the query

2. Cue-Based Graph Traversal — Follows `EncodedBy` edges to find engrams linked to matching cues

3. Vector Similarity Search — Cosine similarity against all engram embeddings (HNSW index when available, fallback to brute-force)

4. Multi-Hop Expansion — Follows `AssociatedWith` edges to discover related memories

5. 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)

6. 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 `AssociatedWith` edges 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_id` to each engram, stored persistently in the database
  • New engrams inherit the `cluster_id` of 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 ( Note:

> - Replace `/Users/yourname` with your actual home directory path

> - MCP clients do not expand `$HOME` or `~` in JSON configs — use absolute paths

> - The `.smriti` volume mount persists your memory database

> - The container runs as non-root user `smriti`

Build locally (optional):

bash
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:

PlatformArchitectureCGO
Linuxamd64Enabled (native)
macOSarm64 (Apple Silicon)Enabled (native)
Windowsamd64Enabled (native)

Each release includes a `checksums-sha256.txt` for verification.

Environment Variables

Core

VariableDefaultDescription
`ACCESSING_USER`OS usernameUser identifier (used for DB isolation)
`STORAGE_LOCATION``~/.smriti`Root storage directory (LadybugDB only)
`DB_TYPE``ladybug`Database backend: `ladybug`, `neo4j`, or `falkordb`

LLM

VariableDefaultDescription
`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

VariableDefaultDescription
`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

VariableDefaultDescription
`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)

VariableDefaultDescription
`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)

VariableDefaultDescription
`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

VariableDefaultDescription
`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.

json
{
  "content": "Kubernetes uses etcd as its backing store for all cluster data",
  "importance": 0.8,
  "tags": "kubernetes,etcd,infrastructure",
  "source": "meeting-notes"
}
ParameterTypeRequiredDescription
`content`stringyesMemory content
`importance`numbernoPriority 0.0–1.0 (default: 0.5)
`tags`stringnoComma-separated tags
`source`stringnoSource/origin label

smriti_recall

"What do I know about X?" — Retrieve memories using multi-stage EcphoryRAG retrieval with cluster-aware scoring.

json
{
  "query": "container orchestration tools",
  "limit": 5,
  "mode": "recall"
}
ParameterTypeRequiredDescription
`query`stringnoNatural language query (omit for list mode)
`limit`numbernoMax results (default: 5)
`mode`stringno`recall` (deep multi-hop), `search` (fast vector-only), or `list` (browse)
`memory_type`stringnoFilter: `episodic`, `semantic`, `procedural`

Modes explained:

  • `recall` (default) — Full pipeline: cue extraction → graph traversal → vector search → multi-hop → cluster-aware composite scoring
  • `search` — 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.

json
{
  "action": "forget",
  "memory_id": "abc-123-def"
}
ParameterTypeRequiredDescription
`action`stringyes`forget` (delete memory) or `sync` (push backup)
`memory_id`stringif forgetEngram ID to delete

Graph Schema

Smriti stores memories in a property graph with the following structure:

code
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:

code
~/.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 a `user` property 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 a `user` property 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

code
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

bash
# 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:

bash
# 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.

Frequently asked questions

What is Smriti-MCP?

Smriti-MCP is Smriti is a Model Context Protocol (MCP) server that provides persistent, graph-based memory for LLM applications. Supports LadybugDB, Neo4j, and FalkorDB backends with EcphoryRAG-inspired multi-stage retrieval, combining cue extraction, graph traversal, vector similarity, and multi-hop association - for human-like memory recall.

How do I install Smriti-MCP?

Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.

Is Smriti-MCP open source?

Yes — it is hosted on GitHub at https://github.com/tejzpr/Smriti-MCP and has 7 stars.

Related MCP tools

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP