knowledge-rag 3.3.0__tar.gz → 3.3.1__tar.gz
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.
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/PKG-INFO +15 -7
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/README.md +14 -6
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/mcp_server/config.py +212 -49
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/mcp_server/server.py +45 -2
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/pyproject.toml +8 -1
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/.gitignore +0 -0
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/LICENSE +0 -0
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/config.example.yaml +0 -0
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/documents/examples/sample-document.md +0 -0
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/mcp_server/__init__.py +0 -0
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/mcp_server/ingestion.py +0 -0
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/presets/cybersecurity.yaml +0 -0
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/presets/developer.yaml +0 -0
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/presets/general.yaml +0 -0
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/presets/research.yaml +0 -0
- {knowledge_rag-3.3.0 → knowledge_rag-3.3.1}/requirements.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: knowledge-rag
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.1
|
|
4
4
|
Summary: Local RAG System for Claude Code — Hybrid search + Cross-encoder Reranking + 12 MCP Tools. Zero external servers.
|
|
5
5
|
Project-URL: Homepage, https://github.com/lyonzin/knowledge-rag
|
|
6
6
|
Project-URL: Repository, https://github.com/lyonzin/knowledge-rag
|
|
@@ -38,7 +38,7 @@ Description-Content-Type: text/markdown
|
|
|
38
38
|
|
|
39
39
|
<div align="center">
|
|
40
40
|
|
|
41
|
-

|
|
42
42
|

|
|
43
43
|

|
|
44
44
|

|
|
@@ -408,21 +408,23 @@ flowchart LR
|
|
|
408
408
|
|
|
409
409
|
### Quick Start (3 steps)
|
|
410
410
|
|
|
411
|
-
**Step 1:
|
|
411
|
+
**Step 1: Install**
|
|
412
412
|
|
|
413
413
|
```bash
|
|
414
|
-
#
|
|
414
|
+
# Option A: pip install (recommended)
|
|
415
|
+
pip install knowledge-rag
|
|
416
|
+
knowledge-rag init # Exports config template, presets, creates documents/
|
|
417
|
+
|
|
418
|
+
# Option B: Clone from source
|
|
415
419
|
git clone https://github.com/lyonzin/knowledge-rag.git ~/knowledge-rag
|
|
416
420
|
cd ~/knowledge-rag
|
|
417
|
-
|
|
418
|
-
# Create virtual environment and install
|
|
419
421
|
python3 -m venv venv
|
|
420
422
|
source venv/bin/activate # Linux/macOS
|
|
421
423
|
# .\venv\Scripts\activate # Windows
|
|
422
424
|
pip install -r requirements.txt
|
|
423
425
|
```
|
|
424
426
|
|
|
425
|
-
> **Windows users**:
|
|
427
|
+
> **Windows users**: Use `python` instead of `python3`.
|
|
426
428
|
|
|
427
429
|
**Step 2: Configure Claude Code**
|
|
428
430
|
|
|
@@ -1193,6 +1195,12 @@ With ~200 documents, expect ~300-500MB RAM. The embedding model (~50MB) and rera
|
|
|
1193
1195
|
|
|
1194
1196
|
## Changelog
|
|
1195
1197
|
|
|
1198
|
+
### v3.3.1 (2026-04-06)
|
|
1199
|
+
|
|
1200
|
+
- **FIX**: YAML null values (`category_mappings:` without value) no longer crash the server — falls back to defaults
|
|
1201
|
+
- **FIX**: Presets and config template now bundled in pip wheel (`knowledge-rag init` exports them)
|
|
1202
|
+
- **NEW**: `knowledge-rag init` CLI command — exports config template, presets, and creates documents/ in current directory
|
|
1203
|
+
|
|
1196
1204
|
### v3.3.0 (2026-04-05)
|
|
1197
1205
|
|
|
1198
1206
|
- **NEW**: YAML configuration system — fully customizable via `config.yaml`
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|

|
|
8
8
|

