Skip to main content
Glama
Hilonew

second-brain-mcp

by Hilonew

second-brain-mcp

把本地的 Markdown 笔记库变成可检索、可对话写入的「第二大脑」, 通过 MCP(Model Context Protocol)交给 Claude Code 等 AI 客户端按需调用。

你不再需要每次把笔记全量塞进 prompt——AI 会在需要时自动检索最相关的几个片段。 全程本地运行、本地索引,检索不调用任何外部 API,也不产生额外费用。

适合谁:手上有一堆 Markdown 笔记(Obsidian / Logseq / 纯文件夹都行), 想让 AI 真正「记得」它们,又不想把笔记上传到任何云端服务的人。

特性

  • 增量建索引 — 只重新处理内容变过的文件(md5 判断),大库日常更新秒级完成

  • 零操作的自动同步 — 服务在启动后与每次检索前按需补差,改完笔记直接提问就行, 不需要挂着任何后台进程(陈旧判断只看目录 stat,代价极小)

  • 索引离线建、在线只读 — BM25 倒排索引在维护阶段构建并落盘,服务端不常驻笔记原文, 检索时内存里只有倒排表;索引过期靠「分片数 + 指纹」签名发现,能捕捉「数量没变但内容变了」

  • 混合检索 — BM25 关键词路(中文走 jieba 分词)∥ 语义向量路,RRF 融合 + 余弦阈值过滤,兼顾「字面命中」和「语义相关」

  • 语言自适应 — 中文(jieba 缺失时自动降级为字/双字 bigram)与英文知识库都开箱即用,中英混排也没问题

  • 本地优先 — Embedding 本地跑(默认 bge-small-zh-v1.5,约 100MB、CPU 秒出、离线可用),笔记不出本机

  • 隐私默认 — 不向 Chroma / HuggingFace 发送遥测,离线模式常开

  • 对话反向写入 — AI 可以把新内容追加到指定笔记并立刻重建索引(可写名单可配置,只追加、不删除)

  • 跨平台 — Windows / macOS / Linux,CPU / GPU 双依赖清单

Related MCP server: MCPedia

工作原理

   Markdown 知识库 (kb_dir)
        │                       ▲
        │ ① 检索前自动补差        │ ③ 对话追加写入
        ▼                       │
   mcp_server.py ──MCP (stdio)──► Claude Code / 任意 MCP 客户端
        │
        │ ② 只读检索:BM25 关键词 ∥ 语义向量 → RRF 融合 → 余弦阈值过滤
        ▼
   ┌───────────────────────────────┐
   │ chroma_store   向量索引         │
   │ bm25_index     倒排索引(落盘)  │
   └───────────────────────────────┘
        ▲
        └── 首次建档:python ingest.py(要联网下 embedding 模型)
            可选预建:python watcher.py(仅当索引需要随时保持新鲜)

索引什么时候更新

这是本项目最容易被误解的一点,所以单独说清楚:索引只在被读取的那一刻才有必要是新鲜的。

因此同步发生在读取侧——mcp_server.py 在启动后、以及每次检索前各做一次增量补差:

  1. 遍历目录,比对每个文件的 mtime + size(不读文件内容)

  2. stat 没变 → 直接跳过

  3. stat 变了才读文件算 md5;md5 没变(touch 过、编辑器原子保存)→ 只刷新 stat,不重新 embedding

  4. md5 也变了 → 只重建这一个文件的分片

因为第 1 步只是一次目录遍历(几千个笔记通常是几十毫秒),它可以被频繁调用而感觉不到。 启动那次跑在后台线程里,等你开口提问时通常已经完成。

所以你不需要挂任何后台进程,也不需要记得重跑脚本。 改完笔记,直接提问。

python ingest.py 只在两种情况下需要手动跑:首次建档(要向 HuggingFace 下载模型, 而服务是离线模式运行的,下不了),以及想一次性补齐大量改动时。

快速开始(5 步,约 5 分钟)

Python 3.10+;建议用独立虚拟环境(conda / venv),别污染 base。

# 1. 进入项目,装依赖(有 NVIDIA 显卡想 GPU 加速就换成 requirements-cuda.txt)
cd second-brain-mcp
pip install -r requirements.txt

# 2. 首次运行:自动生成 config.yaml(从 config.example.yaml 复制)
python ingest.py --kb-dir D:/my-notes

#    如果过了几秒提示 kb_dir 为空——先编辑 config.yaml,把 kb_dir 指到你的笔记目录:
#    # config.yaml
#    kb_dir: D:/my-notes
#    再跑一次 python ingest.py 就会建索引(首次自动下载模型约 100MB,之后离线)

# 3. 注册 MCP 服务到 Claude Code
#    Windows:  双击 register_mcp.bat(或用 register_mcp.bat "你的python.exe")
#    macOS/Linux: ./register_mcp.sh
#    上一步 ingest 跑过、模型已下载,注册才能避开离线问题

