关于 Smriti Mcp
Smriti 是面向 LLM 应用的持久化图式记忆 MCP 服务。多阶段检索结合线索、图遍历、向量相似度和 Leiden 聚类,并支持 LadybugDB、Neo4j 与 FalkorDB 后端。
主要功能
- 01将记忆存储为关联图
- 02通过线索、向量和图遍历检索
- 03使用 Leiden 聚类相关记忆
- 04支持 LadybugDB、Neo4j 和 FalkorDB
- 05自动整合并清理记忆
- 06按用户隔离记忆数据
适用场景
- 01在多个 LLM 会话间保留上下文
- 02通过多跳关联找回相关事实
- 03为多个用户隔离记忆数据
MCP 相关
向 MCP 客户端提供三个工具:`smriti_store`、`smriti_recall` 和 `smriti_manage`,用于存储、检索和管理记忆。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Smriti MCP
基于图的 AI 记忆系统,采用 EcphoryRAG 检索与 Leiden 聚类
Smriti 是一个模型上下文协议(MCP)服务,为大模型应用提供持久化的图式记忆。它支持三种数据库后端——LadybugDB(嵌入式)、Neo4j 和 FalkorDB——并采用受 EcphoryRAG 启发的多阶段检索方式,通过结合线索提取、图遍历、向量相似度和多跳关联,实现类人记忆回想。Smriti 使用 Leiden 算法自动检测社区,从而支持集群感知检索,扩展能力可超越数千条记忆。
功能特性
- 基于图的记忆 — 在属性图中,通过线索和关联连接记忆印迹(记忆)
- EcphoryRAG 检索 — 多跳关联回想,结合线索提取、向量相似度和复合评分
- Leiden 社区检测 — 使用 Leiden 算法自动聚类相关记忆,并通过智能缓存调节分辨率,实现集群感知评分,提升大规模检索效率
- 多后端支持 — LadybugDB(嵌入式、零配置)、Neo4j(企业级图数据库)或 FalkorDB(基于 Redis 的图数据库)
- 多用户隔离 — 按文件(LadybugDB)、按租户属性或按数据库(Neo4j),或按租户属性或按图(FalkorDB)隔离
- 自动整合 — 指数衰减、清除弱记忆、强化频繁访问的记忆,并定期使用 Leiden 重新聚类
- 灵活备份 — 与 GitHub(系统 git)或 S3(AWS SDK)同步,也可使用 noop 仅在本地运行
- 惰性 HNSW 索引 — 数据集超过阈值时按需创建向量和 FTS 索引
- 兼容 OpenAI 的 API — 可与任何兼容 OpenAI 的大模型和嵌入提供方配合使用
- 3 个 MCP 工具 —
smriti_store、smriti_recall、smriti_manage
架构
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 模式执行多阶段检索:
- 线索提取 — 大模型从查询中提取实体和关键词
- 基于线索的图遍历 — 沿
EncodedBy边查找与匹配线索关联的记忆印迹 - 向量相似度搜索 — 将查询与所有记忆印迹嵌入进行余弦相似度比较(若有 HNSW 索引则使用,否则回退到暴力搜索)
- 多跳扩展 — 沿
AssociatedWith边发现相关记忆 - 集群感知复合评分 — 综合向量相似度(40%)、近因性(20%)、重要性(20%)和衰减(20%),并加入跳数深度惩罚和软边界跨集群惩罚(对于位于种子集群之外的跳转结果,权重为 0.5 倍)
- 访问强化 — 被回想的记忆印迹会增加访问计数和衰减因子(强化)
Leiden 聚类
Smriti 使用 Leiden 算法(它是 Louvain 算法的改进版,可确保社区连接良好),自动检测图中相关记忆的聚类。
工作原理:
- 在每次整合周期中自动运行
- 根据 engram 之间的
AssociatedWith边构建加权无向图 - 首次运行时,通过社区分析自动调整分辨率参数
- 使用智能缓存:后续运行复用已调整的分辨率,只有当图增长超过 10% 时才会重新调整
- 为每个 engram 分配
cluster_id,并将其持久化存储在数据库中 - 新 engram 在编码时会继承其最强邻居的
cluster_id
如何改进检索:
- 召回流程会确定一个种子聚类(直接匹配结果中最常见的聚类)
- 跨入其他聚类的多跳结果会受到 0.5 倍分数惩罚(采用软限制:施加惩罚,但不会丢弃结果)
- 这样既能让检索聚焦于最相关的主题聚类,也能保留跨主题发现能力
性能特征:
- 在小型图上(少于 3 个节点或没有边)会平稳跳过
- 对 60 个节点进行聚类:首次运行并自动调优约需 40 毫秒,使用缓存分辨率约需 14 毫秒
- 按用户隔离:每个 Engine 实例都维护自己的独立缓存
整合流程
整合会定期运行(默认:每 3600 秒),并执行以下操作:
- 指数衰减 — 根据上次访问以来的时间降低
decay_factor - 弱记忆清理 — 移除低于最低衰减阈值的 engram
- 频率强化 — 提高频繁访问的记忆的衰减因子
- 孤立提示清理 — 移除不再关联任何 engram 的提示
- Leiden 聚类 — 对记忆图重新聚类(使用智能缓存;如果图没有显著变化则跳过)
- 索引管理 — 当 engram 数量超过阈值(50)时,创建 HNSW 向量索引和 FTS 索引
要求
-
Go 1.25+ — 用于从源代码构建
-
Git 2.x+ — GitHub 备份提供程序必需(必须位于 PATH 中)
-
GCC/构建工具 — CGO 必需(LadybugDB 后端)
- macOS:
xcode-select --install - Linux:
sudo apt install build-essential - Windows:使用 Docker(推荐)或 MinGW
- macOS:
-
liblbug(LadybugDB 共享库) — LadybugDB 后端的运行时依赖项,由
go-ladybug在构建期间自动下载。如果手动构建,请从 LadybugDB/ladybug 获取最新版本:平台 文件 库 macOS liblbug-osx-arm64.tar.gz/liblbug-osx-x86_64.tar.gzliblbug.dylibLinux liblbug-linux-{arch}.tar.gzliblbug.soWindows liblbug-windows-x86_64.zipliblbug.dll运行时,共享库必须位于系统库路径中(例如,macOS 上的
DYLD_LIBRARY_PATH、Linux 上的LD_LIBRARY_PATH,或 Windows 上与二进制文件位于同一目录)。Docker 和发布版二进制文件会自动捆绑该库。 -
Neo4j 5.x+ — 仅在使用
DB_TYPE=neo4j时需要。必须安装 APOC 和 GDS 插件,以支持向量搜索和全文索引。 -
FalkorDB — 仅在使用
DB_TYPE=falkordb时需要。运行于 Redis 协议之上(默认端口 6379)。
快速开始
1. 构建
# 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 客户端集成
选项 1:原生二进制文件
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"
}
}
}
}
选项 2:Go Run
无需安装即可直接运行——类似于 Node.js 的 npx:
{
"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"
}
}
}
}
选项 3:Docker 容器
简单模式(单用户):
{
"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"
]
}
}
}
多用户模式:
{
"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"
]
}
}
}
注意:
- 将
/Users/yourname替换为你的实际主目录路径- MCP 客户端不会在 JSON 配置中展开
$HOME或~,请使用绝对路径.smriti卷挂载会持久保存你的记忆数据库- 容器以非 root 用户
smriti运行
本地构建(可选):
docker build -t smriti-mcp .
然后在配置中使用 smriti-mcp 替代 tejzpr/smriti-mcp。
选项 4:GitHub 发布二进制文件
从 Releases 页面下载预构建的二进制文件。提供以下平台的二进制文件:
| 平台 | 架构 | CGO |
|---|---|---|
| Linux | amd64 | 已启用(原生) |
| macOS | arm64(Apple Silicon) | 已启用(原生) |
| Windows | amd64 | 已启用(原生) |
每个版本都包含用于校验的 checksums-sha256.txt。
环境变量
核心
| 变量 | 默认值 | 说明 |
|---|---|---|
ACCESSING_USER | OS 用户名 | 用户标识符(用于数据库隔离) |
STORAGE_LOCATION | ~/.smriti | 根存储目录(仅限 LadybugDB) |
DB_TYPE | ladybug | 数据库后端:ladybug、neo4j 或 falkordb |
LLM
| 变量 | 默认值 | 说明 |
|---|---|---|
LLM_BASE_URL | https://api.openai.com/v1 | LLM API 端点(兼容 OpenAI) |
LLM_API_KEY | (必填) | LLM API 密钥 |
LLM_MODEL | gpt-4o-mini | LLM 模型名称 |
嵌入
| 变量 | 默认值 | 说明 |
|---|---|---|
EMBEDDING_BASE_URL | https://api.openai.com/v1 | 嵌入 API 端点 |
EMBEDDING_API_KEY | (回退使用 LLM_API_KEY) | 嵌入 API 密钥 |
EMBEDDING_MODEL | text-embedding-3-small | 嵌入模型名称 |
EMBEDDING_DIMS | 1536 | 嵌入向量维度 |
备份
| 变量 | 默认值 | 说明 |
|---|---|---|
BACKUP_TYPE | none | none、github 或 s3 |
BACKUP_SYNC_INTERVAL | 60 | 备份同步间隔秒数(0 = 已禁用) |
GIT_BASE_URL | (空) | Git 远程基础 URL(使用 github 时必填) |
S3_ENDPOINT | (空) | S3 端点(用于非 AWS 提供商) |
S3_REGION | (空) | S3 区域(使用 s3 时必填) |
S3_ACCESS_KEY | (空) | S3 访问密钥(使用 s3 时必填) |
S3_SECRET_KEY | (空) | S3 秘密密钥(使用 s3 时必填) |
Neo4j(当 DB_TYPE=neo4j 时)
| 变量 | 默认值 | 说明 |
|---|---|---|
NEO4J_URI | (必填) | Bolt URI(例如 bolt://localhost:7687) |
NEO4J_USERNAME | (必填) | Neo4j 用户名 |
NEO4J_PASSWORD | (必填) | Neo4j 密码 |
NEO4J_DATABASE | neo4j | 数据库名称(在 database 隔离模式下由用户名覆盖) |
NEO4J_ISOLATION | tenant | tenant(基于属性,Community Edition)或 database(按数据库隔离,Enterprise Edition) |
FalkorDB(当 DB_TYPE=falkordb 时)
| 变量 | 默认值 | 说明 |
|---|---|---|
FALKOR_ADDR | localhost:6379 | FalkorDB Redis 地址 |
FALKOR_PASSWORD | (空) | FalkorDB 密码(若启用身份验证) |
FALKOR_GRAPH | smriti | 图名称(在 graph 隔离模式下由 {user}_smriti 覆盖) |
FALKOR_ISOLATION | tenant | tenant(基于属性)或 graph(按图隔离) |
整合
| 变量 | 默认值 | 说明 |
|---|---|---|
CONSOLIDATION_INTERVAL | 3600 | 整合运行间隔秒数(0 = 已禁用) |
MCP 工具
smriti_store
“记住这个” — 存储一条新记忆。内容会由 LLM 自动分析、嵌入,并编织到记忆图中。新记忆痕迹会继承与其最相似的现有邻居的 cluster_id。
{
"content": "Kubernetes uses etcd as its backing store for all cluster data",
"importance": 0.8,
"tags": "kubernetes,etcd,infrastructure",
"source": "meeting-notes"
}
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
content | string | 是 | 记忆内容 |
importance | number | 否 | 优先级 0.0–1.0(默认值:0.5) |
tags | string | 否 | 以逗号分隔的标签 |
source | string | 否 | 来源/起源标签 |
smriti_recall
“关于 X,我知道什么?” — 使用具备簇感知评分的多阶段 EcphoryRAG 检索来检索记忆。
{
"query": "container orchestration tools",
"limit": 5,
"mode": "recall"
}
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
query | 字符串 | 否 | 自然语言查询(列表模式下省略) |
limit | 数字 | 否 | 最大结果数(默认值:5) |
mode | 字符串 | 否 | recall(深度多跳)、search(快速纯向量)或 list(浏览) |
memory_type | 字符串 | 否 | 筛选条件:episodic、semantic、procedural |
模式说明:
recall(默认)— 完整流程:线索提取 → 图遍历 → 向量搜索 → 多跳检索 → 簇感知综合评分search— 仅使用向量余弦相似度。速度更快,但检索较浅。list— 不执行搜索。按最后访问时间排序,返回最近的记忆。
smriti_manage
“忘记这条 / 立即同步” — 管理操作。
{
"action": "forget",
"memory_id": "abc-123-def"
}
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
action | 字符串 | 是 | forget(删除记忆)或 sync(推送备份) |
memory_id | 字符串 | forget 时必填 | 要删除的 Engram ID |
图架构
Smriti 使用属性图存储记忆,结构如下:
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]
Engram 节点上的 cluster_id 字段由 Leiden 算法管理。值为 -1 表示该 engram 尚未分配到某个簇(例如,图过小或该 engram 没有关联)。
存储与隔离
Smriti 支持三种具有不同存储和隔离模型的数据库后端:
LadybugDB(默认)
每位用户都拥有一个独立的嵌入式数据库文件:
~/.smriti/
└── {username}/
└── memory.lbug # LadybugDB property graph database
STORAGE_LOCATION 环境变量控制根目录。ACCESSING_USER 环境变量指定要打开其数据库的用户。备份提供程序会将用户目录同步到远程存储。
Neo4j
由 NEO4J_ISOLATION 控制的两种隔离模式:
tenant(默认)— 所有用户共用一个数据库。每个节点都有一个user属性,所有查询都会按该属性筛选。适用于 Neo4j Community Edition。database— 每位用户拥有一个独立的 Neo4j 数据库。需要 Neo4j Enterprise Edition。
FalkorDB
由 FALKOR_ISOLATION 控制的两种隔离模式:
tenant(默认)— 所有用户共用一个图。每个节点都有一个user属性,所有查询都会按该属性筛选。graph— 每位用户拥有一个独立的图(命名为{user}_smriti)。
架构迁移(例如,向现有数据库添加 cluster_id)会在启动时自动运行。
项目结构
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
测试
# 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 / 集成测试
E2E 测试需要真实的 LLM/嵌入服务,并通过 integration 构建标签启用:
# 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/
所有 E2E 测试都需要设置 LLM_BASE_URL、LLM_API_KEY、LLM_MODEL、EMBEDDING_BASE_URL、EMBEDDING_MODEL 和 EMBEDDING_API_KEY 环境变量。
贡献
欢迎贡献!请确保:
- 所有测试均通过(
CGO_ENABLED=1 go test ./...) - 代码格式正确(
go fmt ./...) - 新代码包含 SPDX 许可证标头
贡献者名单请参阅 CONTRIBUTORS.md。
许可证
从 v1.0.7 起,本项目根据 GNU Affero 通用公共许可证 v3.0(AGPL-3.0)授权。
v1.0.7 之前的版本根据 Mozilla 公共许可证 2.0 授权。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。