持久存储记忆服务

Memory MCP是一个基于SQLite的持久化记忆存储服务,提供全文检索、关系图遍历和基于令牌预算的上下文检索功能,适用于MCP启用的助手。

  • by j0hanz
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 j0hanz/memory-mcp

使用说明

存储器MCP

支持SQLite的MCP服务器,用于持久内存存储、全文检索和关系图遍历。

概述

内存MCP为启用MCP的助手提供本地持久存储层。它通过FTS5支持的全文搜索、有向关系图、BFS召回遍历和令牌预算感知上下文检索在SQLite中存储SHA-256寻址的内存项,所有这些都可以通过stdio传输访问,没有外部依赖关系。

主要特点

  • 13个MCP工具 用于CRUD、批处理操作、FTS5搜索、BFS图召回、令牌预算上下文检索、关系和统计。
  • 全文搜索 通过带有重要性和类型过滤器的SQLite FTS5对内容和标签进行过滤。
  • 图形召回 具有BFS遍历、有界边界和每跳MCP进度通知。
  • 代币预算检索 (retrieve_context)选择符合调用者指定的令牌预算的内存,无需手动分页。
  • 严格的Zod输入验证 具有键入的输出信封和SHA-256哈希寻址。
  • 资源支持 随着 internal://instructions (Markdown指南)和 memory://memories/{hash} 带有哈希自动补全功能的URI模板。
  • stdio传输 具有干净的停机处理功能(SIGINT, SIGTERM)并且没有HTTP端点。 |

需求

  • Node.js >=24.
  • 支持FTS5的SQLite(在启动时验证)。
  • 任何支持stdio命令服务器的MCP客户端。

快速开始

直接使用npm包 npx --无需安装:

{
  "mcpServers": {
    "memory-mcp": {
      "command": "npx",
      "args": ["-y", "@j0hanz/memory-mcp@latest"]
    }
  }
}

[!提示] 服务器仅使用stdio传输;没有暴露HTTP端点。Stout不得被自定义日志污染。

或者使用Docker运行:

docker run --rm -i ghcr.io/j0hanz/memory-mcp:latest

客户端配置

Install in VS Code

工作区文件 .vscode/mcp.json:

{
  "servers": {
    "memory-mcp": {
      "command": "npx",
      "args": ["-y", "@j0hanz/memory-mcp@latest"]
    }
  }
}

CLI:

code --add-mcp '{"name":"memory-mcp","command":"npx","args":["-y","@j0hanz/memory-mcp@latest"]}'
Install in VS Code Insiders

CLI:

code-insiders --add-mcp '{"name":"memory-mcp","command":"npx","args":["-y","@j0hanz/memory-mcp@latest"]}'
Install in Cursor

~/.cursor/mcp.json:

{
  "mcpServers": {
    "memory-mcp": {
      "command": "npx",
      "args": ["-y", "@j0hanz/memory-mcp@latest"]
    }
  }
}
Install in Claude Desktop / Claude Code

claude_desktop_config.json:

{
  "mcpServers": {
    "memory-mcp": {
      "command": "npx",
      "args": ["-y", "@j0hanz/memory-mcp@latest"]
    }
  }
}

CLI:

claude mcp add memory-mcp -- npx -y @j0hanz/memory-mcp@latest
Install in Windsurf

MCP配置:

{
  "mcpServers": {
    "memory-mcp": {
      "command": "npx",
      "args": ["-y", "@j0hanz/memory-mcp@latest"]
    }
  }
}
Run with Docker
# Pull and run (stdio mode)
docker run --rm -i \
  -e MEMORY_DB_PATH=/data/memory.db \
  -v memory-data:/data \
  ghcr.io/j0hanz/memory-mcp:latest

MCP客户端配置:

{
  "mcpServers": {
    "memory-mcp": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "-e",
        "MEMORY_DB_PATH=/data/memory.db",
        "-v",
        "memory-data:/data",
        "ghcr.io/j0hanz/memory-mcp:latest"
      ]
    }
  }
}

文件维护

  • 所有者:维护人员更新MCP行为 src/ 必须更新 README.md 并受到影响 mcp/ 镜像同一PR中的页面。
  • 链接/版本策略:使用固定 https://modelcontextprotocol.io/specification/2025-11-25/... 协议参考链接;避免 latest 以及混合的遗留目标。
  • 漂移检查清单:
    • 重新验证中的能力声明 src/server.ts.
    • 将工具/资源/提示文档与 src/tools/index.ts, src/resources/index.ts,以及 src/prompts/index.ts.
    • 确认限制/陷阱 src/instructions.md 匹配运行时行为。
  • 验证命令: npm run type-check, npm run test:fast, npm run build.

MCP表面

工具摘要

工具 类别 注释
store_memory 按内容+排序标签哈希写入 标识
store_memories 写入 批处理(1-50),事务包装
get_memory 读取 哈希查找
update_memory 写入 返回 old_hash + new_hash
delete_memory 写入 级联关系删除
delete_memories 写入 批处理(1-50),事务包装
search_memories 读取 FTS5+重要性/类型过滤器+光标
create_relationship 写入 标识定向边创建
delete_relationship 写入 删除精确的定向边
get_relationships 读取 方向过滤器+链接内存字段
recall 读取 FTS5种子+BFS遍历(深度0-3)
retrieve_context 阅读 令牌预算感知上下文检索
memory_stats 阅读 存储聚合和类型细分

