mcp-probe-kit 3.0.17 → 3.0.19

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 (37) hide show
  1. package/README.md +77 -50
  2. package/build/lib/__tests__/agents-md-template.unit.test.d.ts +1 -0
  3. package/build/lib/__tests__/agents-md-template.unit.test.js +25 -0
  4. package/build/lib/__tests__/project-context-layout.unit.test.d.ts +1 -0
  5. package/build/lib/__tests__/project-context-layout.unit.test.js +80 -0
  6. package/build/lib/agents-md-template.d.ts +25 -0
  7. package/build/lib/agents-md-template.js +55 -0
  8. package/build/lib/memory-orchestration.d.ts +3 -1
  9. package/build/lib/memory-orchestration.js +71 -5
  10. package/build/lib/merge-agents-md.d.ts +6 -0
  11. package/build/lib/merge-agents-md.js +51 -0
  12. package/build/lib/project-context-layout.d.ts +78 -0
  13. package/build/lib/project-context-layout.js +350 -0
  14. package/build/lib/workspace-root.js +6 -1
  15. package/build/resources/ui-ux-data/metadata.json +1 -1
  16. package/build/schemas/index.d.ts +25 -3
  17. package/build/schemas/memory-tools.d.ts +1 -1
  18. package/build/schemas/memory-tools.js +1 -1
  19. package/build/schemas/project-tools.d.ts +24 -2
  20. package/build/schemas/project-tools.js +24 -2
  21. package/build/tools/__tests__/code_insight.unit.test.js +3 -3
  22. package/build/tools/__tests__/init_project_context.unit.test.js +32 -21
  23. package/build/tools/__tests__/start_feature.unit.test.js +2 -1
  24. package/build/tools/code_insight.js +11 -9
  25. package/build/tools/init_project_context.js +563 -506
  26. package/build/tools/start_bugfix.js +254 -248
  27. package/build/tools/start_feature.js +137 -131
  28. package/build/tools/start_ui.js +402 -402
  29. package/docs/.mcp-probe/layout.json +11 -0
  30. package/docs/i18n/en.json +36 -5
  31. package/docs/i18n/ja.json +9 -2
  32. package/docs/i18n/ko.json +9 -2
  33. package/docs/i18n/zh-CN.json +36 -5
  34. package/docs/memory-local-setup.md +314 -0
  35. package/docs/memory-local-setup.zh-CN.md +280 -0
  36. package/docs/pages/getting-started.html +249 -31
  37. package/package.json +1 -1
