使用说明
内存MCP服务器
用于LLM的高性能、仅追加内存存储系统,具有语义搜索、全文搜索、版本控制、分叉和时间点恢复功能。
特性
核心内存操作
- 添加回忆 语义搜索的自动嵌入生成
- 更新记忆 保留完整版本历史记录
- 删除记忆 (软删除-已存档但可恢复)
- 找回记忆 通过ID和O(1)查找
- 列出回忆 按类别、类型和分页进行筛选
搜索功能
- 语义搜索 使用HNSW(分层导航小世界)算法
- 全文搜索 BM25排名
- 混合搜索 将语义和文本搜索与可配置权重相结合
- 使用fastembed进行局部嵌入(全MiniLM-L6-v2,384维)
关系
- 在记忆之间建立关系(related_to、取代、反驳、阐述、引用)
- 遍历图以查找相关内存
- 关系版本控制和软删除
节奏/复习系统
- 使用可配置的节奏安排内存检查(每日、每周、每月、每周一天、日历日)
- 根据上次访问时间获取应审查的记忆
版本控制和历史记录
- 每次更改都会创建一个新版本(仅可追加)
- 所有修改的完整审计跟踪
- 使用SHA-256哈希的内容可寻址存储
- 用于密码完整性验证的Merkle树
分叉与分支
- 创建分叉 从任何商店进行实验
- 写时复制语义 -叉子共享历史,但独立进化
- 完全隔离 -一个叉子的变化永远不会影响另一个叉子
- 多个并发分叉 支持
时间点恢复(PITR)
- 从任何历史时间戳创建分叉
- 命名快照便于恢复点
- 将快照还原到新分叉
店铺管理
- 完整性验证 使用merkle树证明
- 重建索引 恢复能力
- 墙体压实 到细分市场
- 平滑关闭 具有数据持久性
建筑
┌─────────────────────────────────────────────────────────────────┐
│ MCP Server / HTTP API │
├─────────────────────────────────────────────────────────────────┤
│ Store Adapter │
├─────────────────────────────────────────────────────────────────┤
│ Memory Store API │
├──────────────┬──────────────┬──────────────┬────────────────────┤
│ Latest Index │ Vector Index │ Text Index │ Merkle Tree │
│ (HashMap) │ (HNSW) │ (Inverted) │ (Integrity) │
├──────────────┴──────────────┴──────────────┴────────────────────┤
│ Write-Ahead Log (WAL) │
├─────────────────────────────────────────────────────────────────┤
│ Segment Files (Immutable) │
└─────────────────────────────────────────────────────────────────┘
安装
先决条件
- Node.js v21.2或更高版本
安装依赖项
npm install
初始设置
在使用内存服务器之前,请运行安装脚本以创建用户存储:
交互式设置
node src/setup.js
这将提示您输入用户名并创建:
- 用户专用商店(主店的叉子)
- 配置文件位于
~/.mcp/memory.json
非交互式设置
# Create store for a specific user
node src/setup.js --user jerry
# Reset an existing user's store
node src/setup.js --user jerry --reset
# Show current configuration
node src/setup.js --show
配置文件
设置创建 ~/.mcp/memory.json:
{
"store_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"user_id": "jerry",
"timezone": "America/Los_Angeles",
"trust_levels": {
"email": "sandbox",
"calendar": "sandbox",
"web_search": "autonomous",
"notifications": "autonomous"
},
"daily_run_time": "06:00",
"briefing_delivery": "memory",
"weekly_review_day": "sunday",
"monthly_review_day": "1",
"created_at": "2024-01-31T12:00:00.000Z"
}
| 字段 | 描述 |
|---|---|
store_id |
个人内存存储的UUID(fork) |
user_id |
您的用户名 |
timezone |
自动检测时区 |
trust_levels |
Daily Runner代理的操作权限 |
daily_run_time |
当Daily Runner执行时 |
briefing_delivery |
如何进行每日简报 |
weekly_review_day |
每周回顾日 |
monthly_review_day |
月度审查日 |
CLI工具
列出商店
node src/cli.js stores
输出(显示fork层次结构的ASCII树视图):
Memory Stores
=============
Current user: Jerry (store: 377e6d5c-5733-461a-9504-e4ec00ef2744)
Main Store - 1/31/2026, 8:41:39 PM
├── User: alice (a1b2c3d4...) - 1/31/2026, 9:00:00 PM
│ 📝 Alice's personal memory store
├── User: bob (e5f6g7h8...) - 1/31/2026, 9:15:00 PM
│ └── Experiment: bob-test (i9j0k1l2...) - 1/31/2026, 9:30:00 PM
│ 📝 Testing new features
│ ⏱️ PITR from: 1/31/2026, 9:00:00 PM
└── User: Jerry * (377e6d5c...) - 1/31/2026, 8:52:12 PM
* = current user store
Total: 5 store(s)
使用笔记创建商店
# Create store with a note
node src/setup.js --user jerry --note "Personal memory store"
# Interactive mode also prompts for a note
node src/setup.js
其他 CLI 命令
# Show store statistics
node src/cli.js stats [store_id]
# List snapshots for a store
node src/cli.js snapshots [store_id]
# Verify store integrity
node src/cli.js verify [store_id]
# Output as JSON
node src/cli.js stores --json
运行服务器
MCP服务器(stdio传输)
node src/index.js
# or explicitly:
node src/index.js --stdio
REST HTTP服务器
node src/index.js --http
# or with custom port:
node src/index.js --http --port 8080
REST HTTP服务器在 http://localhost:3000 默认情况下。它提供了一个标准的REST API和一个调试UI /debug.
MCP HTTP服务器(流式HTTP)
node src/index.js --mcp-http
# or with custom port:
node src/index.js --mcp-http --mcp-port 8080
MCP HTTP服务器在 http://localhost:3001/mcp 默认情况下。它使用 可流式HTTP传输 适用于通过网络而不是stdio连接的MCP客户端。
HTTP传输的MCP客户端配置:
{
"mcpServers": {
"memory": {
"url": "http://localhost:3001/mcp"
}
}
}
多个服务器
# stdio + REST HTTP
node src/index.js --stdio --http
# REST HTTP + MCP HTTP
node src/index.js --http --mcp-http
# All three
node src/index.js --stdio --http --mcp-http
命令行选项
| 选项 | 描述 |
|---|---|
--stdio |
为MCP客户端启动stdio服务器(如果未指定模式,则默认) |
--http |
启动REST HTTP服务器 |
--mcp-http |
使用流式HTTP传输启动MCP服务器 |
--port <port> |
REST HTTP服务器端口(默认值:3000) |
--mcp-port <port> |
MCP HTTP服务器端口(默认:3001) |
--host <host> |
服务器主机名(默认:localhost) |
--store-id <id> |
将所有操作锁定到特定的商店/叉子ID(请参阅 服务器模式) |
--basic |
仅公开基本内存工具(请参见 服务器模式) |
--debug |
为MCP调用启用调试日志记录(输出到stderr) |
--help, -h |
显示帮助消息 |
环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
DATA_DIR |
./data |
用于存储所有数据的目录 |
PORT |
3000 |
REST HTTP服务器端口 |
MCP_PORT |
3001 |
MCP HTTP服务器端口 |
HOST |
localhost |
服务器主机名 |
服务器模式
基本模式(--basic)
当 --basic 启用后,MCP服务器仅向LLM公开核心内存工具:
| 工具 | 说明 |
|---|---|
add_memory |
通过自动嵌入创建新内存 |
get_memory |
按ID检索内存 |
update_memory |
更新现有内存(创建新版本) |
delete_memory |
存档内存(软删除) |
list_memories |
列出带有过滤器和分页的内存 |
search_memories |
使用语义、文本或混合模式进行搜索 |
add_relationship |
在记忆之间建立联系 |
remove_relationship |
删除关系 |
get_relationships |
获取记忆中的所有关系 |
get_related_memories |
导线关系图 |
get_due_memories |
获取到期的回忆以供审查 |
所有其他工具(分叉、PITR、快照、存储管理、统计数据)都对LLM隐藏。当你想要一个没有高级功能的更简单的界面时,这很有用。
node src/index.js --basic
店铺ID锁(--store-id)
当 --store-id 如果提供,所有操作都将锁定到指定的商店/叉子ID store_id 参数已从所有工具模式中删除,因此LLM永远不会看到或需要指定它。
# Lock to a specific user fork
node src/index.js --store-id "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
这在以下情况下很有用:
- 每个用户都有自己的叉子,你希望LLM只在那个叉子上操作
- 您希望防止LLM意外读取/写入错误的存储
- 通过删除不必要的参数简化工具界面
组合模式
这两个选项可以结合使用,以实现最小的锁定配置:
# Simple interface locked to a specific user store
node src/index.js --store-id "user-fork-uuid" --basic
MCP配置示例
标准配置(所有工具,LLM选择存储):
{
"mcpServers": {
"memory": {
"command": "node",
"args": ["/path/to/memory/src/index.js"]
}
}
}
仅使用基本工具锁定到用户叉子:
{
"mcpServers": {
"memory": {
"command": "node",
"args": [
"/path/to/memory/src/index.js",
"--store-id",
"user-fork-uuid",
"--basic"
]
}
}
}
测试
运行所有测试
npx vitest run
运行特定测试文件
# Core store tests (150 tests)
npx vitest run src/store/store.test.js
# Integration tests (43 tests)
npx vitest run src/integration.test.js
# Memory tests (44 tests)
npx vitest run src/memory.test.js
测试覆盖率
| 测试套件 | 测试 | 描述 |
|---|---|---|
| 店铺核心 | 150 | WAL、细分、索引、merkle树、分叉、PITR |
| 集成 | 43 | 端到端API测试、分叉隔离、服务器选项 |
| 记忆 | 44 | 记忆/搜索/关系测试 |
| 总计 | 237 |
API 参考
MCP工具
内存操作
| 工具 | 说明 |
|---|---|
add_memory |
通过自动嵌入创建新内存 |
get_memory |
按ID检索内存 |
update_memory |
更新现有内存(创建新版本) |
delete_memory |
存档内存(软删除) |
list_memories |
列出带有过滤器和分页的内存 |
search_memories |
使用语义、文本或混合模式进行搜索 |
get_due_memories |
获取到期的回忆以供审查 |
get_stats |
获取店铺统计信息 |
关系运营
| 工具 | 说明 |
|---|---|
add_relationship |
在记忆之间建立联系 |
remove_relationship |
删除关系 |
get_relationships |
获取记忆中的所有关系 |
get_related_memories |
导线关系图 |
叉车操作
| 工具 | 说明 |
|---|---|
create_fork |
从当前状态创建分支 |
create_fork_at_time |
从特定时间戳(PITR)创建分叉 |
list_forks |
列出所有分叉 |
delete_fork |
删除叉子 |
快照操作
| 工具 | 说明 |
|---|---|
create_snapshot |
创建命名快照 |
list_snapshots |
列出存储的所有快照 |
restore_snapshot |
从快照还原(创建新分支) |
店铺管理
| 工具 | 说明 |
|---|---|
get_store_snapshot |
获取merkle根进行验证 |
verify_integrity |
验证存储完整性 |
rebuild_indexes |
重建所有索引 |
HTTP端点
回忆
| 方法 | 端点 | 描述 |
|---|---|---|
| 职位 | /memories |
创建内存 |
| 得到 | /memories/:id |
按ID获取内存 |
| PUT | /memories/:id |
更新内存 |
| 删除 | /memories/:id |
删除内存 |
| 得到 | /memories |
列出回忆 |
| 职位 | /memories/search |
搜索记忆 |
| 得到 | /memories/due |
获得应有的回忆 |
| 得到 | /memories/:id/relationships |
建立关系 |
| 得到 | /memories/:id/related |
获取相关回忆 |
关系
| 方法 | 端点 | 描述 |
|---|---|---|
| 职位 | /relationships |
建立关系 |
| 删除 | /relationships/:id |
删除关系 |
分叉
| 方法 | 端点 | 描述 |
|---|---|---|
| 职位 | /forks |
创建fork |
| 职位 | /forks/pitr |
创建PITR分叉 |
| 得到 | /forks |
列表分叉 |
| 删除 | /forks/:id |
删除叉子 |
快照
| 方法 | 端点 | 描述 |
|---|---|---|
| 职位 | /snapshots |
创建快照 |
| 得到 | /snapshots |
列出快照 |
| 职位 | /snapshots/:id/restore |
还原快照 |
店铺管理
| 方法 | 端点 | 描述 |
|---|---|---|
| 得到 | /stats |
获取统计数据 |
| 得到 | /health |
健康检查 |
| 得到 | /store/snapshot |
获取默克尔根 |
| 职位 | /store/verify |
验证完整性 |
| 职位 | /store/rebuild-indexes |
重建索引 |
| 职位 | /store/compact |
紧凑型墙体 |
| 职位 | /store/flush |
刷新写入 |
店铺ID参数
所有操作均支持a store_id 参数,指定要对哪个存储/分支进行操作:
store_id = "main"或省略→ 默认主商店store_id = "<fork-uuid>"→ 专用叉子
查询参数(GET请求):
GET /memories?store_id=abc-123-def
主体参数(POST/PUT请求):
{
"store_id": "abc-123-def",
"category": "people",
"content": "..."
}
数据模型
记忆记录
{
id: string, // UUID, stable across versions
category: string, // e.g., "people", "work", "facts"
type: string, // e.g., "person", "fact", "experience"
content: string, // The memory content
tags: string[], // Flexible organization
importance: number, // 1-10 priority score
cadenceType: string, // "daily", "weekly", "monthly", etc.
cadenceValue: string, // Day name or number for cadence
context: string, // When/why created
version: number, // Incrementing version
contentHash: string, // SHA-256 of content
createdAt: string, // ISO timestamp
archived: boolean, // Soft delete flag
storeId: string // Fork/store ID
}
关系记录
{
id: string, // UUID
memoryId: string, // Source memory
relatedMemoryId: string, // Target memory
relationshipType: string,// "related_to", "supersedes", etc.
version: number,
createdAt: string,
deleted: boolean
}
关系类型
| 类型 | 描述 |
|---|---|
related_to |
一般关系 |
supersedes |
更新的信息替换旧的信息 |
contradicts |
信息冲突 |
elaborates |
扩展现有内存 |
references |
提及另一段记忆 |
文件结构
data/
├── main/ # Main store
│ ├── wal.log # Write-ahead log
│ ├── segments/ # Immutable segment files
│ │ ├── 00000001.seg
│ │ └── ...
│ ├── indexes/ # Persisted indexes
│ │ ├── latest.idx
│ │ ├── vector.idx
│ │ ├── text.idx
│ │ └── merkle.idx
│ └── meta.json # Store metadata
├── forks/ # Fork stores
│ └── {fork-uuid}/ # Same structure as main
└── store.json # Global metadata
配置
默认配置(可以被覆盖):
{
dataDir: "./data", // Root data directory
segmentSizeBytes: 16777216, // 16MB WAL rotation threshold
persistEveryNWrites: 1, // Persist indexes after N writes
memoryBudgetBytes: 536870912,// 512MB memory budget
hnswM: 16, // HNSW graph connections
hnswEfConstruction: 200, // HNSW build quality
hnswEfSearch: 50 // HNSW search quality
}
演出
| 操作 | 目标 | 备注 |
|---|---|---|
| 添加内存 | <100ms | 包括嵌入生成(~40ms) |
| 获取内存 | <1ms | O(1)哈希映射查找 |
| 语义搜索 | <50ms | 用于10K个记忆 |
| 全文搜索 | <20ms | 10K内存 |
| 创建分叉 | <10ms | 写时复制,仅元数据 |
| 冷启动 | <5s | 适用于100K内存 |
| 热启动 | <500ms | 内存中的索引 |
例子
添加内存
curl -X POST http://localhost:3000/memories \
-H "Content-Type: application/json" \
-d '{
"category": "people",
"type": "person",
"content": "Alice is a software engineer who loves hiking",
"tags": ["friend", "engineer"],
"importance": 7
}'
搜索记忆
curl -X POST http://localhost:3000/memories/search \
-H "Content-Type: application/json" \
-d '{
"query": "software engineer hiking",
"mode": "hybrid",
"limit": 10
}'
创建叉子
curl -X POST http://localhost:3000/forks \
-H "Content-Type: application/json" \
-d '{
"source_store_id": "main",
"name": "experiment-branch"
}'
时间点恢复
curl -X POST http://localhost:3000/forks/pitr \
-H "Content-Type: application/json" \
-d '{
"source_store_id": "main",
"timestamp": 1706745600000,
"name": "restored-from-jan-31"
}'
在叉子上操作
# Add memory to a specific fork
curl -X POST "http://localhost:3000/memories?store_id=abc-123" \
-H "Content-Type: application/json" \
-d '{
"category": "experiment",
"type": "fact",
"content": "This only exists in the fork"
}'
MCP客户端配置
Stdio Transport(建议当地使用)
{
"mcpServers": {
"memory": {
"command": "node",
"args": ["/path/to/memory/src/index.js"],
"env": {
"DATA_DIR": "/path/to/data"
}
}
}
}
HTTP传输(用于远程/网络)
启动MCP HTTP服务器,然后配置您的客户端:
node src/index.js --mcp-http
{
"mcpServers": {
"memory": {
"url": "http://localhost:3001/mcp"
}
}
}
发展
项目结构
src/
├── index.js # MCP server entry point
├── http-index.js # HTTP server entry point
├── mcp-server.js # MCP protocol implementation
├── http-server.js # HTTP API implementation
├── store-adapter.js # Bridge to store API
├── embeddings.js # Local embedding generation
├── store/
│ ├── index.js # Store exports
│ ├── config.js # Configuration
│ ├── record.js # Record serialization
│ ├── wal.js # Write-ahead log
│ ├── segment.js # Immutable segments
│ ├── merkle.js # Merkle tree
│ ├── latest-index.js # O(1) version lookup
│ ├── vector-index.js # HNSW semantic search
│ ├── text-index.js # Inverted index + BM25
│ ├── memory-store.js # Main store API
│ └── store.test.js # Store tests
├── integration.test.js # Integration tests
└── memory.test.js # Legacy tests
在发展中奔跑
# Run HTTP server with auto-reload
node --watch src/index.js --http
# Run tests in watch mode
npx vitest --watch
许可证
麻省理工学院