knowledge-rag 4.9.0 → 4.11.0

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.
Files changed (4) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +767 -739
  3. package/bin/cli.js +254 -254
  4. package/package.json +42 -42
package/README.md CHANGED
@@ -1,739 +1,767 @@
1
- <!--
2
- knowledge-rag — Local RAG server for Claude Code, Cursor, Windsurf and other MCP clients.
3
- SEO keywords: local rag, mcp server, self-hosted rag, hybrid search, cross-encoder reranking, claude code rag, cursor rag, python rag, chromadb rag, fastembed rag, air-gapped rag, gdpr rag, retrieval augmented generation, model context protocol server, zero cloud rag.
4
-
5
- Structured data (schema.org SoftwareApplication) — indexed by search engines, invisible on GitHub render:
6
- {
7
- "@context": "https://schema.org",
8
- "@type": "SoftwareApplication",
9
- "name": "knowledge-rag",
10
- "applicationCategory": "DeveloperApplication",
11
- "operatingSystem": "Windows, Linux, macOS",
12
- "description": "Local-first RAG server for AI agents. Hybrid search, MCP-native, zero cloud, enterprise-grade plumbing (bearer auth, Prometheus metrics, rate limiting, health probes, structured JSON logging, zero-downtime reindex).",
13
- "offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
14
- "license": "https://opensource.org/licenses/MIT",
15
- "downloadUrl": "https://pypi.org/project/knowledge-rag/",
16
- "codeRepository": "https://github.com/lyonzin/knowledge-rag",
17
- "programmingLanguage": "Python",
18
- "runtimePlatform": "Python 3.11+"
19
- }
20
- -->
21
-
22
- <p align="center">
23
- <img
24
- src="./assets/knowledge-rag-banner.png"
25
- alt="knowledge-rag — Local Hybrid RAG for MCP"
26
- width="100%"
27
- />
28
- </p>
29
-
30
- # knowledge-rag
31
-
32
- <div align="center">
33
-
34
- [![PyPI](https://img.shields.io/pypi/v/knowledge-rag)](https://pypi.org/project/knowledge-rag/)
35
- [![NPM](https://img.shields.io/npm/v/knowledge-rag)](https://www.npmjs.com/package/knowledge-rag)
36
- [![PyPI Downloads](https://static.pepy.tech/personalized-badge/knowledge-rag?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/knowledge-rag)
37
- ![Python](https://img.shields.io/badge/python-3.11%2B-green.svg)
38
- ![License](https://img.shields.io/badge/license-MIT-yellow.svg)
39
- ![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)
40
- ![GPU](https://img.shields.io/badge/GPU-NVIDIA%20CUDA-76B900.svg?logo=nvidia)
41
- [![CI](https://github.com/lyonzin/knowledge-rag/actions/workflows/ci.yml/badge.svg)](https://github.com/lyonzin/knowledge-rag/actions/workflows/ci.yml)
42
- [![CodeQL](https://github.com/lyonzin/knowledge-rag/actions/workflows/security.yml/badge.svg)](https://github.com/lyonzin/knowledge-rag/actions/workflows/security.yml)
43
- [![Quality Gate](https://github.com/lyonzin/knowledge-rag/actions/workflows/quality-gate.yml/badge.svg)](https://github.com/lyonzin/knowledge-rag/actions/workflows/quality-gate.yml)
44
- [![Glama Score](https://glama.ai/mcp/servers/lyonzin/knowledge-rag/badges/score.svg)](https://glama.ai/mcp/servers/lyonzin/knowledge-rag)
45
- [![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/13864/badge)](https://bestpractices.coreinfrastructure.org/projects/13864)
46
-
47
- ### The MCP-first local RAG server for Claude Code, Cursor, and every AI agent.
48
-
49
- **Hybrid search · Cross-encoder reranking · 35 file formats · 100% local · Zero cloud · Enterprise-grade plumbing built-in.**
50
-
51
- ```bash
52
- pip install knowledge-rag → restart Claude Code → search_knowledge("your query")
53
- ```
54
-
55
- [Quick Start](#quick-start-3-minutes-from-zero-to-your-first-query) ·
56
- [Why knowledge-rag](#why-knowledge-rag) ·
57
- [Compare](#how-knowledge-rag-compares-to-other-rag-frameworks) ·
58
- [Enterprise Features](#enterprise-features-built-in-zero-configuration) ·
59
- [Docs](#documentation)
60
-
61
- </div>
62
-
63
- ---
64
-
65
- ## ⭐ Star History
66
-
67
- <div align="center">
68
-
69
- <a href="https://www.star-history.com/?repos=lyonzin%2Fknowledge-rag&type=date&legend=top-left">
70
- <img alt="knowledge-rag star history chart — GitHub star growth over time" src="./docs/star-history.svg" width="720" />
71
- </a>
72
-
73
- <sub>Chart updated daily by <a href="./.github/workflows/update-star-history.yml">GitHub Action</a></sub>
74
-
75
- </div>
76
-
77
- ---
78
-
79
- ## 🎯 Why knowledge-rag
80
-
81
- Most RAG frameworks fall into one of three traps: (1) they require you to ship your data to a cloud API, (2) they hand you 300 building blocks and 0 opinionated defaults, or (3) they bundle RAG as a 5% feature of a much bigger platform you didn't ask for.
82
-
83
- **knowledge-rag does one thing well:** it is the MCP-native local RAG server that Claude Code, Cursor, Windsurf, VS Code, Cline, Gemini CLI and Zed can search out of the box — with enterprise plumbing (bearer auth, Prometheus metrics, rate limiting, health probes, structured JSON logging, zero-downtime reindex) that no other RAG-focused OSS ships built-in.
84
-
85
- <table>
86
- <tr>
87
- <td width="50%" valign="top">
88
-
89
- ### 🔒 100% local, 0% cloud
90
- Your files never leave the machine. No vendor lock-in, no data-residency headache, no forced cloud dependency. **LGPD / GDPR / HIPAA compliant by architecture** — because there is nothing to comply about when nothing leaves.
91
-
92
- </td>
93
- <td width="50%" valign="top">
94
-
95
- ### 🚀 Zero-friction setup
96
- `pip install knowledge-rag` → restart your MCP client → done. **No Docker mandatory. No Ollama required. No separate embedding server.** Everything runs in-process via FastEmbed ONNX. **Works offline** after the first model download.
97
-
98
- </td>
99
- </tr>
100
- <tr>
101
- <td width="50%" valign="top">
102
-
103
- ### 🛡️ Production-grade OSS
104
- 7-pillar quality gate on every PR (**35+ automated checks**), 9-cell OS×Python CI matrix (Linux + Windows + macOS × 3.11/3.12/3.13), nightly chaos + 50K-iteration soak + mutation testing. **700+ tests. 0 known regressions.**
105
-
106
- </td>
107
- <td width="50%" valign="top">
108
-
109
- ### 💰 Zero ongoing cost
110
- No token bills. No SaaS tier. No paid features hidden behind a wall. **MIT license, forever.** Runs on the laptop you already have — GPU optional, CPU works fine with FastEmbed ONNX.
111
-
112
- </td>
113
- </tr>
114
- </table>
115
-
116
- ---
117
-
118
- ## 📊 How knowledge-rag compares to other RAG frameworks
119
-
120
- We audited **16 popular RAG frameworks and platforms** (LlamaIndex, LangChain, ChromaDB, Weaviate, Qdrant, RAGFlow, LightRAG, DSPy, GraphRAG, Haystack, RAG-Anything, kotaemon, txtai, llmware, Dify, open-webui, FastGPT) so you can pick honestly.
121
-
122
- **Legend:** ✅ built-in · 🟡 plugin / paid tier / partial · ❌ not available · ⚠️ license or default concern
123
-
124
- | Dimension | 🎯 **knowledge-rag** | LlamaIndex | LangChain | Haystack | RAGFlow | txtai | open-webui | Dify | Qdrant |
125
- |---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
126
- | **100% local, zero cloud** | ✅ | 🟡 | ✅ | 🟡 | 🟡 | ✅ | ✅ | 🟡 | 🟡 |
127
- | **MCP native (Claude/Cursor)** | ✅ 13 tools | 🟡 pkg | 🟡 adapter | 🟡 wrapper | 🟡 add-on | ✅ | ✅ consumer | ✅ | ❌ |
128
- | **Hybrid BM25 + semantic** | ✅ 128× faster | 🟡 | 🟡 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
129
- | **Cross-encoder rerank** | ✅ builtin | ❌ | 🟡 | ✅ | ✅ fused | ❌ | ✅ | 🟡 | 🟡 |
130
- | **Bearer auth builtin** | ✅ | ❌ | ❌ | ❌ core | ❌ | 🟡 | ✅ RBAC | ✅ OAuth2 | ✅ |
131
- | **Prometheus `/metrics`** | ✅ | ❌ | ❌ | ❌ core | ❌ | ❌ | ✅ OTel | ❌ | ✅ |
132
- | **Rate limiting** | ✅ sliding-window | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
133
- | **Health probes** (`/health`) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | 🟡 | 🟡 | ✅ |
134
- | **Structured JSON logging** | ✅ opt-in | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ OTel | 🟡 | ✅ |
135
- | **Zero-downtime reindex** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
136
- | **Async background reindex** | ✅ + polling | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | 🟡 |
137
- | **GPU CUDA optional** | ✅ 12 auto | ❌ | 🟡 | ✅ | ✅ | ✅ | ✅ | 🟡 | 🟡 |
138
- | **File formats builtin** | ✅ **20** | 0 (LlamaParse=$) | 50+ plugins | ✅ **36+** | 8+ | ? | ? | ~10 | ❌ |
139
- | **Setup < 5 min POC** | ✅ pip 1-liner | ✅ | ✅ | ✅ | ❌ 16GB RAM | ✅ | ✅ docker | ✅ docker | ✅ |
140
- | **Nightly chaos + soak + mutation** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
141
- | **License** | ✅ MIT | MIT | MIT | Apache-2.0 | Apache-2.0 | Apache-2.0 | ⚠️ preserving | ⚠️ restrictive | Apache-2.0 |
142
-
143
- > **The 5 dimensions where knowledge-rag is unique:** health probes + JSON logging + Prometheus + rate limit + bearer auth **simultaneously built-in on an OSS RAG-focused MCP server**. Zero-downtime reindex + async background reindex + nightly chaos/soak/mutation are documented on nobody else's README.
144
-
145
- ---
146
-
147
- ## 🚀 Quick Start (3 minutes, from zero to your first query)
148
-
149
- Pick your integration path — knowledge-rag ships the same server through every channel.
150
-
151
- ### Path 1 — Claude Code, Cursor, Windsurf, Cline, VS Code, Gemini CLI, Zed (MCP)
152
-
153
- ```bash
154
- pip install knowledge-rag
155
- knowledge-rag init # scaffolds config.yaml + documents/
156
- ```
157
-
158
- Drop your PDFs, markdown, code files into `documents/`. Restart your MCP client. Ask it:
159
-
160
- ```
161
- search_knowledge("your query")
162
- ```
163
-
164
- That's it. First query loads the ONNX embedding model (~200MB, one-off download). Subsequent queries are cached and hit sub-second latency.
165
-
166
- ### Path 2 — HTTP / SSE server (multi-user, air-gapped, load-balanced)
167
-
168
- ```yaml
169
- # config.yaml
170
- server:
171
- transport: "sse" # or "streamable-http"
172
- host: "0.0.0.0"
173
- port: 8179
174
- auth:
175
- bearer_token: "your-secret-token"
176
- rate_limit:
177
- enabled: true
178
- requests_per_minute: 60
179
- metrics:
180
- enabled: true
181
- port: 9179
182
- logging:
183
- format: "json" # ELK / Loki / Datadog / CloudWatch ready
184
- ```
185
-
186
- ```bash
187
- knowledge-rag --transport sse
188
- ```
189
-
190
- - Health probe: `curl http://your-host:8179/health` → 200 + JSON payload
191
- - Prometheus scrape: `http://your-host:9179/metrics`
192
- - MCP dispatcher: authenticated via `Authorization: Bearer your-secret-token`
193
-
194
- ### Path 3 — Docker (models pre-downloaded, air-gapped ready)
195
-
196
- ```bash
197
- docker pull ghcr.io/lyonzin/knowledge-rag:latest
198
- docker run -v $(pwd)/documents:/app/documents -p 8179:8179 ghcr.io/lyonzin/knowledge-rag:latest
199
- ```
200
-
201
- **Full installation guide with all 5 methods, 8 MCP client configurations, and GPU setup:** [docs/INSTALLATION.md →](docs/INSTALLATION.md)
202
-
203
- ---
204
-
205
- ## 🤖 Ready-to-use skills for AI agents
206
-
207
- Installing knowledge-rag gives your agent 13 MCP tools. It does not tell the agent **when** to use them. That is what the [`skills/`](skills/) folder solves — drop-in behavioural skills for Claude Code, Cursor, Windsurf, Cline, Zed, VS Code Copilot that turn "AI with access to RAG" into "AI that actually uses RAG first".
208
-
209
- **10 skills, MIT licensed, organized by kind:**
210
-
211
- | # | Skill | What it does |
212
- |---|---|---|
213
- | 1 | [`rag-check-first`](skills/foundation/rag-check-first/SKILL.md) | Search the corpus **before** answering any technical claim |
214
- | 2 | [`rag-cite-sources`](skills/foundation/rag-cite-sources/SKILL.md) | Every claim ships with `path:line` citations |
215
- | 3 | [`rag-onboard-context`](skills/foundation/rag-onboard-context/SKILL.md) | First interaction of a session probes what is indexed |
216
- | 4 | [`rag-deep-dive`](skills/workflow/rag-deep-dive/SKILL.md) | 3-step drill: `search` → `fetch` → `find similar` |
217
- | 5 | [`rag-web-fallback`](skills/workflow/rag-web-fallback/SKILL.md) | Only hit the web when local RAG comes back empty |
218
- | 6 | [`rag-troubleshoot`](skills/workflow/rag-troubleshoot/SKILL.md) | Bug / error → RAG first for prior fixes |
219
- | 7 | [`rag-code-review`](skills/workflow/rag-code-review/SKILL.md) | Review consults ADRs / patterns before commenting |
220
- | 8 | [`rag-index-decisions`](skills/maintenance/rag-index-decisions/SKILL.md) | After a decision, index it back — close the feedback loop |
221
- | 9 | [`rag-security-first`](skills/domain/rag-security-first/SKILL.md) | Security tasks: MITRE / CVE / runbook first |
222
- | 10 | [`rag-evaluate-quality`](skills/maintenance/rag-evaluate-quality/SKILL.md) | Weekly checkup — MRR@5 · Recall@5 · Precision@5 |
223
-
224
- **Install — pick the shortest path for your machine:**
225
-
226
- ```bash
227
- # Option 1 — Via skills.sh (needs Node — one command, zero clone)
228
- npx skills add lyonzin/knowledge-rag
229
-
230
- # Option 2 — Via our install.sh (no Node needed; works on Linux/macOS/WSL/Git Bash)
231
- curl -fsSL https://raw.githubusercontent.com/lyonzin/knowledge-rag/master/skills/install.sh | bash
232
- ```
233
-
234
- Both restart-Claude-Code and you are done. Option 2 supports `--project`, `--only rag-check-first,rag-cite-sources`, `--dry-run`, `--help`.
235
-
236
- For Cursor, Windsurf, Cline and full manual instructions → [skills/README.md](skills/README.md) · Full catalog with skill chains → [skills/CATALOG.md](skills/CATALOG.md)
237
-
238
- ---
239
-
240
- ## 🛠️ The 13 MCP tools your agent gets
241
-
242
- Once installed, your AI agent gets these 13 tools automatically:
243
-
244
- | Tool | Purpose |
245
- |---|---|
246
- | `search_knowledge` | Hybrid semantic + BM25 with cross-encoder rerank |
247
- | `get_document` | Retrieve full content of one document |
248
- | `search_similar` | Find documents similar to a reference |
249
- | `evaluate_retrieval` | Measure MRR@5 · Recall@5 · Precision@5 |
250
- | `add_document` | Index a new document via MCP |
251
- | `update_document` | Re-index a changed document |
252
- | `remove_document` | Drop a document + all its chunks |
253
- | `add_from_url` | Fetch, sanitize, and index a URL |
254
- | `list_documents` | Enumerate indexed documents |
255
- | `list_categories` | Auto-tagged by folder path |
256
- | `get_index_stats` | Corpus size, cache hit rate, embedding dim |
257
- | `reindex_documents` | Smart incremental OR nuclear rebuild |
258
- | `get_reindex_status` | Live progress polling (async reindex) |
259
-
260
- **Full API reference with parameter details, return schemas, examples:** [docs/API.md →](docs/API.md)
261
-
262
- ---
263
-
264
- ## 🏢 Enterprise Features (built-in, zero configuration)
265
-
266
- Every RAG framework claims "production-ready." Here is what knowledge-rag ships **in the OSS core, verified by regression tests, that competitors either paywall, plugin-ify, or simply don't have.**
267
-
268
- <table>
269
- <tr>
270
- <td valign="top" width="50%">
271
-
272
- ### Security
273
-
274
- - **Bearer token auth** on SSE / HTTP transports — constant-time comparison (`hmac.compare_digest`), RFC 6750 challenge, 401 fenced with `WWW-Authenticate` header
275
- - **Path traversal + symlink escape defenses** — `validate_path_within` guarding 6 CRUD tools (CWE-22, CWE-59)
276
- - **Prompt injection 3-layer defense** — sentinel neutralization + provenance fence + `external_source` flag (OWASP LLM01:2025)
277
- - **OpenSSF Best Practices badge** verified · **CodeQL** weekly scan · **Bandit + Semgrep + Gitleaks + pip-audit** on every PR
278
- - **PyPI Trusted Publishing** via OIDC (zero long-lived tokens in CI)
279
-
280
- </td>
281
- <td valign="top" width="50%">
282
-
283
- ### Observability
284
-
285
- - **Prometheus `/metrics` endpoint** — custom histogram buckets tuned for RAG (p95 ≤ 10ms fast-path targets), 7 canonical metrics via `@instrument` decorator on all 13 tools
286
- - **Rate limiting** — thread-safe sliding-window counter, per-client RPM + burst, zero overhead when disabled
287
- - **Health probes** — `GET /health` and `/healthz` returning `{status, version, uptime_seconds, cache}` in front of the auth middleware (probes always succeed)
288
- - **Structured JSON logging** — opt-in via `server.logging.format: "json"`, one JSON object per record ready for ELK / Loki / Datadog / CloudWatch
289
- - **Public benchmark dashboard** on GitHub Pages
290
-
291
- </td>
292
- </tr>
293
- <tr>
294
- <td valign="top" width="50%">
295
-
296
- ### Scale & performance
297
-
298
- - **SSE / streamable-http transport** — 1 server serves N MCP clients, ChromaDB WAL mode enabled automatically, shared embedding model + query cache
299
- - **BM25 inverted-index** — **128× faster** than linear scan (custom implementation, replaces `rank-bm25`)
300
- - **FTS5 SQLite fast-path** (opt-in, ADR-002/003/006/008) — <10ms cold, <2ms hot on lexical queries
301
- - **Cross-encoder reranking** — Xenova/ms-marco-MiniLM-L-6-v2, +1.88pp Recall@10 (p<0.001)
302
- - **GPU CUDA 12** with auto DLL discovery + graceful CPU fallback
303
- - **Query cache** — LRU + 5-min TTL, cuts p95 latency ~40%
304
- - **Zero-downtime reindex** — staging populate + validation + atomic swap + durable metadata rollback
305
- - **Async background reindex** with `get_reindex_status()` polling
306
-
307
- </td>
308
- <td valign="top" width="50%">
309
-
310
- ### Reliability
311
-
312
- - **Nightly chaos injection** — HuggingFace Hub offline · ONNX zero-byte replay · watchdog crash recovery (3 scenarios in `tests/chaos/`)
313
- - **50 000-iteration soak test** — proves no memory leak after 1h of continuous queries (`KNOWLEDGE_RAG_SOAK_ITERATIONS=50000`)
314
- - **Mutation testing** (mutmut) on `instance_lock` + `preflight` — catches tests that are too weak
315
- - **Determinism check** — full test suite × 3, catches flakes
316
- - **Backwards-compat frozen** — 13 MCP tool parameter names guarded by `tests/test_backwards_compat.py` + legacy YAML fixtures (v3.6.0 / v3.7.0) still parse
317
- - **API surface AST diff** — `check_api_surface.py` blocks any breaking change at PR time
318
- - **9-cell CI matrix** — Linux + Windows + macOS × 3.11 + 3.12 + 3.13
319
-
320
- </td>
321
- </tr>
322
- </table>
323
-
324
- ---
325
-
326
- ## 💼 Use Cases (real corpora, real teams)
327
-
328
- ### Security Teams — Red / Blue / CTF
329
-
330
- **Preset:** [`cybersecurity.yaml`](presets/cybersecurity.yaml) · 8 categories · 200+ routing keywords · 69 query expansions
331
-
332
- Ingest MITRE ATT&CK, threat reports, exploit writeups, incident reports. Search from Claude Code with `search_knowledge("privilege escalation windows")` and get instant recall across your entire corpus. Air-gapped — nothing leaves the laptop.
333
-
334
- ### Development Teams — Design Docs, Runbooks, Code
335
-
336
- **Preset:** [`developer.yaml`](presets/developer.yaml) · 9 categories · 150+ routing keywords · 50+ expansions
337
-
338
- Replace Confluence hunting. Ingest architecture docs, ADRs, runbooks, code, API specs. Devs ask their AI agent "how do we authenticate the payment service" and get the exact ADR + implementation file citation.
339
-
340
- ### Research Labs — Papers, Notebooks, Datasets
341
-
342
- **Preset:** [`research.yaml`](presets/research.yaml) · 9 categories · 100+ routing keywords · 40+ expansions
343
-
344
- Index arXiv papers, lab notebooks, dataset documentation. Semantic search finds papers by intent, not just keywords — cross-encoder reranking surfaces the actually-relevant one instead of five that share a term.
345
-
346
- ### Enterprise Knowledge Base — Air-gapped, Auditable
347
-
348
- **Preset:** [`general.yaml`](presets/general.yaml) · blank slate, pure semantic search
349
-
350
- Deploy via SSE on a single VM. 40+ users authenticated via bearer token, rate-limited, Prometheus-monitored, `/health` probes wired to your load balancer, JSON logs shipped to Datadog. No cloud calls. Meets LGPD, GDPR, HIPAA data-locality requirements by design.
351
-
352
- **Verified at scale:** production reproduction on a **5 889-doc / 75 016-chunk corpus** with concurrent queries during a nuclear rebuild — zero downtime, zero errors (see [CHANGELOG v4.8.3](CHANGELOG.md#v483-2026-08-10--critical-hotfix-nuclear-rebuild--smart-reindex-hardening)).
353
-
354
- ---
355
-
356
- ## 🏗️ Architecture at a glance
357
-
358
- End-to-end view of how MCP clients, the retrieval pipeline, storage, and enterprise plumbing connect. Every arrow is a real code path — nothing pictured here is aspirational.
359
-
360
- ```mermaid
361
- flowchart TB
362
- subgraph CLIENTS["MCP Clients (any of these)"]
363
- C1[Claude Code]
364
- C2[Claude Desktop]
365
- C3[Cursor]
366
- C4[Windsurf]
367
- C5[VS Code · Cline · Gemini CLI · Zed]
368
- end
369
-
370
- subgraph TRANSPORT["Transport Layer"]
371
- T1[stdio<br/>1 process per client]
372
- T2[SSE / streamable-http<br/>1 server serves N clients]
373
- end
374
-
375
- subgraph MIDDLEWARE["ASGI Middleware Chain (HTTP mode)"]
376
- M1[HealthMiddleware<br/>/health · /healthz]
377
- M2[BearerAuthMiddleware<br/>constant-time compare]
378
- M3[Rate Limiter<br/>sliding window]
379
- end
380
-
381
- subgraph MCP["13 MCP Tools (frozen contract)"]
382
- MT1[search_knowledge]
383
- MT2[get_document · search_similar]
384
- MT3[add_document · add_from_url · update · remove]
385
- MT4[reindex_documents · get_reindex_status]
386
- MT5[list_documents · list_categories · get_index_stats · evaluate_retrieval]
387
- end
388
-
389
- subgraph SEARCH["Retrieval Pipeline"]
390
- R[Query Router<br/>lexical vs semantic]
391
- F[FTS5 Fast-Path<br/>opt-in · lt 10ms]
392
- BM[BM25 Inverted Index<br/>128x faster than baseline]
393
- SE[Semantic Search<br/>FastEmbed ONNX lazy-loaded]
394
- RRF[Reciprocal Rank Fusion]
395
- CE[Cross-Encoder Rerank<br/>MiniLM-L-6-v2]
396
- QC[Query Cache<br/>LRU + 5-min TTL]
397
- end
398
-
399
- subgraph STORAGE["Storage (100% local)"]
400
- CH[ChromaDB<br/>vectors + metadata<br/>WAL mode]
401
- FT[SQLite FTS5<br/>lexical index<br/>WAL + busy-timeout]
402
- MD[index_metadata.json<br/>durable state]
403
- end
404
-
405
- subgraph INGEST["Document Ingestion"]
406
- FS[documents/ folder]
407
- WD[Watchdog<br/>10s debounce]
408
- PA[35 Parsers<br/>MD · PDF · DOCX · code · IaC · IPYNB]
409
- CK[Chunker<br/>markdown-aware · code-aware]
410
- EM[FastEmbed ONNX<br/>384D bge-small-en-v1.5]
411
- DD[SHA256 Dedup]
412
- SW[Zero-downtime Staging Swap<br/>rollback on validation fail]
413
- end
414
-
415
- subgraph OBS["Enterprise Observability (opt-in)"]
416
- PM[Prometheus /metrics<br/>7 canonical + histograms]
417
- LG[Structured JSON logs<br/>ELK · Loki · Datadog · CloudWatch]
418
- HC[Health payload<br/>version · uptime · cache stats]
419
- end
420
-
421
- subgraph CFG["Configuration"]
422
- YM[config.yaml<br/>+ 5 domain presets]
423
- end
424
-
425
- C1 & C2 & C3 & C4 & C5 -->|MCP protocol| T1
426
- C1 & C2 & C3 & C4 & C5 -.->|remote deploy| T2
427
- T1 --> MCP
428
- T2 --> M1 --> M2 --> M3 --> MCP
429
-
430
- MT1 --> QC
431
- QC -->|cache miss| R
432
- R -->|lexical| F
433
- R -->|semantic| SE
434
- R -->|hybrid| BM
435
- F --> CH
436
- F --> FT
437
- BM --> CH
438
- SE --> CH
439
- BM --> RRF
440
- SE --> RRF
441
- RRF --> CE
442
- CE --> QC
443
-
444
- MT2 --> CH
445
- MT3 --> INGEST
446
- MT4 --> SW
447
- MT5 --> CH
448
-
449
- FS --> WD --> PA
450
- PA --> CK --> EM --> DD --> CH
451
- SW -.->|atomic swap| CH
452
- SW -.-> FT
453
- CH -.-> MD
454
-
455
- MCP -.->|instrumented| PM
456
- MCP -.->|logs| LG
457
- M1 --> HC
458
-
459
- YM -.-> SEARCH
460
- YM -.-> STORAGE
461
- YM -.-> OBS
462
- YM -.-> MIDDLEWARE
463
-
464
- classDef client fill:#3776AB,stroke:#1e5a8a,color:#fff
465
- classDef transport fill:#00A67E,stroke:#006e54,color:#fff
466
- classDef middleware fill:#6b46c1,stroke:#4c1d95,color:#fff
467
- classDef storage fill:#4b5563,stroke:#1f2937,color:#fff
468
- classDef obs fill:#dc2626,stroke:#7f1d1d,color:#fff
469
- classDef ingest fill:#f59e0b,stroke:#78350f,color:#fff
470
-
471
- class C1,C2,C3,C4,C5 client
472
- class T1,T2 transport
473
- class M1,M2,M3 middleware
474
- class CH,FT,MD storage
475
- class PM,LG,HC obs
476
- class FS,WD,PA,CK,EM,DD,SW ingest
477
- ```
478
-
479
- **Reading the diagram (top → bottom):**
480
-
481
- 1. **Any MCP client** — Claude Code, Cursor, Windsurf, and 5 others — connects via the transport of your choice (stdio for personal use, SSE/streamable-http for teams).
482
- 2. **HTTP mode chains 3 ASGI middlewares in order**: health probes first (always answered), then bearer auth (fenced with `WWW-Authenticate`), then rate limiter (sliding window).
483
- 3. **All 13 MCP tools** are decorated with `@rate_limited` + `@instrument` — Prometheus counts every call, rate limiter enforces RPM+burst, both zero-cost when disabled.
484
- 4. **`search_knowledge` checks the query cache first**; cache miss routes through the Query Router (regex classifier) to either the FTS5 fast-path (lexical) or the hybrid pipeline (BM25 + semantic + RRF + cross-encoder rerank).
485
- 5. **Storage is 100% local**: ChromaDB (WAL mode) for vectors + metadata, SQLite FTS5 (WAL + busy-timeout) for lexical fast-path, `index_metadata.json` for durable state.
486
- 6. **Document ingestion runs continuously**: watchdog observes `documents/`, 35 parsers handle each format, chunker respects language boundaries, FastEmbed ONNX generates embeddings, SHA256 deduplicates, and a staging swap performs zero-downtime rebuilds with rollback-on-failure.
487
- 7. **Enterprise observability** (opt-in) — Prometheus `/metrics`, structured JSON logs, `/health` payload — attaches to the same instrumentation points, no code changes required.
488
- 8. **`config.yaml` (with 5 domain presets)** controls every subsystem — no environment variable spaghetti, no hardcoded paths.
489
-
490
- **Complete architecture — 4 detailed Mermaid diagrams (System Overview · Query Flow · Document Ingestion · hybrid_alpha effect):** [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
491
-
492
- ---
493
-
494
- ## 📄 35 File Formats — parsed natively, no plugins needed
495
-
496
- Every parser is **chunk-aware** — Markdown splits at `##` headers, code splits at function/class boundaries, notebooks skip base64 outputs, PDFs use PyMuPDF, spreadsheets extract sheet-by-sheet. **33 formats are enabled by default**; the 2 MetaTrader formats are opt-in (add to `documents.supported_formats` in `config.yaml`).
497
-
498
- | # | Format | Extension | Parser | Default | Notes |
499
- |---|--------|-----------|--------|:-------:|-------|
500
- | 1 | Markdown | `.md` | Section-aware (splits at `##`) | Yes | Headers preserved as chunk boundaries |
501
- | 2 | Plain Text | `.txt` | Fixed-size chunking | Yes | 1000 chars + 200 overlap |
502
- | 3 | PDF | `.pdf` | PyMuPDF extraction | Yes | Text-based PDFs only (no OCR) |
503
- | 4 | Word | `.docx` | python-docx | Yes | Headings preserved as markdown |
504
- | 5 | Excel | `.xlsx` | openpyxl | Yes | Sheet-by-sheet extraction |
505
- | 6 | PowerPoint | `.pptx` | python-pptx | Yes | Slide-by-slide extraction |
506
- | 7 | Jupyter Notebook | `.ipynb` | Cell-aware parser | Yes | Markdown + code cells only; skips outputs/base64 |
507
- | 8 | JSON | `.json` | Structure-aware | Yes | Flattened key-value extraction |
508
- | 9 | CSV | `.csv` | Row-based parser | Yes | Headers + rows as text |
509
- | 10 | XML | `.xml` | XML parser | Yes | Root element + namespace metadata |
510
- | 11 | Python | `.py` | Code-aware parser | Yes | Functions/classes as chunks |
511
- | 12 | C Source | `.c` | Code-aware parser | Yes | Functions / structs / includes extracted |
512
- | 13 | C/C++ Header | `.h` | Code-aware parser | Yes | Function declarations + structs extracted |
513
- | 14 | C++ Source | `.cpp` | Code-aware parser | Yes | Classes / structs / includes extracted |
514
- | 15 | JavaScript | `.js` | Code-aware parser | Yes | Functions / classes / imports (ESM + CJS) |
515
- | 16 | React JSX | `.jsx` | Code-aware parser | Yes | Same as JS parser |
516
- | 17 | TypeScript | `.ts` | Code-aware parser | Yes | Functions / classes / interfaces / enums / imports |
517
- | 18 | React TSX | `.tsx` | Code-aware parser | Yes | Same as TS parser |
518
- | 19 | Go | `.go` | Code-aware parser | Yes | Functions / structs / imports extracted |
519
- | 20 | Rust | `.rs` | Code-aware parser | Yes | Functions / structs / enums / traits / `use` imports |
520
- | 21 | Kotlin | `.kt` | Code-aware parser | Yes | Functions (incl. class members) / classes extracted |
521
- | 22 | YAML | `.yaml` | YAML parser | Yes | Kubernetes kind / apiVersion / name extracted |
522
- | 23 | YAML | `.yml` | YAML parser | Yes | Same as YAML parser |
523
- | 24 | HuJSON | `.hujson` | HuJSON parser | Yes | JSON with comments + trailing commas (e.g. Tailscale ACLs) |
524
- | 25 | CUE | `.cue` | Code-aware parser | Yes | Imports / package extracted |
525
- | 26 | Protocol Buffers | `.proto` | Proto parser | Yes | Services / messages / RPCs extracted |
526
- | 27 | Rego | `.rego` | Code-aware parser | Yes | OPA policies — imports / package extracted |
527
- | 28 | SQL | `.sql` | SQL parser | Yes | Table names + statement types extracted |
528
- | 29 | Shell | `.sh` | Shell parser | Yes | Function names extracted |
529
- | 30 | jq | `.jq` | Shell parser | Yes | Indexed as shell-style script |
530
- | 31 | Dockerfile | `Dockerfile` | Text parser | Yes | Matched by exact filename (no extension) |
531
- | 32 | Makefile | `Makefile` | Text parser | Yes | Matched by exact filename (no extension) |
532
- | 33 | Tiltfile | `Tiltfile` | Code-aware parser | Yes | Starlark — `def` functions / `load()` extracted |
533
- | 34 | MQL4 Source | `.mq4` | Code parser | **No** | MetaTrader — opt-in via `documents.supported_formats` |
534
- | 35 | MQL4 Header | `.mqh` | Code parser | **No** | MetaTrader — opt-in via `documents.supported_formats` |
535
-
536
- > **Enable an opt-in format** — add the extension to `documents.supported_formats` in your `config.yaml`:
537
- > ```yaml
538
- > documents:
539
- > supported_formats: [".md", ".pdf", ".mq4", ".mqh"]
540
- > ```
541
-
542
- **Full parser reference with per-format notes:** [docs/CONFIGURATION.md](docs/CONFIGURATION.md)
543
-
544
- ---
545
-
546
- ## 🔌 Choose your MCP integration
547
-
548
- <table>
549
- <tr>
550
- <td align="center" width="14%">
551
-
552
- **Claude Code**<br/>
553
- `~/.claude.json`
554
-
555
- </td>
556
- <td align="center" width="14%">
557
-
558
- **Claude Desktop**<br/>
559
- `claude_desktop_config.json`
560
-
561
- </td>
562
- <td align="center" width="14%">
563
-
564
- **Cursor**<br/>
565
- `~/.cursor/mcp.json`
566
-
567
- </td>
568
- <td align="center" width="14%">
569
-
570
- **Windsurf**<br/>
571
- `~/.codeium/windsurf/mcp_config.json`
572
-
573
- </td>
574
- <td align="center" width="14%">
575
-
576
- **VS Code**<br/>
577
- Copilot Chat `mcp.json`
578
-
579
- </td>
580
- <td align="center" width="14%">
581
-
582
- **Cline · Gemini CLI · Zed**<br/>
583
- Native MCP
584
-
585
- </td>
586
- </tr>
587
- </table>
588
-
589
- **Complete client configuration guide with JSON schemas per client:** [docs/INSTALLATION.md#use-with-other-mcp-clients →](docs/INSTALLATION.md#use-with-other-mcp-clients)
590
-
591
- ---
592
-
593
- ## ⚙️ Configuration in 30 seconds
594
-
595
- ```yaml
596
- # config.yaml — everything is optional; defaults just work
597
-
598
- paths:
599
- documents_dir: "./documents"
600
- data_dir: "./data"
601
-
602
- models:
603
- embedding:
604
- profile: "compact" # "compact" | "quality" | "multilingual" | "custom"
605
- gpu: "auto" # "auto" | "true" | "false"
606
- reranker:
607
- enabled: true # cross-encoder rerank
608
-
609
- search:
610
- default_results: 5
611
- max_results: 100
612
-
613
- server: # optional — SSE / HTTP mode
614
- transport: "stdio" # or "sse" / "streamable-http"
615
- auth:
616
- bearer_token: "" # set a secret to enable auth
617
- rate_limit:
618
- enabled: false
619
- metrics:
620
- enabled: false
621
- logging:
622
- format: "text" # or "json"
623
- ```
624
-
625
- **Pre-built presets:** [`cybersecurity.yaml`](presets/cybersecurity.yaml) · [`developer.yaml`](presets/developer.yaml) · [`research.yaml`](presets/research.yaml) · [`general.yaml`](presets/general.yaml) · [`multilingual.yaml`](presets/multilingual.yaml)
626
-
627
- **Complete configuration reference — every field, every default, tuning guide:** [docs/CONFIGURATION.md →](docs/CONFIGURATION.md)
628
-
629
- ---
630
-
631
- ## 🔒 Security & Compliance
632
-
633
- knowledge-rag is designed for teams that cannot let their documents leave the perimeter.
634
-
635
- | Requirement | How knowledge-rag delivers |
636
- |---|---|
637
- | **Data locality (LGPD / GDPR / HIPAA)** | 100% on-premise, zero egress network calls after initial model download |
638
- | **Air-gapped deployment** | ONNX models pre-cached; set `HF_HUB_OFFLINE=1` to enforce zero-network |
639
- | **CVE monitoring** | Dependabot (weekly) + pip-audit + Socket + CodeQL |
640
- | **Supply chain security** | PyPI Trusted Publishing via OIDC (no long-lived tokens) |
641
- | **Vulnerability disclosure** | Private security advisory via [SECURITY.md](SECURITY.md) |
642
- | **Signed release attestations** | GitHub release attestations on every published version |
643
- | **Reproducible builds** | Locked `requirements.txt` with pinned versions |
644
- | **Authenticated access** | Bearer token middleware on SSE / HTTP transports (constant-time compare, RFC 6750) |
645
- | **Rate limiting** | Sliding-window per-client RPM + burst (opt-in, zero-cost when disabled) |
646
- | **Audit-ready logging** | Opt-in structured JSON logs → ship to your SIEM |
647
- | **Path traversal defenses** | CWE-22 / CWE-59 guards on 6 CRUD tools |
648
- | **Prompt injection defense** | 3-layer sanitization on `add_from_url` (OWASP LLM01:2025) |
649
-
650
- **OpenSSF Best Practices** badge: passing · project ID [#13864](https://bestpractices.coreinfrastructure.org/projects/13864)
651
-
652
- ---
653
-
654
- ## 📈 Numbers that matter
655
-
656
- - **26 000+** total downloads on PyPI · **250+** GitHub stars · **70+** enterprise teams (private + community)
657
- - **700+ tests** collected · **1.33:1** test-to-code ratio · **codecov trend gate** ±0.5pp
658
- - **35+ status checks** on every PR (9-cell OS×Python matrix · 7 quality pillars)
659
- - **35 file formats** parsed natively · **13 MCP tools** frozen · **5 domain presets** (cyber · dev · research · multilingual · general)
660
- - **BM25 128× faster** than baseline · **cross-encoder +1.88pp** Recall@10 (p<0.001) · **cache −40%** p95 latency
661
- - **1 800+ files / 39 K chunks indexed in < 3 min** on a modern laptop (typical developer corpus)
662
- - **Verified in production** on 5 889-doc / 75 016-chunk corpora
663
-
664
- **Public benchmark dashboard:** https://lyonzin.github.io/knowledge-rag/
665
-
666
- ---
667
-
668
- ## 📚 Documentation
669
-
670
- | Doc | What's inside |
671
- |---|---|
672
- | [**Installation guide**](docs/INSTALLATION.md) | 5 install methods · 8 MCP client integrations · GPU setup |
673
- | [**API reference**](docs/API.md) | Complete reference for all 13 MCP tools |
674
- | [**Configuration reference**](docs/CONFIGURATION.md) | Every `config.yaml` field · presets · tuning |
675
- | [**Architecture**](docs/ARCHITECTURE.md) | 4 Mermaid diagrams: System Overview · Query Flow · Ingestion · hybrid_alpha |
676
- | [**Troubleshooting**](docs/TROUBLESHOOTING.md) | 11 common issues + solutions |
677
- | [**FTS5 fast-path guide**](docs/features/fts5_fast_path.md) | Opt-in lexical fast-path — when and how |
678
- | [**Reindex operations**](docs/reindex-operations.md) | Zero-downtime rebuild · resume · checkpoint |
679
- | [**GPU setup**](docs/gpu-setup.md) | CUDA 12 installation + troubleshooting |
680
- | [**Migration to v4.8.0**](docs/migration-v4.8.0.md) | Embedding profile · multilingual · zero-downtime |
681
- | [**Security policy**](SECURITY.md) | Threat model · disclosure channel |
682
- | [**Contributing**](CONTRIBUTING.md) | Development · testing · PR process |
683
- | [**Changelog**](CHANGELOG.md) | All release notes since v1.0.0 |
684
-
685
- ---
686
-
687
- ## 🤝 Community & Support
688
-
689
- - **Report a bug** → [Open an issue](https://github.com/lyonzin/knowledge-rag/issues/new/choose)
690
- - **Ask a question** → [GitHub Discussions](https://github.com/lyonzin/knowledge-rag/discussions)
691
- - **Report a vulnerability** → [Security advisory](https://github.com/lyonzin/knowledge-rag/security/advisories/new) (private)
692
- - **Contribute** → [CONTRIBUTING.md](CONTRIBUTING.md)
693
-
694
- **Response SLA (best-effort, community project):**
695
- - Security reports: within 48 h
696
- - Bug reports with reproduction: within 5 business days
697
- - Feature requests: triaged on next release cycle
698
-
699
- ---
700
-
701
- ## 🗺️ Recent releases
702
-
703
- - **v4.8.5** (2026-08-13) — Enterprise observability: `/health` endpoint + opt-in JSON structured logging
704
- - **v4.8.4** (2026-08-13) — Patch: security + durability + defensive fixes
705
- - **v4.8.3** (2026-08-10) — Critical hotfix: nuclear-rebuild + smart-reindex hardening on 50k+ chunk corpora
706
- - **v4.8.2** (2026-08-10) — FTS5 lexical fast-path opt-in release
707
- - **v4.8.0** (2026-08-06) — Multilingual foundation + zero-downtime reindex
708
-
709
- **Full history:** [CHANGELOG.md →](CHANGELOG.md)
710
-
711
- ---
712
-
713
- ## 📜 License
714
-
715
- **MIT License** — [LICENSE](LICENSE). Forever. No cloud upsell, no dual-licensing, no restrictive clauses. Fork it, sell derivatives, embed it in commercial products — the license does not care.
716
-
717
- ---
718
-
719
- ## 🙏 Acknowledgments
720
-
721
- Built on the shoulders of amazing open-source projects:
722
-
723
- - [**Anthropic MCP**](https://modelcontextprotocol.io/) — Model Context Protocol spec + Python SDK
724
- - [**ChromaDB**](https://www.trychroma.com/) — vector database that just works
725
- - [**FastEmbed**](https://github.com/qdrant/fastembed) — ONNX embeddings, no PyTorch bloat
726
- - [**HuggingFace**](https://huggingface.co/) — model hosting + `Xenova/ms-marco-MiniLM-L-6-v2` cross-encoder
727
- - [**BAAI**](https://huggingface.co/BAAI) — the `bge-small-en-v1.5` embedding model
728
-
729
- **Community contributors:** [@Hohlas](https://github.com/Hohlas) · [@eeshsaxena](https://github.com/eeshsaxena) · Sergey Khokhlov · and everyone who filed issues or PRs.
730
-
731
- ---
732
-
733
- <div align="center">
734
-
735
- **Built by [Ailton Rocha (Lyon.)](https://github.com/lyonzin)** · Star ⭐ if this saves you time · [Report an issue](https://github.com/lyonzin/knowledge-rag/issues/new/choose) · [Contribute](CONTRIBUTING.md)
736
-
737
- *knowledge-rag — the MCP-first local RAG server for Claude Code, Cursor, Windsurf, and every AI agent.*
738
-
739
- </div>
1
+ <!--
2
+ knowledge-rag — Local RAG server for Claude Code, Cursor, Windsurf and other MCP clients.
3
+ SEO keywords: local rag, mcp server, self-hosted rag, hybrid search, cross-encoder reranking, claude code rag, cursor rag, python rag, chromadb rag, fastembed rag, air-gapped rag, gdpr rag, retrieval augmented generation, model context protocol server, zero cloud rag.
4
+
5
+ Structured data (schema.org SoftwareApplication) — indexed by search engines, invisible on GitHub render:
6
+ {
7
+ "@context": "https://schema.org",
8
+ "@type": "SoftwareApplication",
9
+ "name": "knowledge-rag",
10
+ "applicationCategory": "DeveloperApplication",
11
+ "operatingSystem": "Windows, Linux, macOS",
12
+ "description": "Local-first RAG server for AI agents. Hybrid search, MCP-native, zero cloud, enterprise-grade plumbing (bearer auth, Prometheus metrics, rate limiting, health probes, structured JSON logging, zero-downtime reindex).",
13
+ "offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
14
+ "license": "https://opensource.org/licenses/MIT",
15
+ "downloadUrl": "https://pypi.org/project/knowledge-rag/",
16
+ "codeRepository": "https://github.com/lyonzin/knowledge-rag",
17
+ "programmingLanguage": "Python",
18
+ "runtimePlatform": "Python 3.11+"
19
+ }
20
+ -->
21
+
22
+ <p align="center">
23
+ <img
24
+ src="./assets/knowledge-rag-banner.png"
25
+ alt="knowledge-rag — Local Hybrid RAG for MCP"
26
+ width="100%"
27
+ />
28
+ </p>
29
+
30
+ # knowledge-rag
31
+
32
+ <div align="center">
33
+
34
+ [![PyPI](https://img.shields.io/pypi/v/knowledge-rag)](https://pypi.org/project/knowledge-rag/)
35
+ [![NPM](https://img.shields.io/npm/v/knowledge-rag)](https://www.npmjs.com/package/knowledge-rag)
36
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/knowledge-rag?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/knowledge-rag)
37
+ ![Python](https://img.shields.io/badge/python-3.11%2B-green.svg)
38
+ ![License](https://img.shields.io/badge/license-MIT-yellow.svg)
39
+ ![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)
40
+ ![GPU](https://img.shields.io/badge/GPU-NVIDIA%20CUDA-76B900.svg?logo=nvidia)
41
+ [![CI](https://github.com/lyonzin/knowledge-rag/actions/workflows/ci.yml/badge.svg)](https://github.com/lyonzin/knowledge-rag/actions/workflows/ci.yml)
42
+ [![CodeQL](https://github.com/lyonzin/knowledge-rag/actions/workflows/security.yml/badge.svg)](https://github.com/lyonzin/knowledge-rag/actions/workflows/security.yml)
43
+ [![Quality Gate](https://github.com/lyonzin/knowledge-rag/actions/workflows/quality-gate.yml/badge.svg)](https://github.com/lyonzin/knowledge-rag/actions/workflows/quality-gate.yml)
44
+ [![Glama Score](https://glama.ai/mcp/servers/lyonzin/knowledge-rag/badges/score.svg)](https://glama.ai/mcp/servers/lyonzin/knowledge-rag)
45
+ [![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/13864/badge)](https://bestpractices.coreinfrastructure.org/projects/13864)
46
+
47
+ ### The MCP-first local RAG server for Claude Code, Cursor, and every AI agent.
48
+
49
+ **Hybrid search · Cross-encoder reranking · 35 file formats · 100% local · Zero cloud · Enterprise-grade plumbing built-in.**
50
+
51
+ ```bash
52
+ pip install knowledge-rag → restart Claude Code → search_knowledge("your query")
53
+ ```
54
+
55
+ [Quick Start](#quick-start-3-minutes-from-zero-to-your-first-query) ·
56
+ [Why knowledge-rag](#why-knowledge-rag) ·
57
+ [Compare](#how-knowledge-rag-compares-to-other-rag-frameworks) ·
58
+ [Enterprise Features](#enterprise-features-built-in-zero-configuration) ·
59
+ [Docs](#documentation)
60
+
61
+ </div>
62
+
63
+ ---
64
+
65
+ ## ⭐ Star History
66
+
67
+ <div align="center">
68
+
69
+ <a href="https://www.star-history.com/?repos=lyonzin%2Fknowledge-rag&type=date&legend=top-left">
70
+ <img alt="knowledge-rag star history chart — GitHub star growth over time" src="./docs/star-history.svg" width="720" />
71
+ </a>
72
+
73
+ <sub>Chart updated daily by <a href="./.github/workflows/update-star-history.yml">GitHub Action</a></sub>
74
+
75
+ </div>
76
+
77
+ ---
78
+
79
+ ## 🎯 Why knowledge-rag
80
+
81
+ Most RAG frameworks fall into one of three traps: (1) they require you to ship your data to a cloud API, (2) they hand you 300 building blocks and 0 opinionated defaults, or (3) they bundle RAG as a 5% feature of a much bigger platform you didn't ask for.
82
+
83
+ **knowledge-rag is an MCP-native local RAG server** for clients such as Claude Code, Cursor, Windsurf, VS Code, Cline, Gemini CLI and Zed. It includes optional bearer authentication, Prometheus metrics, rate limiting, health probes, structured JSON logging and staging-based rebuilds. Configure the transport and access controls for the intended deployment.
84
+
85
+ <table>
86
+ <tr>
87
+ <td width="50%" valign="top">
88
+
89
+ ### 🔒 100% local, 0% cloud
90
+ Embedding generation, indexing, and retrieval run locally. Model downloads and `add_from_url` use network access, and configured MCP clients receive retrieved content. Choose the corpus, client permissions, and network exposure to fit your deployment; this project does not certify regulatory compliance.
91
+
92
+ </td>
93
+ <td width="50%" valign="top">
94
+
95
+ ### 🚀 Zero-friction setup
96
+ `pip install knowledge-rag` → restart your MCP client → done. **No Docker mandatory. No Ollama required. No separate embedding server.** Everything runs in-process via FastEmbed ONNX. **Works offline** after the first model download.
97
+
98
+ </td>
99
+ </tr>
100
+ <tr>
101
+ <td width="50%" valign="top">
102
+
103
+ ### 🛡️ Production-grade OSS
104
+ 7-pillar quality workflow, a 9-cell OS×Python CI matrix (Linux + Windows + macOS × 3.11/3.12/3.13), and nightly chaos, bounded-memory soak and mutation tests. Inspect the checks on the revision being deployed; CI coverage is not a guarantee of zero defects.
105
+
106
+ </td>
107
+ <td width="50%" valign="top">
108
+
109
+ ### 💰 Zero ongoing cost
110
+ No token bills. No SaaS tier. No paid features hidden behind a wall. **MIT license, forever.** Runs on the laptop you already have — GPU optional, CPU works fine with FastEmbed ONNX.
111
+
112
+ </td>
113
+ </tr>
114
+ </table>
115
+
116
+ ---
117
+
118
+ ## 📊 How knowledge-rag compares to other RAG frameworks
119
+
120
+ Compare the features needed for your deployment rather than treating framework
121
+ checklists as a benchmark. Knowledge-rag combines MCP tools, local embeddings,
122
+ ChromaDB persistence, BM25, optional FTS5 and optional reranking in one process.
123
+
124
+ | Decision | What to verify |
125
+ | --- | --- |
126
+ | Local or remote processing | Where models run, which client receives content, and which features need network access |
127
+ | Retrieval quality | Expected-source queries on your corpus, including its languages and identifiers |
128
+ | Performance | Cold initialization, indexing, uncached queries, memory peaks and concurrent use on comparable hardware |
129
+ | Operations | Authentication, metrics exposure, backups, recovery and one-writer ownership |
130
+ | Extensibility | Supported parsers, model profiles and the public MCP contract |
131
+
132
+ The [audit report](docs/audit-2026-10-03.md) records a reproducible local workload
133
+ and its limitations. Results against an older implementation of this project are
134
+ not speed comparisons against other RAG frameworks.
135
+ ---
136
+
137
+ ## 🚀 Quick Start (3 minutes, from zero to your first query)
138
+
139
+ Pick your integration path — knowledge-rag ships the same server through every channel.
140
+
141
+ ### Path 1 — Claude Code, Cursor, Windsurf, Cline, VS Code, Gemini CLI, Zed (MCP)
142
+
143
+ ```bash
144
+ pip install knowledge-rag
145
+ knowledge-rag init # scaffolds config.yaml + documents/
146
+ ```
147
+
148
+ Drop your PDFs, markdown, code files into `documents/`. Restart your MCP client. Ask it:
149
+
150
+ ```
151
+ search_knowledge("your query")
152
+ ```
153
+
154
+ That's it. First query loads the ONNX embedding model (~200MB, one-off download). Subsequent queries are cached and hit sub-second latency.
155
+
156
+ ### Path 2 — HTTP / SSE server (multi-user, air-gapped, load-balanced)
157
+
158
+ ```yaml
159
+ # config.yaml
160
+ server:
161
+ transport: "sse" # or "streamable-http"
162
+ host: "0.0.0.0"
163
+ port: 8179
164
+ auth:
165
+ bearer_token: "your-secret-token"
166
+ rate_limit:
167
+ enabled: true
168
+ requests_per_minute: 60
169
+ metrics:
170
+ enabled: true
171
+ port: 9179
172
+ logging:
173
+ format: "json" # ELK / Loki / Datadog / CloudWatch ready
174
+ ```
175
+
176
+ ```bash
177
+ knowledge-rag --transport sse
178
+ ```
179
+
180
+ - Health probe: `curl http://your-host:8179/health` → 200 + JSON payload
181
+ - Prometheus scrape: `http://your-host:9179/metrics`
182
+ - MCP dispatcher: authenticated via `Authorization: Bearer your-secret-token`
183
+
184
+ ### Multi-client setup (Shared Server via Streamable HTTP)
185
+
186
+ `stdio` is ideal when one MCP client owns one `knowledge-rag` process. If several clients (e.g. Claude, Cursor, LM Studio, or multiple terminal windows) should share one index and one running process, run `knowledge-rag` once with Streamable HTTP and point each HTTP-capable client at the same endpoint (prompted by [#217](https://github.com/lyonzin/knowledge-rag/pull/217) and issue [#223](https://github.com/lyonzin/knowledge-rag/issues/223)):
187
+
188
+ ```bash
189
+ knowledge-rag --transport streamable-http
190
+ # MCP endpoint: http://127.0.0.1:8179/mcp
191
+ ```
192
+
193
+ - **Local MCP clients (Cursor, LM Studio, etc.):** Point their remote-server URL directly at `http://127.0.0.1:8179/mcp`.
194
+ - **Claude Custom Connectors (Remote MCP):**
195
+ - **Network requirement:** Custom connector requests originate from Anthropic's cloud infrastructure across web, desktop, and mobile, so they cannot reach local `127.0.0.1`. You must expose your server via a secure, publicly accessible HTTPS endpoint (e.g. Cloudflare Tunnel, ngrok, or reverse proxy) at `https://your-public-domain/mcp`. Configure the proxy to send an upstream `Host` accepted by the HTTP app for `server.host` (for the default loopback configuration, use `127.0.0.1:8179`); forwarding the public hostname unchanged can produce `421 Invalid Host header`. Keep bearer authentication and HTTPS enabled. Local `claude_desktop_config.json` uses `command`/`args` for local stdio processes and does not support remote HTTP endpoints.
196
+ - **Setup & Auth:** In Claude (Pro/Max plans: **Customize > Connectors > + Add > Add custom connector**; Team/Enterprise owners: **Organization settings > Connectors**), enter your public endpoint. In **Request headers**, set header name `Authorization` with value `Bearer <your-token>` matching `server.auth.bearer_token` in `config.yaml` (see [Anthropic Custom Connectors documentation](https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp)).
197
+
198
+ | Transport | Clients | Shared index / process | RAM overhead | Process management | Startup & query latency | Best fit |
199
+ |---|:---:|:---:|---|---|---|---|
200
+ | `stdio` | 1 | No | 1 runtime per client; models load lazily in each process when queried | Client manages its own process; no separate server | Spawns per client; pays preflight and first-query model load | Simplest local setup (single client) |
201
+ | `sse` | Many | Yes | Shared server process; single shared model load across clients | Operator manages one background server | Reuses warm server; first-query model load still applies | Legacy HTTP clients |
202
+ | `streamable-http` | Many | Yes | Shared server process; single shared model load across clients | Operator manages one background server | Reuses warm server; first-query model load still applies | **Preferred** shared-server setup |
203
+
204
+ When an HTTP transport is selected, `knowledge-rag` automatically enables its single-instance lock (`KNOWLEDGE_RAG_SINGLE_INSTANCE=1`) to prevent multiple servers from binding the same data directory or port.
205
+
206
+ > **Security note:** The default host is `127.0.0.1`. If you bind to `0.0.0.0` or deploy across a network, configure `server.auth.bearer_token` in `config.yaml` and terminate TLS (HTTPS) via a reverse proxy (e.g. Caddy, Nginx) to protect bearer tokens in transit; otherwise the server warns that the HTTP endpoint is unauthenticated.
207
+
208
+ ### Path 3 — Docker (models pre-downloaded, air-gapped ready)
209
+
210
+ ```bash
211
+ docker pull ghcr.io/lyonzin/knowledge-rag:latest
212
+ docker run -v $(pwd)/documents:/app/documents -p 8179:8179 ghcr.io/lyonzin/knowledge-rag:latest
213
+ ```
214
+
215
+ **Full installation guide with all 5 methods, 8 MCP client configurations, and GPU setup:** [docs/INSTALLATION.md →](docs/INSTALLATION.md)
216
+
217
+ ---
218
+
219
+ ## 🤖 Ready-to-use skills for AI agents
220
+
221
+ Installing knowledge-rag gives your agent 13 MCP tools. It does not tell the agent **when** to use them. That is what the [`skills/`](skills/) folder solves — drop-in behavioural skills for Claude Code, Cursor, Windsurf, Cline, Zed, VS Code Copilot that turn "AI with access to RAG" into "AI that actually uses RAG first".
222
+
223
+ **10 skills, MIT licensed, organized by kind:**
224
+
225
+ | # | Skill | What it does |
226
+ |---|---|---|
227
+ | 1 | [`rag-check-first`](skills/foundation/rag-check-first/SKILL.md) | Search the corpus **before** answering any technical claim |
228
+ | 2 | [`rag-cite-sources`](skills/foundation/rag-cite-sources/SKILL.md) | Every claim ships with `path:line` citations |
229
+ | 3 | [`rag-onboard-context`](skills/foundation/rag-onboard-context/SKILL.md) | First interaction of a session probes what is indexed |
230
+ | 4 | [`rag-deep-dive`](skills/workflow/rag-deep-dive/SKILL.md) | 3-step drill: `search` → `fetch` → `find similar` |
231
+ | 5 | [`rag-web-fallback`](skills/workflow/rag-web-fallback/SKILL.md) | Only hit the web when local RAG comes back empty |
232
+ | 6 | [`rag-troubleshoot`](skills/workflow/rag-troubleshoot/SKILL.md) | Bug / error → RAG first for prior fixes |
233
+ | 7 | [`rag-code-review`](skills/workflow/rag-code-review/SKILL.md) | Review consults ADRs / patterns before commenting |
234
+ | 8 | [`rag-index-decisions`](skills/maintenance/rag-index-decisions/SKILL.md) | After a decision, index it back — close the feedback loop |
235
+ | 9 | [`rag-security-first`](skills/domain/rag-security-first/SKILL.md) | Security tasks: MITRE / CVE / runbook first |
236
+ | 10 | [`rag-evaluate-quality`](skills/maintenance/rag-evaluate-quality/SKILL.md) | Weekly checkup — MRR@5 · Recall@5 · Precision@5 |
237
+
238
+ **Install — pick the shortest path for your machine:**
239
+
240
+ ```bash
241
+ # Option 1 — Via skills.sh (needs Node — one command, zero clone)
242
+ npx skills add lyonzin/knowledge-rag
243
+
244
+ # Option 2 — Via our install.sh (no Node needed; works on Linux/macOS/WSL/Git Bash)
245
+ curl -fsSL https://raw.githubusercontent.com/lyonzin/knowledge-rag/master/skills/install.sh | bash
246
+ ```
247
+
248
+ Both restart-Claude-Code and you are done. Option 2 supports `--project`, `--only rag-check-first,rag-cite-sources`, `--dry-run`, `--help`.
249
+
250
+ For Cursor, Windsurf, Cline and full manual instructions → [skills/README.md](skills/README.md) · Full catalog with skill chains → [skills/CATALOG.md](skills/CATALOG.md)
251
+
252
+ ---
253
+
254
+ ## 🛠️ The 13 MCP tools your agent gets
255
+
256
+ Once installed, your AI agent gets these 13 tools automatically:
257
+
258
+ | Tool | Purpose |
259
+ |---|---|
260
+ | `search_knowledge` | Hybrid semantic + BM25 with cross-encoder rerank |
261
+ | `get_document` | Retrieve full content of one document |
262
+ | `search_similar` | Find documents similar to a reference |
263
+ | `evaluate_retrieval` | Measure MRR@5 · Recall@5 · Precision@5 |
264
+ | `add_document` | Index a new document via MCP |
265
+ | `update_document` | Re-index a changed document |
266
+ | `remove_document` | Drop a document + all its chunks |
267
+ | `add_from_url` | Fetch, sanitize, and index a URL |
268
+ | `list_documents` | Enumerate indexed documents |
269
+ | `list_categories` | Auto-tagged by folder path |
270
+ | `get_index_stats` | Corpus size, cache hit rate, embedding dim |
271
+ | `reindex_documents` | Smart incremental OR nuclear rebuild |
272
+ | `get_reindex_status` | Live progress polling (async reindex) |
273
+
274
+ **Full API reference with parameter details, return schemas, examples:** [docs/API.md →](docs/API.md)
275
+
276
+ ---
277
+
278
+ ## 🏢 Enterprise Features (built-in, zero configuration)
279
+
280
+ Every RAG framework claims "production-ready." Here is what knowledge-rag ships **in the OSS core, verified by regression tests, that competitors either paywall, plugin-ify, or simply don't have.**
281
+
282
+ <table>
283
+ <tr>
284
+ <td valign="top" width="50%">
285
+
286
+ ### Security
287
+
288
+ - **Bearer token auth** on SSE / HTTP transports — constant-time comparison (`hmac.compare_digest`), RFC 6750 challenge, 401 fenced with `WWW-Authenticate` header
289
+ - **Path traversal + symlink escape defenses** — `validate_path_within` guarding 6 CRUD tools (CWE-22, CWE-59)
290
+ - **External-content handling** — known-token neutralization and a stored provenance fence, with parser metadata propagation. These are limited mitigations; clients must still treat retrieved content as untrusted data. See [SECURITY.md](SECURITY.md).
291
+ - **OpenSSF Best Practices** project [#13864](https://www.bestpractices.dev/en/projects/13864) · **CodeQL** weekly scan · **Bandit + Semgrep + Gitleaks + pip-audit** workflows. Review actual check results and exceptions for the release you deploy.
292
+ - **PyPI Trusted Publishing** via OIDC (zero long-lived tokens in CI)
293
+
294
+ </td>
295
+ <td valign="top" width="50%">
296
+
297
+ ### Observability
298
+
299
+ - **Prometheus `/metrics` endpoint** — custom histogram buckets tuned for RAG (p95 ≤ 10ms fast-path targets), 7 canonical metrics via `@instrument` decorator on all 13 tools
300
+ - **Rate limiting** — thread-safe sliding-window counter, per-client RPM + burst, zero overhead when disabled
301
+ - **Health probes** — `GET /health` and `/healthz` returning `{status, version, uptime_seconds, cache}` in front of the auth middleware (probes always succeed)
302
+ - **Structured JSON logging** — opt-in via `server.logging.format: "json"`, one JSON object per record ready for ELK / Loki / Datadog / CloudWatch
303
+ - **Public benchmark dashboard** on GitHub Pages
304
+
305
+ </td>
306
+ </tr>
307
+ <tr>
308
+ <td valign="top" width="50%">
309
+
310
+ ### Scale & performance
311
+
312
+ - **SSE / streamable-http transport** — 1 server serves N MCP clients, ChromaDB WAL mode enabled automatically, shared embedding model + query cache
313
+ - **BM25 inverted index** — keyword candidate retrieval without scoring every document for every query
314
+ - **FTS5 SQLite fast path** — opt-in lexical retrieval; measure relevance and latency on your identifiers and corpus
315
+ - **Cross-encoder reranking** — Xenova/ms-marco-MiniLM-L-6-v2; optional model scoring of a candidate pool
316
+ - **NVIDIA CUDA embeddings** and experimental Windows AMD DirectML opt-in, with actual-session checks and CPU fallback; [setup and compatibility limits](docs/gpu-setup.md)
317
+ - **Query cache** — LRU + 5-minute TTL, with mutation invalidation
318
+ - **Staging rebuild** — populate and validate a replacement while the current collection remains available; handled publication failures roll back
319
+ - **Async background reindex** with `get_reindex_status()` polling
320
+
321
+ </td>
322
+ <td valign="top" width="50%">
323
+
324
+ ### Reliability
325
+
326
+ - **Nightly chaos injection** — HuggingFace Hub offline · ONNX zero-byte replay · watchdog crash recovery (3 scenarios in `tests/chaos/`)
327
+ - **50,000-iteration soak test** — checks a fixed memory-growth budget with stub embeddings (`KNOWLEDGE_RAG_SOAK_ITERATIONS=50000`); this is not a one-hour real-model endurance test
328
+ - **Mutation testing** (mutmut) on `instance_lock` + `preflight` — catches tests that are too weak
329
+ - **Determinism check** — full test suite × 3, catches flakes
330
+ - **Backwards compatibility** — 13 MCP tools, signature regression tests and legacy YAML fixtures; optional additions preserve existing calls
331
+ - **API surface AST diff** — checks structural signature changes alongside behavioral tests
332
+ - **9-cell CI matrix** — Linux + Windows + macOS × 3.11 + 3.12 + 3.13
333
+
334
+ </td>
335
+ </tr>
336
+ </table>
337
+
338
+ ---
339
+
340
+ ## 💼 Use Cases (real corpora, real teams)
341
+
342
+ ### Security Teams — Red / Blue / CTF
343
+
344
+ **Preset:** [`cybersecurity.yaml`](presets/cybersecurity.yaml) · 8 categories · 200+ routing keywords · 69 query expansions
345
+
346
+ Ingest MITRE ATT&CK, threat reports, exploit writeups and incident reports. Search from an MCP client with `search_knowledge("privilege escalation windows")`. Offline operation requires cached models; the chosen client receives retrieved content and determines what happens to it afterwards.
347
+
348
+ ### Development Teams — Design Docs, Runbooks, Code
349
+
350
+ **Preset:** [`developer.yaml`](presets/developer.yaml) · 9 categories · 150+ routing keywords · 50+ expansions
351
+
352
+ Replace Confluence hunting. Ingest architecture docs, ADRs, runbooks, code, API specs. Devs ask their AI agent "how do we authenticate the payment service" and get the exact ADR + implementation file citation.
353
+
354
+ ### Research Labs — Papers, Notebooks, Datasets
355
+
356
+ **Preset:** [`research.yaml`](presets/research.yaml) · 9 categories · 100+ routing keywords · 40+ expansions
357
+
358
+ Index arXiv papers, lab notebooks, dataset documentation. Semantic search finds papers by intent, not just keywords — cross-encoder reranking surfaces the actually-relevant one instead of five that share a term.
359
+
360
+ ### Enterprise Knowledge Base — Air-gapped, Auditable
361
+
362
+ **Preset:** [`general.yaml`](presets/general.yaml) · blank slate, pure semantic search
363
+
364
+ Deploy via SSE on a single VM. 40+ users authenticated via bearer token, rate-limited, Prometheus-monitored, `/health` probes wired to your load balancer, JSON logs shipped to Datadog. No cloud calls. Meets LGPD, GDPR, HIPAA data-locality requirements by design.
365
+
366
+ **Verified at scale:** production reproduction on a **5 889-doc / 75 016-chunk corpus** with concurrent queries during a nuclear rebuild — zero downtime, zero errors (see [CHANGELOG v4.8.3](CHANGELOG.md#v483-2026-08-10--critical-hotfix-nuclear-rebuild--smart-reindex-hardening)).
367
+
368
+ ---
369
+
370
+ ## 🏗️ Architecture at a glance
371
+
372
+ End-to-end view of how MCP clients, the retrieval pipeline, storage, and enterprise plumbing connect. Every arrow is a real code path — nothing pictured here is aspirational.
373
+
374
+ ```mermaid
375
+ flowchart TB
376
+ subgraph CLIENTS["MCP Clients (any of these)"]
377
+ C1[Claude Code]
378
+ C2[Claude Desktop]
379
+ C3[Cursor]
380
+ C4[Windsurf]
381
+ C5[VS Code · Cline · Gemini CLI · Zed]
382
+ end
383
+
384
+ subgraph TRANSPORT["Transport Layer"]
385
+ T1[stdio<br/>1 process per client]
386
+ T2[SSE / streamable-http<br/>1 server serves N clients]
387
+ end
388
+
389
+ subgraph MIDDLEWARE["ASGI Middleware Chain (HTTP mode)"]
390
+ M1[HealthMiddleware<br/>/health · /healthz]
391
+ M2[BearerAuthMiddleware<br/>constant-time compare]
392
+ M3[Rate Limiter<br/>sliding window]
393
+ end
394
+
395
+ subgraph MCP["13 MCP Tools (frozen contract)"]
396
+ MT1[search_knowledge]
397
+ MT2[get_document · search_similar]
398
+ MT3[add_document · add_from_url · update · remove]
399
+ MT4[reindex_documents · get_reindex_status]
400
+ MT5[list_documents · list_categories · get_index_stats · evaluate_retrieval]
401
+ end
402
+
403
+ subgraph SEARCH["Retrieval Pipeline"]
404
+ R[Query Router<br/>lexical vs semantic]
405
+ F[FTS5 Fast-Path<br/>opt-in lexical retrieval]
406
+ BM[BM25 Inverted Index<br/>keyword candidates]
407
+ SE[Semantic Search<br/>FastEmbed ONNX lazy-loaded]
408
+ RRF[Reciprocal Rank Fusion]
409
+ CE[Cross-Encoder Rerank<br/>MiniLM-L-6-v2]
410
+ QC[Query Cache<br/>LRU + 5-min TTL]
411
+ end
412
+
413
+ subgraph STORAGE["Storage (100% local)"]
414
+ CH[ChromaDB<br/>vectors + metadata<br/>WAL mode]
415
+ FT[SQLite FTS5<br/>lexical index<br/>WAL + busy-timeout]
416
+ MD[index_metadata.json<br/>durable state]
417
+ end
418
+
419
+ subgraph INGEST["Document Ingestion"]
420
+ FS[documents/ folder]
421
+ WD[Watchdog<br/>10s debounce]
422
+ PA[Format parsers<br/>MD · PDF · DOCX · code · IaC · IPYNB]
423
+ CK[Chunker<br/>markdown-aware · code-aware]
424
+ EM[FastEmbed ONNX<br/>384D bge-small-en-v1.5]
425
+ DD[SHA256 Dedup]
426
+ SW[Staging Rebuild<br/>rollback on handled publication failure]
427
+ end
428
+
429
+ subgraph OBS["Enterprise Observability (opt-in)"]
430
+ PM[Prometheus /metrics<br/>7 canonical + histograms]
431
+ LG[Structured JSON logs<br/>ELK · Loki · Datadog · CloudWatch]
432
+ HC[Health payload<br/>version · uptime · cache stats]
433
+ end
434
+
435
+ subgraph CFG["Configuration"]
436
+ YM[config.yaml<br/>+ 5 domain presets]
437
+ end
438
+
439
+ C1 & C2 & C3 & C4 & C5 -->|MCP protocol| T1
440
+ C1 & C2 & C3 & C4 & C5 -.->|remote deploy| T2
441
+ T1 --> MCP
442
+ T2 --> M1 --> M2 --> M3 --> MCP
443
+
444
+ MT1 --> QC
445
+ QC -->|cache miss| R
446
+ R -->|lexical| F
447
+ R -->|semantic| SE
448
+ R -->|hybrid| BM
449
+ F --> CH
450
+ F --> FT
451
+ BM --> CH
452
+ SE --> CH
453
+ BM --> RRF
454
+ SE --> RRF
455
+ RRF --> CE
456
+ CE --> QC
457
+
458
+ MT2 --> CH
459
+ MT3 --> INGEST
460
+ MT4 --> SW
461
+ MT5 --> CH
462
+
463
+ FS --> WD --> PA
464
+ PA --> CK --> EM --> DD --> CH
465
+ SW -.->|validated publication| CH
466
+ SW -.-> FT
467
+ CH -.-> MD
468
+
469
+ MCP -.->|instrumented| PM
470
+ MCP -.->|logs| LG
471
+ M1 --> HC
472
+
473
+ YM -.-> SEARCH
474
+ YM -.-> STORAGE
475
+ YM -.-> OBS
476
+ YM -.-> MIDDLEWARE
477
+
478
+ classDef client fill:#3776AB,stroke:#1e5a8a,color:#fff
479
+ classDef transport fill:#00A67E,stroke:#006e54,color:#fff
480
+ classDef middleware fill:#6b46c1,stroke:#4c1d95,color:#fff
481
+ classDef storage fill:#4b5563,stroke:#1f2937,color:#fff
482
+ classDef obs fill:#dc2626,stroke:#7f1d1d,color:#fff
483
+ classDef ingest fill:#f59e0b,stroke:#78350f,color:#fff
484
+
485
+ class C1,C2,C3,C4,C5 client
486
+ class T1,T2 transport
487
+ class M1,M2,M3 middleware
488
+ class CH,FT,MD storage
489
+ class PM,LG,HC obs
490
+ class FS,WD,PA,CK,EM,DD,SW ingest
491
+ ```
492
+
493
+ **Reading the diagram (top → bottom):**
494
+
495
+ 1. **Any MCP client** — Claude Code, Cursor, Windsurf, and 5 others — connects via the transport of your choice (stdio for personal use, SSE/streamable-http for teams).
496
+ 2. **HTTP mode chains 3 ASGI middlewares in order**: health probes first (always answered), then bearer auth (fenced with `WWW-Authenticate`), then rate limiter (sliding window).
497
+ 3. **All 13 MCP tools** are decorated with `@rate_limited` + `@instrument` — metrics record calls and the rate limiter enforces RPM+burst when enabled. Disabled features skip that work, while the lightweight wrapper calls remain.
498
+ 4. **`search_knowledge` checks the query cache first**; cache miss routes through the Query Router (regex classifier) to either the FTS5 fast-path (lexical) or the hybrid pipeline (BM25 + semantic + RRF + cross-encoder rerank).
499
+ 5. **Storage is 100% local**: ChromaDB (WAL mode) for vectors + metadata, SQLite FTS5 (WAL + busy-timeout) for lexical fast-path, `index_metadata.json` for durable state.
500
+ 6. **Document ingestion**: when enabled, watchdog observes `documents/`; format parsers create chunks, FastEmbed generates embeddings, and source metadata supports incremental updates. Full rebuilds use staging. See the operations guide for publication and recovery limits.
501
+ 7. **Enterprise observability** (opt-in) — Prometheus `/metrics`, structured JSON logs, `/health` payload — attaches to the same instrumentation points, no code changes required.
502
+ 8. **`config.yaml` (with 5 domain presets)** controls every subsystem — no environment variable spaghetti, no hardcoded paths.
503
+
504
+ **Component ownership, query/ingestion diagrams, memory boundaries and hybrid weights:** [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
505
+
506
+ ---
507
+
508
+ ## 📄 35 File Formats — parsed natively, no plugins needed
509
+
510
+ Parsers use format-specific extraction: Markdown sections, code boundaries, notebook cells without base64 outputs, PDF text and spreadsheet rows. Several extensions share one parser. The runtime fallback list contains 33 formats; the documented template and presets can select a smaller list. Inspect your effective `documents.supported_formats`. The two MetaTrader extensions are opt-in.
511
+
512
+ | # | Format | Extension | Parser | Default | Notes |
513
+ |---|--------|-----------|--------|:-------:|-------|
514
+ | 1 | Markdown | `.md` | Section-aware (splits at `##`) | Yes | Headers preserved as chunk boundaries |
515
+ | 2 | Plain Text | `.txt` | Fixed-size chunking | Yes | 1000 chars + 200 overlap |
516
+ | 3 | PDF | `.pdf` | PyMuPDF extraction or explicit page-marked UTF-8 text | Yes | No OCR; extracted-text recognition is limited to 4 MiB |
517
+ | 4 | Word | `.docx` | python-docx | Yes | Headings preserved as markdown |
518
+ | 5 | Excel | `.xlsx` | openpyxl | Yes | Sheet-by-sheet extraction |
519
+ | 6 | PowerPoint | `.pptx` | python-pptx | Yes | Slide-by-slide extraction |
520
+ | 7 | Jupyter Notebook | `.ipynb` | Cell-aware parser | Yes | Markdown + code cells only; skips outputs/base64 |
521
+ | 8 | JSON | `.json` | Structure-aware | Yes | Flattened key-value extraction |
522
+ | 9 | CSV | `.csv` | Row-based parser | Yes | Headers + rows as text |
523
+ | 10 | XML | `.xml` | XML parser | Yes | Root element + namespace metadata |
524
+ | 11 | Python | `.py` | Code-aware parser | Yes | Functions/classes as chunks |
525
+ | 12 | C Source | `.c` | Code-aware parser | Yes | Functions / structs / includes extracted |
526
+ | 13 | C/C++ Header | `.h` | Code-aware parser | Yes | Function declarations + structs extracted |
527
+ | 14 | C++ Source | `.cpp` | Code-aware parser | Yes | Classes / structs / includes extracted |
528
+ | 15 | JavaScript | `.js` | Code-aware parser | Yes | Functions / classes / imports (ESM + CJS) |
529
+ | 16 | React JSX | `.jsx` | Code-aware parser | Yes | Same as JS parser |
530
+ | 17 | TypeScript | `.ts` | Code-aware parser | Yes | Functions / classes / interfaces / enums / imports |
531
+ | 18 | React TSX | `.tsx` | Code-aware parser | Yes | Same as TS parser |
532
+ | 19 | Go | `.go` | Code-aware parser | Yes | Functions / structs / imports extracted |
533
+ | 20 | Rust | `.rs` | Code-aware parser | Yes | Functions / structs / enums / traits / `use` imports |
534
+ | 21 | Kotlin | `.kt` | Code-aware parser | Yes | Functions (incl. class members) / classes extracted |
535
+ | 22 | YAML | `.yaml` | YAML parser | Yes | Kubernetes kind / apiVersion / name extracted |
536
+ | 23 | YAML | `.yml` | YAML parser | Yes | Same as YAML parser |
537
+ | 24 | HuJSON | `.hujson` | HuJSON parser | Yes | JSON with comments + trailing commas (e.g. Tailscale ACLs) |
538
+ | 25 | CUE | `.cue` | Code-aware parser | Yes | Imports / package extracted |
539
+ | 26 | Protocol Buffers | `.proto` | Proto parser | Yes | Services / messages / RPCs extracted |
540
+ | 27 | Rego | `.rego` | Code-aware parser | Yes | OPA policies — imports / package extracted |
541
+ | 28 | SQL | `.sql` | SQL parser | Yes | Table names + statement types extracted |
542
+ | 29 | Shell | `.sh` | Shell parser | Yes | Function names extracted |
543
+ | 30 | jq | `.jq` | Shell parser | Yes | Indexed as shell-style script |
544
+ | 31 | Dockerfile | `Dockerfile` | Text parser | Yes | Matched by exact filename (no extension) |
545
+ | 32 | Makefile | `Makefile` | Text parser | Yes | Matched by exact filename (no extension) |
546
+ | 33 | Tiltfile | `Tiltfile` | Code-aware parser | Yes | Starlark — `def` functions / `load()` extracted |
547
+ | 34 | MQL4 Source | `.mq4` | Code parser | **No** | MetaTrader — opt-in via `documents.supported_formats` |
548
+ | 35 | MQL4 Header | `.mqh` | Code parser | **No** | MetaTrader — opt-in via `documents.supported_formats` |
549
+
550
+ Files with a `.pdf` extension can also contain an explicit text extraction: the
551
+ first line must be `[Page N]` with a positive page number, followed by nonempty
552
+ UTF-8 text. An optional UTF-8 BOM and tab/CR/LF whitespace are accepted. This
553
+ recognition is limited to 4 MiB, rejects other C0/C1 controls and DEL, and never
554
+ reinterprets a file containing PDF magic in the first 1 KiB as text. Accepted
555
+ extractions retain their source path and are marked `content_format=extracted_text`
556
+ and `page_count_source=markers`; the marker count is not proof of the original
557
+ PDF's total page count. Binary PDFs keep the native parser and its error
558
+ diagnostics. Invalid or oversized textual lookalikes remain errors.
559
+
560
+ > **Enable an opt-in format** — add the extension to `documents.supported_formats` in your `config.yaml`:
561
+ > ```yaml
562
+ > documents:
563
+ > supported_formats: [".md", ".pdf", ".mq4", ".mqh"]
564
+ > ```
565
+
566
+ **Full parser reference with per-format notes:** [docs/CONFIGURATION.md](docs/CONFIGURATION.md)
567
+
568
+ ---
569
+
570
+ ## 🔌 Choose your MCP integration
571
+
572
+ <table>
573
+ <tr>
574
+ <td align="center" width="14%">
575
+
576
+ **Claude Code**<br/>
577
+ `~/.claude.json`
578
+
579
+ </td>
580
+ <td align="center" width="14%">
581
+
582
+ **Claude Desktop**<br/>
583
+ `claude_desktop_config.json`
584
+
585
+ </td>
586
+ <td align="center" width="14%">
587
+
588
+ **Cursor**<br/>
589
+ `~/.cursor/mcp.json`
590
+
591
+ </td>
592
+ <td align="center" width="14%">
593
+
594
+ **Windsurf**<br/>
595
+ `~/.codeium/windsurf/mcp_config.json`
596
+
597
+ </td>
598
+ <td align="center" width="14%">
599
+
600
+ **VS Code**<br/>
601
+ Copilot Chat `mcp.json`
602
+
603
+ </td>
604
+ <td align="center" width="14%">
605
+
606
+ **Cline · Gemini CLI · Zed**<br/>
607
+ Native MCP
608
+
609
+ </td>
610
+ </tr>
611
+ </table>
612
+
613
+ **Complete client configuration guide with JSON schemas per client:** [docs/INSTALLATION.md#use-with-other-mcp-clients →](docs/INSTALLATION.md#use-with-other-mcp-clients)
614
+
615
+ > ⚠️ **Operating model — read once.** In `stdio` mode, your MCP client (Claude Desktop, Code, Cursor, etc.) **spawns and owns the knowledge-rag server process**. Do **NOT** also run a second `knowledge-rag` writer in a terminal while that stdio client is open — two writer processes against the same `data_dir` corrupt the ChromaDB HNSW segment on Windows (see [issue #216](https://github.com/lyonzin/knowledge-rag/issues/216)). For HTTP transports, manually running one server and connecting HTTP clients to it is the supported shared-server workflow; do not mix it with another writer using the same `data_dir`. Recommended baseline for stdio clients: add `"KNOWLEDGE_RAG_SINGLE_INSTANCE": "1"` to the `env` block of your MCP config as a safety net. Full explanation + how to run CLI commands safely: [docs/single-instance.md](docs/single-instance.md).
616
+
617
+ > ⚠️ **Do not install under cloud-sync folders.** Keep `paths.data_dir` on a local path. OneDrive (incl. `OneDrive - <tenant>`), iCloud Drive, Dropbox, Google Drive, Box, pCloud, MEGAsync, Nextcloud/ownCloud and Sync all open file handles on the live index to upload it, racing with ChromaDB's HNSW mmap and SQLite WAL writes and triggering native access violations (`0xC0000005` on Windows, `SIGBUS` on *nix). Preflight auto-repair then moves the active index to `data/backups/auto-repair-*` and you lose the corpus. Since v4.11.0, preflight aborts with `EX_CONFIG` (78) when `data_dir` resolves under one of these providers. Point `data_dir` at a local path (e.g. `%LOCALAPPDATA%\knowledge-rag\data` on Windows, `~/.local/share/knowledge-rag/data` on Linux/macOS). If you really need to run under cloud sync, set `paths.allow_cloud_sync: true` to acknowledge the risk and continue.
618
+
619
+ ---
620
+
621
+ ## ⚙️ Configuration in 30 seconds
622
+
623
+ ```yaml
624
+ # config.yaml — everything is optional; defaults just work
625
+
626
+ paths:
627
+ documents_dir: "./documents"
628
+ data_dir: "./data"
629
+
630
+ models:
631
+ embedding:
632
+ profile: "compact" # "compact" | "quality" | "multilingual" | "custom"
633
+ gpu: "auto" # "auto" | "true" | "false" | "directml"
634
+ device_id: null # DirectML: explicit DXGI adapter index
635
+ reranker:
636
+ enabled: true # cross-encoder rerank
637
+
638
+ search:
639
+ default_results: 5
640
+ max_results: 100
641
+
642
+ server: # optional — SSE / HTTP mode
643
+ transport: "stdio" # or "sse" / "streamable-http"
644
+ auth:
645
+ bearer_token: "" # set a secret to enable auth
646
+ rate_limit:
647
+ enabled: false
648
+ metrics:
649
+ enabled: false
650
+ logging:
651
+ format: "text" # or "json"
652
+ ```
653
+
654
+ **Pre-built presets:** [`cybersecurity.yaml`](presets/cybersecurity.yaml) · [`developer.yaml`](presets/developer.yaml) · [`research.yaml`](presets/research.yaml) · [`general.yaml`](presets/general.yaml) · [`multilingual.yaml`](presets/multilingual.yaml)
655
+
656
+ **Complete configuration reference — every field, every default, tuning guide:** [docs/CONFIGURATION.md →](docs/CONFIGURATION.md)
657
+
658
+ ---
659
+
660
+ ## 🔒 Security & Compliance
661
+
662
+ knowledge-rag is designed for teams that cannot let their documents leave the perimeter.
663
+
664
+ | Requirement | How knowledge-rag delivers |
665
+ |---|---|
666
+ | **Data locality (LGPD / GDPR / HIPAA)** | 100% on-premise, zero egress network calls after initial model download |
667
+ | **Air-gapped deployment** | ONNX models pre-cached; set `HF_HUB_OFFLINE=1` to enforce zero-network |
668
+ | **CVE monitoring** | Dependabot (weekly) + pip-audit + Socket + CodeQL |
669
+ | **Supply chain security** | PyPI Trusted Publishing via OIDC (no long-lived tokens) |
670
+ | **Vulnerability disclosure** | Private security advisory via [SECURITY.md](SECURITY.md) |
671
+ | **Signed release attestations** | GitHub release attestations on every published version |
672
+ | **Dependency management** | Version ranges in `requirements.txt` / `pyproject.toml`; resolve and record a tested environment for reproducibility |
673
+ | **Authenticated access** | Bearer token middleware on SSE / HTTP transports (constant-time compare, RFC 6750) |
674
+ | **Rate limiting** | Sliding-window per-client RPM + burst (opt-in, zero-cost when disabled) |
675
+ | **Audit-ready logging** | Opt-in structured JSON logs → ship to your SIEM |
676
+ | **Path traversal defenses** | CWE-22 / CWE-59 guards on 6 CRUD tools |
677
+ | **External-content mitigation** | Known-token neutralization and provenance fencing on `add_from_url`; not a general prompt-injection prevention guarantee |
678
+
679
+ **OpenSSF Best Practices** badge: passing · project ID [#13864](https://bestpractices.coreinfrastructure.org/projects/13864)
680
+
681
+ ---
682
+
683
+ ## 📈 Numbers that matter
684
+
685
+ - **13 MCP tools**, configurable format selection and five domain presets.
686
+ - **Nine OS/Python CI combinations** configured for Linux, macOS and Windows with Python 3.11–3.13.
687
+ - **Measured CPU/CUDA indexing and retrieval, AMD validation and memory regressions:** [audit results and reproduction](docs/audit-2026-10-03.md).
688
+ - **Historical implementation benchmarks:** [v4.7.1 baseline](docs/perf-baseline-v4.7.1.md). Historical ratios apply to their recorded workloads, not every corpus or competing product.
689
+
690
+ The [public benchmark dashboard](https://lyonzin.github.io/knowledge-rag/) tracks
691
+ CI workloads. Mocked storage/model workloads and real-model measurements answer
692
+ different questions; inspect the methodology and units before comparing them.
693
+ ---
694
+
695
+ ## 📚 Documentation
696
+
697
+ | Doc | What's inside |
698
+ |---|---|
699
+ | [**Installation guide**](docs/INSTALLATION.md) | 5 install methods · 8 MCP client integrations · GPU setup |
700
+ | [**API reference**](docs/API.md) | Complete reference for all 13 MCP tools |
701
+ | [**Configuration reference**](docs/CONFIGURATION.md) | Every `config.yaml` field · presets · tuning |
702
+ | [**Architecture**](docs/ARCHITECTURE.md) | Components · query/ingestion flow · memory/concurrency boundaries · hybrid weights |
703
+ | [**Troubleshooting**](docs/TROUBLESHOOTING.md) | 11 common issues + solutions |
704
+ | [**FTS5 fast-path guide**](docs/features/fts5_fast_path.md) | Opt-in lexical fast-path — when and how |
705
+ | [**Reindex operations**](docs/reindex-operations.md) | Zero-downtime rebuild · resume · checkpoint |
706
+ | [**GPU setup**](docs/gpu-setup.md) | CUDA runtime compatibility · CPU fallback · AMD/macOS GPU limitations |
707
+ | [**Migration to v4.8.0**](docs/migration-v4.8.0.md) | Embedding profile · multilingual · zero-downtime |
708
+ | [**Security policy**](SECURITY.md) | Threat model · disclosure channel |
709
+ | [**Contributing**](CONTRIBUTING.md) | Development · testing · PR process |
710
+ | [**Changelog**](CHANGELOG.md) | All release notes since v1.0.0 |
711
+ | [**Memory/GPU audit**](docs/audit-2026-10-03.md) | Reproducible workloads · measured results · validation limits · open PR/issue review |
712
+
713
+ ---
714
+
715
+ ## 🤝 Community & Support
716
+
717
+ - **Report a bug** → [Open an issue](https://github.com/lyonzin/knowledge-rag/issues/new/choose)
718
+ - **Ask a question** → [GitHub Discussions](https://github.com/lyonzin/knowledge-rag/discussions)
719
+ - **Report a vulnerability** → [Security advisory](https://github.com/lyonzin/knowledge-rag/security/advisories/new) (private)
720
+ - **Contribute** → [CONTRIBUTING.md](CONTRIBUTING.md)
721
+
722
+ **Response SLA (best-effort, community project):**
723
+ - Security reports: within 48 h
724
+ - Bug reports with reproduction: within 5 business days
725
+ - Feature requests: triaged on next release cycle
726
+
727
+ ---
728
+
729
+ ## 🗺️ Recent releases
730
+
731
+ - **v4.8.5** (2026-08-13) — Enterprise observability: `/health` endpoint + opt-in JSON structured logging
732
+ - **v4.8.4** (2026-08-13) — Patch: security + durability + defensive fixes
733
+ - **v4.8.3** (2026-08-10) — Critical hotfix: nuclear-rebuild + smart-reindex hardening on 50k+ chunk corpora
734
+ - **v4.8.2** (2026-08-10) — FTS5 lexical fast-path opt-in release
735
+ - **v4.8.0** (2026-08-06) — Multilingual foundation + zero-downtime reindex
736
+
737
+ **Full history:** [CHANGELOG.md →](CHANGELOG.md)
738
+
739
+ ---
740
+
741
+ ## 📜 License
742
+
743
+ **MIT License** — [LICENSE](LICENSE). Forever. No cloud upsell, no dual-licensing, no restrictive clauses. Fork it, sell derivatives, embed it in commercial products — the license does not care.
744
+
745
+ ---
746
+
747
+ ## 🙏 Acknowledgments
748
+
749
+ Built on the shoulders of amazing open-source projects:
750
+
751
+ - [**Anthropic MCP**](https://modelcontextprotocol.io/) — Model Context Protocol spec + Python SDK
752
+ - [**ChromaDB**](https://www.trychroma.com/) — vector database that just works
753
+ - [**FastEmbed**](https://github.com/qdrant/fastembed) — ONNX embeddings, no PyTorch bloat
754
+ - [**HuggingFace**](https://huggingface.co/) — model hosting + `Xenova/ms-marco-MiniLM-L-6-v2` cross-encoder
755
+ - [**BAAI**](https://huggingface.co/BAAI) — the `bge-small-en-v1.5` embedding model
756
+
757
+ **Community contributors:** [@Hohlas](https://github.com/Hohlas) · [@eeshsaxena](https://github.com/eeshsaxena) · Sergey Khokhlov · and everyone who filed issues or PRs.
758
+
759
+ ---
760
+
761
+ <div align="center">
762
+
763
+ **Built by [Ailton Rocha (Lyon.)](https://github.com/lyonzin)** · Star ⭐ if this saves you time · [Report an issue](https://github.com/lyonzin/knowledge-rag/issues/new/choose) · [Contribute](CONTRIBUTING.md)
764
+
765
+ *knowledge-rag — the MCP-first local RAG server for Claude Code, Cursor, Windsurf, and every AI agent.*
766
+
767
+ </div>