Memdex

io.github.ChoYugyeong由 GitHub 账号 ChoYugyeong 发布v0.3.1更新于 Nov 1, 2026

Shared memory for AI coding agents: summaries, symbol map, notes and agent-to-agent messages.

概览

AI 生成的概览

为 AI 编程代理提供共享记忆的本地 MCP 服务器:按内容哈希缓存文件摘要、符号定位、可失效笔记、交接与代理间消息,全部存于一个 SQLite 文件。

可以做什么
  • 获取会话简报:上次交接、坑点、决策、待办、未读消息和当前占用声明
  • 读取按内容哈希缓存的文件摘要、保存新摘要,并定位符号或读取限定片段
  • 按关键词(可选本地向量)检索笔记、交接和摘要
  • 保存、读取、确认、置顶或归档与文件关联的笔记、决策、坑点与待办
  • 与其他代理协作:声明文件占用、发送消息、读取收件箱、留下交接
适用场景
适合在同一台机器上多个编程代理或多个会话共同处理同一仓库、反复重读相同文件并重复踩坑的场景。中大型代码库收益最明显;README 指出约 20 个文件以下的小仓库用手写 AGENTS.md 更划算。
运行要求
以本地 stdio 进程运行,从 PyPI 安装 memdex-mcp(命令为 memdex,可用 pipx 或 uvx)。需要 MEMDEX_HOME(默认 ~/.memdex)下的本地 SQLite 数据库,并为每个代理设置 MEMDEX_AGENT 名称。可选:MEMDEX_PROJECT、配合本地 Ollama 的 MEMDEX_EMBED 以启用语义检索,以及 Kensaku CLI 路径。无需账号或 API 密钥。
安装前请注意
它会写入共享的本地数据库,并可能修改代理配置文件和 git 钩子:memdex connect 会向客户端配置合并 MCP 条目(保留 .bak 备份),hook install 会写入 pre-commit 钩子和 Claude Code 设置。独占声明可阻止其他代理编辑和提交,prune --all 会删除已不存在项目的笔记、消息和声明。数据全部留在本机,不发送给模型或云服务。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Memdex,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

[memdex — a bookmark in the night ledger]

memdex

Shared, token-saving memory for AI coding agents.
One SQLite file. Zero dependencies. Any MCP client. Claude Code, Codex, Cursor and DeepSeek can all remember the same things — and talk to each other.

[Two agents, one checkout: claim, inbox and handoff in memdex]

[CI] [PyPI] [Python 3.9+] [MIT] [Glama MCP score]

Quick start · How it works · Tools · CLI · Configuration · Comparison · FAQ · 한국어


Every new agent session starts from nothing. It re-reads the same 3,000-token files, re-runs the same searches and re-discovers the same pitfalls — and you pay for every token of it. When several agents work on one machine, they can't see what the others learned, or that another one is editing the same file right now.

memdex is a small MCP server that fixes both:

  • A file summary written once stays valid until the file's content changes. Summaries are keyed to the sha256 of the content, not the path. The next session — or the next agent — gets a 100-token summary instead of the 3,000-token file, and is told the moment it goes stale.
  • Notes know when they rot. Decisions, pitfalls and handoffs cite the files they're based on; when those files change, the note is flagged.
  • Agents coordinate. claim what you're editing, post to other agents, read your inbox, leave a handoff for whoever comes next. All worktrees of a repository share one memory.
text
$ memdex file src/store.pysrc/store.py · python · 444 lines · sha 3adeaf13summary (claude@memdex, 2h ago, matches current content):SQLite store. Tables: files, summaries (keyed by sha), symbols, notes, messages, claims, fts.index() skips files whose stat is unchanged. search() fuses FTS5 and embeddings with RRF.outline: class Store:53; method Store.index:101; method Store.search:280; …

That response is 1.5 KB. The file is 22 KB. Nothing was sent to any model to produce it.

