AI记忆存储服务

MemoryFS是一个轻量级的AI记忆系统,通过Markdown文件存储和多种检索模式为AI代理提供持久化记忆读写功能。

  • by leing2021
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 leing2021/MemoryFS-MCP

使用说明

MemoryFS

English | 中文

MemoryFS 是一个基于「Markdown 文件即数据库」理念的轻量级 AI 记忆系统。作为独立的 MCP (Model Context Protocol) Server,通过 HTTP (JSON-RPC 2.0) 协议为 Claude Code、OpenClaw、Cursor、Windsurf 等 AI Agent 提供持久化记忆读写通道。

核心特性

  • 纯文本存储:记忆以含 YAML Frontmatter 的 Markdown 文件存储,天然兼容 Obsidian。
  • 多因子评分检索:grep 关键词搜索 + 命中率 × 时间衰减 × 类型权重 × 标签匹配 × 项目匹配,配合 MMR 去重召回。
  • 向量语义检索:可选的嵌入向量语义搜索,支持 Ollama / OpenAI / 硅基流动,混合模式效果最佳。
  • 严格鉴权:Bearer Token 验权,支持多客户端区分和角色权限控制。
  • 依赖图谱:自动追踪 blocks / ref 关联,检索时串联依赖注入上下文。
  • Web 管理面板:内建现代极简后台,支持 CRUD、索引重建、压缩归档与 JSON 导入导出。
  • 速率限制:内置防滥用保护,各端点可配置限流。

架构

┌────────────────────┐   HTTP (JSON-RPC)   ┌───────────────┐
│  AI Agent (Claude) │ ◄─────────────────► │   MCP Server  │
└────────────────────┘    鉴权: Bearer      └───────┬───────┘
                                                    │
                          ┌──────────────┬──────────┴──────────┐
                          ▼              ▼                      ▼
                   ┌─────────────┐ ┌──────────┐        ┌────────────┐
                   │ grep/Scorer │ │ YAML 解析 │        │ Web Admin  │
                   └─────────────┘ └──────────┘        └────────────┘
                          │
                          ▼ (可选)
                   ┌─────────────┐
                   │ Vector Store│ ← Ollama / OpenAI / 硅基流动
                   └─────────────┘
                          │
                          ▼
                    /workspace/ (持久化文件系统)

检索模式

MemoryFS 支持三种检索模式:

模式 说明 依赖
grep 纯关键词匹配(默认) 无
vector 语义相似度搜索 需要嵌入 API
hybrid grep + vector 融合(效果最佳) 需要嵌入 API

评分算法

最终分数 = 基础分数 × 重要性权重 × 时间衰减 × 类型权重 × 标签匹配 × 项目匹配

因子 公式 说明
基础分数 grep: 命中率 / vector: 余弦相似度 与查询的相关性
重要性权重 0.7 + 0.3 × importance 用户定义优先级 (0-1)
时间衰减 0.5^(天数/半衰期) 半衰期指数衰减(见下表)
类型权重 decision: 1.4 / reflection: 1.2 / fact: 1.0 / entity: 0.8 / task: 0.6 不同类型权重不同
标签匹配 匹配标签数 / 查询标签数 无标签时为 1.0
项目匹配 同项目 ×1.2,否则 ×1.0 项目亲和性加成

半衰期参数

类型 半衰期 说明
decision 365 天 决策,衰减很慢
fact 180 天 事实/知识,较稳定
reflection 120 天 反思,中速衰减
task 30 天 任务,衰减快
entity ∞ 永不衰减

状态惩罚

状态 惩罚系数 说明
active / todo / doing / blocked / valid 1.0 正常权重
done 0.3 已完成任务
superseded / deprecated / inactive 0.2 被替代决策、废弃知识、不活跃实体

MMR 去重

使用最大边际相关性算法去重,避免相似内容扎堆占据结果列表。

混合模式融合

