mcp-probe-kit 3.0.18 → 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.
- package/README.md +75 -50
- package/build/lib/__tests__/agents-md-template.unit.test.d.ts +1 -0
- package/build/lib/__tests__/agents-md-template.unit.test.js +25 -0
- package/build/lib/__tests__/project-context-layout.unit.test.d.ts +1 -0
- package/build/lib/__tests__/project-context-layout.unit.test.js +80 -0
- package/build/lib/agents-md-template.d.ts +25 -0
- package/build/lib/agents-md-template.js +55 -0
- package/build/lib/memory-orchestration.d.ts +3 -1
- package/build/lib/memory-orchestration.js +71 -5
- package/build/lib/merge-agents-md.d.ts +6 -0
- package/build/lib/merge-agents-md.js +51 -0
- package/build/lib/project-context-layout.d.ts +78 -0
- package/build/lib/project-context-layout.js +350 -0
- package/build/lib/workspace-root.js +6 -1
- package/build/resources/ui-ux-data/metadata.json +1 -1
- package/build/schemas/index.d.ts +25 -3
- package/build/schemas/memory-tools.d.ts +1 -1
- package/build/schemas/memory-tools.js +1 -1
- package/build/schemas/project-tools.d.ts +24 -2
- package/build/schemas/project-tools.js +24 -2
- package/build/tools/__tests__/code_insight.unit.test.js +3 -3
- package/build/tools/__tests__/init_project_context.unit.test.js +32 -21
- package/build/tools/__tests__/start_feature.unit.test.js +2 -1
- package/build/tools/code_insight.js +11 -9
- package/build/tools/init_project_context.js +563 -506
- package/build/tools/start_bugfix.js +254 -248
- package/build/tools/start_feature.js +137 -131
- package/build/tools/start_ui.js +402 -402
- package/docs/.mcp-probe/layout.json +11 -0
- package/docs/i18n/en.json +36 -5
- package/docs/i18n/ja.json +9 -2
- package/docs/i18n/ko.json +9 -2
- package/docs/i18n/zh-CN.json +36 -5
- package/docs/memory-local-setup.md +314 -0
- package/docs/memory-local-setup.zh-CN.md +280 -0
- package/docs/pages/getting-started.html +249 -31
- 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
|
-
<
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
<
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
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<>/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\"* ]]"
|
|
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>$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:
|
|
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": "
|
|
295
|
-
"
|
|
296
|
-
"
|
|
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.
|
|
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",
|