Listed in the official MCP Registry as io.github.ChoYugyeong/memdex and on PyPI as memdex-mcp.

On a real 66-file site repo, memdex bench measures 154,105 tokens to read every file versus 3,471 tokens of outlines — 98% smaller, before an agent saves a single summary. Run memdex bench in your own checkout; the token count is chars / 4, an estimate, and the ratio is the point.

Quick start

bash
pipx install memdex-mcp        # PyPI name is memdex-mcp; the command is `memdex`memdex connect --agent claude  # write the MCP entry into the agents on this machine

Claude Code (user scope, every project) — when the claude CLI is on PATH, memdex connect runs this line for you, and prints it when it is not:

bash
claude mcp add memdex --scope user -e MEMDEX_AGENT=claude -- memdex serve

Everything else that keeps a config file — Claude Desktop, Cursor, VS Code (GitHub Copilot), Windsurf, Zed, Cline, Gemini CLI and Codex CLI: memdex connect finds each one that is already installed, merges mcpServers.memdex into its config (servers.memdex with type: stdio for VS Code, context_servers.memdex for Zed, [mcp_servers.memdex] for Codex), keeps the rest of the file byte for byte, and saves a .bak before it writes. A client whose config folder does not exist is reported as not installed and left alone; a config file it cannot parse is left exactly as it was, and a Zed settings file with comments gets the block printed to paste instead of being rewritten (a rewrite would drop the comments). --list shows what is installed and configured without writing, --dry-run shows the writes, --remove takes the entry out.

--serve-check is the honest end of setup: after writing, memdex starts the server from the entry it just wrote and speaks MCP to it (initialize, then tools/list), so a wrong path, a missing interpreter or a database it cannot open is caught now instead of in the agent:

text
+ serve-check      memdex answered: 13 tools, protocol 2024-11-05

Team scope — put the config in the repo so everyone who clones it gets memdex:

bash
memdex connect --project     # .vscode/mcp.json and .mcp.json, written with a bare `memdex` command

A committed config cannot carry this machine's absolute path, so project scope writes command: "memdex" and the teammate's PATH has to find it (pipx install memdex-mcp). With the claude CLI on PATH and --project, the CLI writes .mcp.json itself (claude mcp add memdex --scope project …) and memdex writes only the VS Code file, so one file never has two owners. --no-claude skips the CLI entirely, and --client claude-code runs only that step.

By hand, or for a client memdex does not know about:

json
{ "mcpServers": { "memdex": { "command": "memdex", "args": ["serve"], "env": { "MEMDEX_AGENT": "codex" } } } }

Give each agent its own MEMDEX_AGENT name; its id becomes name@checkout (e.g. claude@myrepo-wt). memdex config --agent <name> prints the snippets above, plus an optional Claude Code SessionStart hook that injects the project brief automatically.

That's it. The server sends its own usage instructions in the MCP initialize response, so agents know the workflow (brief → file_summary before reading → remember → handoff) without extra prompting.

How it works

text
          agents (Claude Code, Codex, Cursor, DeepSeek, …)               │ MCP stdio        │ CLI               ▼                  ▼        ┌──────────────── memdex ────────────────┐        │ project_brief · file_summary · where_is │        │ read_snippet · search · remember        │        │ handoff · post/inbox · claim            │        ├─────────────────────────────────────────┤        │ incremental index   outlines + symbols  │   only files whose size/mtime        │ (stat → sha256)     (regex/ast, no LLM) │   moved are re-read        ├─────────────────────────────────────────┤        │ summaries keyed by sha256               │   valid until content changes        │ notes with file refs → stale flags      │        │ messages, cursors, claims (expiring)    │        ├─────────────────────────────────────────┤        │ SQLite WAL · FTS5 trigram · vectors     │   ~/.memdex/memdex.db        └─────────────────────────────────────────┘