当 EMBED_MODE=hybrid 时,grep 和 vector 分数融合计算:

  • grep 提供精确关键词匹配
  • vector 捕捉语义相似性
  • 最终分数 = 两者加权融合

部署(Docker,推荐)

前置要求:VM 上安装 Docker + Docker Compose。TypeScript 编译在容器内完成,无需在宿主机安装 Node.js。

1. 获取代码

git clone <repo-url> /opt/memoryfs
cd /opt/memoryfs

2. 配置环境变量

cp .env.example .env
nano .env

必改项:

变量 说明
MCP_TOKEN AI Agent 连接用的 Bearer Token,改为强随机字符串
MEMORYFS_DATA 宿主机数据目录,知识库持久化于此,默认 ./Memory_Data
ADMIN_PASS Web 管理面板密码,建议用 bcrypt 哈希(见下方说明)
HOST_PORT 对外暴露端口,默认 3333

3. 启动

docker compose up -d --build

# 确认运行状态
docker compose ps
curl http://localhost:${HOST_PORT}/health
# 预期:{"status":"ok","workspace":"/workspace"}

4. 常用运维命令

docker compose logs -f                           # 实时日志
docker compose restart                           # 重启服务
docker compose up -d --build                     # 更新重建
docker compose down                              # 停止(数据不丢失)

配置参考

所有配置均通过 .env 文件注入,详见 .env.example(含中文注释)。

鉴权

两种方式二选一,不能同时生效:

# 方式一:单 Token(只有一个 Agent 接入时使用)
MCP_TOKEN=your-secret-token

# 方式二:多客户端(多个 Agent 或需要区分角色时使用)
# 启用后 MCP_TOKEN 将被完全忽略,所有 Token 都写进来
# role 支持:admin(可读写)| viewer(只读)
# MCP_CLIENTS='{"your-token-here": {"name": "claude-code", "role": "admin"}, "token-guest": {"name": "guest", "role": "viewer"}}'

唯一免鉴权路由:GET /health

嵌入模式

EMBED_MODE=grep        # grep(默认,无需外部服务)
                       # vector(需要嵌入 API)
                       # hybrid(grep + vector 融合,效果最佳)
EMBED_URL=http://localhost:11434   # Ollama / OpenAI 兼容服务地址
EMBED_MODEL=nomic-embed-text       # 硅基流动用 BAAI/bge-m3
EMBED_DIMENSIONS=768               # 需与模型匹配
EMBED_API_KEY=                     # Ollama 留空;云端服务填 sk-xxx

兼容的嵌入服务:

服务 URL 示例 模型 维度
Ollama(本地) http://localhost:11434 nomic-embed-text 768
硅基流动 https://api.siliconflow.cn/v1 BAAI/bge-m3 1024
OpenAI https://api.openai.com/v1 text-embedding-3-small 1536

Web 管理面板

访问地址:http://<vm-ip>:<HOST_PORT>/admin

ADMIN_USER=admin
ADMIN_PASS=your-admin-password   # 生产环境务必使用 bcrypt 哈希
ADMIN_ENABLED=true               # false 则关闭 /admin 路由
COOKIE_SECURE=false              # 通过 HTTPS 反向代理时设为 true

生成 bcrypt 密码哈希(登录时仍输入原始密码,系统自动比对):

npm install && npm run hash-password
# 按提示输入密码,复制输出的 $2b$... 哈希值填入 ADMIN_PASS

注意:Docker Compose 中 .env 的 $ 需转义为 $$:

ADMIN_PASS=$$2b$$10$$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

会话配置

SESSION_TTL=86400000             # 24 小时(默认)
SESSION_CLEANUP_INTERVAL=300000  # 5 分钟(默认)

会话以 JSON 文件存储在 <MEMORYFS_DATA>/.sessions/,容器重启后登录状态不丢失。

日志

LOG_LEVEL=info       # 生产用 info,排查问题临时改 debug
LOG_PRETTY=false     # false = JSON(生产);true = 彩色输出(调试)

