
IHMT Memory
io.github.gonzaroman由 GitHub 帳號 gonzaroman 發布v1.2.1更新於 Oct 24, 2026
Long-term memory for AI coding agents, stored as a tree of plain local files.
發布方自己的服務:Memory.fit
概覽
給 AI 程式代理使用的本機長期記憶,以可讀的純文字檔案樹存放在磁碟上,可跨代理、跨專案共用。
- 可以做什麼
- 沿階層樹檢索長期記憶,遇到歧義時要求提供線索,並提示已過時的事實
- 儲存持久事實、決策與更正,並把舊記憶標記為已被取代
- 產生程式碼庫地圖、找出回答問題的特定符號,並在讀取檔案時偵測變更
- 保存工作階段的暫存筆記以撐過上下文壓縮,並濃縮冗長日誌
- 適用情境
- 適合反覆向程式代理說明相同的決策、環境細節或更正,或希望多個代理與專案共用同一份記憶的情境。專案索引類工具屬於選用,主要在代理原本會整份讀取檔案時才有幫助。
- 執行需求
- 以 stdio 本機程序執行,可透過 uvx 從 ihmt-memory 的 PyPI 套件啟動,或從複製的儲存庫搭配 Python 3.10+ 與 git 執行。環境變數 IHMT_HOME 指定記憶資料夾(預設 ~/.ihmt)。只有安裝時需要網路,不需帳號、資料庫或付費服務。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 IHMT Memory,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
IHMT — Infinite Hierarchical Memory Tree
[Listed on mcpservers.org] [ihmt-memory MCP server – quality and maintenance score on Glama]
Long-term memory for your AI coding agents. Tell your agent something once — a decision, how your setup works, a correction — and it remembers it in every future session, in any project, with any of your agents.
What IHMT does
- Remembers across sessions. Decisions and their reasons, your environment, your preferences, people and projects, corrections. Your agent searches the memory before answering and saves what lasts, so you stop repeating yourself.
- One memory for all your agents and models. Claude Code, Codex and opencode can share the same memory: what one saves, the others find. Tested with models from Anthropic, OpenAI, Google and Meta.
- Saves tokens. Instead of pasting your notes or re-explaining context every session, the agent retrieves only what the question needs — typically 200–900 tokens, whether the memory holds 50 entries or 50,000, because search walks a tree instead of reading everything. Honest numbers, including where it does not save.
- Understands time. When something changes ("I moved to Valencia", "staging is on PostgreSQL 17
now"), the old memory is kept as history, flagged
OUTDATED, and searches answer with the current one first. Where you live, where you work and your stack are tracked automatically; any other correction is linked when the agent saves it withreplaces. When a question is ambiguous ("Luis" — which one?), it asks instead of guessing. - Portable. Your memory is one folder of plain text files. Copy it to another computer, back it up, or put it under version control — it works wherever you put it.
- Local, private and readable. No cloud, no database, no account: IHMT stores everything on your disk and sends nothing anywhere. (The memories your agent retrieves reach its model like any other context.) Every memory is a text file you can open, and each person who installs IHMT starts with their own, empty memory.
Compatibility. Officially supported: Claude Code. Also tested: Codex (CLI and the ChatGPT desktop app — setup) and opencode (setup). IHMT is a standard stdio MCP server, so any agent that supports local MCP servers should work — GitHub Copilot, Antigravity, Cursor, Windsurf, Gemini CLI, Claude Desktop… — and
INSTALL.mdknows how to configure them, but we have not tested those yet. All of them can share one memory.
Install
Before you start
Missing Python or git? Your AI agent installs them for you (it is instructed to ask you first). Python goes in your user folder, with no administrator password, so nothing system-wide changes. On a brand-new Mac, git may need one click: Apple shows a window asking to install its command-line tools.
On a Mac, note that the python3 that comes with macOS is version 3.9, which is too old — that is why
your agent may say Python is missing even though python3 exists.
You do not need administrator rights, a database, an account, or any paid service beyond your agent. Tested on macOS and Linux (Ubuntu); on Windows the instructions are included but not tested yet. Details: GUIDE.md §3.
Let your AI agent install it
Paste this into the AI agent you want to give a memory to — Claude Code, Codex and opencode are tested; GitHub Copilot, Antigravity, Cursor, Windsurf, Gemini CLI, Claude Desktop and other MCP clients should work too:
The agent follows INSTALL.md: it downloads IHMT to ~/IHMT-MEMORY, keeps your
memory in ~/.ihmt, registers the server with itself only, adds the usage instructions, and
tells you what it did. Then start a new session so the memory tools load.
Using several agents? Paste the same prompt in each one, whenever you want. If IHMT is already installed — say you have used it with Claude for months and now want it in Codex — the agent finds that installation, updates it if it safely can, and connects to the same memory, so it knows what you told the others from day one.
It needs an agent that can run terminal commands or edit files; chat-only assistants in a browser cannot install anything.
Manual install
Requirements: Python 3.10+, git, and your agent's CLI.
Claude Code
The server name must come before -e. Then append
templates/memory-instructions.md to ~/.claude/CLAUDE.md.
Codex — codex mcp add ihmt-memory --env IHMT_HOME="$HOME/.ihmt" -- "$PWD/.venv/bin/python" "$PWD/mcp_server.py",
then add default_tools_approval_mode = "approve" to the [mcp_servers.ihmt-memory] table in
~/.codex/config.toml (above its env table) and append the template to ~/.codex/AGENTS.md.
Details.
opencode — add an "ihmt-memory" entry ("type": "local", "command": [<python>, <mcp_server.py>],
"environment": {"IHMT_HOME": <memory folder>}) to the "mcp" object of
~/.config/opencode/opencode.json, and append the template to ~/.config/opencode/AGENTS.md.
Details.
Windows, the project scope, the graphical setup and troubleshooting are all in the guide.
Install from PyPI (uvx)
No clone and no venv: uv downloads and runs the
ihmt-memory package. The memory goes to ~/.ihmt; set
IHMT_HOME to use another folder (for example, a memory you already have).
Claude Code
Codex — codex mcp add ihmt-memory -- uvx ihmt-memory, add
default_tools_approval_mode = "approve" to the [mcp_servers.ihmt-memory] table in
~/.codex/config.toml, and run uvx ihmt-memory --instructions >> ~/.codex/AGENTS.md.
opencode — add an "ihmt-memory" entry ("type": "local", "command": ["uvx", "ihmt-memory"]) to
the "mcp" object of ~/.config/opencode/opencode.json, and run
uvx ihmt-memory --instructions >> ~/.config/opencode/AGENTS.md.
The last step matters with any install: the instructions are what make the agent search before
answering and save corrections. pipx install ihmt-memory works too, with ihmt-memory in place of
uvx ihmt-memory.
New here? Read GUIDE.md — everyday use, step by step, with real outputs. The rest
of this README is the technical reference.
How it works
A universal, domain-agnostic long-term memory for LLMs, stored as a recursive tree of plain files on the local disk. No vector database, no server, no third-party dependencies — Python 3.10+ and the standard library.
Instead of embedding everything into one flat index and scanning it, IHMT organizes knowledge into a
tree: raw text leaves at the bottom, recursive JSON summaries above them, and a single root.json
trunk at the top. A query walks that tree — root → branch → branch → leaf — so the number of files
opened grows with the depth of the tree (≈ beam × log_B(n)), not with the amount stored.
Quick start
Then use it on your own material:
As a library:
Graphical interface
Still zero dependencies — the server is http.server from the standard library, it listens only on
the loopback interface, and every /api/* call needs the random token carried in the URL it opens.
Four screens: Set up (pick the memory folder with the system dialog, create the store, choose between per-project and global registration, preview the exact command or JSON before anything is written), Explore (collapsible tree down to the stored text, with supersession notices), Diagnose (a search that reports confidence, files opened vs. total, and the descent path), and Timeline (active vs. historical values and the detected contradictions). The interface is bilingual (ES/EN) and read-only over the memory: it never deletes or edits a leaf.
Use it from Claude Code (MCP)
mcp_server.py exposes the tree to Claude Code as nine tools in three families: long-term memory,
project indexes and session scratch memory. The core stays dependency-free; the
SDK is an optional extra:
For a single project, copy .mcp.json.example to that project's .mcp.json and fill in the absolute
paths; Claude Code asks you to approve it on the next session there (claude mcp list shows it as
Pending approval until then):
or in one command:
IHMT_HOME selects the store ($IHMT_HOME/ihmt_memory), created on first use. Point every project at
one shared directory for a single cross-project memory, or give each project its own.
Saving tokens inside a session
Long-term memory saves tokens between sessions. The project tools save them within one, where the
cost is reading the same files again and again. ProjectIndex (ihmt/project_index.py) keeps a
private store per project under $IHMT_PROJECTS_DIR (default $IHMT_HOME/ihmt_projects):
- one leaf per symbol —
code_chunk_mode="symbol", so a lookup returns a method, not a file; - checksum sync on every call — size and mtime first, SHA-256 only for what moved; changed files are re-ingested, removed ones deleted, and the branches rebuilt. Code is never served stale;
- path-ordered branches — each file is stamped with its rank in path order, so every branch covers neighbouring files and its summary stays meaningful for the descent;
- code-aware ranking — the navigator filters by
scope/path_prefixfrom the catalog, prefers the file a query names, demotes tests unless asked and demotes import lines.
Measured on a 55-file Spring Boot project (8 typical questions): reading the files that hold the
answers costs 3,613 tokens; find_code returns the exact method for all 8 in 1,071. The map of the
project costs 660 tokens against 13,157 to read it whole.
Those savings are against an agent that reads whole files. In an A/B test with 22 real headless
Claude Code sessions, Claude preferred batched grep/sed -n and never called the project tools on
its own; forcing them made sessions 42–71 % more expensive. Keeping the server enabled costs about
460 tokens per conversation, since Claude Code loads MCP tools on demand. IHMT's main value is memory
between sessions; treat the project tools as optional, and do not mandate them in CLAUDE.md.
The server transparently supports MCP SDK 2.x (MCPServer), 1.x (FastMCP) and the standalone
fastmcp package.
The usage instructions in your ~/.claude/CLAUDE.md (template) tell Claude Code when to reach for each tool: search before answering anything that
depends on earlier sessions, save durable facts with their date, never guess on AMBIGUOUS, always
relay OUTDATED, and never store secrets.
Storage layout
Everything lives in one relocatable directory:
root.json lives inside ihmt_memory/ so the store is self-contained: copy the directory and the
memory travels with it.
A leaf is a normal text file that describes itself, so it stays meaningful even if the catalog is lost:
A branch node embeds each child's title, excerpt and keywords. That is the detail that makes the descent cheap: a branch can be ranked without opening any of its children.
The five components
1. UniversalIngestor — detect, split, enrich, store
DomainDetector classifies each document by type (CODE, NARRATIVE, CLINICAL, PERSONAL,
PROCESS, GENERIC) and domain (software.java, medicine.clinical, process.cooking,
personal, …) from its extension plus lexical signatures in English and Spanish. Both can be
overridden with --domain / --type.
The type selects the splitter, and every splitter obeys one invariant:
A logical block is never cut. If a single block exceeds
max_tokensit is stored whole and flaggedoversized. Correctness of the block beats hitting the token budget.
- Code (
chunkers/code.py) — Python via the stdlibast; Java/JS/TS/C/C++/C#/Go/Rust/Kotlin/ Swift/PHP viaBraceScanner, a character-level scanner that tracks brace depth while skipping comments, string literals, char literals, template literals and preprocessor lines. Imports coalesce; each class/function is a block; an oversized class splits per member, and the enclosing class header travels in the leaf'sextra.contextrather than being spliced into the text. Concatenating a file's leaves reproduces the file byte for byte — asserted in the tests. - Narrative — paragraph-atomic, with
***,---,Chapter/Capítuloas hard boundaries. Only a paragraph larger thanmax_tokensis split, and then at sentence boundaries. - Temporal (journals, chats, clinical records) — one dated entry is atomic and a change of date is a hard boundary, so a leaf never mixes two encounters. The date found in the text becomes the leaf's timestamp, which is what makes recency weighting mean when something was true rather than when it was ingested.
- Process (recipes, protocols, runbooks) — steps and ingredient lists stay attached to their heading.
Leaf ids are derived from (domain, source, position, content), so re-ingesting an unchanged
document rewrites the same leaves instead of duplicating them.
2. RecursiveSummarizer — the Summarization Event
It watches layer 0. When branch_factor leaves of one domain have no parent, it fires a
Summarization Event: they are condensed into a layer-1 node, the node is written, and only then
are the children stamped with their parent_id — so an interrupted run re-processes a group instead
of orphaning it. The same rule applies from layer 1 to layer 2, and so on, until the tree converges;
then root.json is rewritten.
consolidate() is idempotent. flush() (--force) also promotes partial groups so the tree closes
completely. Anything still unconsolidated is referenced directly by the trunk, so nothing in the
store is ever unreachable from the root.
3. SemanticNavigator — descent and the Interactive Clue Loop
Ranking uses Okapi BM25 over each candidate's title, keywords, tags and excerpt, with field weights
and document frequencies computed across the siblings of the current level — exactly the
discrimination the descent needs, at no extra I/O cost. The walk keeps a beam of beam_width
branches per level.
Confidence blends two independent signals:
Coverage asks "does this leaf actually contain what was asked?"; margin asks "is it distinguishable from its rivals?". A common first name scores high on the first and near zero on the second — which is precisely when the system must not guess:
The clue triggers a joint cross-reference: candidates matching both term groups are boosted
(×1.6), candidates matching only one are demoted (×0.7). The loop runs up to max_clue_rounds
times, stops early if the user declines, and never silently converts an ambiguous query into a
confident answer.
clue_provider is any callable, so the loop works for a human at a terminal (input) or for an
agent that lets the LLM supply its own follow-up.
4. ConflictResolver — recency weighting and the timeline
Facts are (subject, attribute, value, timestamp, source_leaf), recorded programmatically via
record_fact() or extracted at ingest time by pattern rules (vivo en X / I live in X,
mi stack es Y, trabajo en Z, Diagnóstico:, Tratamiento:, Medicación: …; extend with
add_pattern).
Each (subject, attribute) keeps a dated timeline. The newest value is ACTIVE; every earlier one
becomes HISTORICAL with superseded_by and a valid_from/valid_to interval. Nothing is
deleted, so both questions stay answerable:
Repeating a value at a later date is a confirmation, not a contradiction. A genuine change produces a
transparent notice — "On 2024-03-11 you said user location = 'Madrid', but on 2026-02-03 you updated to
'Valencia'." — and the superseded leaf is annotated, so retrieving outdated material always arrives
with its correction attached (SearchResult.notices).
A leaf itself stays ACTIVE: what it says was true on its own date, and that remains the right
answer to a historical question. What changes is that it can no longer be read as current.
5. Summarization backends
HeuristicSummarizer(default) — stdlib extractive summarization: TF term ranking with EN/ES stop words plus representative-sentence selection. Offline, deterministic, which is what lets the test suite assert on tree shape.AnthropicSummarizer(optional) — used only when selected and theanthropicpackage andANTHROPIC_API_KEYare both present. Every failure path (missing SDK, missing key, network error, unparseable reply) falls back to the heuristic backend, so a consolidation is never lost because a model was unreachable.
Any other model or local runtime plugs in by implementing the same protocol and passing it as
IHMT(..., backend=MyBackend()).
CLI reference
--path selects the store directory and --json emits machine-readable output; both work before or
after the subcommand.
Configuration
ihmt_memory/ihmt.config.json:
Small corpora deserve a small branch factor — the demo uses branch_factor=4, target_tokens=400 so a
handful of documents still builds a genuine multi-layer tree.
Tests
187 tests — 25 of them for the MCP server, skipped without the SDK — covering: byte-exact reconstruction and boundary-depth invariants for Java and Python, scene/date/section atomicity, oversized-block handling, leaf header round-trips, catalog recovery, summarization thresholds, upward propagation, idempotence, full reachability from the root, descent cost bounds, the clue loop, recency weighting, historical preservation, the project indexes, the MCP tools, the graphical interface and the CLI.
Design notes and limits
- Retrieval is a descent, not a scan. That is the whole point, and it means a branch pruned at the trunk is not revisited. Domain-level pruning only happens when a query has actual signal at the trunk; if it has none, every domain stays in play and the beam applies one level down. The clue loop is the recovery mechanism when the descent goes wide.
- Lexical, not semantic. Matching is BM25 over accent-folded, CamelCase-split tokens: it works in
any language and needs no model, but it will not match a synonym. Plugging an embedding re-ranker
into
BM25Rankeris the natural upgrade; the tree structure does not change. - Token counts are estimated at ~4 characters per token. Budgets only need to be consistent, not exact.
- Fact extraction is pattern-based. The bundled rules cover common English/Spanish phrasings and
clinical headers;
record_fact()is the reliable path, andadd_pattern()extends the rules. - Single-writer. Writes are atomic (
tmp+os.replace) and catalog rebuilds take a lock file, but the store assumes one writer at a time. initialize(force=True)discards derived state only — branches, catalog, timeline — and detaches the surviving leaves so the next consolidation rebuilds the hierarchy. Leaf content is never deleted.
Layout
License
MIT © 2026 Gonzalo Román Márquez (gonzaroman)
來源:README.md,提交 3daf512
工具
0版本歷史
2- v1.2.1最新Oct 15, 2026
- v1.2.0Oct 13, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分
其他 Memory 整合

Memory.fit
fit.memory官方發布者
託管式 Memory.fit 伺服器,讓 AI 讀取你的訓練、睡眠、恢復與飲食資料,並寫回每週計畫、每日目標和飲食計畫。
pg.ddx.io: the PostgreSQL community's memory
io.ddx.pg官方發布者
pg.ddx.io: the PostgreSQL community's memory 的託管 MCP 服務,由 pg.ddx.io 發布;無需登入;Streamable HTTP;29 個工具。
var.gg Naming Memory
gg.var官方發布者
遠端 MCP 伺服器,可依領域概念推薦並檢索韓、日、中、越、英多語言的程式識別字名稱,並提供 ERD 結構查詢。

Counterparts
ai.counterparts
為 Claude Code 與 Claude Desktop 提供的本地優先長期記憶:助理自行寫下關於你與專案的筆記,並在之後的對話中回想起來。

LAHZE - Persian AI Memory Platform
由 GitHub 帳號 pedramgholizadeh 發布
以波斯語為先的地理記憶平臺:發現地點,起草併發布僅限波斯語的記憶。AI 翻譯