What it doesBorrowed from
Content-hash summary cacheA summary is stored under the file's sha256. Same content in another worktree or branch shares it; changed content gets "no summary yet, here is the old one and the outline".content-addressed storage
Incremental indexgit ls-files (honours .gitignore), then only files whose size or mtime moved are read. An 800-file repo re-indexes in ~0.2 s.Everything's USN-journal approach
Outlines + symbol mapDocstring/comment head plus classes, functions and line numbers for 30+ languages (Python via ast, the rest via per-language regexes — no tree-sitter, no parser install). where_is replaces repeated grepping.Serena / repo maps
Bounded readsread_snippet returns ~256 tokens around a match or a line instead of the whole file.Kensaku
Rot-aware notesremember links a note to files; search and project_brief show "⚠ changed since" when they move. Notes are append-only (supersedes), so concurrent writers never clobber each other.Basic Memory, mem0
Agent coordinationclaim with expiry and overlap warnings; post/inbox with per-agent cursors; handoff as the first thing the next session sees.—
Hybrid searchFTS5 trigram (works for Korean, Japanese and Chinese; 2-character terms fall back to LIKE) fused with optional local embeddings via reciprocal rank fusion.claude-context
Whole-machine contentIf Kensaku is installed, search also returns full-text, OCR and semantic hits from PDFs, Office files and screenshots.Kensaku

Supported outline languages: Python, JavaScript/TypeScript, Vue, Svelte, Go, Rust, Java, Kotlin, Scala, C#, Swift, Dart, C, C++, Ruby, PHP, Lua, GDScript, Elixir, Clojure, Zig, Julia, R, Haskell, Groovy, Protobuf, GraphQL, SQL, shell, PowerShell, Markdown.

How memdex ranks and forgets

Memory that only grows is as useless as no memory: the brief has to pick a few lines out of hundreds. Every note gets an activation, after ACT-R's base-level learning — the sum of t^-0.5 over its uses, so a note read five times last week outranks one written yesterday and never touched. Pitfalls and decisions carry a prior (ignoring them costs more), and --importance raises a note further.

Three things follow from that score:

  • Pinned core (--pin): a small fixed slot at the top of every brief for the handful of facts every session must see — a system prompt written by the agents themselves.
  • Cold tier: below an activation of −3 a note stays stored and searchable but stops spending brief and default-search budget. Nothing is deleted; search still finds it.
  • Reconsolidation: when a note's files or symbols have changed, note prints ⚠ changed since, and note(id, "confirm") re-stamps its refs to the current code. Confirming is also a use, so a note that keeps being re-verified keeps its place.

Staleness is tracked per symbol, not per file: a note about Store.claim goes stale when that function changes, and stays fresh when other functions in the same file change.

When you save a note, memdex compares it against the project's active notes with a 64-bit SimHash over word n-grams. At ≤12 bits of distance it points at the likely duplicate ("similar to #17 — supersede it instead"). The agent decides; memdex never merges memory on its own.

Tools

ToolWhenWhat you get
project_briefStart of sessionLast handoff, pitfalls, decisions, todos, unread messages, who is editing what. Refreshes the index.
file_summaryBefore reading a fileCached summary if the content is unchanged, otherwise the old summary (marked stale) and a free outline.
file_summary_saveAfter reading a fileStores 2–6 lines for everyone, keyed to the content hash.
where_is"Where is X defined?"path:line kind name matches.
read_snippetReading one part of a fileA bounded slice around query or line.
searchBefore exploring from scratchNotes, handoffs and summaries; keyword + semantic; Kensaku hits when available.
remember / noteSomething non-obviousSave / read / archive a note, decision, pitfall or todo, optionally linked to files.
handoffEnd of sessionDone / next / decisions / pitfalls; releases your claims.
post / inboxTalking to other agentsBroadcast or to: "deepseek"; inbox marks read unless peek.
claimBefore editingAnnounce paths for N minutes; warns about other agents' overlapping claims.

The 12 tool schemas cost about 1,000 tokens per request. Responses are short plain text — every byte is a token.