日志级别:fatal > error > warn > info > debug > trace


内置速率限制

端点 限制 时间窗口
POST /admin/login 5 次 15 分钟
API 写操作 30 次 1 分钟
API 读操作 100 次 1 分钟
JSON-RPC 60 次 1 分钟

接入 AI Agent

接入方式概览

接入方式 适用客户端 前提
HTTP 直连 OpenClaw、Cursor、Windsurf、Claude Code 1.x+ 无额外依赖
Stdio 代理 Claude Code 旧版、其他 Stdio-only 客户端 本机 Node.js 18+

OpenClaw

OpenClaw 原生支持 HTTP MCP,无需额外依赖,直接写入配置即可。

方式 A:跨机器部署(MemoryFS 在远程服务器)

{
  "mcp": {
    "servers": {
      "memoryfs": {
        "url": "http://<vm-ip>:<HOST_PORT>",
        "transport": "http",
        "headers": { "Authorization": "Bearer <MCP_TOKEN>" }
      }
    }
  }
}

方式 B:同 Docker Compose 网络内(MemoryFS 容器名 memoryfs,内部端口 3000)

{
  "mcp": {
    "servers": {
      "memoryfs": {
        "url": "http://memoryfs:3000",
        "transport": "http",
        "headers": { "Authorization": "Bearer <MCP_TOKEN>" }
      }
    }
  }
}

配置文件位置:~/.openclaw/config.json 或项目根目录 openclaw.json,重启 OpenClaw 生效。


Claude Code

方式 A:HTTP 直连(推荐,Claude Code 1.x+)

全局配置:编辑 ~/.claude.json,添加到 mcpServers 对象中:

{
  "mcpServers": {
    "memoryfs": {
      "type": "http",
      "url": "http://<vm-ip>:<HOST_PORT>",
      "headers": { "Authorization": "Bearer <MCP_TOKEN>" }
    }
  }
}

项目级配置:在项目根目录创建 .mcp.json:

{
  "mcpServers": {
    "memoryfs": {
      "type": "http",
      "url": "http://<vm-ip>:<HOST_PORT>",
      "headers": { "Authorization": "Bearer <MCP_TOKEN>" }
    }
  }
}

⚠️ 常见错误:~/.claude/mcp.json 或 ~/.claude/mcp_settings.json 均为无效配置位置。全局配置请用 ~/.claude.json,项目配置请用 .mcp.json。

方式 B:Stdio 代理(旧版兼容,需本机 Node.js 18+)

先从仓库复制代理脚本:

cp /path/to/memoryfs-mcp/scripts/mcp-proxy.mjs ~/mcp-proxy.mjs

项目 .mcp.json 配置:

{
  "mcpServers": {
    "memoryfs": {
      "command": "node",
      "args": ["/Users/<用户名>/mcp-proxy.mjs"],
      "env": {
        "MEMORYFS_URL": "http://<vm-ip>:<HOST_PORT>",
        "MEMORYFS_TOKEN": "<MCP_TOKEN>"
      }
    }
  }
}

Cursor / Windsurf / 其他兼容 MCP 客户端

参考 Claude Code HTTP 直连格式,核心参数不变:

  • 协议:http(JSON-RPC 2.0)
  • 鉴权头:Authorization: Bearer <MCP_TOKEN>
  • 端点:http://<vm-ip>:<HOST_PORT>

一键自动配置(让 AI Agent 帮你接入)

把下方 Prompt 直接发给你的 AI Agent,它会自动完成 MCP 配置写入、连接验证和行为规范注入,无需手动编辑任何文件。

发送前将 <SERVER_URL> 和 <YOUR_TOKEN> 替换为实际值。

[MemoryFS 一键接入任务]
请按以下步骤帮我接入 MemoryFS 持久化记忆系统,每步完成后报告结果。

服务地址:<SERVER_URL>
我的 Token:<YOUR_TOKEN>

