内容
# mcp-memory-ydb
用于人工智能代理的长期记忆MCP服务器。它使用 [mem0](https://github.com/mem0ai/mem0) 将原始文本转换为重复事实,并使用 [YDB Serverless](https://yandex.cloud/zh/services/ydb) 作为其背后的矢量存储。
构建在 [`ydb-mcp`](https://github.com/ydb-platform/ydb-mcp) (Yandex的YDB的MCP服务器)之上:通用SQL工具被关闭,取而代之的是两个内存工具。与任何OpenAI兼容的LLM/嵌入提供商(OpenAI,Ollama,Yandex Cloud等)一起工作。
## 工具
| 工具 | 描述 |
|------|-------------|
| `memory_search(query, limit)` | 跨命名空间内存的语义搜索 |
| `memory_save(text)` | 保存一个事实 — mem0提取并重复该事实 |
## 工作原理
`memory_save` 不仅仅存储您给它的文本。它将文本交给 **mem0**,后者调用您的LLM提取关键事实,与已存储的事实进行重复,并解决矛盾(因此,“我使用Postgres”后来覆盖了“我使用MySQL”,而不是累积起来)。每个生成的事实都被嵌入并写入YDB。
**存储事实的语言。** mem0的提取提示是英语,因此默认情况下,即使用户写入其他语言,事实也存储在英语中。要保留用户自己的语言,请将 `MEMORY_FACT_INSTRUCTIONS` 设置为简短的指令 — 并 **用该语言** 编写:经验表明,模型更可靠地遵循相同语言的指令,而不是英语的“保留源语言”注释。例如,对于俄语:
```
MEMORY_FACT_INSTRUCTIONS=Сохраняй каждый факт на языке исходного сообщения, не переводи.
```
服务器没有附带默认指令,除非您选择启用,否则mem0的良好调优提示保持不变。
`memory_search` 嵌入查询并在YDB中对这些事实运行余弦相似性搜索,返回高于 `MEMORY_THRESHOLD` 的最接近匹配。
```
text ─▶ mem0 (LLM: extract + dedup) ─▶ embeddings ─▶ YDB vector store
│
query ─▶ embeddings ─▶ cosine search ◀────────────────────┘
```
- **mem0** — 事实提取、重复和矛盾解决。这是必需的依赖项,而不是可选层;它使内存智能化,而不是仅限于追加日志。
- **[langchain-ydb](https://github.com/ydb-platform/langchain-ydb)** — 矢量存储;在YDB中嵌入事实并运行相似性搜索。
- **YDB Serverless** — 持有矢量和元数据的数据库。
## 内存命名空间
所有内存都位于单个 **命名空间** 下,该命名空间通过 `MEMORY_NAMESPACE` 设置(默认为 `default`)。命名空间是分区标签 — 使用不同的标签来分隔工作和个人内存,或每个项目一个标签。将第二个服务器实例指向不同的命名空间,两个实例永远不会看到对方的事实。
代理 **不** 选择命名空间:它固定在每个服务器进程上,因此代理调用 `memory_save(text)` / `memory_search(query)`,不能错误地读取或写入错误的分区。要切换命名空间,请运行另一个实例并使用其自己的配置。
> **命名空间不是安全边界。** 它是查询过滤器,而不是行级安全或身份验证。任何具有YDB数据库访问权限的人都可以读取每个命名空间。将服务器视为单用户受信任:针对自己的数据库运行自己的实例。它不是多租户后端 — 需要身份验证传输将每个调用者映射到命名空间,代理无法伪造。
## 快速开始
### 1. 配置
```bash
# 从PyPI(发布后):
uvx mcp-memory-ydb setup
# 从源码 — 选项1:uvx(最接近生产环境,隔离环境):
git clone https://github.com/ydb-platform/mcp-memory-ydb
cd mcp-memory-ydb
uvx --from . mcp-memory-ydb setup
# 从源码 — 选项2:venv(开发便捷):
python -m venv .venv && source .venv/bin/activate
pip install -e .
mcp-memory-ydb setup
```
向导创建 `.mcp-memory-ydb.env` 并打印可用的命令以连接到您的代理。
### 2. 连接到您的代理
**Claude Code:**
```bash
# 从PyPI:
claude mcp add --scope user memory-ydb -- uvx mcp-memory-ydb
# 从源码通过uvx(生产方法):
claude mcp add --scope user memory-ydb -- uvx --from /path/to/mcp-memory-ydb mcp-memory-ydb
# 从源码通过venv:
claude mcp add --scope user memory-ydb -- /path/to/.venv/bin/mcp-memory-ydb
```
**Cursor / VS Code** — 将以下内容添加到您的MCP设置中(向导打印一个可以直接粘贴的版本):
```json
{
"mcpServers": {
"memory-ydb": {
"command": "uvx",
"args": ["mcp-memory-ydb"]
}
}
}
```
服务器从 `~/.mcp-memory-ydb.env` 读取其配置(路径默认为 `setup` 保存的路径),因此MCP条目只需要命令 — 不需要 `env` 块。对于通过uvx的源码,请在 `args` 中添加 `"--from", "/path/to/mcp-memory-ydb"`,然后是 `"mcp-memory-ydb"`。对于venv,请将 `command` 设置为 `/path/to/.venv/bin/mcp-memory-ydb` 并清除 `args`。
### 3. 代理系统提示(通常可选)
服务器附带 **MCP指令**,告诉代理在回答之前搜索内存,在回答后保存。客户端如果遵循服务器指令(例如Claude Code),则在连接时自动获取此信息 — **不需要系统提示**。
对于忽略服务器指令的客户端,请将以下内容添加到代理的系统提示中作为备用:
```
在回答之前,请调用memory_search以获取有关用户的相关上下文。
在回答后,如果您学到了重要的内容,请调用memory_save。
请静默使用这些工具 — 不要宣布或叙述搜索或保存。
以用户的语言保存事实,不要翻译。
```
## 使用方法
您不必手动调用工具。一旦服务器连接(上述步骤2),**代理** 根据服务器的内置指令(或备用系统提示)调用 `memory_search` 和 `memory_save` — 同时您只需进行正常的对话。内存工作在后台。
要确认它是否有效,请通过对话进行测试。流程在Claude Code、Cursor和VS Code中相同:
1. **验证服务器是否已连接。**
- Claude Code:运行 `/mcp` — `memory-ydb` 应该列出其两个工具。
- Cursor / VS Code:打开MCP设置面板 — `memory-ydb` 应该显示连接状态。
2. **教它一个事实。** 说:
*"记住我的最喜欢的语言是Rust,我在莫斯科时区工作。"*
代理调用 `memory_save` (Claude Code内联显示工具调用)。
3. **在新的对话中回忆它。** 开始一个新的聊天并询问:
*"你最喜欢的编程语言是什么?)*
代理调用 `memory_search` 并从内存中回答。
如果步骤3在全新的对话中有效,则整个保存 → 存储 → 搜索流程在会话之间已验证。
## 故障排除
服务器快速失败并显示单个可读错误。两个最常见的错误:
**`Could not connect to YDB … PERMISSION_DENIED`**
服务帐户无法访问数据库。请检查:
- SA在数据库的文件夹上具有 **`ydb.editor`** 角色(`yc resource-manager folder add-access-binding <folder> --role ydb.editor --subject serviceAccount:<sa-id>`);
- `YDB_SA_KEY_FILE` 指向该SA的 **正确** 密钥(错误的SA密钥也导致 `PERMISSION_DENIED`);
- `YDB_DATABASE` 是完整路径 `/ru-central1/<folder>/<db>`。
**`LLM/Embeddings unavailable … CERTIFICATE_VERIFY_FAILED`**
Python无法验证提供商的TLS证书。这几乎总是本地信任存储问题,而不是服务器问题。如果您在环境中设置了自定义 `SSL_CERT_FILE` / `REQUESTS_CA_BUNDLE`,可能是该捆绑包太窄,缺少提供商的CA。您可以将CA添加到该捆绑包中,或在启动服务器时将变量指向 [certifi](https://pypi.org/project/certifi/) 捆绑包:
```bash
SSL_CERT_FILE="$(python -m certifi)" mcp-memory-ydb
```
要确认原因,请比较使用您的捆绑包和certifi的请求 — 如果certifi有效而您的无效,则您的捆绑包缺少CA。
## 配置
所有设置都存储在 `.mcp-memory-ydb.env` 中。注释模板: [.env.example](.env.example)。
服务器验证其配置,在启动时连接到YDB并探测LLM/嵌入。如果某些内容无法访问或配置不正确,它将在 **几秒钟内明确失败** 而不是挂起。
### 环境变量
| 变量 | 必需 | 描述 |
|----------|:---:|-------------|
| `LLM_BASE_URL` | 是 | 提供商基准URL |
| `LLM_MODEL` | 是 | OpenAI: `gpt-4o-mini`; Yandex: `gpt://<folder_id>/yandexgpt/latest`; Ollama: `llama3` |
| `LLM_API_KEY` | 是 | API密钥 |
| `EMBEDDINGS_MODEL` | 是 | OpenAI: `text-embedding-3-small`; Yandex: `emb://<folder_id>/text-search-query/latest` |
| `EMBEDDINGS_BASE_URL` | | 嵌入基准URL(默认为 `LLM_BASE_URL`) |
| `EMBEDDINGS_API_KEY` | | 嵌入API密钥(默认为 `LLM_API_KEY`) |
| `YDB_ENDPOINT` | 是 | `grpcs://ydb.serverless.yandexcloud.net:2135` |
| `YDB_DATABASE` | 是 | `/ru-central1/<folder>/<db>` |
| `YDB_SA_KEY_FILE` | | 服务帐户JSON密钥文件路径 |
| `YDB_SA_KEY` | | 服务帐户密钥为JSON字符串(`YDB_SA_KEY_FILE`替代) |
| `MEMORY_NAMESPACE` | | 内存分区,例如每个项目(默认为 `default`) |
| `MEMORY_FACT_INSTRUCTIONS` | | 控制mem0提取(例如存储语言);为空 = mem0默认。 用您自己的语言编写。 |
| `MEMORY_THRESHOLD` | | 最小余弦分数(默认为 `0.15`) |
| `MEMORY_TIMEOUT` | | 内存操作超时,秒(默认为 `30`) |
| `PROBE_TIMEOUT` | | 启动LLM/嵌入探测超时(默认为 `MEMORY_TIMEOUT`) |
| `YDB_TIMEOUT` | | YDB `discovery_request_timeout`(默认为 `MEMORY_TIMEOUT`) |
## 要求
- Python 3.11+
- 具有API密钥的OpenAI兼容的 **LLM和嵌入** 提供商(OpenAI,Yandex Cloud,Ollama等) — mem0使用LLM提取事实,使用嵌入将其向量化
- YDB Serverless数据库和具有 `ydb.editor` 角色的服务帐户
## 许可证
[Apache 2.0](LICENSE)