knowledge-rag 3.6.1 → 3.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1130 -29
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,61 +1,1162 @@
|
|
|
1
|
-
[](https://www.npmjs.com/package/knowledge-rag)
|
|
2
|
-
|
|
3
1
|
# Knowledge RAG
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
[](https://github.com/lyonzin/knowledge-rag/actions/workflows/ci.yml)
|
|
11
|
+
[](https://github.com/lyonzin/knowledge-rag/actions/workflows/security.yml)
|
|
12
|
+
[](https://glama.ai/mcp/servers/lyonzin/knowledge-rag)
|
|
13
|
+
[](https://pypi.org/project/knowledge-rag/)
|
|
14
|
+
|
|
15
|
+
### Your docs, your machine, zero cloud. Claude Code searches them natively.
|
|
16
|
+
|
|
17
|
+
Drop your PDFs, markdown, code, notebooks — **1800+ files, 39K chunks, indexed in under 3 minutes.**<br/>
|
|
18
|
+
Hybrid search (BM25 + semantic vectors + cross-encoder reranking) through 12 MCP tools.<br/>
|
|
19
|
+
Everything runs locally via ONNX. No Docker, no Ollama, no API keys, no data leaves your machine.
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
pip install knowledge-rag → restart Claude Code → search_knowledge("your query")
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
**12 MCP Tools** | **Hybrid Search + Reranking** | **20 File Formats** | **Optional NVIDIA GPU** | **100% Local**
|
|
28
|
+
|
|
29
|
+
[What's New](#whats-new-in-v360) | [Supported Formats](#supported-formats) | [Installation](#installation) | [Configuration](#configuration) | [API Reference](#api-reference) | [Architecture](#architecture)
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## What's New in v3.6.0
|
|
36
|
+
|
|
37
|
+
### Multi-Language Code Parsing
|
|
38
|
+
|
|
39
|
+
Language-aware extraction for **C**, **C++**, **JavaScript**, **TypeScript**, and **XML** — functions, classes, structs, interfaces, imports, and namespaces are captured as searchable metadata. Total supported formats: **20**.
|
|
40
|
+
|
|
41
|
+
### 5 Ways to Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx -y knowledge-rag # NPM — zero setup, auto-manages Python venv
|
|
45
|
+
pip install knowledge-rag # PyPI — classic Python install
|
|
46
|
+
curl -fsSL .../install.sh | bash # One-line installer (Linux/macOS/Windows)
|
|
47
|
+
docker pull ghcr.io/lyonzin/knowledge-rag # Docker — models pre-downloaded
|
|
48
|
+
git clone ... && pip install -r ... # From source
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
All methods produce the same MCP server. See [Installation](#installation) for full instructions.
|
|
52
|
+
|
|
53
|
+
### Recent Highlights
|
|
54
|
+
|
|
55
|
+
- **v3.6.0** — Multi-language code parsing (C/C++/JS/TS/XML), NPM wrapper, Docker image, automated release pipeline
|
|
56
|
+
- **v3.5.2** — CUDA DLL auto-discovery from pip packages, graceful GPU→CPU fallback, explicit CPU provider (no CUDA noise when `gpu: false`), BASE_DIR resolution fix for editable installs
|
|
57
|
+
- **v3.5.1** — Remove Python `<3.13` upper bound — 3.13 and 3.14 now supported
|
|
58
|
+
- **v3.5.0** — Optional GPU acceleration, supported formats table, full README rewrite
|
|
59
|
+
- **v3.4.3** — MCP stdout save/restore fix (v3.4.2 broke JSON-RPC responses)
|
|
60
|
+
- **v3.4.0** — Persistent model cache, exclude patterns, Jupyter Notebook parser, inotify resilience, MetaTrader support
|
|
61
|
+
|
|
62
|
+
See [Changelog](#changelog) for full history.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Supported Formats
|
|
67
|
+
|
|
68
|
+
| Format | Extension | Parser | Default | Notes |
|
|
69
|
+
|--------|-----------|--------|---------|-------|
|
|
70
|
+
| Markdown | `.md` | Section-aware (splits at `##`) | Yes | Headers preserved as chunk boundaries |
|
|
71
|
+
| Plain Text | `.txt` | Fixed-size chunking | Yes | 1000 chars + 200 overlap |
|
|
72
|
+
| PDF | `.pdf` | PyMuPDF extraction | Yes | Text-based PDFs only (no OCR) |
|
|
73
|
+
| Python | `.py` | Code-aware parser | Yes | Functions/classes as chunks |
|
|
74
|
+
| JSON | `.json` | Structure-aware | Yes | Flattened key-value extraction |
|
|
75
|
+
| CSV | `.csv` | Row-based parser | Yes | Headers + rows as text |
|
|
76
|
+
| Word | `.docx` | python-docx | Yes | Headings preserved as markdown |
|
|
77
|
+
| Excel | `.xlsx` | openpyxl | Yes | Sheet-by-sheet extraction |
|
|
78
|
+
| PowerPoint | `.pptx` | python-pptx | Yes | Slide-by-slide extraction |
|
|
79
|
+
| Jupyter Notebook | `.ipynb` | Cell-aware parser | Yes | Markdown + code cells only, no outputs/base64 |
|
|
80
|
+
| C Source | `.c` | Code-aware parser | Yes | Functions/structs/includes extracted |
|
|
81
|
+
| C/C++ Header | `.h` | Code-aware parser | Yes | Function declarations/structs extracted |
|
|
82
|
+
| C++ Source | `.cpp` | Code-aware parser | Yes | Classes/structs/includes extracted |
|
|
83
|
+
| JavaScript | `.js` | Code-aware parser | Yes | Functions/classes/imports (ESM + CJS) |
|
|
84
|
+
| React JSX | `.jsx` | Code-aware parser | Yes | Same as JS parser |
|
|
85
|
+
| TypeScript | `.ts` | Code-aware parser | Yes | Functions/classes/interfaces/enums/imports |
|
|
86
|
+
| React TSX | `.tsx` | Code-aware parser | Yes | Same as TS parser |
|
|
87
|
+
| XML | `.xml` | XML parser | Yes | Root element and namespace extraction |
|
|
88
|
+
| MQL4 Header | `.mqh` | Code parser | No | MetaTrader — add to `supported_formats` to enable |
|
|
89
|
+
| MQL4 Source | `.mq4` | Code parser | No | MetaTrader — add to `supported_formats` to enable |
|
|
90
|
+
|
|
91
|
+
> **Tip:** The parser dispatch is extensible. Any format mapped in `_parsers` can be enabled via `supported_formats` in config.yaml.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Features
|
|
96
|
+
|
|
97
|
+
| Feature | Description |
|
|
98
|
+
|---------|-------------|
|
|
99
|
+
| **Hybrid Search** | Semantic + BM25 keyword search with Reciprocal Rank Fusion |
|
|
100
|
+
| **Cross-Encoder Reranker** | Xenova/ms-marco-MiniLM-L-6-v2 re-scores top candidates for precision |
|
|
101
|
+
| **GPU Acceleration** | Optional ONNX CUDA support for 5-10x faster indexing |
|
|
102
|
+
| **YAML Configuration** | Fully customizable via `config.yaml` with domain-specific presets |
|
|
103
|
+
| **Query Expansion** | Configurable synonym mappings (69 security-term defaults) |
|
|
104
|
+
| **Markdown-Aware Chunking** | `.md` files split by `##`/`###` sections instead of fixed windows |
|
|
105
|
+
| **In-Process Embeddings** | FastEmbed ONNX Runtime (BAAI/bge-small-en-v1.5, 384D) |
|
|
106
|
+
| **Keyword Routing** | Word-boundary aware routing for domain-specific queries |
|
|
107
|
+
| **20 Format Parsers** | MD, TXT, PDF, PY, C, H, CPP, JS, JSX, TS, TSX, JSON, XML, CSV, DOCX, XLSX, PPTX, IPYNB + opt-in MQH/MQ4 |
|
|
108
|
+
| **Category Organization** | Organize docs by folder, auto-tagged by path |
|
|
109
|
+
| **Incremental Indexing** | Change detection via mtime/size — only re-indexes modified files |
|
|
110
|
+
| **Chunk Deduplication** | SHA256 content hashing prevents duplicate chunks |
|
|
111
|
+
| **Query Cache** | LRU cache with 5-min TTL for instant repeat queries |
|
|
112
|
+
| **Document CRUD** | Add, update, remove documents via MCP tools |
|
|
113
|
+
| **URL Ingestion** | Fetch URLs, strip HTML, convert to markdown, index |
|
|
114
|
+
| **Similarity Search** | Find documents similar to a reference document |
|
|
115
|
+
| **Retrieval Evaluation** | Built-in MRR@5 and Recall@5 metrics |
|
|
116
|
+
| **File Watcher** | Auto-reindex on document changes via watchdog (5s debounce) |
|
|
117
|
+
| **Exclude Patterns** | Glob-based file/directory exclusion during indexing |
|
|
118
|
+
| **MMR Diversification** | Maximal Marginal Relevance reduces redundant results |
|
|
119
|
+
| **Persistent Model Cache** | Embedding models cached in `models_cache/` — survives reboots |
|
|
120
|
+
| **Auto-Migration** | Detects embedding dimension mismatch and rebuilds automatically |
|
|
121
|
+
| **12 MCP Tools** | Full CRUD + search + evaluation via Claude Code |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Architecture
|
|
126
|
+
|
|
127
|
+
### System Overview
|
|
128
|
+
|
|
129
|
+
```mermaid
|
|
130
|
+
flowchart TB
|
|
131
|
+
subgraph MCP["MCP SERVER (FastMCP)"]
|
|
132
|
+
direction TB
|
|
133
|
+
TOOLS["12 MCP Tools<br/>search | get | add | update | remove<br/>reindex | list | stats | url | similar | evaluate"]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
subgraph SEARCH["HYBRID SEARCH ENGINE"]
|
|
137
|
+
direction LR
|
|
138
|
+
ROUTER["Keyword Router<br/>(word boundaries)"]
|
|
139
|
+
SEMANTIC["Semantic Search<br/>(ChromaDB)"]
|
|
140
|
+
BM25["BM25 Keyword<br/>(rank-bm25 + expansion)"]
|
|
141
|
+
RRF["Reciprocal Rank<br/>Fusion (RRF)"]
|
|
142
|
+
RERANK["Cross-Encoder<br/>Reranker"]
|
|
143
|
+
|
|
144
|
+
ROUTER --> SEMANTIC
|
|
145
|
+
ROUTER --> BM25
|
|
146
|
+
SEMANTIC --> RRF
|
|
147
|
+
BM25 --> RRF
|
|
148
|
+
RRF --> RERANK
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
subgraph STORAGE["STORAGE LAYER"]
|
|
152
|
+
direction LR
|
|
153
|
+
CHROMA[("ChromaDB<br/>Vector Database")]
|
|
154
|
+
COLLECTIONS["Collections<br/>security | ctf<br/>logscale | development"]
|
|
155
|
+
CHROMA --- COLLECTIONS
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
subgraph EMBED["EMBEDDINGS (In-Process)"]
|
|
159
|
+
FASTEMBED["FastEmbed ONNX<br/>BAAI/bge-small-en-v1.5<br/>(384D, CPU or GPU)"]
|
|
160
|
+
CROSSENC["Cross-Encoder<br/>ms-marco-MiniLM-L-6-v2"]
|
|
161
|
+
FASTEMBED --- CROSSENC
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
subgraph INGEST["DOCUMENT INGESTION"]
|
|
165
|
+
PARSERS["20 Parsers<br/>MD | PDF | TXT | PY | C | H | CPP | JS | JSX | TS | TSX | JSON | XML | CSV<br/>DOCX | XLSX | PPTX | IPYNB | MQH | MQ4"]
|
|
166
|
+
CHUNKER["Chunking<br/>MD: section-aware<br/>Other: 1000 chars + 200 overlap"]
|
|
167
|
+
PARSERS --> CHUNKER
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
CLAUDE["Claude Code"] --> MCP
|
|
171
|
+
MCP --> SEARCH
|
|
172
|
+
SEARCH --> STORAGE
|
|
173
|
+
STORAGE --> EMBED
|
|
174
|
+
INGEST --> EMBED
|
|
175
|
+
EMBED --> STORAGE
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Query Processing Flow
|
|
179
|
+
|
|
180
|
+
```mermaid
|
|
181
|
+
flowchart TB
|
|
182
|
+
QUERY["User Query<br/>'mimikatz credential dump'"] --> EXPAND
|
|
183
|
+
|
|
184
|
+
subgraph EXPANSION["Query Expansion"]
|
|
185
|
+
EXPAND["Synonym Expansion<br/>mimikatz -> mimikatz, sekurlsa, logonpasswords"]
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
EXPAND --> ROUTER
|
|
189
|
+
|
|
190
|
+
subgraph ROUTING["Keyword Routing"]
|
|
191
|
+
ROUTER["Keyword Router"]
|
|
192
|
+
MATCH{"Word Boundary<br/>Match?"}
|
|
193
|
+
CATEGORY["Filter: redteam"]
|
|
194
|
+
NOFILTER["No Filter"]
|
|
195
|
+
|
|
196
|
+
ROUTER --> MATCH
|
|
197
|
+
MATCH -->|Yes| CATEGORY
|
|
198
|
+
MATCH -->|No| NOFILTER
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
subgraph HYBRID["Hybrid Search"]
|
|
202
|
+
direction LR
|
|
203
|
+
SEMANTIC["Semantic Search<br/>(ChromaDB embeddings)<br/>Conceptual similarity"]
|
|
204
|
+
BM25["BM25 Search<br/>(expanded query)<br/>Exact term matching"]
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
subgraph FUSION["Result Fusion + Reranking"]
|
|
208
|
+
RRF["Reciprocal Rank Fusion<br/>score = alpha * 1/(k+rank_sem)<br/>+ (1-alpha) * 1/(k+rank_bm25)"]
|
|
209
|
+
RERANK["Cross-Encoder Reranker<br/>Re-scores top 3x candidates<br/>query+doc pair scoring"]
|
|
210
|
+
SORT["Sort by Reranker Score<br/>Normalize to 0-1"]
|
|
211
|
+
|
|
212
|
+
RRF --> RERANK --> SORT
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
CATEGORY --> HYBRID
|
|
216
|
+
NOFILTER --> HYBRID
|
|
217
|
+
SEMANTIC --> RRF
|
|
218
|
+
BM25 --> RRF
|
|
219
|
+
|
|
220
|
+
SORT --> RESULTS["Results<br/>search_method: hybrid|semantic|keyword<br/>score + reranker_score + raw_rrf_score"]
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Document Ingestion Flow
|
|
224
|
+
|
|
225
|
+
```mermaid
|
|
226
|
+
flowchart LR
|
|
227
|
+
subgraph INPUT["Input"]
|
|
228
|
+
FILES["documents/<br/>├── security/<br/>├── development/<br/>├── ctf/<br/>└── general/"]
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
subgraph PARSE["Parse (20 formats)"]
|
|
232
|
+
MD["Markdown"]
|
|
233
|
+
PDF["PDF<br/>(PyMuPDF)"]
|
|
234
|
+
OFFICE["DOCX | XLSX<br/>PPTX | CSV"]
|
|
235
|
+
CODE["PY | C | H | CPP | JS | JSX<br/>TS | TSX | JSON | XML | IPYNB"]
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
subgraph CHUNK["Chunk"]
|
|
239
|
+
MDSPLIT["MD: Section-Aware<br/>Split at ## headers"]
|
|
240
|
+
TXTSPLIT["Other: Fixed-Size<br/>1000 chars + 200 overlap"]
|
|
241
|
+
DEDUP["SHA256 Dedup<br/>Skip duplicate content"]
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
subgraph EMBED["Embed"]
|
|
245
|
+
FASTEMBED["FastEmbed ONNX<br/>bge-small-en-v1.5<br/>(384D, CPU or GPU)"]
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
subgraph STORE["Store"]
|
|
249
|
+
CHROMADB[("ChromaDB")]
|
|
250
|
+
BM25IDX["BM25 Index"]
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
FILES --> MD & PDF & OFFICE & CODE
|
|
254
|
+
MD --> MDSPLIT
|
|
255
|
+
PDF & OFFICE & CODE --> TXTSPLIT
|
|
256
|
+
MDSPLIT --> DEDUP
|
|
257
|
+
TXTSPLIT --> DEDUP
|
|
258
|
+
DEDUP --> EMBED
|
|
259
|
+
EMBED --> STORE
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### hybrid_alpha Parameter Effect
|
|
263
|
+
|
|
264
|
+
```mermaid
|
|
265
|
+
flowchart LR
|
|
266
|
+
subgraph ALPHA["hybrid_alpha values"]
|
|
267
|
+
A0["0.0<br/>Pure BM25<br/>Instant"]
|
|
268
|
+
A3["0.3 (default)<br/>Keyword-heavy<br/>Fast"]
|
|
269
|
+
A5["0.5<br/>Balanced"]
|
|
270
|
+
A7["0.7<br/>Semantic-heavy"]
|
|
271
|
+
A10["1.0<br/>Pure Semantic"]
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
subgraph USE["Best For"]
|
|
275
|
+
U0["CVEs, tool names<br/>exact matches"]
|
|
276
|
+
U3["Technical queries<br/>specific terms"]
|
|
277
|
+
U5["General queries"]
|
|
278
|
+
U7["Conceptual queries<br/>related topics"]
|
|
279
|
+
U10["'How to...' questions<br/>conceptual search"]
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
A0 --- U0
|
|
283
|
+
A3 --- U3
|
|
284
|
+
A5 --- U5
|
|
285
|
+
A7 --- U7
|
|
286
|
+
A10 --- U10
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Installation
|
|
292
|
+
|
|
293
|
+
### Prerequisites
|
|
294
|
+
|
|
295
|
+
- Python 3.11+
|
|
296
|
+
- Claude Code CLI
|
|
297
|
+
- ~200MB disk for model cache (auto-downloaded on first run)
|
|
298
|
+
- *Optional:* NVIDIA GPU + CUDA for accelerated embeddings (`pip install knowledge-rag[gpu]` + `models.embedding.gpu: true` in config)
|
|
299
|
+
|
|
300
|
+
### Install Methods
|
|
301
|
+
|
|
302
|
+
Pick one — all produce the same running server.
|
|
303
|
+
|
|
304
|
+
#### Option A: NPX (fastest)
|
|
305
|
+
|
|
306
|
+
Requires Node.js 16+. Handles Python venv, pip install, and version upgrades automatically.
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
claude mcp add knowledge-rag -s user -- npx -y knowledge-rag
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
That's it. On first run, `npx` creates a venv at `~/.knowledge-rag/`, installs the PyPI package, and starts the MCP server. Subsequent runs reuse the cached venv.
|
|
313
|
+
|
|
314
|
+
#### Option B: One-line installer
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# Linux/macOS:
|
|
318
|
+
curl -fsSL https://raw.githubusercontent.com/lyonzin/knowledge-rag/master/install.sh | bash
|
|
319
|
+
|
|
320
|
+
# Windows (PowerShell):
|
|
321
|
+
irm https://raw.githubusercontent.com/lyonzin/knowledge-rag/master/install.ps1 | iex
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Then configure Claude Code:
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
claude mcp add knowledge-rag -s user -- ~/knowledge-rag/venv/bin/python -m mcp_server.server
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
> **Windows**: `claude mcp add knowledge-rag -s user -- %USERPROFILE%\knowledge-rag\venv\Scripts\python.exe -m mcp_server.server`
|
|
331
|
+
|
|
332
|
+
#### Option C: pip install
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
mkdir ~/knowledge-rag && cd ~/knowledge-rag
|
|
336
|
+
python3 -m venv venv && source venv/bin/activate
|
|
337
|
+
pip install knowledge-rag
|
|
338
|
+
knowledge-rag init # Exports config template, presets, creates documents/
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Then configure Claude Code:
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
claude mcp add knowledge-rag -s user -- ~/knowledge-rag/venv/bin/python -m mcp_server.server
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
> **Windows users**: Use `python` instead of `python3`, `venv\Scripts\activate` instead of `source venv/bin/activate`.
|
|
348
|
+
> **Windows path**: `claude mcp add knowledge-rag -s user -- %USERPROFILE%\knowledge-rag\venv\Scripts\python.exe -m mcp_server.server`
|
|
349
|
+
|
|
350
|
+
#### Option D: Clone from source
|
|
6
351
|
|
|
7
|
-
|
|
352
|
+
```bash
|
|
353
|
+
git clone https://github.com/lyonzin/knowledge-rag.git ~/knowledge-rag
|
|
354
|
+
cd ~/knowledge-rag
|
|
355
|
+
python3 -m venv venv && source venv/bin/activate
|
|
356
|
+
pip install -r requirements.txt
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Then configure Claude Code:
|
|
8
360
|
|
|
9
361
|
```bash
|
|
10
|
-
|
|
362
|
+
claude mcp add knowledge-rag -s user -- ~/knowledge-rag/venv/bin/python -m mcp_server.server
|
|
11
363
|
```
|
|
12
364
|
|
|
13
|
-
|
|
365
|
+
#### Option E: Docker
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
docker pull ghcr.io/lyonzin/knowledge-rag:latest
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
claude mcp add knowledge-rag -s user -- \
|
|
373
|
+
docker run -i --rm \
|
|
374
|
+
-v ~/knowledge-rag/documents:/app/documents \
|
|
375
|
+
-v ~/knowledge-rag/data:/app/data \
|
|
376
|
+
ghcr.io/lyonzin/knowledge-rag:latest
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Models are pre-downloaded in the image — no first-run delay.
|
|
380
|
+
|
|
381
|
+
<details>
|
|
382
|
+
<summary>Alternative: manual JSON config</summary>
|
|
14
383
|
|
|
15
|
-
|
|
384
|
+
Add to `~/.claude.json`:
|
|
16
385
|
|
|
17
|
-
|
|
386
|
+
**Windows:**
|
|
387
|
+
```json
|
|
388
|
+
{
|
|
389
|
+
"mcpServers": {
|
|
390
|
+
"knowledge-rag": {
|
|
391
|
+
"command": "C:\\Users\\YOUR_USER\\knowledge-rag\\venv\\Scripts\\python.exe",
|
|
392
|
+
"args": ["-m", "mcp_server.server"]
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
```
|
|
18
397
|
|
|
398
|
+
**Linux / macOS:**
|
|
19
399
|
```json
|
|
20
400
|
{
|
|
21
401
|
"mcpServers": {
|
|
22
402
|
"knowledge-rag": {
|
|
23
|
-
"command": "
|
|
24
|
-
"args": ["-
|
|
403
|
+
"command": "/home/YOUR_USER/knowledge-rag/venv/bin/python",
|
|
404
|
+
"args": ["-m", "mcp_server.server"]
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
> Replace `YOUR_USER` with your username, or use the full path from `echo $HOME`.
|
|
410
|
+
</details>
|
|
411
|
+
|
|
412
|
+
### Verify
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
claude mcp list
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
On first start, the server will:
|
|
419
|
+
1. Download the embedding model (~50MB, cached in `models_cache/`)
|
|
420
|
+
2. Auto-index any documents in the `documents/` directory
|
|
421
|
+
3. Start watching for file changes (auto-reindex)
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## Usage
|
|
426
|
+
|
|
427
|
+
### Adding Documents
|
|
428
|
+
|
|
429
|
+
Place your documents in the `documents/` directory, organized by category:
|
|
430
|
+
|
|
431
|
+
```
|
|
432
|
+
documents/
|
|
433
|
+
├── security/ # Pentest, exploit, vulnerability docs
|
|
434
|
+
├── development/ # Code, APIs, frameworks
|
|
435
|
+
├── ctf/ # CTF writeups and methodology
|
|
436
|
+
├── logscale/ # LogScale/LQL documentation
|
|
437
|
+
└── general/ # Everything else
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Or add documents programmatically via MCP tools:
|
|
441
|
+
|
|
442
|
+
```python
|
|
443
|
+
# Add from content
|
|
444
|
+
add_document(
|
|
445
|
+
content="# My Document\n\nContent here...",
|
|
446
|
+
filepath="security/my-technique.md",
|
|
447
|
+
category="security"
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
# Add from URL
|
|
451
|
+
add_from_url(
|
|
452
|
+
url="https://example.com/article",
|
|
453
|
+
category="security",
|
|
454
|
+
title="Custom Title"
|
|
455
|
+
)
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Searching
|
|
459
|
+
|
|
460
|
+
Claude uses the RAG system automatically when configured. You can also control search behavior:
|
|
461
|
+
|
|
462
|
+
```python
|
|
463
|
+
# Pure keyword search — instant, no embedding needed
|
|
464
|
+
search_knowledge("gtfobins suid", hybrid_alpha=0.0)
|
|
465
|
+
|
|
466
|
+
# Keyword-heavy (default) — fast, slight semantic boost
|
|
467
|
+
search_knowledge("mimikatz", hybrid_alpha=0.3)
|
|
468
|
+
|
|
469
|
+
# Balanced hybrid — both engines equally weighted
|
|
470
|
+
search_knowledge("SQL injection techniques", hybrid_alpha=0.5)
|
|
471
|
+
|
|
472
|
+
# Semantic-heavy — better for conceptual queries
|
|
473
|
+
search_knowledge("how to escalate privileges", hybrid_alpha=0.7)
|
|
474
|
+
|
|
475
|
+
# Pure semantic — embedding similarity only
|
|
476
|
+
search_knowledge("lateral movement strategies", hybrid_alpha=1.0)
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Indexing
|
|
480
|
+
|
|
481
|
+
Documents are automatically indexed on first startup. To manage the index:
|
|
482
|
+
|
|
483
|
+
```python
|
|
484
|
+
# Incremental: only re-index changed files (fast)
|
|
485
|
+
reindex_documents()
|
|
486
|
+
|
|
487
|
+
# Smart reindex: detect changes + rebuild BM25
|
|
488
|
+
reindex_documents(force=True)
|
|
489
|
+
|
|
490
|
+
# Nuclear rebuild: delete everything, re-embed all (use after model change)
|
|
491
|
+
reindex_documents(full_rebuild=True)
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Evaluating Retrieval Quality
|
|
495
|
+
|
|
496
|
+
```python
|
|
497
|
+
evaluate_retrieval(test_cases='[
|
|
498
|
+
{"query": "sql injection", "expected_filepath": "security/sqli-guide.md"},
|
|
499
|
+
{"query": "privilege escalation", "expected_filepath": "security/privesc.md"}
|
|
500
|
+
]')
|
|
501
|
+
# Returns: MRR@5, Recall@5, per-query results
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
## API Reference
|
|
507
|
+
|
|
508
|
+
### Search & Query
|
|
509
|
+
|
|
510
|
+
#### `search_knowledge`
|
|
511
|
+
|
|
512
|
+
Hybrid search combining semantic search + BM25 keyword search with cross-encoder reranking.
|
|
513
|
+
|
|
514
|
+
| Parameter | Type | Default | Description |
|
|
515
|
+
|-----------|------|---------|-------------|
|
|
516
|
+
| `query` | string | required | Search query text (1-3 keywords recommended) |
|
|
517
|
+
| `max_results` | int | 5 | Maximum results to return (1-20) |
|
|
518
|
+
| `category` | string | null | Filter by category |
|
|
519
|
+
| `hybrid_alpha` | float | 0.3 | Balance: 0.0 = keyword only, 1.0 = semantic only |
|
|
520
|
+
|
|
521
|
+
**Returns:**
|
|
522
|
+
|
|
523
|
+
```json
|
|
524
|
+
{
|
|
525
|
+
"status": "success",
|
|
526
|
+
"query": "mimikatz credential dump",
|
|
527
|
+
"hybrid_alpha": 0.5,
|
|
528
|
+
"result_count": 3,
|
|
529
|
+
"cache_hit_rate": "0.0%",
|
|
530
|
+
"results": [
|
|
531
|
+
{
|
|
532
|
+
"content": "Mimikatz can extract credentials from memory...",
|
|
533
|
+
"source": "documents/security/credential-attacks.md",
|
|
534
|
+
"filename": "credential-attacks.md",
|
|
535
|
+
"category": "security",
|
|
536
|
+
"score": 0.9823,
|
|
537
|
+
"raw_rrf_score": 0.016393,
|
|
538
|
+
"reranker_score": 0.987654,
|
|
539
|
+
"semantic_rank": 2,
|
|
540
|
+
"bm25_rank": 1,
|
|
541
|
+
"search_method": "hybrid",
|
|
542
|
+
"keywords": ["mimikatz", "credential", "lsass"],
|
|
543
|
+
"routed_by": "redteam"
|
|
544
|
+
}
|
|
545
|
+
]
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
**Search Method Values:**
|
|
550
|
+
- `hybrid`: Found by both semantic and BM25 search (highest confidence)
|
|
551
|
+
- `semantic`: Found only by semantic search
|
|
552
|
+
- `keyword`: Found only by BM25 keyword search
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
#### `get_document`
|
|
557
|
+
|
|
558
|
+
Retrieve the full content of a specific document.
|
|
559
|
+
|
|
560
|
+
| Parameter | Type | Description |
|
|
561
|
+
|-----------|------|-------------|
|
|
562
|
+
| `filepath` | string | Path to the document file |
|
|
563
|
+
|
|
564
|
+
**Returns:** JSON with document content, metadata, keywords, and chunk count.
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
#### `reindex_documents`
|
|
569
|
+
|
|
570
|
+
Index or reindex all documents in the knowledge base.
|
|
571
|
+
|
|
572
|
+
| Parameter | Type | Default | Description |
|
|
573
|
+
|-----------|------|---------|-------------|
|
|
574
|
+
| `force` | bool | false | Smart reindex: detects changes, rebuilds BM25. Fast. |
|
|
575
|
+
| `full_rebuild` | bool | false | Nuclear rebuild: deletes everything, re-embeds all documents. Use after model change. |
|
|
576
|
+
|
|
577
|
+
**Returns:** JSON with indexing statistics (indexed, updated, skipped, deleted, chunks_added, chunks_removed, dedup_skipped, elapsed_seconds).
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
#### `list_categories`
|
|
582
|
+
|
|
583
|
+
List all document categories with their document counts.
|
|
584
|
+
|
|
585
|
+
**Returns:**
|
|
586
|
+
|
|
587
|
+
```json
|
|
588
|
+
{
|
|
589
|
+
"status": "success",
|
|
590
|
+
"categories": {
|
|
591
|
+
"security": 52,
|
|
592
|
+
"development": 8,
|
|
593
|
+
"ctf": 12,
|
|
594
|
+
"general": 3
|
|
595
|
+
},
|
|
596
|
+
"total_documents": 75
|
|
597
|
+
}
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
#### `list_documents`
|
|
603
|
+
|
|
604
|
+
List all indexed documents, optionally filtered by category.
|
|
605
|
+
|
|
606
|
+
| Parameter | Type | Description |
|
|
607
|
+
|-----------|------|-------------|
|
|
608
|
+
| `category` | string | Optional category filter |
|
|
609
|
+
|
|
610
|
+
**Returns:** JSON array of documents with id, source, category, format, chunks, and keywords.
|
|
611
|
+
|
|
612
|
+
---
|
|
613
|
+
|
|
614
|
+
#### `get_index_stats`
|
|
615
|
+
|
|
616
|
+
Get statistics about the knowledge base index.
|
|
617
|
+
|
|
618
|
+
**Returns:**
|
|
619
|
+
|
|
620
|
+
```json
|
|
621
|
+
{
|
|
622
|
+
"status": "success",
|
|
623
|
+
"stats": {
|
|
624
|
+
"total_documents": 75,
|
|
625
|
+
"total_chunks": 9256,
|
|
626
|
+
"unique_content_hashes": 9100,
|
|
627
|
+
"categories": {"security": 52, "development": 8},
|
|
628
|
+
"supported_formats": [".md", ".txt", ".pdf", ".py", ".json", ".docx", ".xlsx", ".pptx", ".csv", ".ipynb"],
|
|
629
|
+
"embedding_model": "BAAI/bge-small-en-v1.5",
|
|
630
|
+
"embedding_dim": 384,
|
|
631
|
+
"reranker_model": "Xenova/ms-marco-MiniLM-L-6-v2",
|
|
632
|
+
"chunk_size": 1000,
|
|
633
|
+
"chunk_overlap": 200,
|
|
634
|
+
"query_cache": {
|
|
635
|
+
"size": 12,
|
|
636
|
+
"max_size": 100,
|
|
637
|
+
"ttl_seconds": 300,
|
|
638
|
+
"hits": 45,
|
|
639
|
+
"misses": 23,
|
|
640
|
+
"hit_rate": "66.2%"
|
|
25
641
|
}
|
|
26
642
|
}
|
|
27
643
|
}
|
|
28
644
|
```
|
|
29
645
|
|
|
30
|
-
|
|
646
|
+
---
|
|
647
|
+
|
|
648
|
+
### Document Management
|
|
649
|
+
|
|
650
|
+
#### `add_document`
|
|
651
|
+
|
|
652
|
+
Add a new document to the knowledge base from raw content. Saves the file to the documents directory and indexes it immediately.
|
|
653
|
+
|
|
654
|
+
| Parameter | Type | Default | Description |
|
|
655
|
+
|-----------|------|---------|-------------|
|
|
656
|
+
| `content` | string | required | Full text content of the document |
|
|
657
|
+
| `filepath` | string | required | Relative path within documents dir (e.g., `security/new-technique.md`) |
|
|
658
|
+
| `category` | string | "general" | Document category |
|
|
659
|
+
|
|
660
|
+
---
|
|
661
|
+
|
|
662
|
+
#### `update_document`
|
|
663
|
+
|
|
664
|
+
Update an existing document. Removes old chunks from the index and re-indexes with new content.
|
|
665
|
+
|
|
666
|
+
| Parameter | Type | Description |
|
|
667
|
+
|-----------|------|-------------|
|
|
668
|
+
| `filepath` | string | Full path to the document file |
|
|
669
|
+
| `content` | string | New content for the document |
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
673
|
+
#### `remove_document`
|
|
674
|
+
|
|
675
|
+
Remove a document from the knowledge base index. Optionally deletes the file from disk.
|
|
676
|
+
|
|
677
|
+
| Parameter | Type | Default | Description |
|
|
678
|
+
|-----------|------|---------|-------------|
|
|
679
|
+
| `filepath` | string | required | Path to the document file |
|
|
680
|
+
| `delete_file` | bool | false | If true, also delete the file from disk |
|
|
681
|
+
|
|
682
|
+
---
|
|
683
|
+
|
|
684
|
+
#### `add_from_url`
|
|
685
|
+
|
|
686
|
+
Fetch content from a URL, strip HTML (scripts, styles, nav, footer, header), convert to markdown, and add to the knowledge base.
|
|
687
|
+
|
|
688
|
+
| Parameter | Type | Default | Description |
|
|
689
|
+
|-----------|------|---------|-------------|
|
|
690
|
+
| `url` | string | required | URL to fetch content from |
|
|
691
|
+
| `category` | string | "general" | Document category |
|
|
692
|
+
| `title` | string | null | Custom title (auto-detected from `<title>` tag if not provided) |
|
|
693
|
+
|
|
694
|
+
---
|
|
695
|
+
|
|
696
|
+
#### `search_similar`
|
|
697
|
+
|
|
698
|
+
Find documents similar to a given document using embedding similarity.
|
|
699
|
+
|
|
700
|
+
| Parameter | Type | Default | Description |
|
|
701
|
+
|-----------|------|---------|-------------|
|
|
702
|
+
| `filepath` | string | required | Path to the reference document |
|
|
703
|
+
| `max_results` | int | 5 | Number of similar documents to return (1-20) |
|
|
704
|
+
|
|
705
|
+
---
|
|
706
|
+
|
|
707
|
+
#### `evaluate_retrieval`
|
|
708
|
+
|
|
709
|
+
Evaluate retrieval quality with test queries. Useful for tuning `hybrid_alpha`, testing query expansion effectiveness, or validating after reindexing.
|
|
710
|
+
|
|
711
|
+
| Parameter | Type | Description |
|
|
712
|
+
|-----------|------|-------------|
|
|
713
|
+
| `test_cases` | string (JSON) | Array of test cases: `[{"query": "...", "expected_filepath": "..."}, ...]` |
|
|
714
|
+
|
|
715
|
+
**Metrics:**
|
|
716
|
+
- **MRR@5** (Mean Reciprocal Rank): Average of 1/rank for expected documents. 1.0 = always first result.
|
|
717
|
+
- **Recall@5**: Fraction of expected documents found in top 5 results. 1.0 = all found.
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
## Configuration
|
|
722
|
+
|
|
723
|
+
Knowledge RAG is fully configurable via a `config.yaml` file in the project root. If no `config.yaml` exists, sensible defaults are used — the system works out of the box with zero configuration.
|
|
724
|
+
|
|
725
|
+
### Quick Start
|
|
726
|
+
|
|
727
|
+
```bash
|
|
728
|
+
# Option 1: Use a preset
|
|
729
|
+
cp presets/cybersecurity.yaml config.yaml # Offensive/defensive security, CTFs
|
|
730
|
+
cp presets/developer.yaml config.yaml # Software engineering, APIs, DevOps
|
|
731
|
+
cp presets/research.yaml config.yaml # Academic research, papers, studies
|
|
732
|
+
cp presets/general.yaml config.yaml # Blank slate, pure semantic search
|
|
733
|
+
|
|
734
|
+
# Option 2: Start from the documented template
|
|
735
|
+
cp config.example.yaml config.yaml
|
|
736
|
+
# Edit config.yaml to your needs
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
Restart Claude Code after changing `config.yaml`.
|
|
740
|
+
|
|
741
|
+
### config.yaml Structure
|
|
742
|
+
|
|
743
|
+
```yaml
|
|
744
|
+
# Paths — where your documents live
|
|
745
|
+
paths:
|
|
746
|
+
documents_dir: "./documents" # Scanned recursively
|
|
747
|
+
data_dir: "./data" # Index storage
|
|
748
|
+
models_cache_dir: "./models_cache" # Persistent embedding model cache
|
|
749
|
+
|
|
750
|
+
# Documents — what gets indexed and how
|
|
751
|
+
documents:
|
|
752
|
+
supported_formats: # File types to index
|
|
753
|
+
- .md
|
|
754
|
+
- .txt
|
|
755
|
+
- .pdf
|
|
756
|
+
- .docx
|
|
757
|
+
- .ipynb
|
|
758
|
+
# - .py # Uncomment to index code
|
|
759
|
+
exclude_patterns: # Glob patterns to skip
|
|
760
|
+
- "node_modules"
|
|
761
|
+
- ".venv"
|
|
762
|
+
- "__pycache__"
|
|
763
|
+
chunking:
|
|
764
|
+
chunk_size: 1000 # Max chars per chunk
|
|
765
|
+
chunk_overlap: 200 # Shared chars between chunks
|
|
766
|
+
|
|
767
|
+
# Models — AI models for search (all run locally, no API keys)
|
|
768
|
+
models:
|
|
769
|
+
embedding:
|
|
770
|
+
model: "BAAI/bge-small-en-v1.5" # ONNX, ~33MB, auto-downloaded
|
|
771
|
+
dimensions: 384
|
|
772
|
+
gpu: false # Set true + pip install knowledge-rag[gpu]
|
|
773
|
+
reranker:
|
|
774
|
+
enabled: true # Set false on low-resource machines
|
|
775
|
+
model: "Xenova/ms-marco-MiniLM-L-6-v2"
|
|
776
|
+
top_k_multiplier: 3 # Candidates fetched before reranking
|
|
777
|
+
|
|
778
|
+
# Search — result limits and collection name
|
|
779
|
+
search:
|
|
780
|
+
default_results: 5
|
|
781
|
+
max_results: 20
|
|
782
|
+
collection_name: "knowledge_base" # Change for separate knowledge bases
|
|
783
|
+
|
|
784
|
+
# Categories — auto-tag documents by folder path
|
|
785
|
+
# Set to {} to disable categorization entirely
|
|
786
|
+
category_mappings:
|
|
787
|
+
"security/redteam": "redteam"
|
|
788
|
+
"security/blueteam": "blueteam"
|
|
789
|
+
"notes": "notes"
|
|
790
|
+
|
|
791
|
+
# Keyword routing — prioritize categories based on query keywords
|
|
792
|
+
# Set to {} for pure semantic search with no routing bias
|
|
793
|
+
keyword_routes:
|
|
794
|
+
redteam:
|
|
795
|
+
- pentest
|
|
796
|
+
- exploit
|
|
797
|
+
- privilege escalation
|
|
798
|
+
|
|
799
|
+
# Query expansion — expand abbreviations for better BM25 recall
|
|
800
|
+
# Set to {} for no expansion (search terms used as-is)
|
|
801
|
+
query_expansions:
|
|
802
|
+
sqli:
|
|
803
|
+
- sql injection
|
|
804
|
+
- sqli
|
|
805
|
+
privesc:
|
|
806
|
+
- privilege escalation
|
|
807
|
+
- privesc
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
> See `config.example.yaml` for the fully documented template with explanations for every field.
|
|
811
|
+
|
|
812
|
+
### Presets
|
|
813
|
+
|
|
814
|
+
Pre-built configurations for common use cases:
|
|
815
|
+
|
|
816
|
+
| Preset | File | Categories | Keywords | Expansions | Best For |
|
|
817
|
+
|--------|------|-----------|----------|-----------|----------|
|
|
818
|
+
| **Cybersecurity** | `presets/cybersecurity.yaml` | 8 | 200+ | 69 | Red/Blue Team, CTFs, threat hunting, exploit dev |
|
|
819
|
+
| **Developer** | `presets/developer.yaml` | 9 | 150+ | 50+ | Full-stack dev, APIs, DevOps, cloud, databases |
|
|
820
|
+
| **Research** | `presets/research.yaml` | 9 | 100+ | 40+ | Academic papers, thesis, lab notebooks, datasets |
|
|
821
|
+
| **General** | `presets/general.yaml` | 0 | 0 | 0 | Blank slate — pure semantic search, no domain logic |
|
|
822
|
+
|
|
823
|
+
**Creating your own preset**: Copy `config.example.yaml`, fill in your categories/keywords/expansions, save to `presets/your-domain.yaml`.
|
|
824
|
+
|
|
825
|
+
### Configuration Reference
|
|
826
|
+
|
|
827
|
+
#### Paths
|
|
828
|
+
|
|
829
|
+
| Field | Default | Description |
|
|
830
|
+
|-------|---------|-------------|
|
|
831
|
+
| `paths.documents_dir` | `./documents` | Root folder scanned recursively for documents |
|
|
832
|
+
| `paths.data_dir` | `./data` | Internal storage for ChromaDB and index metadata |
|
|
833
|
+
| `paths.models_cache_dir` | `./models_cache` | Persistent cache for embedding models (~250MB). Survives reboots |
|
|
834
|
+
|
|
835
|
+
Relative paths resolve from the project root. Absolute paths work too.
|
|
836
|
+
|
|
837
|
+
#### Documents
|
|
838
|
+
|
|
839
|
+
| Field | Default | Description |
|
|
840
|
+
|-------|---------|-------------|
|
|
841
|
+
| `documents.supported_formats` | .md .txt .pdf .py .json .docx .xlsx .pptx .csv .ipynb | File extensions to index |
|
|
842
|
+
| `documents.exclude_patterns` | `[]` (empty) | Glob patterns for files/dirs to skip during indexing |
|
|
843
|
+
| `documents.chunking.chunk_size` | 1000 | Max characters per chunk |
|
|
844
|
+
| `documents.chunking.chunk_overlap` | 200 | Characters shared between consecutive chunks |
|
|
845
|
+
|
|
846
|
+
**Chunking guidelines**: Short notes → 500/100. General use → 1000/200. Long technical docs → 1500/300.
|
|
847
|
+
|
|
848
|
+
For `.md` files, chunking splits at `##` and `###` header boundaries first. Sections larger than `chunk_size` are sub-chunked with overlap. Non-markdown files use fixed-size chunking.
|
|
849
|
+
|
|
850
|
+
#### Models
|
|
851
|
+
|
|
852
|
+
| Field | Default | Description |
|
|
853
|
+
|-------|---------|-------------|
|
|
854
|
+
| `models.embedding.model` | `BAAI/bge-small-en-v1.5` | Embedding model (ONNX, runs locally) |
|
|
855
|
+
| `models.embedding.dimensions` | 384 | Vector dimensions (must match model) |
|
|
856
|
+
| `models.embedding.gpu` | false | Enable CUDA GPU acceleration. Requires `pip install knowledge-rag[gpu]` |
|
|
857
|
+
| `models.reranker.enabled` | true | Enable cross-encoder reranking |
|
|
858
|
+
| `models.reranker.model` | `Xenova/ms-marco-MiniLM-L-6-v2` | Reranker model |
|
|
859
|
+
| `models.reranker.top_k_multiplier` | 3 | Fetch N*multiplier candidates for reranking |
|
|
860
|
+
|
|
861
|
+
**Embedding model options** (fastest → most accurate):
|
|
862
|
+
- `BAAI/bge-small-en-v1.5` — 384D, ~33MB (default)
|
|
863
|
+
- `BAAI/bge-base-en-v1.5` — 768D, ~130MB
|
|
864
|
+
- `BAAI/bge-large-en-v1.5` — 1024D, ~335MB
|
|
865
|
+
- `intfloat/multilingual-e5-small` — 384D, 100+ languages
|
|
866
|
+
|
|
867
|
+
> **Warning**: Changing the embedding model after indexing requires `reindex_documents(full_rebuild=True)`.
|
|
868
|
+
|
|
869
|
+
#### Search
|
|
870
|
+
|
|
871
|
+
| Field | Default | Description |
|
|
872
|
+
|-------|---------|-------------|
|
|
873
|
+
| `search.default_results` | 5 | Results returned when no limit specified |
|
|
874
|
+
| `search.max_results` | 20 | Hard cap even if client requests more |
|
|
875
|
+
| `search.collection_name` | `knowledge_base` | ChromaDB collection — change for separate KBs |
|
|
876
|
+
|
|
877
|
+
#### Categories
|
|
878
|
+
|
|
879
|
+
Map folder paths to category names. Documents in matching folders get auto-tagged, enabling filtered searches.
|
|
880
|
+
|
|
881
|
+
```yaml
|
|
882
|
+
category_mappings:
|
|
883
|
+
"security/redteam": "redteam"
|
|
884
|
+
"security": "security"
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
Set `category_mappings: {}` to disable — documents are still searchable, just without category filters.
|
|
888
|
+
|
|
889
|
+
#### Keyword Routing
|
|
890
|
+
|
|
891
|
+
Route queries to categories based on keywords. When a query contains listed keywords, results from that category are prioritized (not filtered — other categories still appear, ranked lower).
|
|
892
|
+
|
|
893
|
+
```yaml
|
|
894
|
+
keyword_routes:
|
|
895
|
+
redteam:
|
|
896
|
+
- pentest
|
|
897
|
+
- exploit
|
|
898
|
+
- sqli
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
Single-word keywords use regex word boundaries (`\b`) — "api" won't match "RAPID". Multi-word keywords use substring matching.
|
|
902
|
+
|
|
903
|
+
Set `keyword_routes: {}` for pure semantic search.
|
|
904
|
+
|
|
905
|
+
#### Query Expansion
|
|
906
|
+
|
|
907
|
+
Expand search terms with synonyms before BM25 search. Supports single tokens, bigrams, and full query matches.
|
|
908
|
+
|
|
909
|
+
```yaml
|
|
910
|
+
query_expansions:
|
|
911
|
+
sqli:
|
|
912
|
+
- sql injection
|
|
913
|
+
- sqli
|
|
914
|
+
k8s:
|
|
915
|
+
- kubernetes
|
|
916
|
+
- k8s
|
|
917
|
+
```
|
|
918
|
+
|
|
919
|
+
Set `query_expansions: {}` for no expansion.
|
|
920
|
+
|
|
921
|
+
### Hybrid Search Tuning
|
|
922
|
+
|
|
923
|
+
| hybrid_alpha | Behavior | Best For |
|
|
924
|
+
|--------------|----------|----------|
|
|
925
|
+
| 0.0 | Pure BM25 keyword | Exact terms, CVEs, tool names |
|
|
926
|
+
| 0.3 | Keyword-heavy **(default)** | Technical queries with specific terms |
|
|
927
|
+
| 0.5 | Balanced | General queries |
|
|
928
|
+
| 0.7 | Semantic-heavy | Conceptual queries, related topics |
|
|
929
|
+
| 1.0 | Pure semantic | "How to..." questions, abstract concepts |
|
|
930
|
+
|
|
931
|
+
---
|
|
932
|
+
|
|
933
|
+
## Project Structure
|
|
934
|
+
|
|
935
|
+
```
|
|
936
|
+
knowledge-rag/
|
|
937
|
+
├── mcp_server/
|
|
938
|
+
│ ├── __init__.py # Stdout protection + version
|
|
939
|
+
│ ├── config.py # YAML config loader + defaults
|
|
940
|
+
│ ├── ingestion.py # 20 parsers, chunking, metadata extraction
|
|
941
|
+
│ └── server.py # MCP server, ChromaDB, BM25, reranker, 12 tools
|
|
942
|
+
├── config.example.yaml # Documented config template (copy to config.yaml)
|
|
943
|
+
├── config.yaml # Your active configuration (git-ignored)
|
|
944
|
+
├── presets/ # Ready-to-use domain configurations
|
|
945
|
+
│ ├── cybersecurity.yaml
|
|
946
|
+
│ ├── developer.yaml
|
|
947
|
+
│ ├── research.yaml
|
|
948
|
+
│ └── general.yaml
|
|
949
|
+
├── documents/ # Your documents (scanned recursively)
|
|
950
|
+
├── data/
|
|
951
|
+
│ ├── chroma_db/ # ChromaDB vector database
|
|
952
|
+
│ └── index_metadata.json # Incremental indexing state
|
|
953
|
+
├── models_cache/ # Persistent embedding model cache
|
|
954
|
+
├── tests/ # Test suite (82 tests)
|
|
955
|
+
├── install.sh # Linux/macOS installer
|
|
956
|
+
├── install.ps1 # Windows installer
|
|
957
|
+
├── venv/ # Python virtual environment
|
|
958
|
+
├── requirements.txt
|
|
959
|
+
├── pyproject.toml
|
|
960
|
+
├── LICENSE
|
|
961
|
+
└── README.md
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
---
|
|
965
|
+
|
|
966
|
+
## Troubleshooting
|
|
967
|
+
|
|
968
|
+
### Python version mismatch
|
|
969
|
+
|
|
970
|
+
Requires Python 3.11 or newer.
|
|
971
|
+
|
|
972
|
+
```bash
|
|
973
|
+
python --version # Must be 3.11+
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
### FastEmbed model download fails
|
|
977
|
+
|
|
978
|
+
On first run, FastEmbed downloads models to `models_cache/`. If the download fails:
|
|
979
|
+
|
|
980
|
+
```bash
|
|
981
|
+
# Clear cache and retry
|
|
982
|
+
# Windows:
|
|
983
|
+
rmdir /s /q models_cache
|
|
984
|
+
|
|
985
|
+
# Linux/macOS:
|
|
986
|
+
rm -rf models_cache
|
|
987
|
+
|
|
988
|
+
# Then restart the MCP server
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
### Index is empty
|
|
31
992
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
| `--install-only` | Install the Python package into the venv without starting the server |
|
|
993
|
+
```bash
|
|
994
|
+
# Check documents directory has files
|
|
995
|
+
ls documents/
|
|
36
996
|
|
|
37
|
-
|
|
997
|
+
# Force reindex via Claude Code:
|
|
998
|
+
# reindex_documents(force=True)
|
|
38
999
|
|
|
39
|
-
|
|
40
|
-
|
|
1000
|
+
# Or nuclear rebuild if model changed:
|
|
1001
|
+
# reindex_documents(full_rebuild=True)
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
### MCP server not loading
|
|
1005
|
+
|
|
1006
|
+
1. Check `~/.claude.json` exists and has valid JSON in the `mcpServers` section
|
|
1007
|
+
2. Verify paths use double backslashes (`\\`) on Windows
|
|
1008
|
+
3. Restart Claude Code completely
|
|
1009
|
+
4. Run `claude mcp list` to check connection status
|
|
41
1010
|
|
|
42
|
-
|
|
1011
|
+
### "Failed to connect" error
|
|
43
1012
|
|
|
44
|
-
|
|
1013
|
+
The MCP server uses stdout for JSON-RPC communication. If a library prints to stdout during init, the stream gets corrupted. v3.4.3+ includes stdout protection that prevents this. If you're on an older version, upgrade:
|
|
45
1014
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
4. Starts the MCP server over stdio
|
|
1015
|
+
```bash
|
|
1016
|
+
pip install --upgrade knowledge-rag
|
|
1017
|
+
```
|
|
50
1018
|
|
|
51
|
-
|
|
1019
|
+
### Slow first query
|
|
52
1020
|
|
|
53
|
-
|
|
1021
|
+
The cross-encoder reranker model is lazy-loaded on the first query. This adds a one-time ~2-3 second delay for model download and loading. Subsequent queries are fast.
|
|
54
1022
|
|
|
55
|
-
|
|
1023
|
+
### Memory usage
|
|
56
1024
|
|
|
57
|
-
|
|
1025
|
+
With ~200 documents, expect ~300-500MB RAM. The embedding model (~50MB) and reranker (~25MB) are loaded into memory. For very large knowledge bases (1000+ documents), consider enabling GPU acceleration and using exclude patterns to limit index scope.
|
|
1026
|
+
|
|
1027
|
+
---
|
|
1028
|
+
|
|
1029
|
+
## Changelog
|
|
1030
|
+
|
|
1031
|
+
### v3.6.2 (2026-04-23)
|
|
1032
|
+
|
|
1033
|
+
- **INFRA**: NPM provenance attestation (SLSA supply chain security), full README on npm page
|
|
1034
|
+
- **DOCS**: Reorganize Installation section — add NPX and Docker install methods, update What's New to v3.6.0
|
|
1035
|
+
|
|
1036
|
+
### v3.6.0 (2026-04-23)
|
|
1037
|
+
|
|
1038
|
+
- **NEW**: Multi-language code parsing — C (`.c`), C++ (`.cpp`/`.h`), JavaScript (`.js`/`.jsx`), TypeScript (`.ts`/`.tsx`) with per-language function/class/import extraction
|
|
1039
|
+
- **NEW**: XML parser (`.xml`) — root element and namespace metadata extraction
|
|
1040
|
+
- **NEW**: All 8 new formats default enabled — no config change needed
|
|
1041
|
+
- **NEW**: NPM wrapper (`npx knowledge-rag`) + Docker image (`ghcr.io/lyonzin/knowledge-rag`)
|
|
1042
|
+
- **NEW**: Automated release pipeline — PyPI (Trusted Publishing), NPM, Docker GHCR
|
|
1043
|
+
- **IMPROVED**: Code parser reports correct `language` metadata per file type (was hardcoded to `"python"` for all code files)
|
|
1044
|
+
|
|
1045
|
+
### v3.5.2 (2026-04-16)
|
|
1046
|
+
|
|
1047
|
+
- **NEW**: Auto-discovery of CUDA 12 DLLs from pip-installed NVIDIA packages — no manual PATH configuration needed
|
|
1048
|
+
- **NEW**: Graceful GPU→CPU fallback with `[WARN]` log when CUDA init fails (missing drivers, wrong version, etc.)
|
|
1049
|
+
- **FIX**: Explicit `CPUExecutionProvider` when `gpu: false` — eliminates noisy CUDA probe errors in logs
|
|
1050
|
+
- **FIX**: BASE_DIR resolution now correctly prefers directories with `config.yaml` over those with only `config.example.yaml` (fixes editable installs)
|
|
1051
|
+
|
|
1052
|
+
### v3.5.1 (2026-04-16)
|
|
1053
|
+
|
|
1054
|
+
- **FIX**: Removed Python upper bound constraint (`<3.13` → `>=3.11`). Python 3.13 and 3.14 now supported — onnxruntime ships wheels for both.
|
|
1055
|
+
|
|
1056
|
+
### v3.5.0 (2026-04-16)
|
|
1057
|
+
|
|
1058
|
+
- **NEW**: Optional GPU acceleration for ONNX embeddings — `pip install knowledge-rag[gpu]` + `models.embedding.gpu: true` in config. 5-10x faster indexing on NVIDIA GPUs with automatic CPU fallback.
|
|
1059
|
+
- **DOCS**: Supported formats table added to README (20 formats)
|
|
1060
|
+
|
|
1061
|
+
### v3.4.3 (2026-04-16)
|
|
1062
|
+
|
|
1063
|
+
- **FIX**: Correct stdout protection via save/restore pattern — `__init__.py` saves original stdout and redirects to stderr during init, `server.py main()` restores it before `mcp.run()`. v3.4.2's global redirect broke MCP JSON-RPC response channel.
|
|
1064
|
+
|
|
1065
|
+
### v3.4.1 (2026-04-16)
|
|
1066
|
+
|
|
1067
|
+
- **FIX**: `pip install knowledge-rag` now auto-detects project directory from venv location
|
|
1068
|
+
- **NEW**: `install.sh` — Linux/macOS installer with pip and from-source modes
|
|
1069
|
+
- **IMPROVED**: BASE_DIR resolution chain: env var → source dir → venv parent → CWD → fallback
|
|
1070
|
+
|
|
1071
|
+
### v3.4.0 (2026-04-16)
|
|
1072
|
+
|
|
1073
|
+
- **NEW**: `models_cache_dir` — persistent embedding model cache, prevents re-download after reboots
|
|
1074
|
+
- **NEW**: `exclude_patterns` — glob-based file/directory exclusion during indexing
|
|
1075
|
+
- **NEW**: Jupyter Notebook (.ipynb) parser — extracts markdown and code cell sources only
|
|
1076
|
+
- **NEW**: MCP stdout protection — redirects stdout to stderr before server start
|
|
1077
|
+
- **NEW**: File watcher resilience — graceful fallback when Linux inotify limits are reached
|
|
1078
|
+
- **NEW**: MetaTrader (.mq4, .mqh) support — opt-in code parsing
|
|
1079
|
+
- **NEW**: 23 new tests (exclude patterns, ipynb parser, stdout protection)
|
|
1080
|
+
- Community credit: [@Hohlas](https://github.com/Hohlas) ([PR #18](https://github.com/lyonzin/knowledge-rag/pull/18))
|
|
1081
|
+
|
|
1082
|
+
### v3.3.x
|
|
1083
|
+
|
|
1084
|
+
- **v3.3.2**: Full type validation on YAML config, bounds checking, version sync
|
|
1085
|
+
- **v3.3.1**: YAML null value crash fix, presets bundled in pip wheel, `knowledge-rag init` CLI
|
|
1086
|
+
- **v3.3.0**: YAML configuration system, 4 domain presets, generic use support
|
|
1087
|
+
|
|
1088
|
+
### v3.2.x
|
|
1089
|
+
|
|
1090
|
+
- **v3.2.4**: Symlink support with circular loop protection
|
|
1091
|
+
- **v3.2.3**: BASE_DIR smart detection for pip installs
|
|
1092
|
+
- **v3.2.2**: Plug-and-play pip install, `KNOWLEDGE_RAG_DIR` env var
|
|
1093
|
+
- **v3.2.1**: Auto-recovery from corrupted ChromaDB
|
|
1094
|
+
- **v3.2.0**: Parallel BM25 + Semantic search, adjacent chunk retrieval
|
|
1095
|
+
|
|
1096
|
+
### v3.1.x
|
|
1097
|
+
|
|
1098
|
+
- **v3.1.1**: Code block protection in markdown chunker, AAR category, 14 CVE aliases
|
|
1099
|
+
- **v3.1.0**: DOCX/XLSX/PPTX/CSV support, file watcher, MMR diversification, PyPI publish
|
|
1100
|
+
|
|
1101
|
+
### v3.0.0 (2026-03-19)
|
|
1102
|
+
|
|
1103
|
+
- Replaced Ollama with FastEmbed (ONNX in-process)
|
|
1104
|
+
- Cross-encoder reranking, markdown-aware chunking, query expansion
|
|
1105
|
+
- 6 new MCP tools (12 total), auto-migration from v2.x
|
|
1106
|
+
|
|
1107
|
+
<details>
|
|
1108
|
+
<summary>v2.x and earlier</summary>
|
|
1109
|
+
|
|
1110
|
+
- **v2.2.0**: `hybrid_alpha=0` skips Ollama, default changed from 0.5 to 0.3
|
|
1111
|
+
- **v2.1.0**: Mermaid architecture diagrams
|
|
1112
|
+
- **v2.0.0**: Hybrid search, RRF fusion, `hybrid_alpha` parameter
|
|
1113
|
+
- **v1.1.0**: Incremental indexing, query cache, chunk deduplication
|
|
1114
|
+
- **v1.0.1**: Auto-cleanup orphan folders, removed hardcoded paths
|
|
1115
|
+
- **v1.0.0**: Initial release
|
|
1116
|
+
</details>
|
|
1117
|
+
|
|
1118
|
+
---
|
|
1119
|
+
|
|
1120
|
+
## Contributing
|
|
1121
|
+
|
|
1122
|
+
1. Fork the repository
|
|
1123
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
1124
|
+
3. Commit your changes
|
|
1125
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
1126
|
+
5. Open a Pull Request
|
|
1127
|
+
|
|
1128
|
+
---
|
|
58
1129
|
|
|
59
1130
|
## License
|
|
60
1131
|
|
|
61
|
-
MIT
|
|
1132
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
1133
|
+
|
|
1134
|
+
---
|
|
1135
|
+
|
|
1136
|
+
## Acknowledgments
|
|
1137
|
+
|
|
1138
|
+
- [ChromaDB](https://www.trychroma.com/) — Vector database
|
|
1139
|
+
- [FastEmbed](https://qdrant.github.io/fastembed/) — ONNX Runtime embeddings
|
|
1140
|
+
- [FastMCP](https://github.com/anthropics/mcp) — Model Context Protocol framework
|
|
1141
|
+
- [PyMuPDF](https://pymupdf.readthedocs.io/) — PDF parsing
|
|
1142
|
+
- [rank-bm25](https://github.com/dorianbrown/rank_bm25) — BM25 Okapi implementation
|
|
1143
|
+
- [Watchdog](https://github.com/gorakhargosh/watchdog) — File system monitoring
|
|
1144
|
+
- [python-docx](https://python-docx.readthedocs.io/) / [openpyxl](https://openpyxl.readthedocs.io/) / [python-pptx](https://python-pptx.readthedocs.io/) — Office document parsing
|
|
1145
|
+
- [PyYAML](https://pyyaml.org/) — YAML configuration parsing
|
|
1146
|
+
- [Beautiful Soup](https://www.crummy.com/software/BeautifulSoup/) — HTML parsing for URL ingestion
|
|
1147
|
+
|
|
1148
|
+
---
|
|
1149
|
+
|
|
1150
|
+
## Author
|
|
1151
|
+
|
|
1152
|
+
**Lyon.**
|
|
1153
|
+
|
|
1154
|
+
Security Researcher | Developer
|
|
1155
|
+
|
|
1156
|
+
---
|
|
1157
|
+
|
|
1158
|
+
<div align="center">
|
|
1159
|
+
|
|
1160
|
+
**[Back to Top](#knowledge-rag)**
|
|
1161
|
+
|
|
1162
|
+
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knowledge-rag",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.2",
|
|
4
4
|
"description": "Local RAG System for Claude Code — Hybrid search + Cross-encoder Reranking + 12 MCP Tools + 20 Format Parsers. Zero external servers.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"knowledge-rag": "./bin/cli.js"
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
"bugs": {
|
|
29
29
|
"url": "https://github.com/lyonzin/knowledge-rag/issues"
|
|
30
30
|
},
|
|
31
|
+
"funding": {
|
|
32
|
+
"url": "https://github.com/sponsors/lyonzin"
|
|
33
|
+
},
|
|
31
34
|
"engines": {
|
|
32
35
|
"node": ">=16"
|
|
33
36
|
},
|