@@ -0,0 +1,280 @@
1
+ # 本地记忆栈(Qdrant + Nomic Embed)
2
+
3
+ 面向 `memorize_asset`、`read_memory_asset`、`scan_and_extract_patterns` 的**轻量本机部署**说明:
4
+
5
+ - **Qdrant** — 向量库(端口 `50008`)
6
+ - **Infinity(nomic-embed)** — 向量生成(端口 `50012`),**替代 Ollama**,对用户更轻
7
+
8
+ 建议使用 Docker Compose 统一部署;端口采用 `500xx` 段,避免与其它服务冲突。
9
+
10
+ | 服务 | 宿主机端口 | 容器端口 | 说明 |
11
+ |------|------------|----------|------|
12
+ | Qdrant HTTP | `50008` | `6333` | REST、Dashboard |
13
+ | Qdrant gRPC | `50009` | `6334` | gRPC |
14
+ | Nomic Embed | `50012` | `7997` | OpenAI 兼容 embedding |
15
+
16
+ ---
17
+
18
+ ## 1. Qdrant 向量数据库
19
+
20
+ ### 服务信息
21
+
22
+ | 项 | 值 |
23
+ |----|-----|
24
+ | **镜像** | `qdrant/qdrant:latest` |
25
+ | **容器名** | `qdrant` |
26
+ | **HTTP** | `http://127.0.0.1:50008` |
27
+ | **gRPC** | `127.0.0.1:50009` |
28
+ | **数据** | `./data` → `/qdrant/storage` |
29
+ | **快照** | `./snapshots` → `/qdrant/snapshots` |
30
+ | **认证** | `.env` 中 `QDRANT_API_KEY`,请求头 `api-key` |
31
+
32
+ ### `docker-compose.yml`
33
+
34
+ ```yaml
35
+ services:
36
+ qdrant:
37
+ image: qdrant/qdrant:latest
38
+ container_name: qdrant
39
+ restart: always
40
+ env_file:
41
+ - .env
42
+ ports:
43
+ - "50008:6333"
44
+ - "50009:6334"
45
+ volumes:
46
+ - ./data:/qdrant/storage
47
+ - ./snapshots:/qdrant/snapshots
48
+ environment:
49
+ - QDRANT__SERVICE__HTTP_PORT=6333
50
+ - QDRANT__SERVICE__GRPC_PORT=6334
51
+ - QDRANT__LOG_LEVEL=INFO
52
+ - QDRANT__SERVICE__API_KEY=${QDRANT_API_KEY}
53
+ healthcheck:
54
+ test:
55
+ - "CMD"
56
+ - "bash"
57
+ - "-c"
58
+ - "exec 3<>/dev/tcp/127.0.0.1/6333 && printf 'GET /collections HTTP/1.1\r\nHost: localhost\r\napi-key: ${QDRANT_API_KEY}\r\nConnection: close\r\n\r\n' >&3 && IFS= read -r line <&3 && [[ \"$$line\" == *\"200\"* ]]"
59
+ interval: 30s
60
+ timeout: 10s
61
+ retries: 5
62
+ start_period: 30s
63
+ ```
64
+
65
+ ### `.env.example`
66
+
67
+ ```bash
68
+ # 复制:copy .env.example .env
69
+ # 生成密钥:python -c "import secrets; print(secrets.token_urlsafe(32))"
70
+
71
+ QDRANT_API_KEY=请改为长随机串
72
+ QDRANT_URL=http://127.0.0.1:50008
73
+ ```
74
+
75
+ ### 首次部署
76
+
77
+ ```powershell
78
+ cd qdrant
79
+ copy .env.example .env
80
+ # 编辑 .env,设置 QDRANT_API_KEY
81
+ docker compose up -d
82
+ ```
83
+
84
+ ### 验证
85
+
86
+ ```bash
87
+ curl http://127.0.0.1:50008/collections \
88
+ -H "api-key: 你的QDRANT_API_KEY"
89
+
90
+ # 面板(需填入相同 Key)
91
+ # http://127.0.0.1:50008/dashboard
92
+ ```
93
+
94
+ ### 常用命令
95
+
96
+ ```powershell
97
+ docker compose up -d
98
+ docker compose down
99
+ docker compose logs -f qdrant
100
+ docker compose restart qdrant
101
+ ```
102
+
103
+ ### 说明
104
+
105
+ - 开启 `QDRANT__SERVICE__API_KEY` 后,所有 REST/gRPC 请求必须带 `api-key` 头。
106
+ - mcp-probe-kit 通过环境变量 `MEMORY_QDRANT_API_KEY` 传入。
107
+ - 首次 `memorize_asset` 写入会自动创建 collection `mcp_probe_memory`(Cosine;维度由首次 embedding 推断)。
108
+
109
+ ---
110
+
111
+ ## 2. Nomic Embed(Infinity 推理服务)
112
+
113
+ 基于 [Infinity](https://github.com/michaelfeil/infinity),模型 `nomic-ai/nomic-embed-text-v1.5`,**768 维**,无需 Ollama。
114
+
115
+ ### 服务信息
116
+
117
+ | 项 | 值 |
118
+ |----|-----|
119
+ | **镜像** | `michaelf34/infinity:0.0.70` |
120
+ | **容器名** | `nomic-embed` |
121
+ | **端口** | `50012` → `7997` |
122
+ | **模型** | `nomic-ai/nomic-embed-text-v1.5` |
123
+ | **向量维度** | 768 |
124
+ | **引擎** | `torch`(无 GPU 走 CPU) |
125
+ | **认证** | `INFINITY_API_KEY`(`Authorization: Bearer`) |
126
+ | **模型缓存** | 卷 `hf_cache` → `/app/.cache` |
127
+
128
+ ### `docker-compose.yml`
129
+
130
+ ```yaml
131
+ services:
132
+ nomic-embed:
133
+ image: michaelf34/infinity:0.0.70
134
+ container_name: nomic-embed
135
+ restart: unless-stopped
136
+ ports:
137
+ - "50012:7997"
138
+ volumes:
139
+ - hf_cache:/app/.cache
140
+ environment:
141
+ INFINITY_API_KEY: ${INFINITY_API_KEY}
142
+ command:
143
+ - v2
144
+ - --model-id
145
+ - nomic-ai/nomic-embed-text-v1.5
146
+ - --revision
147
+ - main
148
+ - --dtype
149
+ - float32
150
+ - --batch-size
151
+ - "8"
152
+ - --engine
153
+ - torch
154
+ - --port
155
+ - "7997"
156
+ - --no-bettertransformer
157
+ healthcheck:
158
+ test:
159
+ - "CMD"
160
+ - "curl"
161
+ - "-f"
162
+ - "http://127.0.0.1:7997/health"
163
+ interval: 30s
164
+ timeout: 10s
165
+ retries: 5
166
+ start_period: 120s
167
+
168
+ volumes:
169
+ hf_cache:
170
+ ```
171
+
172
+ ### 首次部署
173
+
174
+ ```powershell
175
+ cd nomic-embed
176
+ copy .env.example .env
177
+ docker compose up -d
178
+ docker logs -f nomic-embed
179
+ ```
180
+
181
+ 冷启动需下载模型,约 **2–5 分钟**,日志出现 `ready to batch requests` 即就绪。
182
+
183
+ ### 访问与验证
184
+
185
+ ```bash
186
+ curl http://127.0.0.1:50012/health
187
+
188
+ curl http://127.0.0.1:50012/models \
189
+ -H "Authorization: Bearer 你的INFINITY_API_KEY"
190
+
191
+ # 注意:路径是 POST /embeddings,不是 /v1/embeddings
192
+ curl http://127.0.0.1:50012/embeddings \
193
+ -H "Authorization: Bearer 你的INFINITY_API_KEY" \
194
+ -H "Content-Type: application/json" \
195
+ -d '{"model":"nomic-ai/nomic-embed-text-v1.5","input":"hello world"}'
196
+ ```
197
+
198
+ Swagger:`http://127.0.0.1:50012/docs`
199
+
200
+ ### 性能(纯 CPU,参考)
201
+
202
+ | 场景 | 约耗时 |
203
+ |------|--------|
204
+ | 单条短文本(热) | 30–50 ms |
205
+ | 首条 | ~150 ms |
206
+ | batch 8 | ~150 ms |
207
+ | 常驻内存 | ~1 GB |
208
+
209
+ 适合 MCP 记忆、低频写入;不适合高并发批量入库。
210
+
211
+ ---
212
+
213
+ ## 3. 与 mcp-probe-kit / Qdrant 配合
214
+
215
+ **推荐组合**:Qdrant `50008` + Infinity `50012`。
216
+
217
+ ```json
218
+ {
219
+ "mcpServers": {
220
+ "mcp-probe-kit": {
221
+ "command": "npx",
222
+ "args": ["-y", "mcp-probe-kit@latest"],
223
+ "env": {
224
+ "MEMORY_QDRANT_URL": "http://127.0.0.1:50008",
225
+ "MEMORY_QDRANT_API_KEY": "与 qdrant/.env 中 QDRANT_API_KEY 相同",
226
+ "MEMORY_QDRANT_COLLECTION": "mcp_probe_memory",
227
+ "MEMORY_EMBEDDING_PROVIDER": "openai-compatible",
228
+ "MEMORY_EMBEDDING_URL": "http://127.0.0.1:50012/embeddings",
229
+ "MEMORY_EMBEDDING_MODEL": "nomic-ai/nomic-embed-text-v1.5",
230
+ "MEMORY_EMBEDDING_API_KEY": "与 nomic-embed/.env 中 INFINITY_API_KEY 相同",
231
+ "MEMORY_SEARCH_LIMIT": "3",
232
+ "MEMORY_SUMMARY_MAX_CHARS": "280"
233
+ }
234
+ }
235
+ }
236
+ }
237
+ ```
238
+
239
+ Claude Code:写入 `.mcp.json` 的 `mcpServers.mcp-probe-kit.env`。修改后**完全重启** Cursor。
240
+
241
+ ---
242
+
243
+ ## 4. 端到端自测
244
+
245
+ ```bash
246
+ curl -s http://127.0.0.1:50008/collections -H "api-key: 你的QDRANT_API_KEY"
247
+
248
+ curl -s -X POST http://127.0.0.1:50012/embeddings \
249
+ -H "Authorization: Bearer 你的INFINITY_API_KEY" \
250
+ -H "Content-Type: application/json" \
251
+ -d '{"model":"nomic-ai/nomic-embed-text-v1.5","input":"测试"}' \
252
+ | jq '.data[0].embedding | length'
253
+ # 期望输出:768
254
+ ```
255
+
256
+ ---
257
+
258
+ ## 5. 故障排查
259
+
260
+ | 现象 | 处理 |
261
+ |------|------|
262
+ | Qdrant `401` | 配置 `MEMORY_QDRANT_API_KEY`,与 `.env` 一致 |
263
+ | Embedding `401` | 检查 `Authorization: Bearer` 与 `INFINITY_API_KEY` |
264
+ | Embedding `404` | URL 必须是 `/embeddings`,勿用 `/v1/embeddings` |
265
+ | health 长期 `starting` | 首次下模型,看 `docker logs nomic-embed` |
266
+ | 日志 `No CUDA runtime` | 正常,表示 CPU 推理 |
267
+ | 向量维度不匹配 | 换模型后需新 collection 或删旧 collection |
268
+ | 记忆写入不可用 | 同时配置 `MEMORY_QDRANT_URL`、`MEMORY_EMBEDDING_URL`、`MEMORY_EMBEDDING_MODEL` |
269
+
270
+ ---
271
+
272
+ ## 6. 其它方案
273
+
274
+ | 方案 | 适用 |
275
+ |------|------|
276
+ | **本指南(Qdrant + Infinity)** | 本地开发默认,比 Ollama 轻 |
277
+ | Qdrant + Ollama | 已用 Ollama 跑聊天模型时 |
278
+ | Qdrant + 云端 OpenAI 兼容 API | 不想跑本地 embedding 容器 |
279
+
280
+ 英文版:[memory-local-setup.md](./memory-local-setup.md)
@@ -255,51 +255,235 @@
255
255
  <code class="bg-gray-200 px-1 rounded text-xs">scan_and_extract_patterns</code>
256
256
  <span data-i18n="gettingStarted.step1.memory.descriptionSuffix">, you need to configure both a vector database and an embedding service.</span>
257
257
  </p>
258
- <div class="space-y-3">
259
- <div>
260
- <p class="font-medium mb-2" data-i18n="gettingStarted.step1.memory.optionA.title">Option A: Qdrant + Ollama (recommended)</p>
261
- <pre class="code-block mb-2 p-3 text-sm text-slate-200 bg-slate-900 rounded overflow-x-auto"><code>docker run -d --name mcp-qdrant -p 6333:6333 qdrant/qdrant
262
- ollama pull nomic-embed-text</code></pre>
263
- <pre class="code-block p-3 text-sm text-slate-200 bg-slate-900 rounded overflow-x-auto"><code>{
264
- "mcpServers": {
265
- "mcp-probe-kit": {
266
- "command": "npx",
267
- "args": ["-y", "mcp-probe-kit@latest"],
268
- "env": {
269
- "MEMORY_QDRANT_URL": "http://127.0.0.1:6333",
270
- "MEMORY_QDRANT_COLLECTION": "mcp_probe_memory",
271
- "MEMORY_EMBEDDING_PROVIDER": "ollama",
272
- "MEMORY_EMBEDDING_URL": "http://127.0.0.1:11434/api/embeddings",
273
- "MEMORY_EMBEDDING_MODEL": "nomic-embed-text",
274
- "MEMORY_SEARCH_LIMIT": "3",
275
- "MEMORY_SUMMARY_MAX_CHARS": "280"
276
- }
277
- }
278
- }
279
- }</code></pre>
258
+ <p class="mb-3 text-text-secondary" data-i18n="gettingStarted.step1.memory.deployIntro">Copy the files below into two folders, start both services, then paste the MCP config. No Ollama required.</p>
259
+ <p class="mb-3 text-text-secondary">
260
+ <span data-i18n="gettingStarted.step1.memory.guideLink">Extended guide (troubleshooting, performance):</span>
261
+ <a class="text-emerald-700 underline" href="https://github.com/mybolide/mcp-probe-kit/blob/main/docs/memory-local-setup.md" data-i18n="gettingStarted.step1.memory.guidePath">docs/memory-local-setup.md</a>
262
+ · <a class="text-emerald-700 underline" href="https://github.com/mybolide/mcp-probe-kit/blob/main/docs/memory-local-setup.zh-CN.md">中文</a>
263
+ </p>
264
+
265
+ <p class="font-medium mb-1" data-i18n="gettingStarted.step1.memory.portTitle">Ports</p>
266
+ <table class="w-full mb-4 text-xs border border-emerald-200 rounded overflow-hidden">
267
+ <thead class="bg-emerald-100"><tr><th class="px-2 py-1 text-left">Service</th><th class="px-2 py-1 text-left">URL</th></tr></thead>
268
+ <tbody>
269
+ <tr class="border-t border-emerald-200"><td class="px-2 py-1">Qdrant HTTP</td><td class="px-2 py-1"><code>http://127.0.0.1:50008</code></td></tr>
270
+ <tr class="border-t border-emerald-200"><td class="px-2 py-1">Qdrant gRPC</td><td class="px-2 py-1"><code>127.0.0.1:50009</code></td></tr>
271
+ <tr class="border-t border-emerald-200"><td class="px-2 py-1">Nomic Embed</td><td class="px-2 py-1"><code>http://127.0.0.1:50012</code></td></tr>
272
+ </tbody>
273
+ </table>
274
+
275
+ <p class="font-medium mb-1" data-i18n="gettingStarted.step1.memory.layoutTitle">0. Directory layout</p>
276
+ <p class="mb-2 text-text-secondary" data-i18n="gettingStarted.step1.memory.layoutText">Create two folders anywhere on your machine (example: ~/mcp-memory/):</p>
277
+ <pre class="code-block mb-4 p-3 text-sm text-slate-200 bg-slate-900 rounded overflow-x-auto"><code>mcp-memory/
278
+ ├── qdrant/
279
+ │ ├── docker-compose.yml
280
+ │ ├── .env
281
+ │ ├── data/
282
+ │ └── snapshots/
283
+ └── nomic-embed/
284
+ ├── docker-compose.yml
285
+ └── .env</code></pre>
286
+
287
+ <!-- Qdrant -->
288
+ <p class="font-semibold mb-2" data-i18n="gettingStarted.step1.memory.qdrantTitle">1. Qdrant (vector DB, port 50008)</p>
289
+ <p class="text-xs text-text-secondary mb-1" data-i18n="gettingStarted.step1.memory.qdrantCompose">qdrant/docker-compose.yml</p>
290
+ <div class="bg-slate-900 rounded-lg overflow-hidden mb-3">
291
+ <div class="flex items-center justify-between px-3 py-2 bg-slate-800">
292
+ <span class="text-xs text-slate-300 font-medium">docker-compose.yml</span>
293
+ <button type="button" onclick="copyCode(this)" class="text-xs text-slate-300 hover:text-white transition-colors" data-i18n="gettingStarted.common.copy">Copy</button>
280
294
  </div>
281
- <div>
282
- <p class="font-medium mb-2" data-i18n="gettingStarted.step1.memory.optionB.title">Option B: Qdrant + OpenAI-Compatible Embedding API</p>
283
- <pre class="code-block mb-2 p-3 text-sm text-slate-200 bg-slate-900 rounded overflow-x-auto"><code>docker run -d --name mcp-qdrant -p 6333:6333 qdrant/qdrant</code></pre>
284
- <pre class="code-block p-3 text-sm text-slate-200 bg-slate-900 rounded overflow-x-auto"><code>{
295
+ <pre class="code-block p-4 text-sm text-slate-200 overflow-x-auto"><code>services:
296
+ qdrant:
297
+ image: qdrant/qdrant:latest
298
+ container_name: qdrant
299
+ restart: always
300
+ env_file:
301
+ - .env
302
+ ports:
303
+ - "50008:6333"
304
+ - "50009:6334"
305
+ volumes:
306
+ - ./data:/qdrant/storage
307
+ - ./snapshots:/qdrant/snapshots
308
+ environment:
309
+ - QDRANT__SERVICE__HTTP_PORT=6333
310
+ - QDRANT__SERVICE__GRPC_PORT=6334
311
+ - QDRANT__LOG_LEVEL=INFO
312
+ - QDRANT__SERVICE__API_KEY=${QDRANT_API_KEY}
313
+ healthcheck:
314
+ test:
315
+ - "CMD"
316
+ - "bash"
317
+ - "-c"
318
+ - "exec 3&lt;&gt;/dev/tcp/127.0.0.1/6333 &amp;&amp; printf 'GET /collections HTTP/1.1\r\nHost: localhost\r\napi-key: ${QDRANT_API_KEY}\r\nConnection: close\r\n\r\n' &gt;&amp;3 &amp;&amp; IFS= read -r line &lt;&amp;3 &amp;&amp; [[ \"$$line\" == *\"200\"* ]]"
319
+ interval: 30s
320
+ timeout: 10s
321
+ retries: 5
322
+ start_period: 30s</code></pre>
323
+ </div>
324
+ <p class="text-xs text-text-secondary mb-1" data-i18n="gettingStarted.step1.memory.qdrantEnv">qdrant/.env</p>
325
+ <div class="bg-slate-900 rounded-lg overflow-hidden mb-3">
326
+ <div class="flex items-center justify-between px-3 py-2 bg-slate-800">
327
+ <span class="text-xs text-slate-300 font-medium">.env</span>
328
+ <button type="button" onclick="copyCode(this)" class="text-xs text-slate-300 hover:text-white transition-colors" data-i18n="gettingStarted.common.copy">Copy</button>
329
+ </div>
330
+ <pre class="code-block p-4 text-sm text-slate-200 overflow-x-auto"><code># Generate: python -c "import secrets; print(secrets.token_urlsafe(32))"
331
+ QDRANT_API_KEY=change-me-to-a-long-random-string
332
+ QDRANT_URL=http://127.0.0.1:50008</code></pre>
333
+ </div>
334
+ <p class="text-xs font-medium mb-1" data-i18n="gettingStarted.step1.memory.qdrantDeploy">Start Qdrant</p>
335
+ <div class="bg-slate-900 rounded-lg overflow-hidden mb-3">
336
+ <div class="flex items-center justify-between px-3 py-2 bg-slate-800">
337
+ <span class="text-xs text-slate-300 font-medium">PowerShell / Bash</span>
338
+ <button type="button" onclick="copyCode(this)" class="text-xs text-slate-300 hover:text-white transition-colors" data-i18n="gettingStarted.common.copy">Copy</button>
339
+ </div>
340
+ <pre class="code-block p-4 text-sm text-slate-200 overflow-x-auto"><code>cd qdrant
341
+ mkdir data snapshots 2&gt;$null; mkdir -p data snapshots
342
+ docker compose up -d
343
+ docker compose ps</code></pre>
344
+ </div>
345
+ <p class="text-xs font-medium mb-1" data-i18n="gettingStarted.step1.memory.qdrantVerify">Verify Qdrant</p>
346
+ <div class="bg-slate-900 rounded-lg overflow-hidden mb-2">
347
+ <div class="flex items-center justify-between px-3 py-2 bg-slate-800">
348
+ <span class="text-xs text-slate-300 font-medium">curl</span>
349
+ <button type="button" onclick="copyCode(this)" class="text-xs text-slate-300 hover:text-white transition-colors" data-i18n="gettingStarted.common.copy">Copy</button>
350
+ </div>
351
+ <pre class="code-block p-4 text-sm text-slate-200 overflow-x-auto"><code>curl http://127.0.0.1:50008/collections \
352
+ -H "api-key: YOUR_QDRANT_API_KEY"</code></pre>
353
+ </div>
354
+ <p class="mb-4 text-xs text-text-secondary" data-i18n="gettingStarted.step1.memory.qdrantNote">When API key is enabled, all requests need header api-key. Dashboard: http://127.0.0.1:50008/dashboard</p>
355
+
356
+ <!-- Nomic Embed -->
357
+ <p class="font-semibold mb-2" data-i18n="gettingStarted.step1.memory.nomicTitle">2. Nomic Embed / Infinity (embeddings, port 50012)</p>
358
+ <p class="text-xs text-text-secondary mb-1" data-i18n="gettingStarted.step1.memory.nomicCompose">nomic-embed/docker-compose.yml</p>
359
+ <div class="bg-slate-900 rounded-lg overflow-hidden mb-3">
360
+ <div class="flex items-center justify-between px-3 py-2 bg-slate-800">
361
+ <span class="text-xs text-slate-300 font-medium">docker-compose.yml</span>
362
+ <button type="button" onclick="copyCode(this)" class="text-xs text-slate-300 hover:text-white transition-colors" data-i18n="gettingStarted.common.copy">Copy</button>
363
+ </div>
364
+ <pre class="code-block p-4 text-sm text-slate-200 overflow-x-auto"><code>services:
365
+ nomic-embed:
366
+ image: michaelf34/infinity:0.0.70
367
+ container_name: nomic-embed
368
+ restart: unless-stopped
369
+ ports:
370
+ - "50012:7997"
371
+ volumes:
372
+ - hf_cache:/app/.cache
373
+ environment:
374
+ INFINITY_API_KEY: ${INFINITY_API_KEY}
375
+ command:
376
+ - v2
377
+ - --model-id
378
+ - nomic-ai/nomic-embed-text-v1.5
379
+ - --revision
380
+ - main
381
+ - --dtype
382
+ - float32
383
+ - --batch-size
384
+ - "8"
385
+ - --engine
386
+ - torch
387
+ - --port
388
+ - "7997"
389
+ - --no-bettertransformer
390
+ healthcheck:
391
+ test:
392
+ - "CMD"
393
+ - "curl"
394
+ - "-f"
395
+ - "http://127.0.0.1:7997/health"
396
+ interval: 30s
397
+ timeout: 10s
398
+ retries: 5
399
+ start_period: 120s
400
+
401
+ volumes:
402
+ hf_cache:</code></pre>
403
+ </div>
404
+ <p class="text-xs text-text-secondary mb-1" data-i18n="gettingStarted.step1.memory.nomicEnv">nomic-embed/.env</p>
405
+ <div class="bg-slate-900 rounded-lg overflow-hidden mb-3">
406
+ <div class="flex items-center justify-between px-3 py-2 bg-slate-800">
407
+ <span class="text-xs text-slate-300 font-medium">.env</span>
408
+ <button type="button" onclick="copyCode(this)" class="text-xs text-slate-300 hover:text-white transition-colors" data-i18n="gettingStarted.common.copy">Copy</button>
409
+ </div>
410
+ <pre class="code-block p-4 text-sm text-slate-200 overflow-x-auto"><code># Generate: python -c "import secrets; print(secrets.token_urlsafe(32))"
411
+ INFINITY_API_KEY=change-me-to-a-long-random-string</code></pre>
412
+ </div>
413
+ <p class="text-xs font-medium mb-1" data-i18n="gettingStarted.step1.memory.nomicDeploy">Start embedding service</p>
414
+ <div class="bg-slate-900 rounded-lg overflow-hidden mb-3">
415
+ <div class="flex items-center justify-between px-3 py-2 bg-slate-800">
416
+ <span class="text-xs text-slate-300 font-medium">PowerShell / Bash</span>
417
+ <button type="button" onclick="copyCode(this)" class="text-xs text-slate-300 hover:text-white transition-colors" data-i18n="gettingStarted.common.copy">Copy</button>
418
+ </div>
419
+ <pre class="code-block p-4 text-sm text-slate-200 overflow-x-auto"><code>cd nomic-embed
420
+ docker compose up -d
421
+ docker logs -f nomic-embed
422
+ # Wait for: ready to batch requests</code></pre>
423
+ </div>
424
+ <p class="text-xs font-medium mb-1" data-i18n="gettingStarted.step1.memory.nomicVerify">Verify embeddings</p>
425
+ <div class="bg-slate-900 rounded-lg overflow-hidden mb-2">
426
+ <div class="flex items-center justify-between px-3 py-2 bg-slate-800">
427
+ <span class="text-xs text-slate-300 font-medium">curl</span>
428
+ <button type="button" onclick="copyCode(this)" class="text-xs text-slate-300 hover:text-white transition-colors" data-i18n="gettingStarted.common.copy">Copy</button>
429
+ </div>
430
+ <pre class="code-block p-4 text-sm text-slate-200 overflow-x-auto"><code>curl http://127.0.0.1:50012/health
431
+
432
+ curl http://127.0.0.1:50012/embeddings \
433
+ -H "Authorization: Bearer YOUR_INFINITY_API_KEY" \
434
+ -H "Content-Type: application/json" \
435
+ -d '{"model":"nomic-ai/nomic-embed-text-v1.5","input":"hello world"}'
436
+ # Expect data[0].embedding length = 768</code></pre>
437
+ </div>
438
+ <p class="mb-4 text-xs text-text-secondary" data-i18n="gettingStarted.step1.memory.nomicNote">First start downloads the model (~2–5 min). Use POST /embeddings (not /v1/embeddings). Returns 768-dim vectors.</p>
439
+
440
+ <!-- MCP -->
441
+ <p class="font-semibold mb-2" data-i18n="gettingStarted.step1.memory.mcpTitle">3. MCP client configuration</p>
442
+ <div class="bg-slate-900 rounded-lg overflow-hidden mb-2">
443
+ <div class="flex items-center justify-between px-3 py-2 bg-slate-800">
444
+ <span class="text-xs text-slate-300 font-medium">Cursor / Claude Desktop mcpServers</span>
445
+ <button type="button" onclick="copyCode(this)" class="text-xs text-slate-300 hover:text-white transition-colors" data-i18n="gettingStarted.common.copy">Copy</button>
446
+ </div>
447
+ <pre class="code-block p-4 text-sm text-slate-200 overflow-x-auto"><code>{
285
448
  "mcpServers": {
286
449
  "mcp-probe-kit": {
287
450
  "command": "npx",
288
451
  "args": ["-y", "mcp-probe-kit@latest"],
289
452
  "env": {
290
- "MEMORY_QDRANT_URL": "http://127.0.0.1:6333",
453
+ "MEMORY_QDRANT_URL": "http://127.0.0.1:50008",
454
+ "MEMORY_QDRANT_API_KEY": "same-as-qdrant-.env-QDRANT_API_KEY",
291
455
  "MEMORY_QDRANT_COLLECTION": "mcp_probe_memory",
292
- "MEMORY_QDRANT_API_KEY": "",
293
456
  "MEMORY_EMBEDDING_PROVIDER": "openai-compatible",
294
- "MEMORY_EMBEDDING_URL": "https://your-embedding-endpoint/v1/embeddings",
295
- "MEMORY_EMBEDDING_API_KEY": "your-api-key",
296
- "MEMORY_EMBEDDING_MODEL": "text-embedding-3-small",
457
+ "MEMORY_EMBEDDING_URL": "http://127.0.0.1:50012/embeddings",
458
+ "MEMORY_EMBEDDING_MODEL": "nomic-ai/nomic-embed-text-v1.5",
459
+ "MEMORY_EMBEDDING_API_KEY": "same-as-nomic-embed-.env-INFINITY_API_KEY",
297
460
  "MEMORY_SEARCH_LIMIT": "3",
298
461
  "MEMORY_SUMMARY_MAX_CHARS": "280"
299
462
  }
300
463
  }
301
464
  }
302
465
  }</code></pre>
466
+ </div>
467
+ <p class="mb-4 text-xs text-text-secondary" data-i18n="gettingStarted.step1.memory.mcpNote">Use the same keys as in qdrant/.env and nomic-embed/.env. Restart Cursor after saving.</p>
468
+
469
+ <p class="font-medium mb-2" data-i18n="gettingStarted.step1.memory.alternativesTitle">Other embedding options</p>
470
+ <div class="space-y-3">
471
+ <div>
472
+ <p class="font-medium mb-2" data-i18n="gettingStarted.step1.memory.optionB.title">Option B: Qdrant + Ollama</p>
473
+ <pre class="code-block mb-2 p-3 text-sm text-slate-200 bg-slate-900 rounded overflow-x-auto"><code>docker run -d --name mcp-qdrant -p 6333:6333 qdrant/qdrant
474
+ ollama pull nomic-embed-text</code></pre>
475
+ <pre class="code-block p-3 text-sm text-slate-200 bg-slate-900 rounded overflow-x-auto"><code>"MEMORY_QDRANT_URL": "http://127.0.0.1:6333",
476
+ "MEMORY_EMBEDDING_PROVIDER": "ollama",
477
+ "MEMORY_EMBEDDING_URL": "http://127.0.0.1:11434/api/embeddings",
478
+ "MEMORY_EMBEDDING_MODEL": "nomic-embed-text"</code></pre>
479
+ </div>
480
+ <div>
481
+ <p class="font-medium mb-2" data-i18n="gettingStarted.step1.memory.optionC.title">Option C: Qdrant + hosted OpenAI-compatible API</p>
482
+ <pre class="code-block p-3 text-sm text-slate-200 bg-slate-900 rounded overflow-x-auto"><code>"MEMORY_QDRANT_URL": "http://127.0.0.1:50008",
483
+ "MEMORY_EMBEDDING_PROVIDER": "openai-compatible",
484
+ "MEMORY_EMBEDDING_URL": "https://your-embedding-endpoint/v1/embeddings",
485
+ "MEMORY_EMBEDDING_API_KEY": "your-api-key",
486
+ "MEMORY_EMBEDDING_MODEL": "text-embedding-3-small"</code></pre>
303
487
  </div>
304
488
  </div>
305
489
  <div class="mt-3">
@@ -511,6 +695,40 @@ npm run build</code></pre>
511
695
  </div>
512
696
  </div>
513
697
  </div>
698
+
699
+ <!-- OpenCode -->
700
+ <div class="border border-border rounded-lg overflow-hidden">
701
+ <button onclick="toggleClient('opencode')" class="w-full px-4 py-3 bg-bg-page flex items-center justify-between text-left hover:bg-gray-100 transition-colors">
702
+ <div class="flex items-center gap-2">
703
+ <span class="text-lg">🤖</span>
704
+ <span class="font-medium text-text-primary" data-i18n="gettingStarted.step2.opencode.title">OpenCode</span>
705
+ </div>
706
+ <svg class="w-5 h-5 text-text-tertiary transition-transform" id="opencode-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
707
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
708
+ </svg>
709
+ </button>
710
+ <div id="opencode-content" class="hidden p-4 border-t border-border">
711
+ <p class="text-text-secondary text-sm mb-3"><span data-i18n="gettingStarted.step2.opencode.description">Create or edit</span> <code class="bg-gray-200 px-1 rounded text-xs">opencode.json</code> <span data-i18n="gettingStarted.step2.opencode.description2">in project root, or globally at</span> <code class="bg-gray-200 px-1 rounded text-xs">~/.config/opencode/opencode.json</code></p>
712
+ <div class="bg-slate-900 rounded-lg overflow-hidden">
713
+ <div class="flex items-center justify-between px-3 py-2 bg-slate-800">
714
+ <span class="text-xs text-slate-300 font-medium">opencode.json</span>
715
+ <button onclick="copyCode(this)" class="text-xs text-slate-300 hover:text-white transition-colors" data-i18n="gettingStarted.common.copy">Copy</button>
716
+ </div>
717
+ <pre class="code-block p-4 text-sm text-slate-200 overflow-x-auto"><code>{
718
+ "mcp": {
719
+ "mcp-probe-kit": {
720
+ "type": "local",
721
+ "command": ["npx", "-y", "mcp-probe-kit@latest"],
722
+ "enabled": true
723
+ }
724
+ }
725
+ }</code></pre>
726
+ </div>
727
+ <div class="p-3 mt-3 bg-blue-50 border-l-3 border-blue-500 rounded-r text-sm text-text-primary">
728
+ <strong>💡 <span data-i18n="gettingStarted.step2.opencode.note">Note:</span></strong><span data-i18n="gettingStarted.step2.opencode.noteText">OpenCode uses <code>"environment"</code> (not <code>"env"</code>) for env vars, <code>"mcp"</code> (not <code>"mcpServers"</code>), and <code>"command"</code> as an array with <code>"type": "local"</code> required. See <a href="https://opencode.ai/docs/mcp" target="_blank" rel="noopener" class="text-primary hover:underline">OpenCode MCP docs</a>.</span>
729
+ </div>
730
+ </div>
731
+ </div>
514
732
  </div>
515
733
  </section>
516
734
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-probe-kit",
3
- "version": "3.0.17",
3
+ "version": "3.0.19",
4
4
  "description": "AI-Powered Development Toolkit - MCP Server with 28 tools covering code quality, development efficiency, project management, and UI/UX design. Features: Structured Output, Workflow Orchestration, UI/UX Pro Max, and Requirements Interview.",
5
5
  "mcpName": "io.github.mybolide/mcp-probe-kit",
6
6
  "type": "module",