zapret2-mcp 0.6.0 → 0.7.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.0](https://github.com/rcd27/zapret2-mcp/compare/v0.6.1...v0.7.0) (2026-03-28)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * **retrival:** техника чанков для retrieve логики, чтобы ИИ агенту не жечь токены
9
+
10
+ ### Features
11
+
12
+ * **retrival:** добавлен context для более точного ранжирования чанков ([568e10d](https://github.com/rcd27/zapret2-mcp/commit/568e10dcadf36ca24a4984988fc3398eb171c906))
13
+ * **retrival:** техника чанков для retrieve логики, чтобы ИИ агенту не жечь токены ([e00cd32](https://github.com/rcd27/zapret2-mcp/commit/e00cd32ec82d6dd7cd89c57246524d810d12edf6))
14
+
15
+ ## [0.6.1](https://github.com/rcd27/zapret2-mcp/compare/v0.6.0...v0.6.1) (2026-03-28)
16
+
17
+
18
+ ### Features
19
+
20
+ * **knowledge:** особенности UCI конфигураций ([87183b0](https://github.com/rcd27/zapret2-mcp/commit/87183b04c0cde28a2afdfcf649531bb312367fc7))
21
+ * **knowledge:** статья про blobs ([107e3c1](https://github.com/rcd27/zapret2-mcp/commit/107e3c162ff8ce0eb57ac48061c92b5b5e5ffa52))
22
+ * **knowledge:** статья про Discord ([f06bced](https://github.com/rcd27/zapret2-mcp/commit/f06bced1feaab72d27ea0599a8155fda9fb1f65a))
23
+ * **knowledge:** типичные проблемы с IPV6 ([7730dd9](https://github.com/rcd27/zapret2-mcp/commit/7730dd9fee564df91f0c24eb4a6c5631ec9324ab))
24
+
25
+
26
+ ### Bug Fixes
27
+
28
+ * **readme:** переработка readme ([1f45a84](https://github.com/rcd27/zapret2-mcp/commit/1f45a84c9cca188b8f16713ff11c8327273ee7f3))
29
+ * **reference:** ссылки на оригинальные статьи по ТСПУ ([c275b60](https://github.com/rcd27/zapret2-mcp/commit/c275b60396d7b00a4f1cc97515e7e1c616eaacdd))
30
+
3
31
  ## [0.6.0](https://github.com/rcd27/zapret2-mcp/compare/v0.5.2...v0.6.0) (2026-03-28)
4
32
 
5
33
 
package/README.md CHANGED
@@ -1,90 +1,99 @@
1
1
  # zapret2-mcp
2
2
 
3
- Knowledge MCP-сервер для [zapret2](https://github.com/bol-van/zapret2) и [blockcheckw](https://github.com/rcd27/blockcheckw). Подключи к AI-агенту — он получит экспертные знания по обходу DPI-блокировок и сможет настроить всё сам.
3
+ [![CI](https://github.com/rcd27/zapret2-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/rcd27/zapret2-mcp/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/zapret2-mcp)](https://www.npmjs.com/package/zapret2-mcp)
5
+ [![Knowledge Base](https://img.shields.io/badge/knowledge_base-27_articles-green)](./knowledge/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
4
7
 
5
- ## Зачем
8
+ База знаний по [zapret2](https://github.com/bol-van/zapret2) (DPI bypass) и [blockcheckw](https://github.com/rcd27/blockcheckw) (сканер стратегий). Работает как [MCP-сервер](https://modelcontextprotocol.io/) для LLM-агентов и как обычная документация.
6
9
 
7
- AI-агент (Claude, Cursor, etc.) умеет выполнять команды в терминале. Но он **не знает** как работает zapret2, какие стратегии бывают, как их подбирать и что делать если не работает. Этот MCP-сервер даёт агенту эти знания.
8
-
9
- **Сервер не выполняет команды** — он отдаёт документацию и экспертизу. Агент читает и действует сам.
10
+ > **Можно использовать без агентов.** [`knowledge/`](./knowledge/) 27 статей на русском языке. Открывайте и читайте как обычную документацию, без установки чего-либо.
10
11
 
11
12
  ## Что внутри
12
13
 
13
- **14 статей** в базе знаний:
14
-
15
- - Стратегии DPI bypass: split2, disorder2, fake, fooling, QUIC, оркестрация
16
- - Справочник параметров nfqws2 и конфига zapret2
17
- - Команды [blockcheckw](https://github.com/rcd27/blockcheckw) для параллельного сканирования стратегий
18
- - Пошаговые workflow-ы установки и диагностики
19
- - Типичные проблемы и решения
14
+ | Раздел | Статей | Темы |
15
+ |--------|--------|------|
16
+ | [strategies/](./knowledge/strategies/) | 8 | TCP segmentation, fake packets, multidisorder, QUIC, circular, Discord, Telegram, orchestration |
17
+ | [config/](./knowledge/config/) | 5 | nfqws2 CLI, zapret2 config, UCI, blobs, миграция v1 → v2 |
18
+ | [troubleshooting/](./knowledge/troubleshooting/) | 5 | Smart TV + YouTube, QUIC, IPv6, FLOWOFFLOAD, конфликты с Podkop |
19
+ | [tspu/](./knowledge/tspu/) | 4 | Архитектура ТСПУ, DPI engine, методы блокировки, двухстадийная система |
20
+ | [workflows/](./knowledge/workflows/) | 2 | Установка, поиск стратегии |
21
+ | [blockcheckw/](./knowledge/blockcheckw/) | 2 | Overview, команды |
22
+ | [platforms/](./knowledge/platforms/) | 1 | Поддерживаемые платформы |
20
23
 
21
- ## Установка
24
+ ## Подключение к LLM-агенту
22
25
 
23
- ```bash
24
- npm install -g zapret2-mcp
25
- ```
26
+ Сервер **не выполняет команды** — он отдаёт знания. Агент читает и действует сам.
26
27
 
27
- ## Подключение
28
-
29
- ### Claude Desktop / Claude Code
28
+ ### Claude Code / Claude Desktop
30
29
 
31
30
  ```json
32
31
  {
33
32
  "mcpServers": {
34
33
  "zapret2": {
35
34
  "command": "npx",
36
- "args": ["zapret2-mcp"]
35
+ "args": ["-y", "zapret2-mcp"]
37
36
  }
38
37
  }
39
38
  }
40
39
  ```
41
40
 
42
- Никаких переменных окружения не нужно — сервер только отдаёт знания.
41
+ ### Cursor
42
+
43
+ Settings → MCP Servers → Add:
44
+
45
+ ```json
46
+ {
47
+ "zapret2": {
48
+ "command": "npx",
49
+ "args": ["-y", "zapret2-mcp"]
50
+ }
51
+ }
52
+ ```
53
+
54
+ ### Из исходников
55
+
56
+ ```bash
57
+ git clone --recurse-submodules https://github.com/rcd27/zapret2-mcp.git
58
+ cd zapret2-mcp
59
+ npm install && npm run build
60
+ npm start
61
+ ```
43
62
 
44
63
  ## MCP API
45
64
 
46
65
  ### Tool
47
66
 
48
67
  | Tool | Описание |
49
- |---|---|
50
- | `query-zapret-knowledge` | Поиск по базе знаний. Параметры: `topic` (строка), `tokens` (лимит, опционально) |
51
-
52
- ```
53
- query-zapret-knowledge({ topic: "split2 strategy" })
54
- query-zapret-knowledge({ topic: "blockcheckw scan", tokens: 2000 })
55
- query-zapret-knowledge({ topic: "troubleshooting dns" })
56
- ```
68
+ |------|----------|
69
+ | `query-zapret-knowledge(topic, tokens?)` | Keyword-поиск по базе знаний с ранжированием |
57
70
 
58
71
  ### Prompts
59
72
 
60
73
  | Prompt | Описание |
61
- |---|---|
74
+ |--------|----------|
62
75
  | `setup-zapret` | Пошаговая установка zapret2 |
63
- | `find-bypass-strategy` | Поиск рабочей стратегии через blockcheckw |
76
+ | `find-bypass-strategy` | Поиск стратегии через blockcheckw |
64
77
  | `troubleshoot` | Диагностика проблем |
65
- | `strategy-knowledge` | Полный справочник стратегий DPI bypass |
78
+ | `strategy-knowledge` | Справочник стратегий DPI bypass |
66
79
 
67
- ## Пример использования
80
+ ## Примеры вопросов
68
81
 
69
- > "Настрой zapret2 на моём роутере, найди рабочую стратегию для youtube.com"
70
-
71
- Агент:
72
- 1. Вызывает `query-zapret-knowledge({ topic: "setup installation" })` — получает инструкции
73
- 2. Выполняет команды установки в терминале
74
- 3. Вызывает `query-zapret-knowledge({ topic: "blockcheckw scan" })` узнаёт как искать стратегии
75
- 4. Запускает `blockcheckw scan -d youtube.com`
76
- 5. Вызывает `query-zapret-knowledge({ topic: "strategy selection criteria" })` — понимает как выбрать лучшую
77
- 6. Применяет стратегию в конфиг, запускает сервис
82
+ ```
83
+ "YouTube тормозит на Samsung TV — что делать?"
84
+ "Как настроить голос Discord через zapret2?"
85
+ "blockcheck нашёл стратегию, но сайт не открывается"
86
+ "Как перевести стратегию с zapret v1 на zapret2?"
87
+ "Что такое circular и как настроить автоперебор?"
88
+ "QUIC отключать или обрабатывать?"
89
+ ```
78
90
 
79
- ## Разработка
91
+ ## Источники
80
92
 
81
- ```bash
82
- git clone --recurse-submodules https://github.com/rcd27/zapret2-mcp.git
83
- cd zapret2-mcp
84
- npm install
85
- npm run build
86
- npm test
87
- ```
93
+ - [zapret2](https://github.com/bol-van/zapret2) — DPI bypass от bol-van
94
+ - [blockcheckw](https://github.com/rcd27/blockcheckw) — быстрый сканер стратегий
95
+ - [tspu-docs](https://github.com/DanielLavrushin/tspu-docs) — документация ТСПУ
96
+ - Community — обезличенные знания из открытых обсуждений
88
97
 
89
98
  ## Лицензия
90
99
 
package/build/index.js CHANGED
@@ -29,9 +29,11 @@ This server does NOT execute commands — it provides knowledge and guidance. Th
29
29
  });
30
30
  server.tool("query-zapret-knowledge", "Search zapret2 and blockcheckw knowledge base by topic. Returns relevant documentation, strategy guides, configuration references, and troubleshooting information.", {
31
31
  topic: z.string().describe("What to search for (e.g. 'split2 strategy', 'blockcheckw scan', 'troubleshooting dns', 'config nfqws2_opt')"),
32
- tokens: z.number().optional().describe("Maximum approximate token count for the response (default: no limit)"),
32
+ tokens: z.number().optional().describe("Maximum approximate token count for the response (default: 4000). Use 0 for unlimited."),
33
+ context: z.string().optional().describe("What you already know or checked (e.g. 'curl OK on router, QUIC disabled, flow_offloading_hw=1'). Helps narrow results by deprioritizing already-covered topics."),
33
34
  }, async (args) => {
34
- const results = index.query(args.topic, args.tokens);
35
+ const tokenLimit = args.tokens === 0 ? undefined : (args.tokens ?? 4000);
36
+ const results = index.query(args.topic, tokenLimit, args.context);
35
37
  if (results.length === 0) {
36
38
  return {
37
39
  content: [
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -15,11 +15,24 @@ export interface KnowledgeEntry {
15
15
  export declare class KnowledgeIndex {
16
16
  private knowledgeDir;
17
17
  private entries;
18
+ private chunks;
18
19
  constructor(knowledgeDir: string);
19
20
  rebuild(): void;
20
- /** Keyword-based search. Returns entries ranked by relevance. */
21
- query(topic: string, maxTokens?: number): KnowledgeEntry[];
21
+ /**
22
+ * Keyword-based search with chunk-level retrieval, intent detection, and context narrowing.
23
+ * @param context - what the agent already knows/checked (used to deprioritize already-covered topics)
24
+ */
25
+ query(topic: string, maxTokens?: number, context?: string): KnowledgeEntry[];
22
26
  /** Get all entries (for listing) */
23
27
  all(): KnowledgeEntry[];
28
+ private assembleResults;
29
+ private detectIntent;
30
+ /**
31
+ * Adjust score based on context (what agent already knows).
32
+ * Chunks heavily overlapping with context get deprioritized.
33
+ * Chunks that add NEW information relative to context get boosted.
34
+ */
35
+ private contextAdjust;
36
+ private intentBoost;
24
37
  private tokenize;
25
38
  }
package/build/indexer.js CHANGED
@@ -27,50 +27,107 @@ function collectMarkdownFiles(dir) {
27
27
  }
28
28
  return files;
29
29
  }
30
+ function splitIntoChunks(entry) {
31
+ const chunks = [];
32
+ const lines = entry.content.split("\n");
33
+ let currentSection = "";
34
+ let currentLines = [];
35
+ let order = 0;
36
+ const flush = () => {
37
+ const content = currentLines.join("\n").trim();
38
+ if (content) {
39
+ chunks.push({
40
+ docPath: entry.path,
41
+ docTitle: entry.title,
42
+ docTags: entry.tags,
43
+ zapret2Version: entry.zapret2Version,
44
+ blockcheckwVersion: entry.blockcheckwVersion,
45
+ sectionTitle: currentSection,
46
+ content,
47
+ order: order++,
48
+ });
49
+ }
50
+ };
51
+ for (const line of lines) {
52
+ if (line.startsWith("## ")) {
53
+ flush();
54
+ currentSection = line.slice(3).trim();
55
+ currentLines = [];
56
+ }
57
+ else {
58
+ currentLines.push(line);
59
+ }
60
+ }
61
+ flush();
62
+ if (chunks.length > 0)
63
+ return chunks;
64
+ return [{
65
+ docPath: entry.path,
66
+ docTitle: entry.title,
67
+ docTags: entry.tags,
68
+ zapret2Version: entry.zapret2Version,
69
+ blockcheckwVersion: entry.blockcheckwVersion,
70
+ sectionTitle: "",
71
+ content: entry.content,
72
+ order: 0,
73
+ }];
74
+ }
30
75
  export class KnowledgeIndex {
31
76
  knowledgeDir;
32
77
  entries = [];
78
+ chunks = [];
33
79
  constructor(knowledgeDir) {
34
80
  this.knowledgeDir = knowledgeDir;
35
81
  this.rebuild();
36
82
  }
37
83
  rebuild() {
38
84
  this.entries = [];
85
+ this.chunks = [];
39
86
  const files = collectMarkdownFiles(this.knowledgeDir);
40
87
  for (const file of files) {
41
88
  const raw = readFileSync(file, "utf-8");
42
89
  const { meta, content } = parseFrontmatter(raw);
43
- this.entries.push({
90
+ const entry = {
44
91
  path: relative(this.knowledgeDir, file),
45
92
  title: meta.title ?? file,
46
93
  tags: (meta.tags ?? "").split(",").map((t) => t.trim()).filter(Boolean),
47
94
  content: content.trim(),
48
95
  zapret2Version: meta["zapret2-version"],
49
96
  blockcheckwVersion: meta["blockcheckw-version"],
50
- });
97
+ };
98
+ this.entries.push(entry);
99
+ this.chunks.push(...splitIntoChunks(entry));
51
100
  }
52
101
  }
53
- /** Keyword-based search. Returns entries ranked by relevance. */
54
- query(topic, maxTokens) {
102
+ /**
103
+ * Keyword-based search with chunk-level retrieval, intent detection, and context narrowing.
104
+ * @param context - what the agent already knows/checked (used to deprioritize already-covered topics)
105
+ */
106
+ query(topic, maxTokens, context) {
55
107
  const keywords = this.tokenize(topic);
56
108
  if (keywords.length === 0)
57
109
  return this.entries;
58
- const scored = [];
59
- for (const entry of this.entries) {
110
+ const intent = this.detectIntent(keywords);
111
+ const contextKeywords = context ? this.tokenize(context) : [];
112
+ const scoredChunks = [];
113
+ for (const chunk of this.chunks) {
60
114
  let score = 0;
61
115
  for (const keyword of keywords) {
62
116
  const kw = keyword.toLowerCase();
63
- // Title match (highest weight)
64
- if (entry.title.toLowerCase().includes(kw))
117
+ // Document title match (highest weight)
118
+ if (chunk.docTitle.toLowerCase().includes(kw))
65
119
  score += 10;
66
- // Tag exact match (high weight)
67
- if (entry.tags.some((t) => t.toLowerCase() === kw))
120
+ // Section title match
121
+ if (chunk.sectionTitle.toLowerCase().includes(kw))
122
+ score += 8;
123
+ // Tag exact match
124
+ if (chunk.docTags.some((t) => t.toLowerCase() === kw))
68
125
  score += 8;
69
126
  // Tag partial match
70
- if (entry.tags.some((t) => t.toLowerCase().includes(kw)))
127
+ if (chunk.docTags.some((t) => t.toLowerCase().includes(kw)))
71
128
  score += 4;
72
129
  // Content match (count occurrences, capped)
73
- const contentLower = entry.content.toLowerCase();
130
+ const contentLower = chunk.content.toLowerCase();
74
131
  let idx = 0;
75
132
  let count = 0;
76
133
  while ((idx = contentLower.indexOf(kw, idx)) !== -1) {
@@ -79,29 +136,130 @@ export class KnowledgeIndex {
79
136
  }
80
137
  score += Math.min(count, 5) * 2;
81
138
  }
139
+ // Intent boost
140
+ score += this.intentBoost(chunk.docPath, intent);
141
+ // Context narrowing: deprioritize chunks that cover already-known topics
142
+ if (contextKeywords.length > 0) {
143
+ score += this.contextAdjust(chunk, contextKeywords);
144
+ }
82
145
  if (score > 0) {
83
- scored.push({ entry, score });
146
+ scoredChunks.push({ chunk, score });
84
147
  }
85
148
  }
86
- scored.sort((a, b) => b.score - a.score);
87
- if (!maxTokens)
88
- return scored.map((s) => s.entry);
89
- // Approximate token limit (1 token ≈ 4 chars)
90
- const charLimit = maxTokens * 4;
149
+ scoredChunks.sort((a, b) => b.score - a.score);
150
+ return this.assembleResults(scoredChunks, maxTokens);
151
+ }
152
+ /** Get all entries (for listing) */
153
+ all() {
154
+ return this.entries;
155
+ }
156
+ assembleResults(scoredChunks, maxTokens) {
157
+ const docOrder = [];
158
+ const docChunks = new Map();
159
+ for (const { chunk } of scoredChunks) {
160
+ const existing = docChunks.get(chunk.docPath);
161
+ if (existing) {
162
+ if (!existing.some((c) => c.order === chunk.order)) {
163
+ existing.push(chunk);
164
+ }
165
+ }
166
+ else {
167
+ docOrder.push(chunk.docPath);
168
+ docChunks.set(chunk.docPath, [chunk]);
169
+ }
170
+ }
171
+ const charLimit = maxTokens ? maxTokens * 4 : undefined;
91
172
  let totalChars = 0;
92
173
  const result = [];
93
- for (const { entry } of scored) {
174
+ for (const path of docOrder) {
175
+ const chunks = docChunks.get(path);
176
+ const parent = this.entries.find((e) => e.path === path);
177
+ const assembledContent = chunks
178
+ .sort((a, b) => a.order - b.order)
179
+ .map((c) => c.sectionTitle ? `## ${c.sectionTitle}\n\n${c.content}` : c.content)
180
+ .join("\n\n");
181
+ const entry = {
182
+ path: parent.path,
183
+ title: parent.title,
184
+ tags: parent.tags,
185
+ content: assembledContent,
186
+ zapret2Version: parent.zapret2Version,
187
+ blockcheckwVersion: parent.blockcheckwVersion,
188
+ };
94
189
  const entryChars = entry.title.length + entry.content.length + 50;
95
- if (totalChars + entryChars > charLimit && result.length > 0)
190
+ if (charLimit && totalChars + entryChars > charLimit && result.length > 0)
96
191
  break;
97
192
  result.push(entry);
98
193
  totalChars += entryChars;
99
194
  }
100
195
  return result;
101
196
  }
102
- /** Get all entries (for listing) */
103
- all() {
104
- return this.entries;
197
+ detectIntent(keywords) {
198
+ const INTENTS = {
199
+ TROUBLESHOOTING: [
200
+ "error", "failed", "problem", "работает", "тормозит",
201
+ "ошибка", "broken", "timeout", "открывается", "fix", "issue",
202
+ "debug", "диагностика", "troubleshoot", "troubleshooting",
203
+ "конфликт", "conflict",
204
+ ],
205
+ REFERENCE: [
206
+ "параметры", "options", "reference", "syntax", "список", "опции",
207
+ "cli", "параметр", "флаг", "flag", "blobs", "blob",
208
+ ],
209
+ HOWTO: [
210
+ "как", "setup", "install", "настроить", "configure", "установка",
211
+ "подключить", "установить", "how", "guide", "workflow", "миграция",
212
+ "migration",
213
+ ],
214
+ };
215
+ let bestIntent = null;
216
+ let bestCount = 0;
217
+ for (const [intent, triggers] of Object.entries(INTENTS)) {
218
+ const count = keywords.filter((kw) => triggers.some((t) => t === kw || kw.includes(t))).length;
219
+ if (count > bestCount) {
220
+ bestCount = count;
221
+ bestIntent = intent;
222
+ }
223
+ }
224
+ return bestIntent;
225
+ }
226
+ /**
227
+ * Adjust score based on context (what agent already knows).
228
+ * Chunks heavily overlapping with context get deprioritized.
229
+ * Chunks that add NEW information relative to context get boosted.
230
+ */
231
+ contextAdjust(chunk, contextKeywords) {
232
+ const chunkText = (chunk.sectionTitle + " " + chunk.content).toLowerCase();
233
+ let overlapCount = 0;
234
+ for (const ckw of contextKeywords) {
235
+ if (chunkText.includes(ckw)) {
236
+ overlapCount++;
237
+ }
238
+ }
239
+ const overlapRatio = contextKeywords.length > 0 ? overlapCount / contextKeywords.length : 0;
240
+ // High overlap (>60% of context keywords found in chunk) → deprioritize
241
+ if (overlapRatio > 0.6)
242
+ return -8;
243
+ // Medium overlap (30-60%) → slight penalty
244
+ if (overlapRatio > 0.3)
245
+ return -3;
246
+ // Low overlap (<30%) → this chunk has new info, slight boost
247
+ return 2;
248
+ }
249
+ intentBoost(docPath, intent) {
250
+ if (!intent)
251
+ return 0;
252
+ const PATH_INTENT_MAP = {
253
+ "troubleshooting/": "TROUBLESHOOTING",
254
+ "config/": "REFERENCE",
255
+ "workflows/": "HOWTO",
256
+ };
257
+ for (const [prefix, matchIntent] of Object.entries(PATH_INTENT_MAP)) {
258
+ if (docPath.startsWith(prefix) && intent === matchIntent) {
259
+ return 5;
260
+ }
261
+ }
262
+ return 0;
105
263
  }
106
264
  tokenize(text) {
107
265
  return text
@@ -1 +1 @@
1
- {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"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"}