CLI

Everything the tools do is also a command, for shell-only agents, hooks and humans:

bash
memdex brief --agent codex              # start of sessionmemdex file src/store.py                # cached summary + outlinememdex file src/store.py --summary "…"  # save a summarymemdex snippet src/store.py --query "def index"memdex where_is index                   # where a symbol is definedmemdex search "locked"memdex remember pitfall "WAL mode needed" --body "…" --files src/store.pymemdex remember decision "sqlite only" --importance 3 --pinmemdex claim src/store.py --intent "refactor"memdex claim src/store.py --exclusive  # lock: other agents' claims on it are refusedmemdex post "store.py is mine for an hour" --to claudememdex inboxmemdex note 7                            # read itmemdex note 7 --confirm                 # it still holds: re-stamp its refs, clear the ⚠memdex note 7 --pin                     # always at the top of the briefmemdex note 7 --archive                 # read a note, or archive itmemdex handoff "Done X" --next "Y" --pitfalls "Z"memdex index                            # refresh the index for the current projectmemdex export --out notes/              # notes as Markdown, one file eachmemdex export --sync ../shared          # notes + summaries as JSON, for another machinememdex merge ../shared                  # apply what the other machine exported (LWW by updated_at)memdex digest                           # notes that say the same thing, for an agent to consolidatememdex import                           # read AGENTS.md / CLAUDE.md into notes (cold start)memdex statsmemdex bench                            # what the outlines save on this repomemdex prune --dry-run                  # drop index rows of deleted projectsmemdex doctor                           # database, schema, project index, optional integrationsmemdex doctor --serve-check             # …and start the server to verify the MCP handshakememdex connect --agent claude           # write the MCP entry into each installed client's configmemdex hook install                     # git pre-commit: refuse commits on a locked filememdex skills                           # skills this machine's agents sharememdex skills scan                      # (re)read the SKILL.md files, register themmemdex skills show deploy               # print one skill so an agent can follow it

Locks and shared checkouts

Advisory claims are enough between friendly agents, but they do not stop a git commit. Two commands close that gap:

bash
memdex claim src/store.py --exclusive --intent "rewrite the retry loop"memdex hook install

--exclusive makes the claim a lock: another agent's claim on that path is refused, and their commits are refused while it is live. --force records the claim anyway and tells them why. Every claim expires, so a session that dies cannot lock you out forever.

memdex hook install writes .git/hooks/pre-commit (a small sh script that calls memdex hook pre-commit); it only checks the staged files and only reads the local database:

$ git commit -m "retry loop"memdex: commit blocked — these staged files are locked by another agent:  src/store.py  ←  claude@memdex (rewrite the retry loop, 41m left)

An advisory claim still commits — it just prints a note. MEMDEX_ALLOW_LOCK=1 git commit … skips the check for a lock you know is stale, and --force on hook install replaces a hook that memdex did not write.

A commit is late, though: by then the edit already happened. Harnesses that expose a pre-tool hook can refuse the edit itself. Claude Code has PreToolUse:

bash
memdex hook install --claude            # ~/.claude/settings.jsonmemdex hook install --claude --project  # ./.claude/settings.json
json
{"hooks": {"PreToolUse": [{"matcher": "Edit|Write|MultiEdit",  "hooks": [{"type": "command", "command": "memdex hook pre-edit --agent claude"}]}]}}

The hook reads Claude Code's JSON on stdin, turns tool_input.file_path into a project-relative path, and exits 2 (blocked, with stderr shown to the model) when another agent holds an exclusive claim there:

blocked: locked by deepseek@memdex (refactor, 40m left) — post to them or claim --force

Advisory claims print a note and let the edit through, edits outside the checkout are ignored, and MEMDEX_ALLOW_LOCK=1 bypasses the check. The installer merges into an existing settings.json (backing it up as .bak) and never rewrites a file it cannot parse. memdex config prints the same snippet.