|
|
@@ -372,21 +372,23 @@ flowchart LR
|
|
|
372
372
|
|
|
373
373
|
### Quick Start (3 steps)
|
|
374
374
|
|
|
375
|
-
**Step 1:
|
|
375
|
+
**Step 1: Install**
|
|
376
376
|
|
|
377
377
|
```bash
|
|
378
|
-
#
|
|
378
|
+
# Option A: pip install (recommended)
|
|
379
|
+
pip install knowledge-rag
|
|
380
|
+
knowledge-rag init # Exports config template, presets, creates documents/
|
|
381
|
+
|
|
382
|
+
# Option B: Clone from source
|
|
379
383
|
git clone https://github.com/lyonzin/knowledge-rag.git ~/knowledge-rag
|
|
380
384
|
cd ~/knowledge-rag
|
|
381
|
-
|
|
382
|
-
# Create virtual environment and install
|
|
383
385
|
python3 -m venv venv
|
|
384
386
|
source venv/bin/activate # Linux/macOS
|
|
385
387
|
# .\venv\Scripts\activate # Windows
|
|
386
388
|
pip install -r requirements.txt
|
|
387
389
|
```
|
|
388
390
|
|
|
389
|
-
> **Windows users**:
|
|
391
|
+
> **Windows users**: Use `python` instead of `python3`.
|
|
390
392
|
|
|
391
393
|
**Step 2: Configure Claude Code**
|
|
392
394
|
|
|
@@ -1157,6 +1159,12 @@ With ~200 documents, expect ~300-500MB RAM. The embedding model (~50MB) and rera
|
|
|
1157
1159
|
|
|
1158
1160
|
## Changelog
|
|
1159
1161
|
|
|
1162
|
+
### v3.3.1 (2026-04-06)
|
|
1163
|
+
|
|
1164
|
+
- **FIX**: YAML null values (`category_mappings:` without value) no longer crash the server — falls back to defaults
|
|
1165
|
+
- **FIX**: Presets and config template now bundled in pip wheel (`knowledge-rag init` exports them)
|
|
1166
|
+
- **NEW**: `knowledge-rag init` CLI command — exports config template, presets, and creates documents/ in current directory
|
|
1167
|
+
|
|
1160
1168
|
### v3.3.0 (2026-04-05)
|
|
1161
1169
|
|
|
1162
1170
|
- **NEW**: YAML configuration system — fully customizable via `config.yaml`
|
|
@@ -44,6 +44,7 @@ else:
|
|
|
44
44
|
# YAML CONFIG LOADER
|
|
45
45
|
# ============================================================================
|
|
46
46
|
|
|
47
|
+
|
|
47
48
|
def _load_yaml_config() -> dict:
|
|
48
49
|
"""Load config.yaml from BASE_DIR if it exists, otherwise return empty dict."""
|
|
49
50
|
config_path = BASE_DIR / "config.yaml"
|
|
@@ -54,7 +55,7 @@ def _load_yaml_config() -> dict:
|
|
|
54
55
|
with open(config_path, "r", encoding="utf-8") as f:
|
|
55
56
|
data = yaml.safe_load(f)
|
|
56
57
|
if not isinstance(data, dict):
|
|
57
|
-
print(
|
|
58
|
+
print("[WARN] config.yaml is not a valid mapping, ignoring")
|
|
58
59
|
return {}
|
|
59
60
|
print(f"[INFO] Loaded config from {config_path}")
|
|
60
61
|
return data
|
|
@@ -75,6 +76,16 @@ def _get(section: str, key: str, default):
|
|
|
75
76
|
return val if val is not None else default
|
|
76
77
|
|
|
77
78
|
|
|
79
|
+
def _get_top(key: str, default):
|
|
80
|
+
"""Get a top-level value from YAML, falling back to default if missing or None."""
|
|
81
|
+
val = _yaml.get(key)
|
|
82
|
+
if val is None:
|
|
83
|
+
return default
|
|
84
|
+
if not isinstance(val, type(default)):
|
|
85
|
+
return default
|
|
86
|
+
return val
|
|
87
|
+
|
|
88
|
+
|
|
78
89
|
# ============================================================================
|
|
79
90
|
# DEFAULTS (used when no config.yaml or field is omitted)
|
|
80
91
|
# ============================================================================
|
|
@@ -92,44 +103,145 @@ _DEFAULT_CATEGORY_MAPPINGS = {
|
|
|
92
103
|
|
|
93
104
|
_DEFAULT_KEYWORD_ROUTES = {
|
|
94
105
|
"logscale": [
|
|
95
|
-
"logscale",
|
|
96
|
-
"
|
|
106
|
+
"logscale",
|
|
107
|
+
"lql",
|
|
108
|
+
"cql",
|
|
109
|
+
"humio",
|
|
110
|
+
"crowdstrike query",
|
|
111
|
+
"formattime",
|
|
112
|
+
"groupby",
|
|
113
|
+
"base64decode",
|
|
114
|
+
"case{}",
|
|
115
|
+
"regex",
|
|
97
116
|
],
|
|
98
117
|
"redteam": [
|
|
99
|
-
"pentest",
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"
|
|
118
|
+
"pentest",
|
|
119
|
+
"exploit",
|
|
120
|
+
"payload",
|
|
121
|
+
"reverse shell",
|
|
122
|
+
"privilege escalation",
|
|
123
|
+
"lateral movement",
|
|
124
|
+
"c2",
|
|
125
|
+
"beacon",
|
|
126
|
+
"cobalt strike",
|
|
127
|
+
"metasploit",
|
|
128
|
+
"gtfobins",
|
|
129
|
+
"lolbas",
|
|
130
|
+
"lolbin",
|
|
131
|
+
"suid",
|
|
132
|
+
"sudo",
|
|
133
|
+
"byovd",
|
|
134
|
+
"lol driver",
|
|
135
|
+
"lolad",
|
|
136
|
+
"lolapps",
|
|
137
|
+
"hacktricks",
|
|
138
|
+
"privesc",
|
|
139
|
+
"kerberoast",
|
|
140
|
+
"dcsync",
|
|
141
|
+
"golden ticket",
|
|
142
|
+
"pass-the-hash",
|
|
143
|
+
"bloodhound",
|
|
144
|
+
"mimikatz",
|
|
145
|
+
"rubeus",
|
|
146
|
+
"certipy",
|
|
147
|
+
"adcs",
|
|
148
|
+
"sqli",
|
|
149
|
+
"xss",
|
|
150
|
+
"ssti",
|
|
151
|
+
"ssrf",
|
|
152
|
+
"lfi",
|
|
153
|
+
"rfi",
|
|
154
|
+
"xxe",
|
|
155
|
+
"deserialization",
|
|
156
|
+
"ysoserial",
|
|
157
|
+
"upload bypass",
|
|
158
|
+
"reverse shell",
|
|
159
|
+
"web shell",
|
|
160
|
+
"hash cracking",
|
|
161
|
+
"hashcat",
|
|
162
|
+
"waf bypass",
|
|
163
|
+
"amsi bypass",
|
|
164
|
+
"uac bypass",
|
|
165
|
+
"potato",
|
|
166
|
+
"searchsploit",
|
|
167
|
+
"exploit-db",
|
|
168
|
+
"cve",
|
|
108
169
|
],
|
|
109
170
|
"blueteam": [
|
|
110
|
-
"detection",
|
|
111
|
-
"
|
|
171
|
+
"detection",
|
|
172
|
+
"sigma",
|
|
173
|
+
"yara",
|
|
174
|
+
"ioc",
|
|
175
|
+
"threat hunting",
|
|
176
|
+
"incident response",
|
|
177
|
+
"forensics",
|
|
178
|
+
"malware analysis",
|
|
112
179
|
],
|
|
113
180
|
"ctf": [
|
|
114
|
-
"ctf",
|
|
115
|
-
"
|
|
181
|
+
"ctf",
|
|
182
|
+
"flag",
|
|
183
|
+
"hackthebox",
|
|
184
|
+
"htb",
|
|
185
|
+
"tryhackme",
|
|
186
|
+
"picoctf",
|
|
187
|
+
"writeup",
|
|
188
|
+
"challenge",
|
|
116
189
|
],
|
|
117
190
|
"development": [
|
|
118
|
-
"python",
|
|
119
|
-
"
|
|
191
|
+
"python",
|
|
192
|
+
"typescript",
|
|
193
|
+
"javascript",
|
|
194
|
+
"api",
|
|
195
|
+
"fastapi",
|
|
196
|
+
"django",
|
|
197
|
+
"react",
|
|
198
|
+
"nodejs",
|
|
120
199
|
],
|
|
121
200
|
"security": [
|
|
122
|
-
"anti-bot",
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
126
|
-
"
|
|
127
|
-
"
|
|
128
|
-
"
|
|
129
|
-
"
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
"
|
|
201
|
+
"anti-bot",
|
|
202
|
+
"antibot",
|
|
203
|
+
"js challenge",
|
|
204
|
+
"javascript challenge",
|
|
205
|
+
"cdp detection",
|
|
206
|
+
"runtime.enable",
|
|
207
|
+
"puppeteer",
|
|
208
|
+
"playwright",
|
|
209
|
+
"selenium",
|
|
210
|
+
"nodriver",
|
|
211
|
+
"stealth",
|
|
212
|
+
"undetected",
|
|
213
|
+
"ja3",
|
|
214
|
+
"ja4",
|
|
215
|
+
"tls fingerprint",
|
|
216
|
+
"fingerprinting",
|
|
217
|
+
"curl_cffi",
|
|
218
|
+
"got-scraping",
|
|
219
|
+
"impersonate",
|
|
220
|
+
"http/2 settings",
|
|
221
|
+
"browser fingerprint",
|
|
222
|
+
"canvas fingerprint",
|
|
223
|
+
"webgl fingerprint",
|
|
224
|
+
"navigator.webdriver",
|
|
225
|
+
"audio context",
|
|
226
|
+
"hardware concurrency",
|
|
227
|
+
"waf bypass",
|
|
228
|
+
"aws waf",
|
|
229
|
+
"cloudflare bypass",
|
|
230
|
+
"akamai bypass",
|
|
231
|
+
"datadome",
|
|
232
|
+
"perimeterx",
|
|
233
|
+
"imperva bypass",
|
|
234
|
+
"8kb bypass",
|
|
235
|
+
"body size limit",
|
|
236
|
+
"json sqli",
|
|
237
|
+
"behavioral",
|
|
238
|
+
"mouse movement",
|
|
239
|
+
"ghost-cursor",
|
|
240
|
+
"humanized",
|
|
241
|
+
"flaresolverr",
|
|
242
|
+
"turnstile",
|
|
243
|
+
"rebrowser",
|
|
244
|
+
"botbrowser",
|
|
133
245
|
],
|
|
134
246
|
}
|
|
135
247
|
|
|
@@ -210,6 +322,7 @@ _DEFAULT_QUERY_EXPANSIONS = {
|
|
|
210
322
|
# CONFIG DATACLASS
|
|
211
323
|
# ============================================================================
|
|
212
324
|
|
|
325
|
+
|
|
213
326
|
def _resolve_path(raw, default: Path) -> Path:
|
|
214
327
|
"""Resolve a path from YAML (string) or use default (Path)."""
|
|
215
328
|
if raw is None:
|
|
@@ -225,43 +338,93 @@ class Config:
|
|
|
225
338
|
"""Central configuration for the RAG system — loads from config.yaml when available."""
|
|
226
339
|
|
|
227
340
|
# Paths
|
|
228
|
-
data_dir: Path = field(default_factory=lambda: _resolve_path(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
_get("paths", "documents_dir", None), BASE_DIR / "documents"
|
|
236
|
-
))
|
|
341
|
+
data_dir: Path = field(default_factory=lambda: _resolve_path(_get("paths", "data_dir", None), BASE_DIR / "data"))
|
|
342
|
+
chroma_dir: Path = field(
|
|
343
|
+
default_factory=lambda: _resolve_path(_get("paths", "data_dir", None), BASE_DIR / "data") / "chroma_db"
|
|
344
|
+
)
|
|
345
|
+
documents_dir: Path = field(
|
|
346
|
+
default_factory=lambda: _resolve_path(_get("paths", "documents_dir", None), BASE_DIR / "documents")
|
|
347
|
+
)
|
|
237
348
|
|
|
238
349
|
# Chunking
|
|
239
|
-
chunk_size: int = field(
|
|
240
|
-
|
|
350
|
+
chunk_size: int = field(
|
|
351
|
+
default_factory=lambda: (
|
|
352
|
+
_get("documents", "chunking", {}).get("chunk_size", 1000)
|
|
353
|
+
if isinstance(_get("documents", "chunking", {}), dict)
|
|
354
|
+
else 1000
|
|
355
|
+
)
|
|
356
|
+
)
|
|
357
|
+
chunk_overlap: int = field(
|
|
358
|
+
default_factory=lambda: (
|
|
359
|
+
_get("documents", "chunking", {}).get("chunk_overlap", 200)
|
|
360
|
+
if isinstance(_get("documents", "chunking", {}), dict)
|
|
361
|
+
else 200
|
|
362
|
+
)
|
|
363
|
+
)
|
|
241
364
|
|
|
242
365
|
# Embeddings
|
|
243
|
-
embedding_model: str = field(
|
|
244
|
-
|
|
366
|
+
embedding_model: str = field(
|
|
367
|
+
default_factory=lambda: (
|
|
368
|
+
_get("models", "embedding", {}).get("model", "BAAI/bge-small-en-v1.5")
|
|
369
|
+
if isinstance(_get("models", "embedding", {}), dict)
|
|
370
|
+
else "BAAI/bge-small-en-v1.5"
|
|
371
|
+
)
|
|
372
|
+
)
|
|
373
|
+
embedding_dim: int = field(
|
|
374
|
+
default_factory=lambda: (
|
|
375
|
+
_get("models", "embedding", {}).get("dimensions", 384)
|
|
376
|
+
if isinstance(_get("models", "embedding", {}), dict)
|
|
377
|
+
else 384
|
|
378
|
+
)
|
|
379
|
+
)
|
|
245
380
|
|
|
246
381
|
# Reranker
|
|
247
|
-
reranker_model: str = field(
|
|
248
|
-
|
|
249
|
-
|
|
382
|
+
reranker_model: str = field(
|
|
383
|
+
default_factory=lambda: (
|
|
384
|
+
_get("models", "reranker", {}).get("model", "Xenova/ms-marco-MiniLM-L-6-v2")
|
|
385
|
+
if isinstance(_get("models", "reranker", {}), dict)
|
|
386
|
+
else "Xenova/ms-marco-MiniLM-L-6-v2"
|
|
387
|
+
)
|
|
388
|
+
)
|
|
389
|
+
reranker_enabled: bool = field(
|
|
390
|
+
default_factory=lambda: (
|
|
391
|
+
_get("models", "reranker", {}).get("enabled", True)
|
|
392
|
+
if isinstance(_get("models", "reranker", {}), dict)
|
|
393
|
+
else True
|
|
394
|
+
)
|
|
395
|
+
)
|
|
396
|
+
reranker_top_k_multiplier: int = field(
|
|
397
|
+
default_factory=lambda: (
|
|
398
|
+
_get("models", "reranker", {}).get("top_k_multiplier", 3)
|
|
399
|
+
if isinstance(_get("models", "reranker", {}), dict)
|
|
400
|
+
else 3
|
|
401
|
+
)
|
|
402
|
+
)
|
|
250
403
|
|
|
251
404
|
# ChromaDB
|
|
252
405
|
collection_name: str = field(default_factory=lambda: _get("search", "collection_name", "knowledge_base"))
|
|
253
406
|
|
|
254
407
|
# Supported formats
|
|
255
|
-
supported_formats: List[str] = field(
|
|
408
|
+
supported_formats: List[str] = field(
|
|
409
|
+
default_factory=lambda: _get(
|
|
410
|
+
"documents", "supported_formats", [".md", ".txt", ".pdf", ".py", ".json", ".docx", ".xlsx", ".pptx", ".csv"]
|
|
411
|
+
)
|
|
412
|
+
)
|
|
256
413
|
|
|
257
414
|
# Category mappings
|
|
258
|
-
category_mappings: Dict[str, str] = field(
|
|
415
|
+
category_mappings: Dict[str, str] = field(
|
|
416
|
+
default_factory=lambda: _get_top("category_mappings", _DEFAULT_CATEGORY_MAPPINGS)
|
|
417
|
+
)
|
|
259
418
|
|
|
260
419
|
# Keyword routes
|
|
261
|
-
keyword_routes: Dict[str, List[str]] = field(
|
|
420
|
+
keyword_routes: Dict[str, List[str]] = field(
|
|
421
|
+
default_factory=lambda: _get_top("keyword_routes", _DEFAULT_KEYWORD_ROUTES)
|
|
422
|
+
)
|
|
262
423
|
|
|
263
424
|
# Query expansions
|
|
264
|
-
query_expansions: Dict[str, List[str]] = field(
|
|
425
|
+
query_expansions: Dict[str, List[str]] = field(
|
|
426
|
+
default_factory=lambda: _get_top("query_expansions", _DEFAULT_QUERY_EXPANSIONS)
|
|
427
|
+
)
|
|
265
428
|
|
|
266
429
|
# Search settings
|
|
267
430
|
default_results: int = field(default_factory=lambda: _get("search", "default_results", 5))
|
|
@@ -21,8 +21,6 @@ Features:
|
|
|
21
21
|
Autor: Lyon (Ailton Rocha)
|
|
22
22
|
Versao: 3.0.0
|
|
23
23
|
Data: 2026-03-19
|
|
24
|
-
|
|
25
|
-
By Lyon :) Legal Ne?
|
|
26
24
|
"""
|
|
27
25
|
|
|
28
26
|
import hashlib
|
|
@@ -1827,8 +1825,53 @@ def evaluate_retrieval(test_cases: str) -> str:
|
|
|
1827
1825
|
# =============================================================================
|
|
1828
1826
|
|
|
1829
1827
|
|
|
1828
|
+
def _handle_init():
|
|
1829
|
+
"""Export config template and presets to current directory."""
|
|
1830
|
+
import shutil
|
|
1831
|
+
|
|
1832
|
+
data_dir = Path(__file__).parent / "data"
|
|
1833
|
+
if not data_dir.exists():
|
|
1834
|
+
print("[ERROR] Bundled data not found. If installed from git, use presets/ directly.")
|
|
1835
|
+
return
|
|
1836
|
+
|
|
1837
|
+
cwd = Path.cwd()
|
|
1838
|
+
|
|
1839
|
+
# Copy config.example.yaml
|
|
1840
|
+
src = data_dir / "config.example.yaml"
|
|
1841
|
+
if src.exists():
|
|
1842
|
+
dst = cwd / "config.example.yaml"
|
|
1843
|
+
shutil.copy2(src, dst)
|
|
1844
|
+
print(f"[OK] {dst}")
|
|
1845
|
+
|
|
1846
|
+
# Copy presets
|
|
1847
|
+
presets_dir = cwd / "presets"
|
|
1848
|
+
presets_dir.mkdir(exist_ok=True)
|
|
1849
|
+
for f in data_dir.glob("*.yaml"):
|
|
1850
|
+
if f.name == "config.example.yaml":
|
|
1851
|
+
continue
|
|
1852
|
+
dst = presets_dir / f.name
|
|
1853
|
+
shutil.copy2(f, dst)
|
|
1854
|
+
print(f"[OK] {dst}")
|
|
1855
|
+
|
|
1856
|
+
# Create documents dir
|
|
1857
|
+
docs_dir = cwd / "documents"
|
|
1858
|
+
docs_dir.mkdir(exist_ok=True)
|
|
1859
|
+
print(f"[OK] {docs_dir}/")
|
|
1860
|
+
|
|
1861
|
+
print("\nDone. Quick start:")
|
|
1862
|
+
print(" cp presets/general.yaml config.yaml # or cybersecurity, developer, research")
|
|
1863
|
+
print(" # Add your documents to documents/")
|
|
1864
|
+
print(" # Restart Claude Code")
|
|
1865
|
+
|
|
1866
|
+
|
|
1830
1867
|
def main():
|
|
1831
1868
|
"""Run the MCP server"""
|
|
1869
|
+
import sys
|
|
1870
|
+
|
|
1871
|
+
if len(sys.argv) > 1 and sys.argv[1] == "init":
|
|
1872
|
+
_handle_init()
|
|
1873
|
+
return
|
|
1874
|
+
|
|
1832
1875
|
orchestrator = get_orchestrator()
|
|
1833
1876
|
|
|
1834
1877
|
# Migration: check dimension mismatch AFTER full init (avoids segfault during __init__)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "knowledge-rag"
|
|
7
|
-
version = "3.3.
|
|
7
|
+
version = "3.3.1"
|
|
8
8
|
description = "Local RAG System for Claude Code — Hybrid search + Cross-encoder Reranking + 12 MCP Tools. Zero external servers."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -55,6 +55,13 @@ knowledge-rag = "mcp_server.server:main"
|
|
|
55
55
|
[tool.hatch.build.targets.wheel]
|
|
56
56
|
packages = ["mcp_server"]
|
|
57
57
|
|
|
58
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
59
|
+
"config.example.yaml" = "mcp_server/data/config.example.yaml"
|
|
60
|
+
"presets/cybersecurity.yaml" = "mcp_server/data/cybersecurity.yaml"
|
|
61
|
+
"presets/developer.yaml" = "mcp_server/data/developer.yaml"
|
|
62
|
+
"presets/research.yaml" = "mcp_server/data/research.yaml"
|
|
63
|
+
"presets/general.yaml" = "mcp_server/data/general.yaml"
|
|
64
|
+
|
|
58
65
|
[tool.hatch.build.targets.sdist]
|
|
59
66
|
include = [
|
|
60
67
|
"mcp_server/",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|