关于 MemPersist
MemPersist 是用于持久存储和检索 AI 对话记忆的远程 MCP 服务,读取可固定到指定修订版本。它将规范归档与可重建索引分离,并支持导入 ChatGPT 导出文件及主动写入。
主要功能
- 01持久化规范对话归档
- 02导入 ChatGPT 导出文件
- 03混合记忆搜索
- 04固定修订版本读取与上下文
- 05原子化、带修订校验的写入
适用场景
- 01搜索过往对话中的相关信息
- 02导入并检索 ChatGPT 对话历史
- 03从选定对话构建上下文
- 04带修订校验地存储键控消息
MCP 相关
通过无状态 Streamable HTTP 向 MCP 客户端提供记忆搜索、上下文、对话与消息读取、导入及带修订校验的写入工具。支持 OAuth 2.1 和 PKCE。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mempersist.codifiedtech.id/mcpclaude mcp add --transport http ravhirizaldi-mempersist https://mempersist.codifiedtech.id/mcp{"mcpServers":{"ravhirizaldi-mempersist":{"type":"http","url":"https://mempersist.codifiedtech.id/mcp"}}}在 Cursor 中打开{"servers":{"ravhirizaldi-mempersist":{"type":"http","url":"https://mempersist.codifiedtech.id/mcp"}}}在 VS Code 中打开{"mcpServers":{"ravhirizaldi-mempersist":{"type":"http","url":"https://mempersist.codifiedtech.id/mcp"}}}{"mcpServers":{"ravhirizaldi-mempersist":{"serverUrl":"https://mempersist.codifiedtech.id/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
MemPersist
完全运行于 Cloudflare 上的 AI 对话长期记忆。原始 ChatGPT 导出文件和规范化后的对话图存储在 R2 中,D1 目录使其可供查询,词法和语义索引可随时重建,而 MCP 则提供精简的检索和有意执行的写入。
| MCP 端点 | https://mempersist.codifiedtech.id/mcp |
| 注册表 | io.github.ravhirizaldi/mempersist — 版本 1.0.1 |
| 运行时 | Workers、D1、R2、Queues、Workers AI (BGE-M3)、Vectorize、OAuth KV |
| 协议 | 基于无状态 Streamable HTTP 的 MCP v2,OAuth 2.1 与 PKCE S256 |
| 范围 | 单运营者 V1、一个 Worker、一个 TypeScript 包 |
功能。 逐字节保留每个上传的 ChatGPT 导出文件,将分支和节点元数据规范化为固定到特定修订版的规范 JSONL,索引派生的 FTS 和向量数据,并通过确定性 ID 响应搜索、上下文和批量读取。写入需显式执行并经过修订版校验,且会先持久化,再加入索引队列。
不做什么。 它不会拦截 ChatGPT 流量、提取替代“事实”、使用模型生成摘要,也不会将任何索引视为规范数据。不包含计费、组织或臆测性的多租户功能;不使用 Durable Objects、Workflows、cron 触发器或容器。删除所有分块、FTS 行和向量并不会删除记忆。“无限”表示没有应用级消息配额——但仍受 Cloudflare 的限制和计费约束。
架构
flowchart TD
IMP["ChatGPT data export (conversations.json)"] --> V
WRITE["MCP writes from any client"] --> V
V["Validation and stable IDs"] --> R2[("R2 canonical archive<br/>raw import + immutable revisions")]
R2 --> D1[("D1 catalog<br/>imports, revisions, graph, R2 pointers")]
D1 --> Q["Cloudflare Queues<br/>import and index jobs"]
Q --> FTS[("D1 FTS5<br/>lexical chunks")]
Q --> AI["Workers AI BGE-M3"] --> VEC[("Vectorize<br/>embeddings")]
FTS --> SEARCH["Normalized hybrid search<br/>plus recent-canonical fallback"]
VEC --> SEARCH
SEARCH --> OUT["HTTP API and OAuth-protected MCP"]
R2 --> EXPORT["Lossless export and recovery"]
两种导入路径彼此独立:ChatGPT 数据导出解析器只接受原生的 conversations.json 格式,而写入则通过 MCP 从调用方使用的任意客户端传入。两者最终都采用相同的规范修订版模型,因此,通过工具调用创建的记忆和从导出文件导入的记忆,在读取、固定版本和还原时完全一致。
R2 是事实来源。规范写入完成后才会将索引任务加入队列,索引失败也绝不会报告持久化的记忆已丢失。重建时会读取 R2,因此无需重复上传导出文件。详情请参阅 ARCHITECTURE.md 和 docs/storage-and-indexing.md。
快速入门
yarn install
cp .dev.vars.example .dev.vars # set a long random MEMORY_API_TOKEN
yarn types:bindings
yarn db:migrate:local
yarn dev
需要 WSL2/Linux、Node.js 22+、Yarn 1.22,以及通过 yarn wrangler whoami 完成身份验证的 Wrangler 4.x。请仅使用 Yarn。本地 D1、R2、KV 和 Queues 均为模拟服务;主配置中的 Workers AI 和 Vectorize 则指向真实的远程绑定,而单元测试和集成测试绝不会调用远程 AI。
连接任意 MCP 客户端
MemPersist 是一个标准的远程 MCP 服务:采用无状态的 Streamable HTTP,地址为
https://mempersist.codifiedtech.id/mcp,使用 OAuth 2.1 授权码和 PKCE S256,作用域为
memory。端点中的任何内容都不针对特定客户端——所有调用方使用相同的握手流程、工具契约和服务说明。将客户端指向该 URL 即可使用:
| 客户端 | 添加方式 |
|---|---|
| Claude Code | 运行 claude mcp add --transport http mempersist https://mempersist.codifiedtech.id/mcp,然后完成电子邮件提示 |
| Codex CLI、ChatGPT 桌面版、IDE 扩展 | 配置 ~/.codex/config.toml(或项目中的 .codex/config.toml),然后运行 codex mcp login mempersist |
| Cursor、Claude Desktop、VS Code、Zed | 在客户端的 MCP 设置中将该 URL 添加为远程(HTTP)MCP 服务;客户端会启动 OAuth 流程 |
| ChatGPT | 启用开发者模式,然后将该 URL 添加为自定义 MCP 应用 |
| MCP Inspector、自定义 SDK 客户端 | 运行 npx @modelcontextprotocol/inspector,或使用官方 SDK 客户端;使用该 URL,并选择 OAuth 或开发者令牌 |
| 仅支持 stdio 的客户端 | 保持服务为远程服务,并通过支持 OAuth 的代理将 stdio 桥接到 HTTP;MemPersist 本身无需使用 npx |
Codex 配置:
[mcp_servers.mempersist]
type = "remote"
url = "https://mempersist.codifiedtech.id/mcp"
# auth = "oauth" is the default; run `codex mcp login mempersist` to authorize
客户端会从 401 挑战中发现 OAuth,打开授权页面,并保存签发的访问令牌和刷新令牌。授权页面会收集电子邮件地址,并通过 EMAIL 绑定发送一封一次性、有效期为 15 分钟的魔法链接;只有打开该链接后,连接才会完成,已有电子邮件地址重新连接时会关联到其存档。唯一的作用域是 memory,发件人地址属于配置项(AUTH_EMAIL_FROM、LEGACY_AUTH_EMAIL_FROM),而非 API 契约的一部分。切勿将 MEMORY_API_TOKEN 粘贴到连接器中。
已配置的连接在升级后仍可继续使用,无需重新授权;旧主机名仍受支持,将某个客户端迁移到主主机名只需重新授权一次。
开发者令牌
脚本、CLI 和非交互式自动化可以发送
Authorization: Bearer <MEMORY_API_TOKEN> 代替 OAuth,该方式始终映射到所有者存档。每个账户都可以拥有多个命名空间;两个账户中名称相同的命名空间是彼此独立的数据,且只有在调用方拥有所提供的 namespace 时,该值才会生效。
本地运行,无需部署
MCP 受众属于部署配置,因此可将开发服务器指向自身:
yarn dev --local --port 8787 --local-protocol https \
--var MCP_ORIGIN_OVERRIDE:https://127.0.0.1:8787
发现、授权和令牌的受众随后会使用 https://127.0.0.1:8787,.dev.vars 中的开发者令牌和完整 OAuth 流程也都能正常工作。本地 send_email 会将每个魔法链接写入 .wrangler/tmp/email/<id>/email-text/。请参阅
docs/development.md。
工具
共有 24 个工具,每个工具都带有人类可读的标题,以及只读或破坏性注释。先检索,再仅展开所选内容。
读取
| 工具 | 标题 | 说明 |
|---|---|---|
memory_search | 搜索记忆 | 混合搜索,1–20 条引用;支持筛选和不透明游标分页 |
memory_get_context | 获取记忆上下文 | 获取某个结果片段周围的规范消息,前后各最多 10 条 |
memory_get_conversation | 获取对话 | 分页读取一个对话的活跃时间线或完整图谱 |
memory_get_messages | 获取消息 | 按精确源节点或可选键查找;固定修订版本,按序批量读取,并提供不透明游标和字节预算 |
memory_get_conversations | 获取对话 | 固定修订版本,批量读取 1–20 个对话,支持游标分页 |
memory_list_conversations | 列出对话 | 仅包含元数据和标签,不包含正文 |
memory_list_revisions | 列出修订版本 | 不可变的修订历史,按时间从新到旧排序 |
memory_resolve_conversations | 解析对话 | 精确标题查找,不进行语义搜索 |
memory_list_namespaces | 列出命名空间 | 自有命名空间及其对话数量 |
memory_stats | 获取记忆统计信息 | 每个命名空间的数量和索引健康状况 |
memory_import_status | 获取导入状态 | 导入进度、重复项或失败情况 |
memory_get_capabilities | 获取功能信息 | 已部署的契约:版本、限制、每个工具的边界,以及 message_keys / atomic_multi_conversation_commit 功能标志 |
memory_get_messages 接受 1–100 个有序选择器。每个选择器指定一个
conversation_id,可选地固定一个 revision_id,并且必须且只能使用
source_node_id(最多 200 个字符)或前向兼容的 message_key
(1–128 个小写 ASCII 字母、数字、.、_、/ 或 -,且以字母或数字开头和结尾)。省略修订版本时,会在加载任何规范 R2 正文之前固定每个对话的当前头部;
规范内容会按唯一固定修订版本去重加载,而重复选择器仍会保留重复的有序结果。
只读查找不会使用 FTS 或 Vectorize。缺失、无权访问、已删除或未知的对话、
修订版本、节点和键,都会返回相同的有界 NOT_FOUND 结果。重复的规范消息键会返回有界的规范存储错误,绝不会通过任选一个来解决。完整消息会在 32 KiB 默认、4 KiB 最小和 48 KiB 最大的序列化预算内纳入;超大消息不会截断,而只返回有界的标识和字节诊断信息。后续读取
使用不透明的 HMAC 签名、绑定租户的游标,以保留选择器顺序和修订版本固定信息。
可选的 message_key 选择器会读取由 memory_upsert_messages 写入的键控字段(以及包含这些字段的规范数据)。memory_upsert_messages 是用于逻辑记录的稳定键写入工具;其约定见下文的「写入」部分。
上下文组装
| 工具 | 标题 | 说明 |
|---|---|---|
memory_build_context | 构建记忆上下文 | 从 1–20 个必需对话中生成确定性、固定版本的内容包,可选混合证据,并指定令牌和字节预算 |
写入
每次写入都会返回一份有界的持久化回执,其中分别标明索引和验证状态,并接受 verify: true 以重新加载已提交的 R2 版本。memory_commit_batch 会在一个同账户原子提交中,对不同对话执行 1–20 个追加或完整替换操作;每个操作都必须提供明确的 base_revision_id。
memory_upsert_messages 接受一组用于一个自有对话的 1–100 条唯一键控文本消息。每个请求都必须包含 base_revision_id 和角色;键必须是 1–128 个字符的精确小写 ASCII 字符串,匹配 [a-z0-9._/-],且以字母或数字开头和结尾。已有键会替换文本,同时保留来源标识、角色、创建时间、图谱和元数据;角色不匹配时会被拒绝。缺失的键会按请求顺序追加,并使用服务端标识和时间戳。所有条目都会先经过验证,然后再原子提交一个版本。若请求中的所有条目均未变化,则返回 no_change,不创建版本或索引任务;若请求同时包含新增、更新和未变化条目,则会创建一个版本。verify: true 会检查已提交的规范版本,并在持久化回执中报告每个键的结果;只有在成功转换当前头版本后才会开始索引。
已部署的能力响应会公布 features.message_keys: true。
使用相同幂等键和内容重放批处理时,会返回已有结果,不会创建重复版本或任务。使用过的键对应的内容发生变化时会产生冲突;过时的操作会阻止该批次中的所有操作提交。一个批次中可以混合多个自有命名空间;不同账户彼此隔离。
| 工具 | 标题 | 说明 |
|---|---|---|
memory_store | 存储记忆 | 创建新的、主动写入的记忆;首次写入会占用你指定的命名空间 |
memory_upsert_messages | 写入或更新键控消息 | 按精确键原子新增/更新/跳过 1–100 条消息;必须提供基础版本 |
memory_append | 追加记忆 | 使用 base_revision_id 继续对话 |
memory_replace | 替换记忆 | 用完整转录内容取代现有内容,同时保留标识和标签 |
memory_commit_batch | 提交记忆批次 | 使用明确的基础版本,原子追加/替换 1–20 个对话 |
memory_edit_messages | 编辑记忆消息 | 原位编辑 1–100 个已知来源节点;不接受结构化内容 |
memory_restore_revision | 恢复记忆版本 | 将头版本回退到历史版本,不创建重复版本 |
memory_copy_conversations | 复制对话 | 无损复制 R2 数据到另一个自有命名空间,并使用幂等键 |
memory_update_tags | 更新记忆标签 | 通过乐观并发控制添加或移除标签 |
管理
| 工具 | 标题 | 说明 |
|---|---|---|
memory_delete_conversations | 删除对话 | 最多 100 条;精确确认后同时删除规范数据和派生数据 |
memory_empty_namespace | 清空命名空间 | 精确确认后执行有界、可恢复的批量清空 |
重试、重新索引和完整性命令仅支持通过 HTTP/CLI 使用,以防模型触发开销高昂的维护操作。完整的工具契约、回执和批处理语义请参阅 docs/mcp.md。
搜索分页
首次调用 memory_search 时必须提供 query,并可接受 limit(1–20,默认值为 8)、可选的
namespace、tags、tag_mode(all 或 any),以及可选的 max_serialized_bytes。字节预算
默认为 32 KiB,可设置为 4–48 KiB。响应可能包含 next_cursor;继续搜索时,请使用该不透明游标、
下一个 limit 和字节预算。继续搜索时不要重新提交查询或更改筛选条件。
不请求分页的兼容性响应可能不包含仅用于分页的元数据。
搜索游标标识一个短期有效、绑定租户的快照。该快照保留首次调用时的确切排序、分数和顺序,为每条
结果固定其修订版本,并沿用原始的 degraded 和 unavailable 诊断信息。其元数据会报告排序
版本、候选项数量和上限、创建和过期时间,以及有界的省略数量和原因。读取时会清理过期游标。格式错误、
伪造、过期、不兼容或跨账户的游标会返回有界验证错误;游标不会暴露任何内部存储或账户标识符。
搜索范围限定为经过身份验证的账户。命名空间筛选条件仅对账户拥有的命名空间有效;省略该条件时,会搜索 账户拥有的命名空间。已删除、过时或不再归该账户所有的快照候选项会被省略,并附带安全的有界诊断信息, 而不会替换快照或暴露其他账户的数据。搜索游标仅用于 MCP/HTTP 搜索分页,不是导出或规范读取游标。
限制
memory_get_capabilities 是唯一契约:它会报告各传输方式实际执行的常量,确保引用的数值与实际限制保持一致。已部署的值:
| 限制 | 值 |
|---|---|
| MCP 工具输出保护 | 65,536 字节(64 KiB) |
| 建议的工具输出/回执上限 | 49,152 字节(48 KiB) |
| 两种传输方式的内联 JSON 写入 | 1,048,576 字节(1 MiB) |
| 直接导入请求正文及每个多部分分段 | 16,777,216 字节(16 MiB) |
| 单条消息内容 | 1,000,000 个字符 |
| 批量对话读取响应 | 默认 32 KiB,最大 48 KiB |
| 搜索响应 | 默认 32 KiB,最小 4 KiB,最大 48 KiB |
| 精确消息查找响应 | 默认 32 KiB,最小 4 KiB,最大 48 KiB |
总量限制按完整序列化请求的 UTF-8 字节数计算,并在任何规范处理开始前测量。超大请求不会写入任何内容,
并会返回 REQUEST_TOO_LARGE(retryable: false)以及保守估算的 suggested_max_items,
绝不会静默截断。
ChatGPT 导入
从 ChatGPT 导出数据,提取 conversations.json,然后:
MEMPERSIST_URL=http://localhost:8787 \
MEMPERSIST_TOKEN='your-token' \
yarn import:chatgpt /path/to/conversations.json
MEMPERSIST_TOKEN='your-token' yarn import:status <import-id>
上传的字节会原样存储,并在服务器端进行哈希处理;完全重复的内容会标记为
duplicate,且不会重新处理。每个队列轮次会从序号检查点开始处理 25 个对话,因此可以安全地重试和恢复。较大的文件使用 R2 分段上传。未知字段、备用分支和图结构异常都可以恢复。请参阅
docs/chatgpt-import.md。
控制面板
打开 /login,即可免密码访问服务器渲染的控制面板:存档总量、确定性记忆地图、固定到特定修订版本的规范阅读、显示名称编辑,以及流式无损导出。清空命名空间会异步执行;删除账户设有七天的可取消宽限期,等待期间写入操作将变为只读。无需前端框架或额外的 Cloudflare 资源。请参阅 docs/dashboard.md 和
ADR 0028。
公共网站、OAuth 页面和魔法链接邮件支持英语和印度尼西亚语; API、MCP 和 CLI 合约仍为英语。
开发
yarn verify
运行格式检查、绑定类型最新状态检查、lint、针对 Worker 和 web/mindmap/ 浏览器项目的严格 TypeScript 检查、记忆地图捆绑检查、单元测试和 MCP 测试、Workers 运行时 D1/R2 集成测试,以及 Wrangler 部署试运行。除非调用 yarn deploy,否则不会部署任何内容。编辑 web/mindmap/ 下的任何内容后,运行 yarn build:mindmap,使生成的捆绑包与源文件保持一致。
yarn admin search 'api.internal.example' # CLI search against canonical data
yarn retry <job-id> # re-run a failed import or index job
yarn reindex # rebuild derived indexes from R2
yarn verify:integrity # check catalog, R2 pointers, and revision hashes
架构变更需编号为 SQL 迁移,并通过 Wrangler 应用;应用后不得再编辑。架构变更需要在 docs/adr/ 中添加 ADR。提交拉取请求前,请参阅 CONTRIBUTING.md 和 AGENTS.md。
文档
| 文档 | 内容 |
|---|---|
| ARCHITECTURE.md | 系统结构、规范数据与派生数据、写入顺序、检索 |
| CONTRIBUTING.md | 设置、各项更改要求、测试、授权门槛 |
| SECURITY.md | 威胁模型、信任边界、限制、轮换、报告 |
| docs/mcp.md | 工具契约、回执、批次、能力、拒绝形式 |
| docs/development.md | 本地开发循环、本地 MCP 客户端、浏览器页面、记忆地图客户端 |
| docs/deployment.md | 配置、迁移、部署、部署后检查 |
| docs/cloudflare-resources.md | 必需资源和手动配置步骤 |
| docs/chatgpt-import.md | 导入保证、上传路径、解析器限制 |
| docs/dashboard.md | 仪表板、导出和删除流程 |
| docs/storage-and-indexing.md | 规范存储布局和索引代次 |
| docs/operations-and-recovery.md | 恢复流程和删除任务重新入队 |
| docs/rp-workflow.md | 可审查的运行时规则工作流 |
| docs/adr/ | 决策日志,最新优先 |
| docs/adr/0040-atomic-multi-conversation-commit.md | 原子多对话提交、重放、恢复 |
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。