store_memory

存储包含内容、标签和可选类型/重要性的新内存。Idempotent——存储相同的内容+标签会返回现有的哈希值 created: false.

名称 类型 必填 默认 描述
content string 是 -- 内存内容(1-100000个字符)
tags string[] 是 -- 1-100个标签,每个标签最多50个字符,没有空格
memory_type enum 否 general general, fact, plan, decision, reflection, lesson, error, gradient
importance integer 没有 0 优先级0-10

退货: { hash, created }


store_memories

在一次交易中存储多个内存(最多50个项目)。

名称 类型 必填 描述
items Array<StoreMemoryItem> 是 1-50个项目,每个项目 content, tags,可选 memory_type,可选 importance

退货: { items, succeeded, failed }


get_memory

通过SHA-256哈希值检索一个内存。

名称 类型 必填 描述
hash string 是 64个字符小写SHA-256十六进制

退货: Memory 或 { ok: false, error } 上 E_NOT_FOUND.


update_memory

更新现有内存的内容和可选标签。返回两个哈希值。

名称 类型 必填 默认 描述
hash string 是 -- 现有内存哈希
content string 是 -- 替换内容
tags string[] 否 现有标签 替换标签

退货: { old_hash, new_hash }


delete_memory

按哈希删除一个内存。级联到相关关系行。

名称 类型 必填 描述
hash string 是 内存哈希

退货: { hash, deleted }


delete_memories

在一个事务中通过哈希删除多个内存。

名称 类型 必填 描述
hashes string[] 是 1-50个内存哈希值

退货: { items, succeeded, failed }


search_memories

使用FTS5对内存内容和标签进行全文搜索。支持带有光标分页的重要性和类型过滤器。

名称 类型 必填 默认 描述
query string 是 -- 搜索文本(1-1000个字符)
limit integer 没有 20 每页结果(1–100)
cursor string 没有 -- 来自上一个响应的分页光标
min_importance integer 否 -- 仅返回重要性>=此值(0-10)的记忆
max_importance integer 否 -- 仅返回重要性<=此值(0-10)的内存
memory_type enum 否 -- 按内存类型筛选

退货: { memories, total_returned, nextCursor? }


create_relationship

在两个记忆之间建立有向关系边。我暂时没有。

建议 relation_type 值: related_to, causes, depends_on, parent_of, child_of, supersedes, contradicts, supports, references.

名称 类型 必填 描述
from_hash string 是 源内存哈希
to_hash string 是 目标内存哈希
relation_type string 是 边缘标签(1-50个字符,无空格,自由格式)

退货: { created }


delete_relationship

删除一条有向关系边。

名称 类型 必填 描述
from_hash string 是 源哈希
to_hash string 是 目标哈希
relation_type string 是 关系类型

退货: { deleted } 或 { ok: false, error } 上 E_NOT_FOUND.


get_relationships

使用可选的方向过滤器检索内存的关系。

名称 类型 必填 默认 描述
hash string 是 -- 内存哈希
direction enum 否 both outgoing, incoming,或 both

退货: { relationships, count }

每种关系包括 from_hash, to_hash, relation_type, created_at, linked_hash, linked_content,以及 linked_tags.


recall

通过全文查询搜索内存,然后遍历关系图,直到 depth 通过BFS跳转。每跳发送MCP进度通知。

名称 类型 必填 默认 描述
query string 是 -- 种子搜索查询(1-1000个字符)
depth integer 没有 1 BFS跳数(0–3)
limit integer 没有 10 种子内存计数(1-50)
cursor string 没有 -- 来自上一个响应的分页光标
min_importance integer 否 -- 种子过滤器:只有重要性>=值(0-10)的记忆
max_importance integer 否 -- 种子过滤器:只有重要性<=值(0-10)的记忆
memory_type enum 否 -- 种子过滤器:仅此类型的内存

退货: { memories, graph, depth_reached, aborted?, nextCursor? }

中的每个项目 graph 使用形状:

{ "from_hash": "...", "to_hash": "...", "relation_type": "..." }

[!注意] aborted: true 表示遍历达到了安全限制(RECALL_MAX_FRONTIER_SIZE, RECALL_MAX_EDGE_ROWS,或 RECALL_MAX_VISITED_NODES).部分结果仍然返回。


retrieve_context

搜索记忆并返回符合呼叫者指定的令牌预算的相关性排名结果。消除了用于上下文窗口管理的手动分页和令牌计数。

名称 类型 必填 默认 描述
query string 是 -- 搜索查询(1-1000个字符)
token_budget integer 没有 4000 预计可返还的最大代币数量(100-200000)
strategy enum 否 relevance 排序顺序: relevance (FTS排名), importance (最高优先), recency (最新优先)

退货: { memories, estimated_tokens, truncated }

