mcpField
M
memshelf-mcp

memshelf-mcp

本地服务
ignatenkofi.github.io记忆与知识02 周前更新

关于 memshelf-mcp

memshelf-mcp 是面向 Agent 的本地优先工作记忆系统,将已结束的话题和大量上下文保存为带索引的 Markdown 片段,并验证摘要。它通过 MCP 和命令行支持按需回忆,默认使用本地 git 仓库存储。

主要功能

  1. 01将话题保存为 Markdown 片段
  2. 02验证片段摘要
  3. 03按需回忆单个章节
  4. 04搜索并检查记忆架
  5. 05重建索引及派生文件
  6. 06可选语义搜索侧车

适用场景

  1. 01在 Agent 会话间保留决策
  2. 02从过往研究中提取单个章节
  3. 03导入并整理导出的对话
  4. 04跟踪记忆规模和 token 节省

MCP 相关

它向 MCP 客户端提供记忆架创建、片段存储、索引、回忆、搜索和维护工具。相同的核心操作也可通过命令行使用。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"ignatenkofi-memshelf": {
"command": "uvx",
"args": [
"memshelf-mcp"
]
}
}
}
启动命令uvx memshelf-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypimemshelf-mcp0.4.0

工具

15

收录的工具列表 · 更新于 2 周前

参数类型必填说明
paramsany是

详细介绍

memshelf-mcp

把 Agent 的记忆放上架,并把索引交给它。

PyPI Python Glama ci security License: MIT Docs Sibling: docshelf

                              _          _  __
 _ __ ___   ___ _ __ ___  ___| |__   ___| |/ _|
