mcpField
V
vault-index

vault-index

本地服务
github.com/GitGudatCodeing记忆与知识11 天前更新

关于 vault-index

vault-index 是用于 Markdown 笔记和代码的本地混合搜索 MCP 服务,面向需要在本机检索长期资料的用户。它结合关键词与向量检索,并通过重排改善结果相关性。

主要功能

  1. 01结合 FTS5 关键词与向量搜索
  2. 02交叉编码器重排搜索结果
  3. 03按标题分块并返回路径
  4. 04增量索引 Markdown 来源
  5. 05支持文件夹排除规则

适用场景

  1. 01搜索笔记中的改写问题答案
  2. 02在本地检索项目文档与决策记录
  3. 03为 Claude Code 提供长期笔记检索
  4. 04通过命令行索引并搜索资料

MCP 相关

作为 MCP 服务,它向客户端提供 index_paths、search_notes、get_note、list_sources 和 remove_source 工具。可通过 stdio 连接,并支持注册笔记来源及搜索内容。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"gitgudatcodeing-vault-index": {
"command": "uvx",
"args": [
"vault-index"
],
"env": {
"VAULT_INDEX_DB": "<VAULT_INDEX_DB>",
"VAULT_RERANK": "<VAULT_RERANK>",
"VAULT_MODEL_CACHE": "<VAULT_MODEL_CACHE>"
}
}
}
}
启动命令uvx vault-index
需要配置的环境变量
VAULT_INDEX_DBPath to the SQLite index file (default ~/.mcp-memory/vault-index.db)
VAULT_RERANKSet to 0 to turn off the cross-encoder rerank of the top 10 results
VAULT_MODEL_CACHEEmbedding model cache folder (default ~/.mcp-memory/models)

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

安装包
pypivault-index0.4.2

工具

5

收录的工具列表 · 更新于 1 天前

参数类型必填说明
pathsany否
reindexboolean否

详细介绍

claude-second-brain

CI Python PyPI License

为 Claude Code 提供本地、私密的长期记忆。Markdown 笔记始终是记录的依据。Claude 通过混合关键词 + 向量索引搜索笔记,将决策和经验教训以纯文本文件的形式写回;钩子则确保索引、知识图谱和长会话都正常运行。

所有操作都在你的机器上运行:一个 SQLite 文件、两个轻量级 CPU 模型,无需云服务。

演示:session-start 检查、混合搜索、/recall 基于示例知识库和来源回答,以及评估

使用示例知识库,对 v0.1.0 全新克隆进行真实输出的终端回放(当时的评估包含 32 个问题);仅添加了打字动画。

为什么需要它

Claude Code 会在会话之间忘记所有内容。常见的解决方法是使用庞大的 CLAUDE.md(每轮对话都会产生高昂开销),或使用无人能读懂或修复的向量存储。本项目采用了不同的思路:

  • 文件才是真相。 笔记、决策记录和经验教训都以 Markdown 格式保存,你可以阅读、编辑和版本管理。索引和知识图谱随时都能从这些文件重建。
  • 先搜索,再猜测。 Claude 会先搜索知识库,再回答有关过往工作的内容,并可使用真正能找到改述答案的工具。
  • 以测量为准,而非凭感觉。 每项搜索变更都会根据黄金测试集评分,只有胜过基线才会保留。失败的实验也有记录。
  • 自我检查。 会话开始时会验证各项不变量,确保每条流水线仍能到达其使用方,因此问题会在当天显现,而不会悄无声息地发生。

工作原理

flowchart LR
    subgraph files["Markdown files: the record"]
        notes["notes/"]
        adr["docs/adr/"]
        lessons["docs/lessons.md"]
        handoffs["docs/handoffs/"]
    end

    cc["Claude Code"]
    vi["vault-index MCP server<br/>mcp/server.py"]
    db[("vault-index.db<br/>FTS5 + sqlite-vec")]
    mem["memory MCP server"]
    kg[("memory.jsonl<br/>entities and relations")]

    cc -- "Write / Edit" --> files
    cc -- "PostToolUse hook<br/>reindex_hook.py" --> db
    cc -- "search_notes, get_note" --> vi
    vi --> db
    files -- "index_paths" --> db
    cc -- "search_nodes" --> mem
    mem --> kg
    kg -. "each fact names its source file" .-> files
