内容
mcp一个 [Model Context Protocol](https://modelcontextprotocol.io) (MCP) 服务器,为LLM代理提供持久的**知识图谱内存** —— 存储在嵌入式SQLite数据库中的实体、关系和观察结果,支持FTS5全文搜索。
它是一个**统一的服务器**,可选启用向量子系统:
| 调用方式 | 功能 | 工具 |
|---|---|---|
| `mcp-memory` | 知识图谱服务器 | 26 |
| `mcp-memory --vectors` | 知识图谱服务器 + 向量嵌入和语义/混合/MMR搜索(usearch HNSW **或** IVF-Flat) | 38 |
| `mcp-memory-vec` | `mcp-memory --vectors`的向后兼容别名 | 38 |
> **v4 注意:** 以前的独立 `mcp-memory-vec` 服务器已合并到 `mcp-memory` 中。向量现在通过 `--vectors` 标志启用;`mcp-memory-vec` 仍然是一个薄薄的别名,启用该标志,以便现有的配置文件继续工作。
它通过 **stdio、TCP 和 HTTP** (带有可选的 bearer-token 认证和 TLS)支持MCP。
```
┌────────────────────────────────────────────────┐
│ mcp-memory (+ --vectors / -vec 别名) │
│ │
┌───────┐ ┌────────── ┌─────────────────────────┐ │
│ │──────│─ stdio />│ GraphHandle │ │
│ / │ │ │ LRU 实体 │ │
─┘ │ │ HTTP │ ├ FxHash名称→ID │ │ └────┬─────┘ │ └ FTS5 全文索引 │ │
│ │ ─┬──────────── │
│ (--vectors 仅 │
│ ┌───────────┴─────────────┐ │
│ ┌──────── │ VectorStore │
│ 调度 │>│ ├ ANNNSW *或* IVF │ │
└──────── │ └ pet邻接矩阵 │ │
│ │───────────┬─────────────┘ │
│ v │
┌──────────────────────────────── │
│ (WAL, 4 KB 页面, 自动 │ │
│ 实体、关系、*_fts、 │ │
│ 类型字典、向量嵌入 │
│ └──────────────────────────────────────────┘ │
────────────────────────────────────────────────┘
```
## 安装
```cargo install mcp-memory
```
这同时安装mcp-memory` 和 `mcp-memory-vec## 快速开始
```sh
# 知识服务器
mcp-memory --transport stdio
图谱 + 向量mcp-memorytransport stdio --embedding-dims 384
# 等效的向后兼容别名
mcp-memory-vec --transport stdio --embedding-dims 384
```
数据库路径按以下顺序解析:
1. `--memory-file` / `-f` 标志
2. `MEMORY_FILE_PATH` 环境3. 默认:当前中的 `memory.mcpmem`
文件在启用或禁用 `--vectors` 的情况下,因此您可以先填充图谱,然后在启用向量后提供服务。关闭 `--vectors` 时,向量工具 `tools/list`宣传或提供服务。
### 传输
| 传输 | 标志 | 描述-----------|------|-------------|
| stdio | `--` | 标准输入/输出上的换行分隔 JSON(默认,适用于 / Claude Code) tcp | `--transport 0.0.0:8080` | TCP 上的换行分隔 JSON,支持并发连接 |
| http | http --bind 0.0.0.8080` | MCP 流式 HTTP(POSTmcp`, |
### Claude Claude Code 配置
```json
{
"": {
": {
"mcp-memory"
}
}
```
添加 `"args": ["", "--embedding-d "384"]` 以启用向量搜索(或command": "mcpec"`)。
认证
`tcp` 和 `http`接受可选的 bearerstdio 永远不会)。使用 `--auth 或 `--auth-token(修剪;空拒绝)或 `_MEMORY_AUTH_TOKEN` 环境变量设置它。
```mcp-memory -- --bind 0.0.0:8080 --auth-token3cr3t"
mcp-memory --vectors --transport http --bind 0.0.0.8080 --auths3cr3```
在 HTTP 上,token 作为 `Authorization:token>` 发送;在,它是连接的第一行。比较是恒定时间的。绑定一个非环回地址 **而没有** token 会将整个图谱暴露给网络。
### TLS(HTTPS)
`http` 传输可以通过 TLS(rustls,`ring` 提供程序)提供服务。提供一个 PEM 证书链作为 `--tls-cert `--tls-key两者必须同时提供将被拒绝。CP_TLS_CERT`MCP_TLS_KEY变量被接受为后两者都未传输保持明默认)。
```cp-memory --transport http --bind 0.0.0:8080 \
-- ./cert.pem --tls-key ./key.pem
代码索引(`)
使用`,服务器可以解析树并将其为普通的图谱内存服务器变成终端编码代理(Claude Code,opencode,codex的持久的、语义可搜索的图**。由于符号是普通实体,因此所有工具 — `search_nodes`、`extract_sub、`get_neighbors`_path` 和(vectors`)`hybrid_search` — 代码。
- **存储内容。** 函数、方法、模块和名为 `relpath` 的实体,类型code:<kind>`。元数据(文件、行范围、签名、第一个文档行、语言)存储在观察中。`defines`(文件→符号)和 `calls`/`references`(调用者→被调用者不**存储正文 — 仅签名和,以便代理读取确(比 grep 更少的- **增量。** 每个文件的 内容哈希 存储;`code_index` 仅重新。重新运行编辑后以保持映射更新时的符号映射比 `grep` 更糟- **无歧仅。** tree 提供语法,而不是已解析的语义,因此当被调用者名称解析为恰好一个定义时,会创建 `calls` 边。模糊引用被丢弃而不是记录为假边。调用边在索引整个存储库根目录后最完整。
- **语言。** Rust、Python、JavaScript、TypeScript/TSX、Go、Java、**C**、**C++**、**Ruby**、**PHP**文件(`.h`.hpp`hh`、`.`)与源索引。遍历遵循 `.gitignore` 并跳过 `target`/`node_modules`/`dist`/`build` 和超大文件。
启用 `--code公开的四个工具:
| 工具 | |
| --- || `code 将文件/目录解析为图谱(增量;`force` 重新解析所有文件)。 |
| `code_outline 列出文件中定义的类型、行、签名)。 |
| `` | 代码符号TS → 紧凑的位置行(按 `kind`/`lang`)。 |
| `_symbol` | 的元数据及其调用者和被调用者```bash
m --code --transport
# 然后,通过 code_index {" "src"}
```
` Cargo 功能**默认启用**;` --no-default-features一个精简的二进制文件,不编译 tree-sitter 语法量搜索(`)
使用 `--vectors`,服务器图谱之上层叠一个向量存储。每个附加到一个**现有**实体(按索引到内存中的 ANN 索引中,并vector_embedding` SQLite 表中的 blob 持久启动时,索引从这些 blob 中重建。
- **自带嵌入。** 服务器存储和搜索向量;它不调用嵌入模型。客户端计算嵌入(例如,使用嵌入 API)并传入。所有向量必须与 `--embedding-dims` 匹配。
- **语义搜索** — `vector_search_entities` 按余弦相似度(可配置)返回最近的实体,可选按实体类型过滤。
- **类似和推荐** — `vector_search_by_entity` 查找与给定实体的嵌入相似的实体;`vector_recommend` 从正(减负实体构建- **MMR 多样化** — `vector_mmr_search` 返回平衡相关性和性的结果(最大边际相关性),这是常见的 RAG 上下文选择步骤,抑制近命中。
- **入** —_batch_upsert` 每次插入最多 1,024 个嵌入,报告逐项失败而不是中止 **混合搜索** — `hybrid_search`运行向量搜索和 FTS5 文本搜索,并使用相互排名融合(RRF,常数 60两个排名,然后可选图谱中心性提升结果。
### 索引后端:HNS IVF-Flat
通过 `--vec-index` ANN 后端: 后端 | 何时使用 | 备注---|---|---|
| ` *(默认)* | 大多数工作负载的最佳召回率/延迟 | [usearch](github.com/unumearch) 图索引 `f16`16`/` 量化 |
| `ivf`型、批量摄入、定期重建料库 | k区(IVF);构建更便宜更轻。(蛮力训练**,因此正确 |
IVF 索引在打开填充时自动训练。在将大量批次摄入到新的数据库后,vector_reindex`)运行 k-means 并保持高召回HNSW 的无操作)。
### 向量配置
索引可以从命令行调整(都需要`):
| 标志 | 默认含义 |
|---|---|---|
| `--embedding-d | `384 向量维度;必须匹配 |
vec-index` |sw` |端:`hn `ivf` |
| `--vec | `cos` | 距离度量:`cos`、`ip`(点积 `l2sq| `--vec-quantization` | `f32` | HNSW 标量存储:`f32`、`f16`、`bf16` 或 `i8`(越低 = 内存越小) |
| `--vec-connectivity` | `16` | HNSW 图度 `M` = 回率,更多内存) |
| `--vec-expansion-add` | `200` |W `efConstruction`(越高 = 更好的,插入越| `--vec-search` | `50` | HNSefSearch` = 更好的召回率,查询越 |
| `--ivf` |` | IVF Vor单元格 / 中 |
| `--ivprobe` | `8` | 查询时探测的 IVF 单元格数量(越高 = 更好的召回率,越慢) |
```sh 具有半精度 HNSW
mcp-memory --vectors --transport http --bind 0.0.0.0:8080 --embedding-dims 768 --vec-metric cos --vec-quantization f16 \
--vec-connectivity 32 --vec-expansion-search 128
# 用于大型语料库的 IVF-Flat
mcp-memory --vectors --embedding-dims 768 \
--vec-index ivf --ivf-nlist 1024 --ivf-nprobe 16
```
用于混合搜索中心性提升的 petgraph 邻接缓存是惰性构建的;在修改关系后调用 `vector_refresh_graph_cache` 以刷新它。
## MCP 合规性
实现了 [Model Context Protocol](https://modelcontextprotocol.io) 修订版 **`2025-11-25`**,通过 JSON-RPC 2.0 stdio、TCP 或 HTTP。
| 领域 | 支持 |
|---|---|
| 传输 | stdio、TCP、**流式 HTTP**/GET `/m,SSE) 协议版本 | `2025-11`,协商至 `2025-06-18` / `2025-03-26` / `2024-11-05` |
| `initialize` | 版本协商 + `instructions` |
| `tools/list`、`tools/call` | 26 个工具(仅 KG)/ 38 个工具(启用 `--vectors`) |
| `CallToolResult` | `content[]` + `isError` |
| 认证 | TCP/HTTP 上的可选 bearer token(恒定时间) |
| 广告功能 | 仅 `tools` |
工具失败作为 `CallToolResult` 返回,具有 `isError: true`(不是 JSON-RPC 协议错误),以便自我纠正 数据模型
```
Entity(name, entityType, observations[]) ──relationType──▶```
- ** — 具有例如 `person``、`project和自由格式的命名节点。唯一且区分大小写的。
- **关系** — 有向边 `(from, to, relationType)`。遍历是无向的(BFS/DFS 遵循两个方向)。
- **观察** — 附加到实体的非结构化事实。
- **嵌入** *(`--vectors`)* — 附加到实体的固定维度 `f32` 向量,带有可选的模型标识符。
搜索使用具有 `unicode61 remove_diacritics 2` 标记化的 FTS5 全文索引。名称和观察正文分别位于单独的外部内容 FTS5 表中(`name_fts`、`obs_fts`)。
## 存储与性能
### SQLite(WAL 模式)
单个 WAL 模式下的 SQLite 数据库:
| 表 | 键 | 目的 |
|---|---|---|
| `entity` | `INTEGER PRIMARY KEY`(行 ID)| 主要实体存储;物化 `obs_count`、`out_deg`、`in_deg`;`name_hash` 用于 O(1) 路由 |
| `observation` | `entity_id`(FK)+ 行 ID | 每个实体 1:N 观察 |
| `relation` | 复合索引 | 有向边;覆盖索引 `rel_out(from_id,type_id,to_id)` 和 `rel_in(to_id,type_id,from_id)` 用于仅索引扫描 |
| `name_fts` | `content_rowid` | `entity.name` 的外部内容 FTS5 |
| `obs_fts` | `content_rowid` | `observation.body` 的外部内容 FTS5 |
| `type_dict` | 名称 | 带有实时计数的 interned 实体/关系类型(加载到 RAM) |
| `graph_stat` | 键(单例)| `WITHOUT ROWID` 计数器:实体、关系、观察、序列 |
| `vector_embedding` | `entity_id` | *(`--vectors`)* `dims`、`blob`(f32 向量)、`model`、`created_us` |
关键 pragma(默认值,均可通过标志调整):`page_size=4096`、`journal_mode=WAL`、`auto_vacuum=INCREMENTAL`、`synchronous=NORMAL`、`cache_size=-50000`(约 50 MB, `--cache-size-mb`)、`mmap_size=256 MB`(`--mmap-size`)、`temp_store=MEMORY`、`busy_timeout=5000`(`--busy-timeout-ms`)。后台 `wal_checkpoint(PASSIVE)` 每 `--wal-flush-ms`(默认 250 毫秒)运行一次,以限制异步持久性窗口。
### 内存缓存
| 缓存 | 目的 |
|---|---|
| 实体 LRU(10,000 条目)| 避免反序列化热门实体;存储 `EntityMeta{id, type_id, obs_count, out_deg, in_deg}` |
| 名称哈希映射 | O(1) 名称到 ID 解析,通过 64 位哈希 |
| 预备语句缓存 | 重用编译后的 SQLite| ANN 索引 *(`--vectors`)* | 内存 HNSW 或 IVF-Flat 索引,从 `vector_embedding` 重建启动 |
| petgraph 邻接矩阵 *(`--vectors`)* | 有向图缓存用于混合搜索中心性提升 |
### 写入批处理
每个突变都经过一个分层写入路径,该路径将事务计数从 O(N) 折叠为每次 `create_entities` / `create_relations` 调用 O(1):
1. 批量存在检查在一个读取事务中
2. 在一个写入事务中批量提交所有新实体/关系
3. 在一个写入事务中批量 FTS 索引更新
4. 受影响名称的缓存失效
### 持久性
| 模式 | 行为 | 数据丢失窗口 |
|---|---|---|
| `async`(默认)| 刷新到内核页缓存,背景同步 | 最多 ~1 秒,电源故障时 |
| `sync` | 每个写入前 fsync零 |
通过环境变量 `_MEMORY_DURABILITY=sync` 设置(无论是否启用 `--vectors`)。
### 背景维护
一个 任务每 5 分钟运行一次:WAL 检查点(`PRAGMA wal_checkpoint(TRUNCATE)`)、规划器分析(`PRAGMA optimize`)和 FTS 优化。
## 基准测试
通过 `bench` 二进制文件进行端到端测量,1,000 个实体(每个 5 个观察)+ 999 个关系预先填充,在 **MacBook Pro (Apple M1 Pro, 32 GB)** 上运行。数字是平均值,会因硬件而异 — 在您自己的目标上运行 `cargo run --release --bin bench`。
| 操作 | 平均延迟 | 备注 |
|---|---|---|
| `degree`(缓存命中) | ~44 纳秒 | 物化列 |
| `relation` | ~2.3 µs | RAM 缓存类型字典 |
| `get_entity_count` | ~3.0 µs | RAM 计数器 |
| `entity_type_counts` | ~4.5 µs | RAM 缓存类型字典 |
| `get_entity`(缓存命中) | ~5.4 µs | LRU 命中;无 SQLite I/O |
| `describe_entity` | ~5.4 µs | 实体 + 事件关系 |
| `search_relations`(来自 / 来自 + 类型) | ~6.3 µs | 覆盖索引扫描 |
| `delete_observations`(1) | ~11 µs | |
| `find_all_paths`(A→C,深度 5) | ~12 µs | 有界 DFS |
| `upsert_entities`(类型更改 + 观察) | ~27 µs | |
| `entities_exist`(10 个名称) | ~38 µs | 哈希查找 |
| `_entities`(10 个) | ~42 µs | 批量获取 |
| `neighbors`(深度 1 / 深度 2) | ~50 µs | 索引覆盖扫描 |
| `open_nodes`(单个 / 5 个名称) | ~53–77 µs | LRU + SQLite |
| `search_nodes`(名称匹配) | ~96 µs | FTS5 查询 + 实体查找 |
| `add_observations`(2) | ~163 µs | 追加 + FTS 索引 |
| `search_nodes`(观察匹配) | ~161 µs | 观察正文上的 FTS5 |
| `find_path`(BFS) | ~453 µs | 最坏情况:完整 BFS |
| `search_nodes`(过滤) | ~623 µs | FTS5 + 类型过滤 |
| `export`(JSON) | ~2.5 毫秒 | 序列化所有实体 + 关系 |
| `read_graph` ~3.毫秒 | 完整转储 |
| ``(999)10 毫秒 | 批量写入 + 度更新 |
| `create(1000) | ~41 | 批量写入 + 索引 |
## 工具
### 知识图谱工具()
**写入:**_entities`、`create_relations`_observations`、`delete_entitiesdelete_observations`、`delete、`upsert_entities`、``、`compact`。
**** `
### 向量工具(仅限 `--vectors`)
- `vector_upsert_embedding` — 在现有实体上附加或替换嵌入
- `vector_batch_upsert` — 批量插入最多 1,024 个嵌入;逐项错误报告
- `vector_get_embedding` — 获取存储的实体嵌入(和模型)
- `vector_search_entities` — 按向量相似度获取前 K 个最近的实体(可选类型过滤)
- `vector_search_by_entity` — “类似”:最近的实体嵌入
- `vector_recommend` — 基于正/负实体的示例推荐
- `vector_mmr_search` — 通过最大边缘相关性 (`lambda`) 实现的多样化检索
- `hybrid_search` — 向量 + FTS5 通过 RRF 融合,可选图中心性提升
- `vector_delete_embedding` — 删除实体的嵌入(实体被保留)
- `vector_reindex` — 在当前向量上重新训练 IVF 索引(HNSW 为空操作)
- `vector_refresh_graph_cache` — 从关系中重建 petgraph 邻接缓存
- `vector_store_stats` — 嵌入计数、维度、后端类型、索引/图大小
## 架构
```
main.rs / vec_main.rs → MCPServer { kg, vs: Option<VectorStore> }
├── run_stdio() — 基于 stdio 的换行 JSON-RPC
├── run_tcp() — 相同帧格式,并发连接
└── run_http() — MCP 流式 HTTP(axum, POST/GET /mcp)
└── process_request()
├── "initialize" → 协议版本 + 功能
├── "tools/list" → 缓存工具列表
├── "tools/call" → 按名称分派到处理程序
├── "ping" → 空
└── "notifications/…" → 无回复
```
所有传输方式都共享传输无关的分派核心
(`dispatch_line()` / `dispatch_http_body()`)。
### 并发与锁定
- `GraphHandle` 使用 `parking_lot::Mutex` 进行写入连接和缓存;只读连接池在 WAL 下提供并发读取。
- `VectorStore` 使用 `DashMap` 进行名称↔ID 映射和 `RwLock` 进行 petgraph 缓存;HNSW 索引是内部同步的,IVF 索引在其自己的 `RwLock` 后面。向量工具在 `--vectors` 后被禁用;纯 KG 服务器不携带向量状态。
- 重型分派(图形锁定 + 可选 fsync)被卸载到
`tokio::task::spawn_blocking` 以保持反应性。
- TCP 连接限制在 128 个并发连接。
### 请求大小限制
| 参数 | 限制 |
|---|---|
| 最大请求体 | 16 MB |
| 名称最大字节数 | 1,024 |
| 观察最大字节数 | 65,536 |
| 每请求最大实体/关系/观察/名称 | 1,000 |
| 最大搜索限制 | 1,000 |
| 最大邻居深度 | 16 |
| 最大 `find_all_paths` 深度/结果 | 10 / 100 |
| 最大嵌入维度 *(`--vectors`)* | 4,096 |
| 最大 `topK` *(`--vectors`)* | 100 |
| 每 `vector_batch_upsert` 最大项目数 | 1,024 |
## 开发
```sh
cargo test # 100+ 个单元测试 + 集成测试
cargo clippy # 代码检查(库 + 二进制文件)
cargo build --release # LTO + fat, 优化级别 3
cargo run --release --bin bench # 独立基准测试
```
测试套件涵盖协议处理、所有工具处理程序、CRUD/搜索/路径持久性、并发性、模糊不变性检查,以及对于向量子系统 —
IVF-Flat 索引(训练、探测搜索、插入/删除、指标)、两种 ANN
后端端到端、现代检索工具(批量插入、类似、推荐、MMR)、当 `--vectors` 关闭时的向量门控、输入验证、可调索引配置和 HTTP 持有者令牌身份验证。
## 许可证
在 [Apache License, Version 2.0](LICENSE) 下许可。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器