| '_ ` _ \ / _ \ '_ ` _ \/ __| '_ \ / _ \ | |_
| | | | | |  __/ | | | | \__ \ | | |  __/ |  _|
|_| |_| |_|\___|_| |_| |_|___/_| |_|\___|_|_|
  ____________________________________________
 | INDEX >> | E-01 | E-02 | E-03 | E-04 | ... |
 |__________|______|______|______|______|_____|
        memory shelves for AI agents

项目介绍

长期运行的 Agent 会话会因反复发送历史记录而消耗大量令牌,也会因有损自动压缩而丢失细节。memshelf 将 docshelf 的模式——在上下文中保留小型索引,按需获取正文——应用于 Agent 自身的工作记忆:

  1. 已结束的对话主题、研究资料和庞大的工具输出会作为 Markdown 片段转存到本地存储架。
  2. 每个片段都带有由大模型编写、经过契约验证的摘要,保留决策、被否决的替代方案、产物和未解决事项。
  3. Agent 只需在上下文中保留 INDEX.md(几 KB)和摘要,并通过 MCP 按 INDEX → 片段 → 章节切片的路径回忆确切内容。

一句话定位:claude-mem 的循环、git 的底层、docshelf 的导航——可用 grep 搜索、比较差异、审阅并在主机之间携带的情景记忆。默认私密且存储在本地:标准存储模式是一个未配置远程服务的本地 git 仓库。工具是公开的,记忆永远不会公开。

实测,而非承诺

在实际存储架上进行一周的自用测试——完整数据和方法见 docs/demo.md:

指标结果
存储架上的片段数34
每次会话固定占用(INDEX + 摘要)~8.6K 个令牌
这些片段取代的存储内容~1.9M 个令牌 — ≈220 : 1
从记忆中回答一个问题~1.8K 个令牌(INDEX + 一个片段)
回忆测试:全新 Agent,仅使用 INDEX 路径5 / 5 — 零遗漏,零过量获取

所有令牌数均按字符数/4 计算,因此比率不受估算器影响;绝对数值会随分词器而变化。

快速开始

作为 MCP 服务:

# Claude Code
claude mcp add memshelf -- uvx memshelf-mcp
// Claude Desktop (claude_desktop_config.json)
{
  "mcpServers": {
    "memshelf": { "command": "uvx", "args": ["memshelf-mcp"] }
  }
}

作为 Claude Desktop 扩展 — adapters/claude-desktop/: 一个 .mcpb 捆绑包,可从设置 → 扩展安装,并提供默认存储架设置,因此调用时无需重复指定路径。无需额外安装任何内容,甚至不需要 Python。

作为 Claude Code 插件 — adapters/claude-code/: 包含一个 /shelve 技能,以及 SessionStart / SessionEnd / PreCompact 钩子。

也可以通过命令行使用(pip install memshelf-mcp,Python ≥ 3.10)——相同的工作流程,无需 MCP:

memshelf init   --shelf ~/my-shelf --name "My working memory"
memshelf shelve --shelf ~/my-shelf --slug 2026-07-23-topic --kind topic \
  --digest "What was decided, what was rejected and why, what stays open." \
  --section "Decisions=What was decided, and what was rejected instead — one line each."
memshelf recall --shelf ~/my-shelf --id 2026-07-23-topic --section Decisions --log
memshelf rebuild --shelf ~/my-shelf  # render ledger/INDEX from the episode (a bot's job on shelves that have one)
memshelf stats  --shelf ~/my-shelf   # claimed + realized savings
memshelf doctor --shelf ~/my-shelf   # exit 1 on integrity errors

pip install 'memshelf-mcp[semantic]' 会添加一个嵌入向量辅助组件,让 search 也能找到释义相同的内容和另一种语言的内容(执行一次 memshelf semantic build --shelf ~/my-shelf;设置 MEMSHELF_SEMANTIC=off 可关闭)。此项为可选功能: 基础安装仍仅使用 grep 搜索,保持轻量不变。

工具范围

每项任务对应一个动词;MCP 中(memshelf_*)和 CLI 中的名称相同 (完整描述见:docs/tools.md):

工具功能
init创建(或补全)记忆架:采用 docshelf 布局和固定分类
shelve将一个已结束的话题归档为持久化、带索引的事件;--amend 会原位重写
lint_digest根据契约验证摘要,不触碰记忆架
import将整个导出的对话回溯归档,无需将其载入上下文
index返回记忆架的 INDEX——轻量的回忆入口
recall按 ID 获取事件,或获取其中单个 ## Section
search在记忆架中 grep;返回匹配的事件
stats记忆架的 Token 经济账:常驻成本与归档总量、声称值与实际值
advise展示上下文由什么构成,以及可以放下什么——仅提供建议
rebuild从事件重新生成所有派生文件
rollup将一个时期归档为一份摘要的摘要
purge删除超过 retain_until 的事件,然后重新建立索引——默认试运行
resolve解决多写入者冲突:重新生成派生文件,合并回忆日志
doctor诊断:事件架构、静态摘要契约、密钥形态、索引膨胀情况
freshness仅限 CLI——检查哪个已安装的使用方(pipx、Desktop 扩展)会响应调用,以及哪些更改已合并但尚未发布(#125)
sync仅限 CLI——获取记忆架克隆,并快进到其远程版本(#157)
prune-splits仅限 CLI——移除 git 未跟踪到的 H2 拆分目录(#109 的迁移工具)
tags仅限 CLI——按 frontmatter 标签分组事件(#18)
graph仅限 CLI——谁提到了谁:以 JSON 或 Mermaid 格式展示跨事件 ID 引用(#18)
retro仅限 CLI——将记忆架的一个季度内容整理为 Markdown 回顾(#18)
fork仅限 CLI——从 INDEX 和选定的事件或章节引导一个新会话(#18)
mirror仅限 CLI——将 INDEX(± 事件)整理为一个独立的 HTML 页面,方便在手机上阅读(#18)
semantic仅限 CLI——build / status / drop 将 search 转为混合搜索的嵌入旁文件;位于记忆架之外,需运行 pip install 'memshelf-mcp[semantic]'(#17)
search-bench仅限 CLI——在 query<TAB>expected-id 文件上测量 grep 与混合搜索的 hit@1 / hit@k / MRR(#17)

工具执行的规则

摘要是契约,不是惯例。 回忆时,获取正文前唯一会读取的就是摘要,因此摘要质量差会降低整个事件的价值。 lint_digest 会运行与 shelve 相同的验证器,且不会产生副作用 (--strict 会将警告视为失败);错误会阻止归档,警告则不会——纯引用摘要不带决策标记也完全合理。摘要被拒绝是件好事:工具会明确指出需要修正的内容,且不会写入任何内容。

--amend 会重新运行整个流程——脱敏、摘要契约、内容编排——因此修订后的事件受到的保护与新事件完全相同,而手动编辑文件永远无法做到这一点。修订不在记忆架中的 slug 会报错,不会创建新事件。

事件是数据源;其他一切都是输出。 ledger.tsv、 INDEX.md、stats.svg 和各分类中的 .meta.json 都是派生文件: shelve 只写入并提交事件本身,rebuild 则生成其余内容——删除这四类文件后,运行 rebuild 就会逐字节还原它们。正因如此,两个会话并行归档不会引发问题:合并从设计上就不会产生冲突。在共享记忆架上,让机器人在 main 分支负责派生文件——可直接复制使用的工作流见 adapters/shelf-repo/; rebuild --adopt 可一次性迁移旧版记忆架,rebuild --check 则是 CI 防护措施。

有两点值得明确说明,因为弄错了会导致合并冲突:

  • 正确执行一次 shelve 后,doctor 会立即报告 no-ledger-row 和 stale-index——所有分支都如此,包括 main。 这并不代表出了问题:片段已写入,但派生文件尚未渲染。下一次 rebuild 后它们就会消失——对于有机器人的 shelf 来说,就是机器人运行时。
  • 不要手动重建并提交派生文件来消除这些警告。 这正是拆分要消除的冲突类型:手动重新生成的 ledger.tsv/INDEX.md/stats.svg 会与机器人的版本相遇,合并从一开始就无法保持干净。请等待渲染器;对于没有机器人的 shelf,请单独执行 memshelf rebuild --shelf .。

如果这些警告持续了一天,期间仍不断有片段到来,那就是另一种情况——渲染器不是延迟,而是已停止——doctor 会另行以错误严重级别报告 derived-stale。这一天从渲染器首次能够看到这些工作时开始计算,而不是从账本最近一次提交时开始:几分钟前才推送到 shelf 的片段,如果所在 shelf 的账本自昨天以来都没有变动,并不能说明渲染器的状况;过去说成相反的情况,会让读者去手动执行 rebuild,而这正是整个拆分要避免的冲突。

这个到达时间取自此克隆中跟踪上游分支的 reflog——这是唯一能记录引用何时移动到此处的本地记录。提交日期不能替代它:提交日期表示片段的写入时间,而“先 shelve,确认后再推送”是有文档记录的工作方式,因此两者可能相隔一个工作日。如果 reflog 无法提供信息——新克隆的 reflog 为空,CI 和临时 Agent 会话运行时就是如此——doctor 会以 unknown 级别报告 renderer-wait-unknown,而不是擅自判断:此时“已停止”和“刚在一分钟前交付工作”看起来一样,因此必须在可观察到渲染器的地方,也就是它自己的任务运行中,判断它的状态。对于没有上游分支的 shelf,不必为渲染器考虑,账本自身的更新时间仍是计时依据。

判断渲染器所依据的引用是渲染分支,而不是检出分支碰巧跟踪的分支(#180)。机器人只渲染一个分支——远程仓库的默认分支:克隆中存在 origin/HEAD 时读取它,否则使用 origin/main,再否则使用 origin/master——因此,处于 PR 分支的克隆不会因为某个片段只存在于 origin/<pr-branch> 上而被报告 derived-stale。该片段要等的是合并,而不是渲染器;doctor 会用警告 upstream-not-rendered 说明这一点。若片段确实已到达渲染分支,则即使当前处于 PR 分支,也会在那里判断;任一分支上的本地提交仍会标为 episode-unpushed。

以前还有第三种会让 stale-index 永远存在的情况;现在已修复,无需再写进文档:docshelf 会把超过 50 KiB 的片段拆分成与其相邻的章节文件,shelve 只提交片段本身,从此这个工作副本渲染出的 INDEX 便成了其他检出都无法生成的版本——任何 rebuild 都无法清除它,而且 search 返回的地址只在一台机器上存在(#109)。shelve 不再拆分片段。已包含此类目录的 shelf 会继续报告 local-split-dir,直到执行 memshelf prune-splits --shelf . --apply 将其移除;片段文件包含所有章节,因此不会丢失内容。若不带 --apply,该操作会进行试运行;已提交的拆分目录会被报告,但不会改动。

advise 只提出建议,绝不写入。 它回答的是项目创立之初就关注的问题——一个已失效的话题占用了 30K 个令牌达四十分钟。工具看不到你的窗口,因此需要你告诉它窗口里有什么:

memshelf advise --shelf ~/my-shelf \
  --occupant 'auth refactor=42000,closed' \
  --occupant 'search dump=9000,idle=18' \
  --occupant 'Case B verdict=12000,live,episode=2026-07-22-case-b-verdict'

有三件事能确保它诚实:它会将自身计入(INDEX 和摘要包含在报告中,不会被漏掉);它会在建议移除前验证 episode= 声明;它会报告净值——如果一个话题太小,连自己的摘要成本都无法弥补,就不会被建议移除。 Rollup 只精简导航,不会做其他事。 当 INDEX 在窗口中占据的空间越来越大时,rollup 会将一个时期折叠为一份摘要的摘要,并把原始内容移到 archive/——仍可通过 recall 和 search 访问,账本中的每一行也都完整保留。Rollup 摘要由你撰写,而不是工具:综合一个季度的内容,是工具无法完成的部分。

index-bloat 不是 rollup 要解决的问题。 INDEX 列出你的经历,因此它的大小会随着存档架的增长而有意增长;它的预算也会随存档架增长(INDEX_BASE_TOKENS + INDEX_TOKENS_PER_ENTRY × listed)。因此,超出预算意味着条目定价过高,绝不是条目太多——所以 doctor 会报告每一行的成本,解决办法是精简内容并 rebuild。Rollup 会同时移除条目及其对应的预算额度,价格却维持不变。将这两者配对反了,才会让“归档三分之一的记忆”成为解决格式问题的常规做法。

purge 删除的是工作树,不是历史记录。 保留策略需按经历单独启用(--retain-until);在指定 --apply 前,purge 都只是试运行——即便指定了,文件仍保留在 git 历史记录中。真正的彻底删除需要对整个仓库有意执行 filter-repo,绝不会作为工具调用的副作用发生;purge 报告也会明确说明这一点。

resolve 会重新生成派生路径,绝不会合并它们——派生文件没有历史记录,只有当前的正确值。它会合并的唯一文件是 recall-log.tsv,因为 recall 是一个事件,而不是关于这些经历的事实。冲突的经历属于内容问题,不是机制问题:resolve 会报告它们,然后不再处理。

工具响应会说明其背后的代码是否过时。 同一份代码以五种方式发布,版本号在各个版本间不会变化;此前两次,合并后的修复都未生效,因为响应调用的副本落后于 main(#125、#158)——几个小时后才旁敲侧击地发现问题,起初看起来像是工具故障。doctor 会将这种差异报告为 served-code-differs;由于只有运行 doctor 的人才能看到 doctor 的发现,MCP 服务现在会直接在响应中说明:当已提供服务的包的哈希与存档架旁边的 memshelf-mcp 检出版本(或 $MEMSHELF_CHECKOUT)不同时,每个信封——无论成功还是出错——都会以一条 warning 开头,其中包含该代码、两个短哈希及各自的位置。代码相同时不会添加任何内容。每次调用时,如果没有可供比对的检出版本,也不会添加任何内容;但 initialize 说明会指出新旧状态未知,以及如何确定。若这种差异是有意的,可通过 MEMSHELF_FRESHNESS_WARNING=0 关闭每次调用的警告。

每条规则背后的设计依据见 docs/DECISIONS.md 和 docs/ARCHITECTURE.md。

一个记忆,多个 AI

这种记忆可跨厂商使用,而且这是经过验证的事实,并非设计意图:同一个正在使用的存档架已通过一个 shelf-spec 服务,由 Claude Code(Anthropic)和 Gemini CLI(Google)读取并交叉写入——协议和实测记录见 docs/portability.md。

状态

M0 已完成:该模式已在一个正在使用的存档架上通过零代码验证——回溯导入数月的材料,然后连续一周在关闭时收纳 (docs/M0.md)。M1 已发布用于执行该模式的服务/CLI,以及 Claude Code 插件。带有退出标准的后续里程碑: docs/ROADMAP.md;发布历史: CHANGELOG.md。

文档

渲染后的站点:https://ignatenkofi.github.io/memshelf-mcp/ — 包含来自内部试用记忆架的周报信息图。

文档内容
docs/MANIFEST.md问题、核心设想、核心场景、原则、非目标
docs/tools.md工具参考:每个 memshelf_* 工具的详细说明(MCP schema 中只包含简短说明)
docs/ARCHITECTURE.md片段格式、摘要约定、存储模式、触发条件、MCP 工具接口、可移植性模型、隐私、故障模式
docs/LANDSCAPE.md先例调研(2026-07)、平台内置功能、定位、风险
docs/ROADMAP.md里程碑 M0–M3 及退出标准
docs/DECISIONS.md决策日志
docs/M0.mdM0 实验方案与结果:案例、令牌账本、回忆测试
docs/demo.md内部试用记忆架的测量数据:压缩、回忆测试、检查结果
docs/portability.md一份记忆,多个 AI:跨供应商实验
docs/chat-projects.md不使用 hooks 的 Claude Desktop 和 claude.ai 项目:设置、回忆、存入记忆架、保持索引最新
docs/examples/一份完整的片段文件示例和一个记忆架 INDEX
adapters/claude-code/Claude Code 插件:/shelve 技能 + SessionStart/SessionEnd/PreCompact hooks
adapters/claude-desktop/Claude Desktop .mcpb 扩展:构建器、打包检查器、默认记忆架设置
adapters/claude-account/claude.ai 账户技能的存档镜像 — 不可安装,仅用于对照

项目记忆架

shelf/ 是本项目自己的记忆架,用它所发布的工具进行内部试用: 其中保存了包含决策、被否决的选项及其原因的会话片段。在断言此处任何有关过往工作的内容前, 请先阅读 shelf/INDEX.md 并获取它指向的那份片段 — 对过往决策的猜测是缺陷, 不是估算。派生文件(ledger.tsv、INDEX.md、stats.svg、 .meta.json)与片段在同一次提交中写入 (memshelf rebuild --shelf shelf);若这些文件发生偏差,shelf-pr-guard 工作流会阻止 PR 或 推送到 main。

起源

本项目最初以 RFC-0001 的形式在 docshelf-mcp 仓库中设计 (#42, #43, #44);自 2026-07-13 起,本仓库成为 该项目的主仓库。docshelf 中的副本已冻结为 历史快照。

相关项目

  • docshelf-mcp — 关联项目和存储层:PDF/Markdown → 适合聊天项目的 文档架,采用相同的索引与按需获取机制 (测量数据: 每个问题约 3.7K 个令牌,而非 1.2M)。memshelf 最初作为 RFC-0001 在其仓库中诞生,并逐字复用了其拆分器/索引器/读取/搜索功能。
  • 内部试用记忆架是一个私有仓库 — 这是有意为之 (MANIFEST 原则 5)。

许可证

MIT — 参见 LICENSE。


mcp-name: io.github.ignatenkofi/memshelf-mcp

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。