步骤 1 — 写入 MCP 配置
在当前项目的 .mcp.json(若不存在则新建)中写入以下内容:
{
  "mcpServers": {
    "memoryfs": {
      "type": "http",
      "url": "<SERVER_URL>",
      "headers": { "Authorization": "Bearer <YOUR_TOKEN>" }
    }
  }
}

步骤 2 — 验证连接
调用 memory_stats 工具,确认返回知识库统计信息(正常返回即连接成功)。

步骤 3 — 注入行为规范
在当前项目的 AGENTS.md(若不存在则新建)末尾追加以下内容(原样追加,保留格式):

---
# 记忆库使用规范 (MemoryFS)

你已连接 MemoryFS 持久化外部记忆系统,存储了跨项目的架构决策、经验复盘与技术知识。

1. 先回忆,后行动:遇到问题或新任务前先用 memory_recall 搜索关键词,遭遇报错绝不盲目重试,立刻 recall 错误特征。
2. 按场景分类入库(认知循环:fact→decision→task→reflection→fact):
   - 稳定技术知识/规范 → fact(importance ≥ 0.7)
   - 架构/行为决策 → decision(importance ≥ 0.85)
   - 踩坑/调试经验/完成任务复盘 → reflection(importance ≥ 0.8)
   - 新项目/服务/人员 → entity
3. 记忆卫生:条目原子化(<500字),title 携带具体特征词,禁止堆栈倾倒。
4. 项目隔离:当前项目存对应 proj,跨项目知识存 global,切换项目调用 project_switch。
5. 决策演进:更新决策时创建新条目并通过 supersedes 指向旧条目,系统自动建立双向链接。
---

完成后,用中文汇报每步操作结果。

Agent 行为规范(推荐注入系统提示词)

将以下内容注入 AI Agent 的系统提示词(AGENTS.md / CLAUDE.md / system prompt 均可):

# 记忆库使用规范 (MemoryFS)
你已连接到一个被称为 MemoryFS 的持久化外部记忆系统,存储了跨项目的架构决策、行事偏好、历史踩坑与通用规范。必须遵守以下行为逻辑:

1. 先回忆,后重试 (Recall before Retry)
   - 回答问题、生成代码或设计架构前,先用 memory_recall 搜索关键词查阅已有规范。
   - 遭遇工具失败、代码报错或异常行为时,绝对不准盲目重试!立刻对错误特征和核心对象执行
     memory_recall,找寻历史踩坑记录和解决方案。

2. 分类入库(认知循环: fact → decision → task → reflection → fact)
   按以下场景选择类型:
   - 稳定技术知识、设计规范、公司规范 → fact(importance ≥ 0.7)
   - 架构选型、当触发 X → 必须执行 Y → decision(importance ≥ 0.85)
   - 未完成工作、依赖任务 → task
   - 踩坑记录、调试经验、任务完成后复盘 → reflection(importance ≥ 0.8)
   - 项目/服务/人员/外部系统 → entity

   【重要】踩坑记录存 reflection,不存 fact。

3. 记忆卫生 (Hygiene)
   - 条目必须短小、原子化(< 500 字)。
   - title 应携带高度具体的报错特征、函数名或专有名词,保证关键词搜索高命中率。
   - 禁止倾倒原始堆栈、重复结论或对话流水账。

4. 项目隔离与感知 (Scope)
   - 当前项目记忆存入对应 proj,跨项目通用知识存 global。
   - 对话转移到新项目域时,调用 project_switch 切换工作区并获取阻塞任务列表。
   - 不定期调用 memory_stats 审查系统健康度。

5. 决策演进 (Decision Evolution)
   - 更新决策时不修改旧条目,而是创建新条目并通过 supersedes 字段指向被替代的旧条目。
   - 系统会自动将旧条目标记为 superseded 状态,并建立双向链接。
   - 使用 memory_expand 可展开记忆图谱,沿 refs/blocks/supersedes 关系递归追踪依赖链。