# 4. 验证注册
claude mcp list          # 应看到 second-brain(或你改的服务名)

# 5. (可选)自测检索,不启动 MCP 直接跑一遍完整流程
python mcp_server.py --search "第二大脑是什么"

然后正常启动 claude 聊天。问到笔记里已有内容时,AI 会自动调用 search_my_knowledge_base;说「帮我记一下……」时会调用 update_knowledge_base 追加写入。

先跑 ingest.py 再注册,顺序很重要:首次建档会下载 embedding 模型, 而 MCP 服务是固定离线模式运行的;不先下载,检索时模型加载会失败。

之后就什么都不用管了。 改完笔记直接提问即可——服务会在检索前自动把改动补进索引, 不用手动重跑脚本,也不用挂后台进程。原因见上面「索引什么时候更新」。

配置参考(config.yaml)

字段

默认

说明

kb_dir

空(必填)

知识库根目录,递归扫 .md,跳过隐藏目录

chroma_dir / hash_file

项目目录下

向量库存储 / 索引状态(每个文件的 md5 + mtime/size)。可删,重跑 ingest 即恢复

bm25_index_file

项目目录下

BM25 倒排索引落盘位置。可删,下次检索自动重建

collection

personal_kb

Chroma 集合名,换库实测时别忘换

embedding.model

BAAI/bge-small-zh-v1.5

换模型请同时删 chroma_dir 重建(维度可能变)

embedding.device

auto

auto / cpu / cuda

chunking.chunk_size / chunk_overlap

400 / 50

切块字数与重叠

ignore.dirs

常见依赖/构建目录

命中目录名即整棵子树跳过,避免依赖包的 README 被当笔记索引

ignore.patterns

*.tmp.md 等

文件名 glob,排掉编辑器的半成品写入。写 [] 关闭该类忽略

sync.on_startup

true

服务启动后在后台线程补一次索引差量,你提问时通常已就绪

sync.check_interval

60

两次陈旧性检查的最小间隔(秒)。设 0 = 每次检索都检查

watch.debounce_seconds

2.0

仅 watcher.py 使用:监听事件合并窗口,窗口内多个事件折叠成一次重建

retrieval.top_k

5

最终返回片段数

retrieval.recall_k

25

每路候选数(RRF 交叉印证用)

retrieval.min_cos_sim

0.4

向量路余弦阈值,宁缺毋滥

retrieval.bm25_k1 / bm25_b / rrf_k

1.5 / 0.75 / 60

BM25 与 RRF 参数,一般不动

mcp.server_name

second-brain

注册进客户端时的服务名

mcp.allowed_write_files

[]

对话可追加写入的文件(相对 kb_dir),留空关闭

可用环境变量临时覆盖(KB_DIR、KB_TOP_K、KB_EMBED_MODEL、KB_BM25_INDEX_FILE、 KB_SYNC_CHECK_INTERVAL、KB_SERVER_NAME 等, 完整清单见 kb_config.py 顶部注释),适合 CI 或临时换库。

日常维护

日常不需要任何维护。 改完笔记直接提问,服务会在检索前自动补差。

需要你出手的只有两种情况:首次建档(跑一次 python ingest.py,要向 HuggingFace 下载模型),以及彻底重建(改了 chunk_size、切块逻辑或 embedding 模型之后):

rm -rf chroma_store .file_hashes.json bm25_index.pkl.gz   # 全是衍生产物,删了不心疼
python ingest.py                                          # 全新重建

为什么改了切块参数必须彻底重建? 索引状态只对「文件内容」敏感,认不出切块 参数变了——不重建的话库里会同时残留新旧两种切法的分片,而且不报错。

什么时候才需要 watcher.py

只有这两个场景:

  • 不聊天的时候索引也必须是新的,例如另一个程序直接读 Chroma 或倒排索引文件

  • 知识库极大,想把同步开销彻底移出检索路径

它是个可选的加速器,不是必需品:

python watcher.py --verbose      # 看每个文件的处理明细
python watcher.py --debounce 5   # 批量同步大量文件时调大合并窗口
python watcher.py --poll         # 网络盘 / 虚拟共享目录上改用轮询

它和自动同步同时开着也不会损坏数据(索引状态是原子替换、分片按确定性 id 覆写), 最多是重复劳动。真想常驻的话,Windows 用任务计划程序,macOS/Linux 写 systemd / launchd 服务。

性能参考

自动同步的成本 ≈ 一次目录遍历 + 每个文件一次 stat。几百到几千个笔记是几十毫秒量级, 基本感觉不到。如果你有十万量级的笔记,把 sync.check_interval 调大(比如 600), 或者干脆改用 watcher.py 预建。

常见问题排查

症状

原因 / 处理

检索报「模型加载失败」

没先跑过 ingest,embedding 模型从未下载;先 python ingest.py 一次

首次 ingest.py 长时间无响应