[!提示] 令牌估计是近似的(内容长度÷4)。 truncated: true 意味着在所有候选人都被纳入之前,预算已经达成。


memory_stats

返回聚合内存和关系统计数据。不接受任何输入。

退货:

{
  "memories": {
    "total": 0,
    "oldest": null,
    "newest": null,
    "avg_importance": null
  },
  "relationships": { "total": 0 },
  "by_type": {}
}

资源

URI MIME 描述
internal://instructions text/markdown 所有工具和工作流程的Markdown使用指南
memory://memories/{hash} application/json 以JSON格式返回一个内存;支持哈希完成

提示

名称 参数 目的
get-help none 返回所有工具的完整使用说明

配置

环境变量

变量 描述 默认值 必填
MEMORY_DB_PATH SQLite数据库文件路径 memory_db/memory.db 没有
RECALL_MAX_FRONTIER_SIZE 每跳最大BFS边界节点数(100-50000) 1000 没有
RECALL_MAX_EDGE_ROWS 每次遍历获取的最大关系行数(100-50000) 5000 没有
RECALL_MAX_VISITED_NODES 整个遍历过程中访问的最大节点数(100-50000) 5000 没有

[!重要] 如果 MEMORY_DB_PATH 是相对的(包括默认值 memory_db/memory.db),它从进程工作目录解析。

[!提示] 添加 memory_db/ 到你的 .gitignore 为了使数据库不受版本控制,它包含本地会话数据,不应被共享或提交。

限制和约束

项目 价值
内容长度 1–100000个字符
标签计数 1–100个/内存
标签长度 1-50个字符,无空格
哈希格式 64个字符小写十六进制SHA-256
搜索查询长度 1–1000个字符
search_memories.limit 1–100(默认值20)
recall.depth 0–3(默认值1)
recall.limit 1–50(默认值10)
retrieve_context.token_budget 100–200000(默认值4000)
批量 1-50个项目(store_memories, delete_memories)
召回边防警卫 RECALL_MAX_FRONTIER_SIZE (默认每跳1000)
SQLite繁忙超时 5000毫秒

[!注意] 游标值是不透明的base64url编码令牌。将它们视为不透明的,不要解析它们。

安全

  • 传输仅限stdio(StdioServerTransport)--没有HTTP端点。
  • 致命的流程错误将写入 stderr;对于MCP协议,stdout必须保持干净。
  • 在任何数据库访问之前,所有输入都会使用严格的Zod模式和有界字段约束进行验证。
  • 哈希根据小写64字符SHA-256十六进制正则表达式进行验证。
  • 在FTS之前,搜索输入被标记为字母数字术语 MATCH 执行(非字母数字字符充当分隔符,防止FTS注入)。
  • SQLite外键已启用;当内存被移除时,关系行会级联删除。

发展

安装依赖项:

npm install

核心脚本:

脚本 命令 目的
build npm run build 清理、编译、验证指令、复制资产、chmod可执行文件
dev npm run dev TypeScript监视模式
dev:run npm run dev:run 使用运行内置服务器 .env 和文件监视
start npm run start 启动内置服务器
test npm run test 通过任务运行器进行完整构建+测试
test:fast npm run test:fast 直接使用Node测试运行器运行TS测试
lint npm run lint ESLint检查
lint:fix npm run lint:fix ESLint自动修复
type-check npm run type-check 严格的TypeScript检查
format npm run format 预处理格式
inspector npm run inspector 针对stdio服务器构建并打开MCP检查器

与MCP检查员一起检查:

npx @modelcontextprotocol/inspector node dist/index.js

构建与发布

GitHub操作发布工作流(.github/workflows/release.yml)通过单一工具处理版本控制、验证和发布 workflow_dispatch 触发:

workflow_dispatch (patch / minor / major / custom)
    │
    ▼
  release — bump package.json + server.json → lint → type-check → test → build → tag → GitHub Release
    │
    ├──► publish-npm ──► publish-mcp   (npm Trusted Publishing OIDC → MCP Registry)
    │
    └──► publish-docker                (GHCR, linux/amd64 + linux/arm64)

触发释放:

gh workflow run release.yml -f bump=patch

或者使用GitHub UI: 行动→ 发布→ 运行工作流.

[!注意] npm发布使用OIDC可信发布——否 NPM_TOKEN 需要保密。MCP注册表使用GitHub OIDC。Docker使用内置 GITHUB_TOKEN.

故障排除

症状 原因 修复
启动失败,出现FTS5错误 在没有FTS5的情况下构建Node.js 使用支持SQLite FTS5的Node.js 24+
E_NOT_FOUND 上 get_memory 哈希不存在 通过验证 search_memories 首先
E_INVALID_CURSOR 过时或格式错误的光标 在没有光标的情况下重试请求 cursor 参数
MCP客户端无法连接 添加了自定义stdout日志 确保服务器进程中没有任何内容写入stdout
aborted: true 召回 Traversal达到安全极限 减少 depth,或调整 RECALL_MAX_* 环境变量
数据库锁定错误 高并发写负载 SQLite繁忙超时为5000毫秒;减少并发写入

许可证

麻省理工学院