A lock is a lease with a number. Every grant carries a fencing token and the sha of the file it was taken against, so a lock can be told apart from the one before it — and an edit computed from a stale read is refused instead of overwriting what moved underneath:

blocked: src/store.py changed since you claimed it (token 7, sha 3adeaf13 → b71f0c92).Re-read the file, then re-stamp the lock:  memdex claim src/store.py --exclusive --refresh

--refresh re-stamps your own claim (new token, current sha); it never takes a new lock and never overrides someone else's.

Measure it on your repo

The first thing anyone asks is "how much does this actually save?". Run it yourself:

bash
cd your-repo && memdex bench
your-repo: 812 files · 3.4 MB indexed in 0.21s (812 changed)reading every file whole: ~871,000 tokensoutline instead:          ~96,120 tokens  (89% smaller; 640 files have symbols)biggest wins (file → outline):  src/generated/api.ts                            144.0 KB →    1.6 KB  ( 99% smaller)  src/store.ts                                     22.2 KB →    1.0 KB  ( 95% smaller)

--json prints the same numbers for scripts. Tokens are estimated as chars / 4; the ratio is the point, not the absolute number — and file_summary gets smaller still once agents save real 2–6 line summaries.

Maintenance

One SQLite file is shared by every project on the machine, so it grows. memdex prune drops index rows for project directories that no longer exist, then VACUUMs:

bash
memdex prune --dry-run     # report onlymemdex prune               # drop stale file index, VACUUMmemdex prune --all         # also notes/messages/claims of missing projects (destructive)

Configuration

