mcp召回
自托管 主控程序 为AI助手提供持久语义记忆的内存服务器。存储事实、按意义搜索、交换嵌入模型——所有这些都在您自己的硬件上本地运行。
没有云API。无需GPU。无API成本。
You: "What do we know about the backup configuration?"
Claude: memory_search → finds relevant memories in milliseconds它做什么
mcp-recall将内存作为向量嵌入存储在PostgreSQL中,并通过模型上下文协议使其可搜索。你的AI助手可以在会话、项目和设备之间记住事情。
| 功能 | 详细信息 |
|---|---|
| 语义搜索 | 按意义而非关键字查找记忆 |
| 可更换型号 | 在不丢失数据的情况下更改嵌入模型 |
| 内置基准测试 | 将模型与实际数据进行比较 |
| 双重运输 | 流式HTTP+SSE(传统) |
| 本地嵌入 | ONNX模型在进程内运行,无外部调用 |
| 资源量低 | 在具有16 GB RAM的Celeron J1900上运行 |
快速开始
1.克隆和配置
git clone https://github.com/Jensimogit/mcp-recall.git
cd mcp-recall
npm install
cp .env.example .env
# Generate a random database password (you'll never need to type it)
echo "POSTGRES_PASSWORD=$(openssl rand -base64 32)" >> .env2.下载嵌入模型
存储库中不包括模型(它们的大小为170–560 MB)。下载一个:
node scripts/download-model.js multilingual-e5-large验证模型文件是否到位:
ls models/multilingual-e5-large/
# Expected: config.json onnx/ tokenizer.json tokenizer_config.json如果目录为空(罕见,取决于缓存布局),请手动复制:
find node_modules/@xenova/transformers/.cache -name "config.json"
# Copy the directory that contains config.json + tokenizer.json:
cp -r node_modules/@xenova/transformers/.cache/Xenova/multilingual-e5-large/* models/multilingual-e5-large/3.启动服务器
docker compose up -d就是这样。服务器启动,运行数据库迁移,加载嵌入模型,并在端口3000上监听。
# Verify it's running
curl http://localhost:3000/health
# {"status":"ok","version":"0.2.0","model":"multilingual-e5-large","memories":0,"sessions":0}4.种子示例存储器(可选)
加载一些示例内存以验证搜索是否有效并运行基准测试:
docker compose run --rm mcp-recall node scripts/seed-examples.js这存储了10个关于mcp回忆本身的记忆。您可以立即搜索它们:
# Quick test via the health endpoint — should show memories: 10
curl http://localhost:3000/health5.连接您的AI助手
克劳德代码:
claude mcp add -s user --transport http mcp-recall http://localhost:3000/mcp克劳德代码(苏格兰和南方能源公司运输):
claude mcp add -s user --transport sse mcp-recall http://localhost:3000/sse其他MCP客户端 --指出他们 http://localhost:3000/mcp (流式HTTP)或 http://localhost:3000/sse 上海证券交易所
6.验证其是否正常工作
启动一个新的Claude Code会话并尝试以下工具:
$ claude
❯ Use memory_stats to check the database
● mcp-recall - memory_stats (MCP)
⎿ Total memories: 10
Unique tags: 14
● The database has 10 memories with 14 unique tags.
❯ Search memories for "backup"
● mcp-recall - memory_search (MCP)(query: "backup")
⎿ [1] (79.1% match) Database backup: docker exec mcp-recall-db pg_dump -U mcp
mcp_recall > backup.sql. Restore: cat backup.sql | docker exec -i
mcp-recall-db psql -U mcp mcp_recall.
Tags: operations, backup
❯ Store a new memory: "The deploy key is in 1Password under 'production-deploy'"
● mcp-recall - memory_store (MCP)(content: "The deploy key is in 1Password under
'production-deploy'", tags: ["deployment","credentials"])
⎿ Stored memory 33c6f4e8-f0bc-435a-bb46-fd83676698dd:
The deploy key is in 1Password under 'production-deploy'
❯ Search for "deploy credentials"
● mcp-recall - memory_search (MCP)(query: "deploy credentials")
⎿ [1] (85.0% match) The deploy key is in 1Password under 'production-deploy'
Tags: deployment, credentials请注意,“部署凭据”如何将“1Password中的部署密钥”与85%的相似性相匹配——这是语义搜索,匹配的是含义而不是关键字。
建筑
┌─────────────────────────────────────────────┐
│ MCP Client (Claude Code, claude.ai, etc.) │
└─────────────────┬───────────────────────────┘
│ HTTP (Streamable HTTP or SSE)
▼
┌─────────────────────────────────────────────┐
│ mcp-recall-server (Node.js 22) │
│ ├── MCP Protocol (6 tools) │
│ ├── Express HTTP │
│ └── @xenova/transformers (ONNX, local) │
│ └── Embedding model (volume mount) │
└─────────────────┬───────────────────────────┘
│
┌─────────────────▼───────────────────────────┐
│ PostgreSQL 16 + pgvector │
│ └── HNSW index (cosine similarity) │
└─────────────────────────────────────────────┘所有组件都在Docker中运行。嵌入模型使用ONNX Runtime直接在Node.js进程中运行——没有Ollama,没有Python,也没有单独的推理服务器。
MCP工具
你的AI助手会得到这些工具:
| 工具 | 说明 |
|---|---|
memory_store | 存储新内存(自动生成嵌入) |
memory_search | 按语义相似度搜索 |
memory_update | 更新内容、标签或元数据(如果内容发生变化,则重新嵌入) |
memory_delete | 按ID删除内存 |
memory_list | 列出记忆,可选择按标签筛选 |
memory_stats | 显示数据库统计信息 |
嵌入模型
推荐:多语言e5-large(1024d)
这是默认和推荐的型号。它是专门为 信息检索 (简短查询→ 长文本),这正是内存搜索的工作原理。
可用型号
| 型号 | 尺寸 | 大小(量化) | 最适合 |
|---|---|---|---|
multilingual-e5-large | 1024 | ~553 MB | 一般用途(推荐) |
bge-m3 | 1024 | ~560 MB | 多粒度检索 |
all-MiniLM-L6-v2 | 384 | ~22 MB | 资源最少,仅限英语 |
您可以使用与兼容的任何ONNX型号 @xenova/transformers。把它放进去就行了 models// 使用标准的HuggingFace文件结构。
基准测试结果
我们用8个搜索查询对201个真实记忆测试了三个模型:
| 型号 | 正确前1名 | 平均相似度 | 速度 |
|---|---|---|---|
| 多语言e5-large | 8/8 (100%) | 85.0% | 0.1/s\* |
| bge-m3 | 8/8(100%) | 61.3% | 0.1/s\* |
| 罗伯塔十字架 | 2/8(25%) | 35.3% | 0.5/s\* |
\*Intel Celeron J1900的嵌入速度。在现代CPU上速度更快。
关键发现: 无论语言专业化如何,为信息检索训练的模型(e5,bge)在记忆搜索方面都明显优于句子相似性模型(roberta)。
切换模型
# Compare models against your data (read-only, no changes)
docker compose run --rm mcp-recall node scripts/benchmark-models.js multilingual-e5-large
# Switch to a different model (migrates DB, re-embeds everything)
docker compose run --rm mcp-recall node scripts/switch-model.js bge-m3
# Restart the server to use the new model
docker compose restart mcp-recallswitch脚本处理一切:
- 检测维度更改并迁移数据库
- 用新型号重新嵌入所有记忆
- 更新
.env文件 - 验证结果
您的文本数据永远不会丢失。 仅重新生成向量嵌入。PostgreSQL中的内容、标签和元数据保持不变。
配置
环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
POSTGRES_PASSWORD | (必填) | 数据库密码 |
EMBEDDINGS_MODEL | multilingual-e5-large | 中的模型目录名称 ./models/ |
MCP_PORT | 3000 | 服务器端口 |
TRUST_PROXY | 0 | 代理信任级别(设置为 1 在nginx/Caddy后面) |
MCP_API_KEY | (无) | CLI客户端的静态承载令牌(Claude代码) |
MCP_AUTH_PIN | (无) | OAuth 2.1同意流的PIN(claude.ai,移动设备) |
MCP_BASE_URL | (无) | 服务器的公共URL(OAuth需要) |
认证
mcp recall支持两种可选的身份验证方法。如果两者都没有配置,则允许所有请求(仅适用于本地使用)。
API密钥 (适用于Claude Code和其他CLI客户端):
# Generate a key and add to .env
echo "MCP_API_KEY=$(openssl rand -base64 32)" >> .env
# Configure Claude Code with the key
claude mcp add -s user --transport http \
--header "Authorization: Bearer YOUR_API_KEY" \
mcp-recall http://localhost:3000/mcp带PIN的OAuth 2.1 (适用于claude.ai、移动客户端):
# Add to .env
MCP_AUTH_PIN=123456 # choose a secure PIN
MCP_BASE_URL=https://your-server.example.com # public URL当web客户端连接时,它会被重定向到PIN输入页面。输入正确的PIN后,客户端将收到OAuth令牌(24小时有效,刷新30天)。PIN尝试失败会随着延迟的增加而受到速率限制。
反向代理的背后
如果你在反向代理(nginx、Caddy、Traefik)后面运行mcp-recall:
- 集
TRUST_PROXY=1在.env - 代理到
http://localhost:3000 - 对于流式HTTP:代理
POST/GET/DELETE /mcp - 对于SSE:代理
GET /sse和POST /messages
资源使用
在具有16 GB RAM的Intel Celeron J1900(4核@2.0 GHz)上测量:
| 组件 | RAM | CPU(空闲) | 磁盘 |
|---|---|---|---|
| mcp召回服务器 | ~1.1 GB | 0% | ~50 MB(图像) |
| PostgreSQL+pgvector | 约26 MB | 0% | 约20 MB(200个内存) |
| 总计 | ~1.1 GB | 0% | - |
| 嵌入模型(在磁盘上) | - | - | 553 MB(e5大) |
- 内存使用主要由加载到RAM中的ONNX模型决定
- CPU峰值仅在嵌入生成期间出现(每次查询约100-200ms)
- 在Celeron上重新嵌入200个内存大约需要30分钟,在现代硬件上则要少得多
项目结构
mcp-recall/
├── compose.yml # Docker Compose (2 services)
├── Dockerfile # Server image (node:22-slim)
├── .env.example # Configuration template
├── package.json # 5 dependencies
├── models/ # Embedding models (git-ignored, volume-mounted)
│ └── multilingual-e5-large/
│ ├── config.json
│ ├── tokenizer.json
│ ├── tokenizer_config.json
│ └── onnx/model_quantized.onnx
├── migrations/
│ └── 001_init.sql # Schema: memories table + HNSW index
├── scripts/
│ ├── switch-model.js # Switch models with DB migration + re-embedding
│ ├── benchmark-models.js # A/B compare models against your data
│ ├── download-model.js # Download models from Hugging Face
│ └── seed-examples.js # Load example memories for testing
└── src/
├── index.js # MCP server, Express, dual transport (308 lines)
├── database.js # PostgreSQL CRUD operations (158 lines)
├── embeddings.js # Model-agnostic embedding engine (42 lines)
└── migrate.js # Standalone migration runner (16 lines)总共970行代码。没有框架开销,没有不必要的抽象。
数据库
模式很简单——一个表:
CREATE TABLE memories (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
content TEXT NOT NULL,
metadata JSONB DEFAULT '{}',
tags TEXT[] DEFAULT '{}',
embedding vector(1024) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);索引:HNSW(嵌入上的余弦相似性)、GIN(标签过滤)、B-树(created_at)。
备份
# Dump the database
docker exec mcp-recall-db pg_dump -U mcp mcp_recall > backup.sql
# Restore
cat backup.sql | docker exec -i mcp-recall-db psql -U mcp mcp_recall常见问题解答
Q: 我需要GPU吗? 否。嵌入模型通过ONNX Runtime在CPU上运行。它在Celeron J1900等低功耗硬件上运行良好。嵌入生成每个查询需要大约100-200ms——在正常使用过程中是不可察觉的。
Q: 它能处理多少记忆? HNSW索引可以高效地处理数万个条目。在这个规模上,考虑IVFFlat指数。
Q: 我可以将其与ChatGPT/其他LLM一起使用吗? 是的,任何兼容MCP的客户端都可以工作。服务器实现了标准的模型上下文协议。
Q: 如果我更换型号,会发生什么? 您的文本数据(内容、标签、元数据)将被保留。仅重新生成向量嵌入。这 switch-model.js 脚本处理整个过程,包括数据库维度更改。
Q: 我的数据是否被发送到任何地方? 否。嵌入是在本地生成的。服务器没有出站连接。您的数据保留在硬件上。然而,当MCP客户端检索内存时,内容会流向客户端使用的任何LLM提供程序。
依赖关系和许可证
| 软件包 | 许可证 | 目的 |
|---|---|---|
| @模型上下文协议/sdk | MIT | MCP协议实现 |
| @xenova/变压器 | Apache-2.0 | 用于嵌入的ONNX运行时 |
| 表达 | MIT | HTTP服务器 |
| 页 PostgreSQL 客户端 | ||
| 黄道带 | MIT | 模式验证 |
| pg向量 | PostgreSQL许可证 | 向量相似性搜索 |
所有依赖项都是许可的(MIT或Apache-2.0)。
贡献
欢迎投稿!这个项目重视简单性——请保持更改的重点和最小化。
