
Memshelf Mcp
io.github.ignatenkofi由 GitHub 帳號 ignatenkofi 發布v0.4.0更新於 Oct 25, 2026
Working memory for AI agents: digest-indexed episodes on a git shelf, recalled a section at a time.
概覽
本機 MCP 伺服器,為 AI 助理提供以 git 為底的記憶架:把已結束的主題存成帶摘要索引的片段,並按小節召回
- 可以做什麼
- 建立並維護具固定分類的記憶架,把已結束的主題存成可索引的片段,支援批次匯入匯出的對話紀錄,並可原地修訂既有片段。在不更動記憶架的前提下依契約驗證摘要。讀取記憶架索引,依 id 召回整個片段或其中某一小節,並檢索相符的片段。回報 token 開銷並建議哪些內容可以下架,僅提出建議而不寫入。重新產生衍生檔案、把一段時間彙整成一個摘要、依保留期限清除片段(預設試跑)、解決多寫入者衝突,並診斷結構、摘要、敏感資訊樣態與索引膨脹問題。
- 適用情境
- 適合長時間執行的助理工作階段:這類工作階段反覆傳送歷史會耗費大量 token,或因自動壓縮而遺失細節。也適合希望擁有本機、可檢索、可比對審閱、可跨主機攜帶並能在不同 AI 工具間共用的片段式工作記憶的人。
- 執行需求
- 以本機 stdio 程序執行,通常透過 uvx 從 PyPI 套件 memshelf-mcp 啟動;命令列安裝需要 Python 3.10 或更新版本。記憶架是一個本機 git 儲存庫,預設不設定遠端。選用的語意擴充會加入嵌入側車以支援同義改寫檢索。未宣告驗證或環境變數。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Memshelf Mcp,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
memshelf-mcp
Put your agent's memory on a shelf, hand it the index.
[PyPI] [Python] [Glama] [ci] [security] [License: MIT] [Docs] [Sibling: docshelf]
What this is
Long-running agent sessions burn tokens re-sending history and lose detail to lossy auto-compaction. memshelf applies the docshelf pattern — tiny index in context, bodies fetched on demand — to the agent's own working memory:
- Closed conversation topics, research dumps, and bulky tool output are offloaded to a local shelf as Markdown episodes.
- Each episode carries an LLM-written, contract-validated digest that preserves decisions, rejected alternatives, artifacts, and open threads.
- The agent keeps only
INDEX.md(kilobytes) + digests in context and recalls exact sections via INDEX → episode → section slice over MCP.
Positioning in one sentence: claude-mem's loop, git's substrate, docshelf's navigation — episodic memory you can grep, diff, review, and carry between hosts. Private and local by default: the standard storage mode is a local git repo with no remote configured. The tool is public; the memory never is.
Measured, not promised
One week of dogfooding on the live shelf — full numbers and methodology in
docs/demo.md:
Tokens are counted as chars/4 everywhere, so the ratios are estimator-independent; absolute counts move with the tokenizer.
Quick start
As an MCP server:
As a Claude Desktop extension — adapters/claude-desktop/:
an .mcpb bundle installed from Settings → Extensions, with a Default
shelf setting so calls need not repeat the path. Nothing has to be installed
alongside it — not even Python.
As a Claude Code plugin — adapters/claude-code/:
a /shelve skill plus SessionStart / SessionEnd / PreCompact hooks.
Or from the shell (pip install memshelf-mcp, Python ≥ 3.10) — the same
loop, no MCP:
pip install 'memshelf-mcp[semantic]' adds an embedding sidecar so search
also finds paraphrases and the other language (memshelf semantic build --shelf ~/my-shelf once; MEMSHELF_SEMANTIC=off turns it off). Optional:
the base install stays grep-only and as light as it is.
Tool surface
One verb per job; the same names over MCP (memshelf_*) and in the CLI
(long-form descriptions: docs/tools.md):
The rules the tools enforce
The digest is a contract, not a convention. It is the only thing read at
recall before fetching a body, so a weak one devalues the whole episode.
lint_digest runs the same validator as shelve with no side effects
(--strict turns warnings into failures); errors block a shelve, warnings do
not — a pure reference digest legitimately carries no decision marker. A
rejected digest is a feature: the tool prints exactly what to fix and writes
nothing.
--amend re-runs the whole pipeline — redaction, the digest contract,
composition — so an amended episode is exactly as guarded as a fresh one,
which a hand-edit of the file never is. Amending a slug that is not on the
shelf is an error, not a create.
The episode is the source; everything else is output. ledger.tsv,
INDEX.md, stats.svg and each category's .meta.json are derived:
shelve writes and commits the episode alone, rebuild renders the rest —
delete all four and rebuild restores them byte-identically. That is what
makes two sessions shelving in parallel a non-event: the merge is clean by
construction. On a shared shelf, let a bot own the derived files on main —
ready-to-copy workflows in adapters/shelf-repo/;
rebuild --adopt migrates an older shelf once, rebuild --check is the
CI guard.
Two consequences worth stating plainly, because getting them wrong costs a merge conflict:
doctorreportsno-ledger-rowandstale-indeximmediately after a correctshelve— on every branch,mainincluded. Nothing is broken: the episode is written, the derived files are not rendered yet. They clear on the nextrebuild— the bot's run, on a shelf that has one.- Do not rebuild and commit the derived files by hand to silence them.
That is exactly the conflict class the split removes: a hand-regenerated
ledger.tsv/INDEX.md/stats.svgmeets the bot's, and the merge stops being clean by construction. Wait for the renderer; on a shelf without a bot, runmemshelf rebuild --shelf .as its own step.
If those warnings persist for a day while episodes keep arriving, that is a
different state — the renderer is not lagging, it is stopped — and doctor
says so separately, as derived-stale at error severity. The day is counted
from when the renderer could first see the work, not from the ledger's last
commit: an episode pushed minutes ago onto a shelf whose ledger has not moved
since yesterday says nothing about the renderer, and saying otherwise sent
readers to a manual rebuild, which is the conflict this whole split exists
to avoid.
That arrival is read from this clone's reflog for the tracked upstream — the
one local record of when the ref moved here. A commit date is not a
substitute: it says when the episode was written, and «shelve now, push when
confirmed» is a documented way to work, so the two can be a working day apart.
Where the reflog cannot say — a fresh clone starts an empty one, which is what
CI and ephemeral agent sessions run in — doctor reports
renderer-wait-unknown at the unknown level instead of picking a verdict:
from there, «stopped» and «handed the work a minute ago» look the same, and
the renderer has to be judged where it can be observed, on its own job's run.
On a shelf with no upstream there is no renderer to be fair to, and the
ledger's own age stays the clock.
The ref the renderer is judged by is the render branch, not whatever the
checkout happens to track (#180). The bot renders one branch — the remote's
default one, read as origin/HEAD when the clone has it, else origin/main,
else origin/master — so a clone standing on a PR branch is not told
derived-stale for an episode that sits on origin/<pr-branch> only. That
episode waits for a merge, not for the renderer, and doctor says so with the
warning upstream-not-rendered; one that did reach the render branch is judged
there even from the PR branch, and a local commit on either stays
episode-unpushed.
There was a third way to hold stale-index forever, and it is fixed rather
than documented: docshelf split any episode past 50 KiB into section files
beside it, shelve committed the episode alone, and from then on this working
copy rendered an INDEX no other checkout could produce — no rebuild could
clear it, and search answered with addresses that existed on one machine
(#109). shelve no longer splits. A shelf that already carries such
directories keeps reporting them as local-split-dir until
memshelf prune-splits --shelf . --apply removes them; the episode file holds
every section, so nothing is lost. It is a dry run without --apply, and a
split directory that is committed is reported and left alone.
advise proposes, never writes. It answers the question the project was
founded on — a dead topic has been occupying 30K tokens for forty minutes.
The tool cannot see your window, so you tell it what is in there:
Three things keep it honest: it counts itself (INDEX + digests are in the
report, not left out of it), it verifies episode= claims before
proposing a drop, and it reports net — a topic too small to pay for its
own digest is not proposed at all.
Rollup shrinks navigation and nothing else. When INDEX grows into a real
share of your window, rollup collapses a period into one digest-of-digests
and moves the originals to archive/ — still reachable by recall and
search, every ledger row intact. The rollup digest is yours, not the tool's:
synthesizing a quarter is the part a tool cannot do.
index-bloat is not what a rollup is for. INDEX lists your episodes, so
its size grows with the shelf by design; its budget grows with the shelf too
(INDEX_BASE_TOKENS + INDEX_TOKENS_PER_ENTRY × listed). Over budget therefore
means entries are overpriced, never that there are too many of them — so
doctor reports the cost of one line, and the fix is to trim it and
rebuild. A rollup would remove entries and their allowance together and
leave the price where it was. Having the two paired the other way is what made
"archive a third of your memory" the standard way to silence a formatting
problem.
purge deletes the working tree, not history. Retention is opt-in per
episode (--retain-until); purge is a dry run until --apply — and even
then git history still has the file. Real erasure is a deliberate
filter-repo pass over the whole repository, never a side effect of a tool
call, and the purge report says so.
resolve regenerates derived paths, never merges them — a derived file
has no history, only a current correct value. The one file it unions is
recall-log.tsv, because a recall is an event, not a fact about the
episodes. Conflicting episodes are content, not mechanics: resolve
reports them and steps aside.
A tool answer says when the code behind it is stale. The same code ships
five ways, the version number does not move between releases, and twice a
merged fix was not acting because the copy answering the calls was behind
main (#125, #158) — found hours later, sideways, as what looked like a tool
bug. doctor reports that gap as served-code-differs; since a doctor finding
is read only by whoever runs doctor, the MCP server now says it in the response
itself: when the served package's hash differs from the memshelf-mcp checkout
next to the shelf (or $MEMSHELF_CHECKOUT), every envelope — success or error
— opens with a warning carrying that code, both short hashes and where each
lives. Identical code adds nothing. No checkout to compare with adds nothing
per call either, but the initialize instructions say the freshness is unknown
and how to make it known. MEMSHELF_FRESHNESS_WARNING=0 switches the per-call
warning off where the difference is intended.
The design rationale behind each rule lives in
docs/DECISIONS.md and
docs/ARCHITECTURE.md.
One memory, multiple AIs
The memory is vendor-portable, and that is a measured fact, not a design
intention: the same live shelf has been read and cross-written by Claude Code
(Anthropic) and Gemini CLI (Google) through one shelf-spec server —
protocol and field notes in docs/portability.md.
Status
M0 complete: the pattern was validated with zero code on a live shelf —
retro-import of months of material, then a week of shelve-at-close
(docs/M0.md). M1 shipped the server/CLI that enforces it,
plus the Claude Code plugin. Next milestones with exit criteria:
docs/ROADMAP.md; release history:
CHANGELOG.md.
Documents
Rendered site: https://ignatenkofi.github.io/memshelf-mcp/ — including the week-report infographic from the dogfood shelf.
Project memory shelf
shelf/ is this project's own memory shelf, dogfooding the tool it ships:
session episodes with decisions, rejected options and their reasons. Before
asserting anything about past work here, read shelf/INDEX.md
and fetch the one episode it points at — a guess about a past decision is a
defect, not an estimate. Derived files (ledger.tsv, INDEX.md, stats.svg,
.meta.json) are written by the same commit as the episode
(memshelf rebuild --shelf shelf); the shelf-pr-guard workflow fails a PR or
a push to main where they drifted.
Origin
Designed as RFC-0001 in the docshelf-mcp repo (#42, #43, #44); this repo is the project's home from 2026-07-13 on. The docshelf copy is frozen as a historical snapshot.
Related projects
- docshelf-mcp — the sibling project and storage layer: PDFs/Markdown → chat-project-friendly document shelves with the same index-and-fetch economics (measured: ~3.7K tokens vs 1.2M per question). memshelf was born as RFC-0001 in its repo and reuses its splitter/indexer/read/search verbatim.
- The dogfood memory shelf is a private repo — by design (MANIFEST principle 5).
License
MIT — see LICENSE.
mcp-name: io.github.ignatenkofi/memshelf-mcp
來源:README.md,提交 b6fa0b8
工具
0版本歷史
2- v0.4.0最新Oct 7, 2026
- v0.3.0Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分