MCP Tool API

工具 说明
memory_store 存入新事实、决策、任务,自动管理元数据
memory_recall 基于关键词的多阶段评分检索
memory_expand 展开记忆图谱,沿 refs/blocks/supersedes 关系递归追踪
memory_forget 物理删除废弃记忆(soft/hard 模式)
memory_compress 归档低权重/已完成条目,瘦身知识库
memory_stats 知识库统计:容量、阻塞任务、清理建议
project_switch 切换 AI 工作焦点项目
index_rebuild 强制重建全局 _index.md 缓存和向量索引

工具参数

memory_store:

{
  type: 'decision' | 'task' | 'fact' | 'entity' | 'reflection',
  title: string,           // 应包含具体关键词便于搜索
  content: string,         // Markdown 正文,建议 < 500 字
  proj?: string,           // 项目名,默认 'global'
  importance?: number,     // 0-1,默认 0.6;踩坑/决策用 0.8+
  confidence?: number,     // 0-1,默认 0.9;置信度
  status?: string,         // 状态(按类型,默认自动填充)
  tags?: string[],         // 可选标签
  blocks?: string[],       // 阻塞的条目 ID
  refs?: string[],         // 关联的条目 ID 数组
  supersedes?: string,     // 被替代的旧条目 ID(用于决策更新)
}

memory_recall:

{
  query: string,           // 关键词或语义描述
  limit?: number,          // 最大返回数,默认 10
  proj?: string,           // 按项目过滤
  type?: string,           // 按类型过滤
  force?: boolean          // 强制刷新索引
}

memory_expand:

{
  id: string,              // 起始条目 ID
  depth?: number,          // 展开深度,默认 2,最大 5
}

Web Admin API

方法 端点 说明
GET /admin/api/entries 列出条目(可按 type/proj/q 过滤)
GET /admin/api/entries/:id 获取单条
POST /admin/api/entries 创建条目
PUT /admin/api/entries/:id 更新条目
DELETE /admin/api/entries/:id 删除条目
POST /admin/api/rebuild 重建索引
POST /admin/api/compress 压缩归档
GET /admin/api/stats 获取统计
GET /admin/api/export 导出所有条目(JSON)
POST /admin/api/import 导入条目(JSON)

工作区文件结构

MEMORYFS_DATA 宿主机目录在容器内挂载为 /workspace:

Memory_Data/                # 宿主机目录(MEMORYFS_DATA)
├── memory.md               # 高重要性记忆摘要(热数据)
├── projects.md             # 项目注册表
├── user.md                 # 用户身份与偏好
├── journal/                # 每日操作日志
├── kb/
│   ├── _index.md           # 全局知识索引(缓存,自动维护)
│   ├── decisions/          # 架构与技术决策
│   ├── tasks/              # 任务与里程碑
│   ├── facts/              # 稳定技术知识与规范
│   ├── entities/           # 重要实体配置
│   └── reflections/        # 经验复盘与踩坑记录
├── .sessions/              # Web Admin 会话文件(自动管理)
└── .mcp/
    └── vector.db/          # LanceDB 向量索引(EMBED_MODE=vector/hybrid 时)

开发与测试

# 本地开发(需 Node.js 18+)
npm install
npm run dev            # tsx watch 热重载

# 构建
npm run build

# 测试(289 tests / 9 模块)
npm test
npm run test:coverage  # 生成覆盖率报告(coverage/index.html)

# 生成密码哈希
npm run hash-password

技术栈

  • 运行时:Node.js 20 + TypeScript
  • 框架:Hono(轻量级 HTTP 框架)
  • 日志:Pino(结构化 JSON 日志)
  • 鉴权:bcrypt 密码哈希
  • 向量库:LanceDB(嵌入式,无需外部服务)
  • 测试:Vitest
  • 部署:Docker 多阶段构建