VariableDefaultMeaning
MEMDEX_AGENTagent (or the MCP client's name)Who this agent is. Shown on notes, messages and claims.
MEMDEX_HOME~/.memdexWhere memdex.db lives. Nothing is ever written inside a repository.
MEMDEX_PROJECTcurrent directoryProject root, when the server is not started inside it.
MEMDEX_EMBEDoffollama:<model> turns on semantic search, e.g. ollama:bge-m3 (multilingual).
MEMDEX_OLLAMA_URLhttp://localhost:11434Ollama endpoint. Unreachable → silent fallback to keyword search.
MEMDEX_KENSAKUkensaku-cli on PATHPath to Kensaku's CLI, or off.

What is never read: files that look like secrets (.env*, *.pem, *.key, *secret*, *credential*, .npmrc, …), binaries, lockfiles, files over 512 KB and anything git ignores.

Project identity: the git common directory. All worktrees of a repository share notes, messages and claims; each worktree keeps its own file index.

Limits (read this before adopting it)

memdex is honest about what it is not. docs/LIMITS.md takes each item below and records what removing it would take, and which published technique is the cheapest honest answer:

  • The bench baseline is generous. memdex bench compares "read every file whole" with "take the outline"; a real agent greps and reads slices, so the saving is smaller than 98%. memdex stats reports the usage signal instead (summaries served fresh, notes read by another agent, re-confirmed after a change, cold notes), which is the honest number. The win that does hold is that nobody re-discovers the same file, symbol or pitfall twice.
  • Nothing is shared between machines. One SQLite file, local only. There is no team sync, no cloud, no SSO — by design, but it does mean it cannot replace a team knowledge base.
  • Locks are enforced where memdex is asked, not at the file system. claim(exclusive=true) refuses other agents' claims, the pre-edit hook (Claude Code) refuses the edit, and the pre-commit hook refuses the commit — but memdex cannot stop an editor writing bytes through a path it never sees: a session without the hook, or a tool that edits outside the checkout, can still write. Git is still the source of truth.
  • A tiny repo may not need it. Under ~20 files, a hand-written AGENTS.md is cheaper than any tool.
  • The first brief on a huge checkout is partial. Indexing runs at about 0.4 ms per file (20,000 files ≈ 8 s), but a first read of a fresh clone costs far more on Windows, where the antivirus scans each new file. So the brief indexes at most INDEX_BUDGET (2,000) files per call and says how many are left; the next brief continues. memdex index is uncapped, MEMDEX_INDEX_BUDGET=0 lifts the cap, memdex brief never blocks for more than that one batch.
  • It is young. One maintainer. Schema v5 with in-place migrations from every earlier version; a database written by a newer memdex is refused rather than silently corrupted. Expect rough edges.
  • Outlines are regex-level, not semantic. Python uses ast; everything else is per-language regexes. Expect good results on normal code and occasional misses in exotic syntax. where_is still falls back to substring search.

How it compares

memdex is deliberately small. These tools are good at things memdex doesn't try to do, and several of them inspired it.

FocusDependenciesRelationship
memdexCross-session, cross-agent memory: content-hash summaries, rot-aware notes, coordinationnone—
SerenaPrecise symbol navigation and editing through language serversLSP servers per languageUse both: Serena for editing, memdex for memory. memdex's where_is is a regex-level stand-in.
Basic MemoryMarkdown knowledge base with a graph of notesPython packages, Markdown files in your projectmemdex keeps notes out of the repo and ties them to file hashes.
mem0Memory layer for LLM apps, hosted or self-hostedvector DB / LLMmemdex is local-only and aimed at coding agents on one machine.
claude-contextVector search over a codebaseMilvus/Zilliz, embedding APImemdex searches notes and summaries; code search stays keyword + symbols, optionally embeddings via Ollama.
KensakuDesktop search: file names, PDF/Office text, OCR, semantic, for humans and agentsRust desktop appComplementary: memdex bridges to it for whole-machine content search.

FAQ

Does anything leave my machine? No. SQLite file, local subprocesses, optional local Ollama. No telemetry.

Who writes the summaries? The agents, when they read a file that has no fresh summary. The server's instructions ask for 2–6 lines. You can also write them: memdex file path --summary "…".

What if two agents edit the same file? claim warns, it doesn't lock. memdex coordinates; it doesn't replace git.

How much context does it cost? About 1,000 tokens of tool schemas per request, a few hundred for project_brief (hard-capped at 4,000 chars; memdex brief --max-chars 0 shows everything). It pays for itself the first time a file isn't re-read.

Something is broken — what do I run? memdex doctor. It reports the database path, size, schema version, whether it is writable, whether the current project is indexed, which installed agents carry the MCP entry, and which optional integrations are on. Add --serve-check and it starts the server the way an agent would and speaks MCP to it, so "installed but cannot start" shows up as a ✗ instead of a mystery:

text
✓ serve-check     memdex answered: 13 tools, protocol 2024-11-05

Can I see or edit the memory? memdex export writes every note as a Markdown file. The database is plain SQLite. Delete ~/.memdex to start over.

Why not just a vector database? Exact names beat embeddings for code; embeddings help for fuzzy recollection of notes. memdex does keyword + symbols by default and adds vectors only when you turn them on.

Brand

The identity is Ledger Ribbon: a bookmark left in the file, set in Hahmlet, on the night ledger's ink with one amber rule.

Contributing

bash
git clone https://github.com/ChoYugyeong/memdex && cd memdexpip install -e .python -m unittest discover tests     # 165 tests, ~17 s, spawns real processes for the concurrency suite

Ground rules are short: no runtime dependencies, keep tool descriptions terse (they are tokens on every request), and every outline regex captures the symbol name in group 1. See CONTRIBUTING.md.

memdex was built by Claude Code and DeepSeek working on the same checkout — coordinated through memdex itself.

License

MIT

来源:README.md,提交 83228cb

工具

0
SourceWeft 曾在隔离沙箱中以无凭据方式启动该软件包一次,以列出其工具,但未能完成:该软件包类型无法在沙箱中运行。

版本历史

2
  1. v0.3.1最新Nov 1, 2026
  2. v0.2.1Nov 1, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分