Skip to main content
Glama
BairuiZhang

agent-bm25-knowledge-mcp

by BairuiZhang
README.md
# Agent BM25 Knowledge MCP

一个面向 Claude Code、Kiro CLI、Codex 等 Agent 的本地知识检索工具。它模仿 Kiro CLI `Fast` Knowledge 的公开行为:对显式配置的文件或目录递归扫描、分块、构建持久化 BM25 索引,并通过 MCP 向 Agent 提供可解释检索。

## 它解决什么问题

普通 Agent 的 `grep` 很适合已知代码符号,但不适合在大量产品文档、PageIndex 节点或领域资料中进行排序召回。本工具提供:

- BM25 倒排索引,启动后无需重新扫描所有文件;
- 中文词语与字符二元组分词;
- camelCase、snake_case、路径和代码标识符分词;
- 配置式同义词;
- 原始 Query 与 Agent 扩展 Query 分路检索;
- RRF 或归一化加权分数融合;
- PageIndex JSON 的 `node_id`、`title`、`keywords`、`path` 保留;
- 命中词、分路排名、文件和行号解释;
- 只访问配置文件中授权的知识源。

## 快速开始

要求 Node.js 20 或更高版本。

```bash
cd /Users/zhangbairui/Desktop/agent-bm25-knowledge-mcp
npm install
npm run build
npm run index -- --config knowledge.config.example.json
npm run search -- \
  --config knowledge.config.example.json \
  --query "研发投入下降是不是裁员造成的" \
  --variant "研究开发支出下降原因 项目结项"
```

运行验证:

```bash
npm test
npm run smoke:mcp
```

## 指定检索内容

复制并修改 `knowledge.config.example.json`:

```json
{
  "indexDir": ".knowledge-index",
  "synonyms": [
    {
      "canonical": "研发投入",
      "aliases": ["研发费用", "研究开发支出", "R&D expense"],
      "weight": 0.75
    }
  ],
  "sources": [
    {
      "name": "product-docs",
      "path": "/absolute/path/to/approved/docs",
      "description": "产品规范和设计文档",
      "include": ["**/*.md", "**/*.json"],
      "exclude": ["**/.git/**", "**/node_modules/**"],
      "parser": "auto",
      "chunkSize": 1600,
      "chunkOverlap": 240,
      "maxFileBytes": 2000000,
      "enabled": true
    }
  ]
}
```

`parser` 支持:

- `text`:所有匹配文件按普通文本分块;
- `pageindex-json`:强制按 PageIndex 风格节点解析;
- `auto`:JSON 中识别到 PageIndex 节点时保留节点元数据,否则按文本处理。

修改知识文件后重新构建:

```bash
npm run index -- --config /path/to/knowledge.config.json
```

Agent 也可以调用 `knowledge_reindex`,但该工具只会重建配置中已经授权的源,不能传入新路径。

## MCP 工具

### `knowledge_list_sources`

列出当前索引时间、授权知识源、文件数、chunk 数和跳过文件。

### `knowledge_search`

主要参数:

```json
{
  "query": "用户的原始问题,保留实体、数字和否定词",
  "query_variants": [
    {
      "text": "正式术语 同义词 缩写",
      "weight": 0.7,
      "purpose": "formal domain wording"
    }
  ],
  "source_names": ["product-docs"],
  "fusion": "rrf",
  "limit": 10,
  "response_format": "json"
}
```

不要把所有扩展词拼成一条查询。原始 Query 与扩展 Query 会独立排名后融合,从而保护型号、数字、否定词和用户原话。

### `knowledge_get_chunk`

读取 `knowledge_search` 返回的一个完整 chunk。参数只能是索引生成的 `chunk_id`,不能传任意文件路径。

### `knowledge_reindex`

重新扫描所有启用的配置源并原子替换索引。该工具会写索引文件,因此默认不建议在 Kiro 中自动批准。

## 接入 Kiro CLI

项目级 MCP 配置位置为 `.kiro/settings/mcp.json`。可直接使用本仓库的配置模板:

```bash
mkdir -p /path/to/your-project/.kiro/settings
cp configs/kiro-mcp.json /path/to/your-project/.kiro/settings/mcp.json
```

也可以执行:

```bash
kiro-cli mcp add \
  --name agent-knowledge \
  --command "node /Users/zhangbairui/Desktop/agent-bm25-knowledge-mcp/dist/index.js" \
  --scope workspace
```

然后确保 MCP 进程环境包含:

```text
KNOWLEDGE_CONFIG=/absolute/path/to/knowledge.config.json
```

Kiro 会监听 `mcp.json` 并在会话空闲边界热更新。进入会话后使用 `/mcp` 检查四个工具是否加载。

## 接入 Claude Code

将 `configs/claude-mcp.json` 复制成项目根目录的 `.mcp.json`,或执行:

```bash
claude mcp add-json agent-knowledge \
  '{"type":"stdio","command":"node","args":["/Users/zhangbairui/Desktop/agent-bm25-knowledge-mcp/dist/index.js"],"env":{"KNOWLEDGE_CONFIG":"/absolute/path/to/knowledge.config.json"}}'
```

## 接入 Codex

把 `configs/codex-config.toml.example` 中的段落加入 Codex `config.toml`,或使用 `codex mcp add` 添加本地 stdio server。

## 推荐 Agent 工作方式

参考 `AGENT_RETRIEVAL_PROMPT.md`。核心循环是:

```text
保留原始 Query
→ 生成少量目的明确的查询变体
→ knowledge_search
→ 查看命中词和 PageIndex 路径
→ knowledge_get_chunk 读取证据
→ 使用结果中发现的文档真实术语再次检索
→ 证据充分后停止
```

## 安全边界

- 知识路径只能在静态配置中指定,Agent 调用时不能增加路径;
- 目录扫描不跟随符号链接,并验证文件真实路径仍位于授权根目录;
- 默认排除 `.git`、`node_modules`、构建目录和虚拟环境;
- 限制文件大小、查询长度、查询变体数和返回字符数;
- stdio 模式只向 stderr 输出日志,避免破坏 MCP JSON-RPC;
- 索引使用临时文件加原子 rename,避免中断时留下半个索引。

## 当前限制与下一步

- 当前是单机 JSON 倒排索引,适合数万到中等规模 chunk;百万级 chunk 应迁移到 SQLite FTS5、Tantivy 或 Lucene/OpenSearch;
- 同义词配置按等价词组处理,非等价的上下位关系更适合由 Agent 作为低权重 `query_variants` 提供;
- PDF、DOCX 等二进制文件需要先转换成文本或 PageIndex JSON;
- 尚未实现 Kiro 的语义 `Best` 路线,可后续加入本地 embedding 并通过 RRF 与 BM25 融合;
- 尚未做文件系统 watcher,源内容变化后通过 CLI 或 `knowledge_reindex` 更新。

## 目录

```text
src/index.ts                MCP stdio server
src/cli.ts                  index/search/inspect CLI
src/services/indexer.ts     文件发现、PageIndex 解析和倒排索引
src/services/search.ts      BM25、多查询和融合
src/services/tokenizer.ts   中文及代码分词
src/tests/                  单元测试
scripts/smoke-mcp.mjs       真实 MCP 客户端烟雾测试
evals/evaluation.xml        10 个只读 Agent 评测问题
RESEARCH.md                 调研结论与设计取舍
```