钩子脚本功能
SessionStartscripts/invariants.py --hook10 项检查:MCP 服务可启动、知识图谱来源存在、索引为最新、钩子已连接、黄金标签有效、经验教训格式正确、上下文预算充足。
PostToolUse (Write, Edit)mcp/reindex_hook.py如果已编辑文件位于已注册的来源目录下,则重新为其建立索引。不会阻塞操作。
UserPromptSubmitscripts/context_guard.py从记录稿中读取实际上下文大小。达到 450k 个 token 前保持静默(.claude/handoff.json);之后要求使用 /handoff:创建一条笔记和一张卡片,以便开始新会话。
PreCompactscripts/precompact_snapshot.py在压缩前,将近期请求和修改过的文件保存到 docs/handoffs/auto/,作为备用记录。
搜索
flowchart LR
    q["query"] --> sw["drop stopwords"] --> fts["FTS5 bm25<br/>top 4 x limit"]
    q --> emb["embed with<br/>bge-small-en-v1.5"] --> vec["sqlite-vec kNN<br/>top 4 x limit"]
    fts --> rrf["reciprocal rank fusion<br/>k = 60, keyword weight 0.1"]
    vec --> rrf
    rrf --> rr["cross-encoder rerank<br/>top 10, MiniLM-L6"]
    rr --> out["top chunks with<br/>file path and heading path"]
  • Markdown 按标题分块(每块最多约 1,200 个字符),因此每条命中结果都会附带类似 Recipe box data model > Units 的路径。
  • 索引采用增量更新:根据修改时间和内容哈希跳过未更改的文件;删除的文件会在下次同步时移除。
  • 关键词排名的权重是向量排名的十分之一;它用于打破平局并提升精确词项(ID、工具名称)的排名,不会压过语义匹配。
  • 随后,一个小型交叉编码器(ms-marco-MiniLM-L-6-v2,80 MB)会同时读取查询和文本块,将排名最高的 10 条结果重新排序。在 CPU 上每次搜索约增加 200 ms;设置 VAULT_RERANK=0 可将其关闭。
  • 每个文件夹中的 .indexignore 都可将工具代码排除在搜索结果之外。

MCP 工具:index_paths、search_notes、get_note、list_sources、remove_source。

命令

命令功能
/recall <topic>同时搜索笔记、经验教训和图谱,并通过可点击的来源作答。只读。
/adr <title>将决策记录写入 docs/adr/,并在图谱中添加链接。
/learn <what happened>将经验教训记录为可测试的指令(scripts/learn.py):经验、原因以及检测方法。应替代或退役,切勿删除。
/ingest <path>为文件或文件夹建立索引,并将其中持久的实体添加到图谱中。
/handoff [topic]编写交接笔记,并据此开始新的会话。

快速入门

需要 uv(会获取 Python 3.10 到 3.13)、用于记忆服务的 Node.js,以及 Claude Code。

git clone https://github.com/GitGudatCodeing/claude-second-brain.git
cd claude-second-brain
uv run --project mcp python scripts/setup.py

setup.py 会写入 .mcp.json(除非传入 --memory-file,否则记忆图谱位于 ~/.mcp-memory/memory.jsonl)、为文件夹建立索引并运行不变量检查。然后在该文件夹中启动 claude,批准项目 MCP 服务和钩子,再试试 /recall garden sensor battery life。随时可以运行 python scripts/invariants.py 检查配置是否正确。

你自己的笔记放在 notes/ 中。不再需要评估时,删除 example-vault/,并用关于你自己笔记的问题更新 eval/golden.jsonl。

在 Windows 上,Claude Code 通过 Git Bash 运行钩子;钩子命令已经使用正斜杠。

仅使用搜索服务

vault-index 已发布在 PyPI 和 MCP registry 中。若要在任意笔记文件夹上使用混合搜索,而不使用此仓库的其他部分:

claude mcp add vault-index -- uvx --python 3.12 vault-index

然后让 Claude 为文件夹建立索引(例如:“index_paths ~/notes”),并使用 search_notes 搜索。

也可以在终端中使用。先在那里为大型知识库建立索引,可以显示进度,并缩短 Claude 的首次工具调用:

uvx --python 3.12 vault-index index ~/notes        # no paths re-syncs every source
uvx --python 3.12 vault-index search "your question" -n 5
uvx --python 3.12 vault-index sources
uvx --python 3.12 vault-index --help

不带命令时,它会通过 stdio 提供 MCP 服务。索引位于 ~/.mcp-memory/vault-index.db。要更改其位置,请在 shell 环境中设置 VAULT_INDEX_DB,而不是只在 MCP 配置中设置,这样服务、重新索引钩子和不变量检查都会使用同一个文件。--python 3.12 可避免 uvx 使用嵌入运行时尚不支持的较新 Python 版本。

检索评估

example-vault/ 是某个虚构人物的笔记、决策和经验教训。eval/golden.jsonl 中有 44 个关于这些内容以及此仓库自身文档的问题;这些问题刻意使用与笔记不同的措辞,因此仅靠关键词重合通常无法找到大多数答案。最后 12 个问题是较难的释义,与答案几乎没有共同词汇。(不要将黄金问题放进这份 README 等已建立索引的文件中,否则它们会与真实答案竞争。)