模型需联网下载但连不上 HuggingFace(WinError 10060)。设镜像重试:Windows set HF_ENDPOINT=https://hf-mirror.com,macOS/Linux export HF_ENDPOINT=https://hf-mirror.com。模型一旦缓存,之后全部离线加载,不再碰网络

MCP 连上但工具不可用

环境变量 HF_HUB_OFFLINE/TRANSFORMERS_OFFLINE 没传,服务启动时联网挂起(一键注册脚本已带)

中文检索疑似失效

依赖缺 jieba:pip install jieba(会有一次性的降级警告)。降级走字/双字 bigram,能用但召回率明显下降

改完笔记搜不到

① 首次建档跑过 python ingest.py 吗?没跑过库里就是空的。② 文件是否被 ignore 规则排除(隐藏目录、node_modules、*.tmp.md)。③ 同步发生在检索时,先问一句触发它再确认

改了笔记,服务端好像没跟上

服务在每次检索前自动补差。刚改完就问可能撞上后台正在同步——再问一次即可。经常遇到可把 sync.check_interval 设为 0(每次检索都检查)

要不要一直挂着后台进程

不用。 同步发生在服务端检索前,不需要常驻进程,也不需要记得重跑脚本

一次保存触发了多次重建(仅 watcher.py)

调大 watch.debounce_seconds。编辑器(尤其带自动保存/原子写入的)一次保存可能产生 create+move+modify 多个事件

watcher.py 启动后一直没动静

正常。kb_dir 不存在时它会等目录出现(不退出);建好后会自动全量对账。也可能改动被忽略规则排掉了——加 --verbose 看明细

bm25_index.pkl.gz 是什么,能删吗

BM25 倒排索引,从知识库派生。能删,下次检索会自动重建(index 缺失时服务端会自己补上)

索引疑似是旧的 / 结果对不上

彻底重建:删掉 chroma_store、.file_hashes.json、bm25_index.pkl.gz 后重跑 ingest

想和已有的同名 MCP 服务并存

改 config.yaml 的 mcp.server_name(如 my-brain)再注册;同名服务无法并存

--search 能通,注册进 claude 后用不了

确认 config.yaml 的 kb_dir 已配且已 ingest 过

改了 register_mcp.bat 后报奇怪的「不是内部或外部命令」

.bat 必须是纯 ASCII:cmd 按控制台代码页解析批处理,UTF-8 中文会让解析器错位、把半行注释当命令执行。改注释也用英文

依赖与 Python 版本

  • 锁定版本见 requirements.txt(CPU 可用)、requirements-cuda.txt(GPU,需 NVIDIA 驱动 ≥ CUDA 12.6)

  • 默认模型 bge-small-zh-v1.5 中英通用、只占 ~100MB 磁盘,embedding 计算纯本地

目录结构

second-brain-mcp/
├── README.md                 # 本文档
├── config.example.yaml       # 配置模板(含注释,可入仓库)
├── config.yaml               # 你的个人配置(.gitignore 已忽略,不入仓库)
│
│   ── 基础层:无副作用,所有入口共用 ──
├── kb_config.py              # 配置加载:默认值 ⇠ config.yaml ⇠ 环境变量
├── kb_scan.py                # 文件发现、忽略规则、安全路径解析(读写两侧共用同一条边界)
├── kb_text.py                # 切块与分词(入库与检索共用同一份实现)
│
│   ── 索引层 ──
├── bm25_index.py             # BM25 倒排索引:构建 / 落盘 / 加载 / 打分 / 过期签名
├── ingest.py                 # 增量引擎:sync_all(全库对账)+ apply_file_changes(按路径)
│
│   ── 入口层 ──
├── mcp_server.py             # MCP 服务:检索前自动补差 + 检索 + 对话写入(含 --search 自测)
├── watcher.py                # 【可选】常驻监听,改动后立刻重建;仅特殊场景才需要
├── register_mcp.bat          # Windows 一键注册
├── register_mcp.sh           # macOS / Linux 一键注册
├── requirements[-cuda].txt   # 依赖清单(CPU / GPU 两版)
├── LICENSE                   # MIT
└── examples/sample_kb/       # 演示知识库,跑通即懂

运行期产物(均已 gitignore):chroma_store/、.file_hashes.json(索引状态:每个文件的 md5 + mtime/size)、bm25_index.pkl.gz。

许可证

MIT —— 随意使用、修改、分发、商用,保留版权声明即可。

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    F
    maintenance
    Turns a local folder of notes and documents into a searchable knowledge base for AI assistants via MCP, enabling semantic search, reading, and adding notes entirely on-device.
    4
    9
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server for a content-first knowledge base, enabling AI agents to search (full-text, semantic, hybrid) and retrieve Markdown documents, list content, and find related docs.
    15 npm
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    Enables local hybrid search over Obsidian and Markdown vaults via MCP, combining vector retrieval, full-text search, reranking, graph navigation, and safe CRUD while keeping data local.
    43
    MIT