多内存MCP服务器
使用SQLite进行持久存储的多类别知识图存储服务器。为了不同的目的(工作、个人、项目等)将记忆组织到孤立的环境中。
基于 @modelcontextprotocol/server-memory 通过增强功能:
- 具有适当索引和事务的SQLite数据库存储
- 具有隔离内存上下文的多类别支持
- LRU连接缓存(防止内存泄漏)
- 基于ID的操作 -所有对象都有唯一的ID,用于精确操作
- 双重身份识别 -使用ID或名称/类型复合键
- 自定义属性 -实体、观察和关系的JSON属性(可搜索)
- 超控模式 -更新现有记录,而不是跳过重复记录
- SQL注入保护
- 全测试覆盖率(141次测试)
快速开始
直接使用npx运行(无需安装)
使用多内存mcp的最快方法是直接从GitHub运行它,使用 npx:
npx github:DanNsk/multi-memory-mcp这将自动下载、构建和运行服务器。非常适合试用或在Claude Desktop配置中使用:
{
"mcpServers": {
"multi-memory": {
"command": "npx",
"args": ["github:DanNsk/multi-memory-mcp"],
"env": {
"MEMORY_BASE_DIR": "/path/to/.memory",
"DEFAULT_CATEGORY": "default"
}
}
}
}安装(本地开发)
git clone https://github.com/DanNsk/multi-memory-mcp
cd multi-memory-mcp
npm install
npm run build配置
添加到Claude桌面配置:
配置文件位置:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - 窗户:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
使用npx(推荐):
{
"mcpServers": {
"multi-memory": {
"command": "npx",
"args": ["github:DanNsk/multi-memory-mcp"],
"env": {
"MEMORY_BASE_DIR": "/Users/yourname/.memory",
"DEFAULT_CATEGORY": "default"
}
}
}
}使用本地安装(macOS/Linux):
{
"mcpServers": {
"multi-memory": {
"command": "node",
"args": ["/absolute/path/to/multi-memory-mcp/dist/index.js"],
"env": {
"MEMORY_BASE_DIR": "/Users/yourname/.memory",
"DEFAULT_CATEGORY": "default"
}
}
}
}使用本地安装(Windows):
{
"mcpServers": {
"multi-memory": {
"command": "node",
"args": ["C:\\path\\to\\multi-memory-mcp\\dist\\index.js"],
"env": {
"MEMORY_BASE_DIR": "C:\\Users\\yourname\\.memory",
"DEFAULT_CATEGORY": "default"
}
}
}
}环境变量
MEMORY_BASE_DIR:所有内存类别的基本目录(默认:.aim在当前工作目录中)DEFAULT_CATEGORY:未指定时的默认类别(默认:"default")SERIALIZATION_FORMAT:工具响应的输出格式(默认值:"json")
- json -带2空格缩进的标准JSON - toon -TOON(面向令牌的对象表示法)-针对LLM优化的紧凑格式,令牌减少30-60%
TOON格式
当 SERIALIZATION_FORMAT=toon,响应使用TOON格式,这对于LLM上下文来说更具令牌效率。
结构:
- 物体:
key: value带有2空间缩进用于嵌套 - 数组:
name[count]{field1,field2}:后面是逗号分隔的行 - 基元:除非包含特殊字符,否则不带引号
逃避规则 (只有这些转义序列有效):
\\-反斜杠\"-双引号\n-换行符\r-回车\t-选项卡
在以下情况下需要报价: 空字符串、前导/尾随空格、匹配项 true/false/null、数字或包含 : " \ [ ] { } ,
JSON与TOON的示例:
JSON(标准):
{
"entities": [
{"id": "1", "name": "AuthService", "entityType": "module", "observations": []}
]
}TOON(紧凑型):
entities[1]{id,name,entityType,observations}:
1,AuthService,module,[]看 TOON规格 有关完整格式的详细信息。
数据库模式
每个类别都使用以下模式将数据存储在单独的SQLite数据库中:
表格
entities
图节点的主存储。
| 列 | 类型 | 描述 |
|---|---|---|
id | INTEGER主键自动递增 | 唯一实体标识符 |
name | TEXT NOT NULL | 实体名称 |
entity_type | TEXT NOT NULL | 实体分类类型 |
properties | TEXT | JSON属性(可搜索) |
created_at | INTEGER | Unix创建时间戳 |
updated_at | INTEGER | 上次更新的Unix时间戳 |
唯一约束: (name, entity_type) -实体由名称+类型组合标识
observations
与实体有关的事实和说明。
| 列 | 类型 | 描述 |
|---|---|---|
id | INTEGER主键自动增量 | 唯一观察标识符 |
entity_id | 整数不能为空 | 外键 到 entities(id) |
observation_type | TEXT NOT NULL默认值“” | 观察值的类型/类别 |
content | 文本非空 | 观察文本 |
timestamp | 文本 | ISO 8601时间戳 |
source | TEXT NOT NULL默认值“” | 观察来源 |
properties | TEXT | JSON属性(可搜索) |
created_at | INTEGER | Unix创建时间戳 |
外键: entity_id → entities(id) 删除时级联
唯一约束: (entity_id, observation_type, source) -每种类型一个观察+每个实体一个来源
relations
实体之间的定向连接。
| 列 | 类型 | 描述 |
|---|---|---|
id | INTEGER主键自动递增 | 唯一关系标识符 |
from_entity_id | 整数不能为空 | 外键 到 entities(id) -源实体 |
to_entity_id | 整数不能为空 | 外键 到 entities(id) -目标实体 |
relation_type | TEXT NOT NULL | 关系类型 |
properties | TEXT | JSON属性 |
created_at | INTEGER | Unix创建时间戳 |
外键:
from_entity_id→entities(id)删除时级联to_entity_id→entities(id)删除时级联
唯一约束: (from_entity_id, to_entity_id, relation_type)
索引
idx_entities_name-按实体名称快速查找idx_entities_type-按实体类型快速查找idx_entities_name_type-按名称+类型组合快速查找idx_observations_entity-按实体快速查找观察结果idx_relations_from-按源实体快速查找idx_relations_to-按目标实体快速查找idx_relations_type-按关系类型快速查找
实体关系图
┌─────────────────┐
│ entities │
├─────────────────┤
│ id (PK) │◄─────────────┬──────────────┐
│ name │ │ │
│ entity_type │ │ │
│ created_at │ │ │
│ updated_at │ │ │
└─────────────────┘ │ │
│ │
┌─────────────────┐ │ │
│ observations │ │ │
├─────────────────┤ │ │
│ id (PK) │ │ │
│ entity_id (FK) │──────────────┘ │
│ content │ (ON DELETE CASCADE) │
│ timestamp │ │
│ source │ │
│ created_at │ │
└─────────────────┘ │
│
┌─────────────────┐ │
│ relations │ │
├─────────────────┤ │
│ id (PK) │ │
│ from_entity_id │─────────────────────────────┤
│ to_entity_id │─────────────────────────────┘
│ relation_type │ (Both FK: ON DELETE CASCADE)
│ created_at │
└─────────────────┘笔记:
- 所有ID都是自动生成的整数
- 删除实体会级联删除其所有观察值和关系
- 关系存储实体ID,但API接受解析为ID的名称/类型
核心概念
分类
将内存组织到单独的隔离数据库中。每个类别都有自己的SQLite数据库文件。
类别命名规则:
- 仅限小写字母、数字、连字符和下划线
- 不能以点开头
- 示例:
work,personal,project-alpha,dependencies
目录结构:
.memory/
├── work.db
├── personal.db
└── project-alpha.db实体
知识图中的节点具有:
- ID -唯一数字标识符(自动生成)
- 名字 -人类可读标识符
- 实体类型 -分类(例如,“模块”、“类别”、“人员”、“项目”)
- 观察 -带有元数据的事实列表
{
"id": "1",
"name": "AuthService",
"entityType": "module",
"observations": [
{
"id": "1",
"observationType": "description",
"text": "Handles authentication",
"timestamp": "2025-11-19T10:30:00Z",
"source": "code-analysis"
},
{
"id": "2",
"observationType": "location",
"text": "Located in src/auth/",
"timestamp": "2025-11-19T10:31:00Z",
"source": "code-analysis"
}
]
}关系
具有自己ID的实体之间的定向连接:
{
"id": "1",
"from": "APIController",
"fromType": "controller",
"to": "AuthService",
"toType": "module",
"relationType": "depends_on"
}双重身份识别
所有操作都支持通过以下方式识别对象:
- ID -快速、精确、明确
- 名称/类型 -人性化复合钥匙
当您有ID(例如,来自以前的响应)或需要按名称引用时,这允许灵活性。
API工具
所有工具均接受可选 category 参数(默认为 DEFAULT_CATEGORY).
______________________________________________________________________
create_entities
在知识图中创建新实体。
输入:
{
"category": "work",
"override": false,
"entities": [
{
"name": "UserService",
"entityType": "service",
"properties": {
"filePath": "/src/services/user.ts",
"tags": ["core", "authentication"]
},
"observations": [
{
"observationType": "description",
"text": "Manages user data",
"timestamp": "2025-11-19T10:00:00Z",
"source": "code-analysis",
"properties": {
"confidence": 0.95,
"lineNumber": 42
}
}
]
}
]
}*笔记:*
entityType默认为空字符串- 观察结果按(实体、观察类型、来源)是唯一的
properties是自定义元数据的可选JSON(可搜索)override: true替换现有实体而不是跳过它们
输出:
[
{
"id": "1",
"name": "UserService",
"entityType": "service",
"properties": {
"filePath": "/src/services/user.ts",
"tags": ["core", "authentication"]
},
"observations": [
{
"id": "1",
"observationType": "description",
"text": "Manages user data",
"timestamp": "2025-11-19T10:00:00Z",
"source": "code-analysis",
"properties": {
"confidence": 0.95,
"lineNumber": 42
}
}
]
}
]______________________________________________________________________
创建关系
创建实体之间的关系。每个端点都可以通过ID或名称/类型指定。
输入(使用名称/类型):
{
"category": "work",
"override": false,
"relations": [
{
"from": {
"name": "APIController",
"type": "controller"
},
"to": {
"name": "UserService",
"type": "service"
},
"relationType": "uses",
"properties": {
"weight": 0.8,
"since": "2024-01-01"
}
}
]
}*笔记:*
type如果未提供,则默认为空字符串properties是自定义元数据的可选JSONoverride: true更新现有关系,而不是跳过它们
输入(使用ID):
{
"category": "work",
"relations": [
{
"from": { "id": "1" },
"to": { "id": "2" },
"relationType": "uses"
}
]
}*注意:您可以混合ID和名称/类型-例如。, from 通过ID和 to 按名称/类型。*
输出:
[
{
"id": "1",
"from": "APIController",
"fromType": "controller",
"to": "UserService",
"toType": "service",
"relationType": "uses",
"properties": {
"weight": 0.8,
"since": "2024-01-01"
}
}
]______________________________________________________________________
添加观察结果
将观察结果添加到现有实体中。实体可以通过ID或名称/类型进行标识。
输入(使用名称/类型):
{
"category": "work",
"override": false,
"observations": [
{
"entityName": "UserService",
"entityType": "service",
"contents": [
{
"observationType": "version",
"text": "Updated to v2.0",
"timestamp": "2025-11-19T14:30:00Z",
"source": "changelog",
"properties": {
"semver": "2.0.0",
"breaking": true
}
},
{
"observationType": "feature",
"text": "Added caching",
"source": "changelog"
}
]
}
]
}*注: override: true 更新现有观测值(由observationType+源匹配),而不是跳过它们。*
输入(使用实体ID):
{
"category": "work",
"observations": [
{
"entityId": "1",
"contents": [
{
"observationType": "version",
"text": "Updated to v2.0",
"timestamp": "2025-11-19T14:30:00Z",
"source": "release-notes"
}
]
}
]
}输出:
[
{
"entityId": "1",
"entityName": "UserService",
"entityType": "service",
"addedObservations": [
{
"id": "3",
"observationType": "version",
"text": "Updated to v2.0",
"timestamp": "2025-11-19T14:30:00Z",
"source": "changelog",
"properties": {
"semver": "2.0.0",
"breaking": true
}
},
{
"id": "4",
"observationType": "feature",
"text": "Added caching",
"timestamp": "2025-11-19T14:30:01Z",
"source": "changelog"
}
]
}
]______________________________________________________________________
删除内容
删除实体及其关系。通过ID或姓名/类型进行识别。
输入(使用名称/类型):
{
"category": "work",
"entities": [
{
"name": "UserService",
"entityType": "service"
}
]
}输入(使用ID):
{
"category": "work",
"entities": [
{ "id": "1" }
]
}输出:
"Entities deleted successfully"______________________________________________________________________
删除观察
删除具体意见。通过观察ID或实体+观察类型+来源进行识别。
输入(使用观察ID):
{
"category": "work",
"deletions": [
{ "id": "3" }
]
}输入(使用实体名称+观测类型+源):
{
"category": "work",
"deletions": [
{
"entityName": "UserService",
"entityType": "service",
"observationType": "version",
"source": "changelog"
}
]
}输入(使用实体ID+观测类型+源):
{
"category": "work",
"deletions": [
{
"entityId": "1",
"observationType": "version",
"source": "changelog"
}
]
}输出:
"Observations deleted successfully"______________________________________________________________________
删除关系
删除关系。通过关系ID或复合键进行标识。
输入(使用关系ID):
{
"category": "work",
"relations": [
{ "id": "1" }
]
}输入(使用复合键):
{
"category": "work",
"relations": [
{
"from": "APIController",
"fromType": "controller",
"to": "UserService",
"toType": "service",
"relationType": "uses"
}
]
}输出:
"Relations deleted successfully"______________________________________________________________________
read_graph
获取某一类别的完整知识图谱。
输入:
{
"category": "work"
}输出:
{
"entities": [
{
"id": "1",
"name": "UserService",
"entityType": "service",
"observations": [
{
"id": "1",
"text": "Manages user data",
"timestamp": "2025-11-19T10:00:00Z"
}
]
}
],
"relations": [
{
"id": "1",
"from": "APIController",
"fromType": "controller",
"to": "UserService",
"toType": "service",
"relationType": "uses"
}
]
}______________________________________________________________________
搜索节点
按名称、类型、观察内容或属性搜索(均可通过FTS5搜索)。
输入:
{
"category": "work",
"query": "authentication"
}输出:
{
"entities": [
{
"id": "2",
"name": "AuthService",
"entityType": "service",
"observations": [
{
"id": "5",
"text": "Handles authentication",
"timestamp": "2025-11-19T10:30:00Z"
}
]
}
],
"relations": [
{
"id": "3",
"from": "APIController",
"fromType": "controller",
"to": "AuthService",
"toType": "service",
"relationType": "uses"
}
]
}______________________________________________________________________
open_nodes
获取特定实体。通过ID或姓名/类型进行识别。
输入(使用名称/类型):
{
"category": "work",
"entities": [
{
"name": "UserService",
"entityType": "service"
},
{
"name": "AuthService",
"entityType": "service"
}
]
}输入(使用ID):
{
"category": "work",
"entities": [
{ "id": "1" },
{ "id": "2" }
]
}输出:
{
"entities": [
{
"id": "1",
"name": "UserService",
"entityType": "service",
"observations": [...]
},
{
"id": "2",
"name": "AuthService",
"entityType": "service",
"observations": [...]
}
],
"relations": [
{
"id": "2",
"from": "UserService",
"fromType": "service",
"to": "AuthService",
"toType": "service",
"relationType": "depends_on"
}
]
}______________________________________________________________________
列表_类别
获取所有可用的类别名称。
输入:
{}输出:
["work", "personal", "project-alpha"]______________________________________________________________________
删除类别
删除整个类别及其数据库。
输入:
{
"category": "old-project"
}输出:
"Category 'old-project' deleted successfully"______________________________________________________________________
用例
代码依赖性跟踪
跟踪每个项目的模块依赖关系:
{
"category": "backend-service",
"entities": [
{
"name": "AuthModule",
"entityType": "module",
"observations": [
{
"text": "Exports login, logout",
"source": "code-analysis"
}
]
},
{
"name": "UserModule",
"entityType": "module",
"observations": [
{
"text": "User CRUD operations",
"source": "documentation"
}
]
},
{
"name": "Database",
"entityType": "library",
"observations": [
{
"text": "PostgreSQL client"
}
]
}
]
}然后创建关系:
{
"category": "backend-service",
"relations": [
{
"from": { "name": "AuthModule", "type": "module" },
"to": { "name": "UserModule", "type": "module" },
"relationType": "imports"
},
{
"from": { "name": "AuthModule", "type": "module" },
"to": { "name": "Database", "type": "library" },
"relationType": "uses"
}
]
}查询依赖关系:
{"category": "backend-service", "query": "AuthModule"}多项目组织
每个项目单独分类:
project-frontend-前端依赖关系project-backend-后端依赖关系project-mobile-移动应用依赖关系
工作/个人分离
保持上下文隔离:
work-专业联系人和项目personal-个人笔记和关系learning-学习笔记和资源
发展
构建
npm run build # Compile TypeScript
npm run watch # Watch mode测试
npm test # Run all tests (141 tests)覆盖率:SQLiteStorage 98%,CategoryManager 87%,KnowledgeGraphManager 100%
项目结构
src/
├── index.ts # MCP server
├── storage/
│ └── SQLiteStorage.ts # Database operations
├── managers/
│ ├── CategoryManager.ts # Category lifecycle & LRU cache
│ └── KnowledgeGraphManager.ts # Graph operations
└── types/
└── graph.ts # Type definitions
tests/
├── storage/ # Storage layer tests
├── managers/ # Manager tests
├── integration/ # End-to-end tests
└── benchmarks/ # Performance benchmarks技术细节
存储
- 数据库:带WAL模式的SQLite 3
- 模式:单一版本,全新
- 索引:关于实体名称、类型、关系
- 交易:符合ACID标准的操作
- 连接限制:最多50个并发(LRU驱逐)
安全
- 参数化查询(SQL注入保护)
- 类别名称验证(防止路径遍历)
- 外键约束
- 级联删除
演出
- 索引查询以实现快速查找
- 并发读取的WAL模式
- LRU驱逐的连接缓存
- 通过交易进行批量操作
故障排除
数据库锁定错误
SQLite使用允许并发读取的WAL模式。如果您遇到锁定错误:
- 确保没有其他进程正在写入数据库
- 检查数据库目录上的文件权限
记忆随着时间的推移而增长
CategoryManager实现了LRU缓存,默认连接限制为50。达到限制时,最旧的连接会自动关闭。
许可证
MIT许可证
原创作品版权所有(c)中国人民银行Anthropic 2025 修改作品版权所有(c)2025 DanNsk
基于 @modelcontextprotocol/server-memory
特此免费向任何获得副本的人授予许可 本软件和相关文档文件(“软件”),以处理 在软件中不受限制,包括但不限于权利 使用、复制、修改、合并、发布、分发、再许可和/或销售 软件的副本,并允许软件的接收者 根据以下条件提供:
上述版权声明和本许可声明应包含在所有 软件的副本或实质性部分。
软件按“原样”提供,不提供任何形式的明示或明示担保 隐含的,包括但不限于适销性保证, 适用于特定目的且不造成伤害。在任何情况下 作者或版权持有人对任何索赔、损害赔偿或其他 因以下原因产生的责任,无论是在合同、侵权或其他诉讼中, 出于或与软件、使用或其他交易有关 软件。