VAULT_INDEX_DB=/tmp/csb-eval.db uv run --project mcp python eval/run_eval.py --modes all -v
模式NDCG@5MRRRecall@5
混合搜索 + 重排序(search_notes 提供的模式)0.7470.7970.780
混合搜索,仅融合(无重排序)0.6860.7240.758
仅关键词(FTS5)0.4910.5440.576
仅向量0.6970.7290.758
朴素 grep,无索引(基线)0.3050.3410.375

grep 行会根据每个块包含的查询词数量进行排序,大致相当于对每个词使用 rg 搜索。

在没有重排序器时,样本知识库中的仅向量搜索略胜融合搜索(较难的释义没有可供关键词匹配的内容);重排序器则让混合搜索重新领先。在作者的私人知识库(41 个问题)中,排序也相同:混合搜索 + 重排序为 0.550,仅融合为 0.487,向量为 0.473,关键词为 0.433,grep 为 0.327。

与 basic-memory 的比较

basic-memory 是一款热门的 Markdown 记忆 MCP 服务,拥有自己的混合搜索功能。eval/compare_basic_memory.py 会在同一批 Markdown 文件的副本上运行它(v0.24.1,使用相同的 bge-small 模型),并针对相同的 44 个问题对两者进行评分。basic-memory 返回整篇笔记,因此这里两者都按文件评分(将 vault-index 的分块合并到所属文件):

系统(文件级别)NDCG@5MRRRecall@5
vault-index 混合搜索 + 重排0.8290.8580.886
basic-memory,默认搜索0.6190.6110.750
basic-memory,仅向量搜索0.7080.7360.814

basic-memory 的功能远不止搜索(它可以写入笔记、据此构建图谱、提供云同步);这里仅比较检索效果。其默认搜索在不同运行之间的波动约为 0.005。CI 中不会运行它。

如果任何混合搜索指标比 eval/baseline.json 低超过 0.03,CI 就会失败。在 Ubuntu 和 Windows 上,分数完全相同。

哪些改动有效,哪些无效

每项改动都单独对照已保存的基线进行测试,大多数测试使用作者的私人知识库:

改动对 NDCG@5 的影响是否保留
对排名前 10 的结果进行交叉编码器重排(MiniLM-L6,80 MB)样本 +0.061,私人知识库 +0.063是:每次搜索约 200 ms
更大的重排模型(MiniLM-L12、Jina v1 tiny/turbo、bge-reranker-base)结果不一:部分模型在样本集上表现更差否
融合中的关键词权重设为 0.1(原为 1.0)私人知识库 +0.037,样本 +0.066是
排除工具代码(.indexignore)+0.063是
从 FTS 查询中去除停用词+0.018是
使用 all-MiniLM-L6-v2 替代 bge-small-0.024否
提高 bm25 中标题的权重(x2 至 x10)-0.015 至 -0.036否
使用 bge-base + 查询前缀(768 维)+0.030,约提升一道题否:模型体积是 3 倍,收益却只有噪声级别

使用相同权重时,在样本知识库上纯向量搜索优于混合搜索,而在私人知识库上混合搜索更胜一筹(行话需要关键词)。在两组数据上按 RRF k 值扫描关键词权重后,找到了一组设置,在两组数据上都表现更好;纯向量搜索在私人知识库上仍然较差,因此保留了低权重的关键词搜索。详情见 docs/adr/。

仓库结构

mcp/            vault-index MCP server and re-index hook
scripts/        invariants, learn.py, context guard, pre-compact snapshot
eval/           golden set, baseline, run_eval.py, compare_basic_memory.py
tests/          pytest suite (fake embedder, no model download)
example-vault/  fictional sample notes for the eval
docs/adr/       decision records for this system
docs/lessons.md lessons learned while building it
.claude/        slash commands, hook settings, handoff thresholds

开发

uv run --project mcp --with pytest pytest tests -q
uvx ruff check .

测试使用虚假的词袋嵌入器,因此运行时间约为 1 秒。每次推送时,CI 都会在 Ubuntu 和 Windows 上运行 lint、测试、检索评估和不变量检查。请参阅 CONTRIBUTING.md。

状态

项目尚处早期阶段,且观点鲜明:最初是为一个人的日常使用而构建,之后才泛化。已在 Windows 11 上使用 Claude 桌面应用进行日常测试;CI 覆盖 Ubuntu 和 Windows。可移植的钩子命令($CLAUDE_PROJECT_DIR)已通过 CI 中的不变量检查,但尚未在 macOS 或 Linux 的实际会话中运行。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

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

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