@mhalder/qdrant-mcp-server 1.1.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/.env.example +92 -0
- package/.github/workflows/ci.yml +61 -0
- package/.github/workflows/claude-code-review.yml +57 -0
- package/.github/workflows/claude.yml +50 -0
- package/.github/workflows/release.yml +52 -0
- package/.husky/commit-msg +1 -0
- package/.husky/pre-commit +1 -0
- package/.releaserc.json +59 -0
- package/.yamlfmt +4 -0
- package/CHANGELOG.md +73 -0
- package/CONTRIBUTING.md +176 -0
- package/LICENSE +21 -0
- package/README.md +714 -0
- package/build/embeddings/base.d.ts +23 -0
- package/build/embeddings/base.d.ts.map +1 -0
- package/build/embeddings/base.js +2 -0
- package/build/embeddings/base.js.map +1 -0
- package/build/embeddings/cohere.d.ts +17 -0
- package/build/embeddings/cohere.d.ts.map +1 -0
- package/build/embeddings/cohere.js +102 -0
- package/build/embeddings/cohere.js.map +1 -0
- package/build/embeddings/cohere.test.d.ts +2 -0
- package/build/embeddings/cohere.test.d.ts.map +1 -0
- package/build/embeddings/cohere.test.js +279 -0
- package/build/embeddings/cohere.test.js.map +1 -0
- package/build/embeddings/factory.d.ts +10 -0
- package/build/embeddings/factory.d.ts.map +1 -0
- package/build/embeddings/factory.js +98 -0
- package/build/embeddings/factory.js.map +1 -0
- package/build/embeddings/factory.test.d.ts +2 -0
- package/build/embeddings/factory.test.d.ts.map +1 -0
- package/build/embeddings/factory.test.js +329 -0
- package/build/embeddings/factory.test.js.map +1 -0
- package/build/embeddings/ollama.d.ts +18 -0
- package/build/embeddings/ollama.d.ts.map +1 -0
- package/build/embeddings/ollama.js +135 -0
- package/build/embeddings/ollama.js.map +1 -0
- package/build/embeddings/ollama.test.d.ts +2 -0
- package/build/embeddings/ollama.test.d.ts.map +1 -0
- package/build/embeddings/ollama.test.js +399 -0
- package/build/embeddings/ollama.test.js.map +1 -0
- package/build/embeddings/openai.d.ts +16 -0
- package/build/embeddings/openai.d.ts.map +1 -0
- package/build/embeddings/openai.js +108 -0
- package/build/embeddings/openai.js.map +1 -0
- package/build/embeddings/openai.test.d.ts +2 -0
- package/build/embeddings/openai.test.d.ts.map +1 -0
- package/build/embeddings/openai.test.js +283 -0
- package/build/embeddings/openai.test.js.map +1 -0
- package/build/embeddings/voyage.d.ts +19 -0
- package/build/embeddings/voyage.d.ts.map +1 -0
- package/build/embeddings/voyage.js +113 -0
- package/build/embeddings/voyage.js.map +1 -0
- package/build/embeddings/voyage.test.d.ts +2 -0
- package/build/embeddings/voyage.test.d.ts.map +1 -0
- package/build/embeddings/voyage.test.js +371 -0
- package/build/embeddings/voyage.test.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +534 -0
- package/build/index.js.map +1 -0
- package/build/index.test.d.ts +2 -0
- package/build/index.test.d.ts.map +1 -0
- package/build/index.test.js +241 -0
- package/build/index.test.js.map +1 -0
- package/build/qdrant/client.d.ts +37 -0
- package/build/qdrant/client.d.ts.map +1 -0
- package/build/qdrant/client.js +142 -0
- package/build/qdrant/client.js.map +1 -0
- package/build/qdrant/client.test.d.ts +2 -0
- package/build/qdrant/client.test.d.ts.map +1 -0
- package/build/qdrant/client.test.js +340 -0
- package/build/qdrant/client.test.js.map +1 -0
- package/commitlint.config.js +25 -0
- package/docker-compose.yml +22 -0
- package/docs/test_report.md +259 -0
- package/examples/README.md +315 -0
- package/examples/basic/README.md +111 -0
- package/examples/filters/README.md +262 -0
- package/examples/knowledge-base/README.md +207 -0
- package/examples/rate-limiting/README.md +376 -0
- package/package.json +59 -0
- package/scripts/verify-providers.js +238 -0
- package/src/embeddings/base.ts +25 -0
- package/src/embeddings/cohere.test.ts +408 -0
- package/src/embeddings/cohere.ts +152 -0
- package/src/embeddings/factory.test.ts +453 -0
- package/src/embeddings/factory.ts +163 -0
- package/src/embeddings/ollama.test.ts +543 -0
- package/src/embeddings/ollama.ts +196 -0
- package/src/embeddings/openai.test.ts +402 -0
- package/src/embeddings/openai.ts +158 -0
- package/src/embeddings/voyage.test.ts +520 -0
- package/src/embeddings/voyage.ts +168 -0
- package/src/index.test.ts +304 -0
- package/src/index.ts +614 -0
- package/src/qdrant/client.test.ts +456 -0
- package/src/qdrant/client.ts +195 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,714 @@
|
|
|
1
|
+
# Qdrant MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://github.com/mhalder/qdrant-mcp-server/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/gh/mhalder/qdrant-mcp-server)
|
|
5
|
+
|
|
6
|
+
A Model Context Protocol (MCP) server that provides semantic search capabilities using a local Qdrant vector database with support for multiple embedding providers (Ollama, OpenAI, Cohere, and Voyage AI).
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Zero Setup Required**: Works out of the box with Ollama (no API keys needed)
|
|
11
|
+
- **Semantic Search**: Natural language search across your document collections
|
|
12
|
+
- **Multiple Embedding Providers**: Support for Ollama (local, default), OpenAI, Cohere, and Voyage AI
|
|
13
|
+
- **Privacy-First**: Default local embeddings with Ollama - your data never leaves your machine
|
|
14
|
+
- **Metadata Filtering**: Filter search results by metadata fields using Qdrant's powerful filter syntax
|
|
15
|
+
- **Local Vector Database**: Runs Qdrant locally via Docker for complete data privacy
|
|
16
|
+
- **Automatic Embeddings**: Converts text to vectors using your choice of embedding provider
|
|
17
|
+
- **Rate Limiting**: Intelligent request throttling with exponential backoff to prevent API rate limit errors
|
|
18
|
+
- **MCP Integration**: Works seamlessly with Claude Code and other MCP clients
|
|
19
|
+
- **Collection Management**: Create, list, and delete vector collections
|
|
20
|
+
- **Document Operations**: Add, search, and delete documents with metadata support
|
|
21
|
+
- **Flexible Configuration**: Easy provider switching via environment variables
|
|
22
|
+
|
|
23
|
+
## Prerequisites
|
|
24
|
+
|
|
25
|
+
- Node.js 20+ (tested on Node.js 20 and 22)
|
|
26
|
+
- Docker and Docker Compose
|
|
27
|
+
|
|
28
|
+
**Optional** (for alternative embedding providers):
|
|
29
|
+
|
|
30
|
+
- OpenAI API key
|
|
31
|
+
- Cohere API key
|
|
32
|
+
- Voyage AI API key
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
1. Clone the repository:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone <your-repo-url>
|
|
40
|
+
cd qdrant-mcp-server
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
2. Install dependencies:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
3. Start Qdrant and Ollama:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
docker compose up -d
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
4. Pull the Ollama embedding model:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
docker exec ollama ollama pull nomic-embed-text
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
5. Build the project:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm run build
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Usage
|
|
68
|
+
|
|
69
|
+
### Running the Server
|
|
70
|
+
|
|
71
|
+
For development:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm run dev
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
For production:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
node build/index.js
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Claude Code Configuration (Linux)
|
|
84
|
+
|
|
85
|
+
Add this to your Claude Code configuration file at `~/.claude/claude_code_config.json`:
|
|
86
|
+
|
|
87
|
+
**Default (Ollama - No API Key Required):**
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"mcpServers": {
|
|
92
|
+
"qdrant": {
|
|
93
|
+
"command": "node",
|
|
94
|
+
"args": [
|
|
95
|
+
"/home/YOUR_USERNAME/projects/active/qdrant-mcp-server/build/index.js"
|
|
96
|
+
],
|
|
97
|
+
"env": {
|
|
98
|
+
"QDRANT_URL": "http://localhost:6333",
|
|
99
|
+
"EMBEDDING_BASE_URL": "http://localhost:11434"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**With OpenAI (Alternative):**
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"mcpServers": {
|
|
111
|
+
"qdrant": {
|
|
112
|
+
"command": "node",
|
|
113
|
+
"args": [
|
|
114
|
+
"/home/YOUR_USERNAME/projects/active/qdrant-mcp-server/build/index.js"
|
|
115
|
+
],
|
|
116
|
+
"env": {
|
|
117
|
+
"EMBEDDING_PROVIDER": "openai",
|
|
118
|
+
"OPENAI_API_KEY": "sk-your-api-key-here",
|
|
119
|
+
"QDRANT_URL": "http://localhost:6333"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**With Cohere (Alternative):**
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"mcpServers": {
|
|
131
|
+
"qdrant": {
|
|
132
|
+
"command": "node",
|
|
133
|
+
"args": [
|
|
134
|
+
"/home/YOUR_USERNAME/projects/active/qdrant-mcp-server/build/index.js"
|
|
135
|
+
],
|
|
136
|
+
"env": {
|
|
137
|
+
"EMBEDDING_PROVIDER": "cohere",
|
|
138
|
+
"COHERE_API_KEY": "your-cohere-api-key-here",
|
|
139
|
+
"QDRANT_URL": "http://localhost:6333"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**With Voyage AI (Alternative):**
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"mcpServers": {
|
|
151
|
+
"qdrant": {
|
|
152
|
+
"command": "node",
|
|
153
|
+
"args": [
|
|
154
|
+
"/home/YOUR_USERNAME/projects/active/qdrant-mcp-server/build/index.js"
|
|
155
|
+
],
|
|
156
|
+
"env": {
|
|
157
|
+
"EMBEDDING_PROVIDER": "voyage",
|
|
158
|
+
"VOYAGE_API_KEY": "your-voyage-api-key-here",
|
|
159
|
+
"QDRANT_URL": "http://localhost:6333"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Replace `YOUR_USERNAME` and the path with your actual username and installation path.
|
|
167
|
+
|
|
168
|
+
Restart Claude Code after making this change.
|
|
169
|
+
|
|
170
|
+
## Available Tools
|
|
171
|
+
|
|
172
|
+
### `create_collection`
|
|
173
|
+
|
|
174
|
+
Create a new vector collection.
|
|
175
|
+
|
|
176
|
+
**Parameters:**
|
|
177
|
+
|
|
178
|
+
- `name` (string, required): Collection name
|
|
179
|
+
- `distance` (string, optional): Distance metric - "Cosine", "Euclid", or "Dot" (default: "Cosine")
|
|
180
|
+
|
|
181
|
+
**Example:**
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
Create a collection named "my-docs"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### `add_documents`
|
|
188
|
+
|
|
189
|
+
Add documents to a collection with automatic embedding generation.
|
|
190
|
+
|
|
191
|
+
**Parameters:**
|
|
192
|
+
|
|
193
|
+
- `collection` (string, required): Collection name
|
|
194
|
+
- `documents` (array, required): Array of documents with:
|
|
195
|
+
- `id` (string/number, required): Unique identifier (string IDs are automatically normalized to UUID format)
|
|
196
|
+
- `text` (string, required): Document text content
|
|
197
|
+
- `metadata` (object, optional): Additional metadata
|
|
198
|
+
|
|
199
|
+
**Note:** String IDs are automatically normalized to UUID format for Qdrant compatibility. The normalization is deterministic, so the same string ID will always produce the same UUID.
|
|
200
|
+
|
|
201
|
+
**Example:**
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
Add these documents to "my-docs" collection:
|
|
205
|
+
- id: 1, text: "Introduction to vector databases"
|
|
206
|
+
- id: 2, text: "Semantic search with embeddings"
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### `semantic_search`
|
|
210
|
+
|
|
211
|
+
Search for documents using natural language.
|
|
212
|
+
|
|
213
|
+
**Parameters:**
|
|
214
|
+
|
|
215
|
+
- `collection` (string, required): Collection to search
|
|
216
|
+
- `query` (string, required): Search query
|
|
217
|
+
- `limit` (number, optional): Max results (default: 5)
|
|
218
|
+
- `filter` (object, optional): Metadata filter in Qdrant format
|
|
219
|
+
|
|
220
|
+
**Filter Format:**
|
|
221
|
+
|
|
222
|
+
The filter parameter accepts Qdrant's native filter format for powerful metadata-based filtering:
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"must": [{ "key": "category", "match": { "value": "database" } }]
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
You can also use more complex filters:
|
|
231
|
+
|
|
232
|
+
- **Multiple conditions (AND)**: Use `must` with multiple conditions
|
|
233
|
+
- **Any condition (OR)**: Use `should` with multiple conditions
|
|
234
|
+
- **Negation (NOT)**: Use `must_not` with conditions
|
|
235
|
+
|
|
236
|
+
Example with multiple conditions:
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"must": [
|
|
241
|
+
{ "key": "category", "match": { "value": "database" } },
|
|
242
|
+
{ "key": "level", "match": { "value": "beginner" } }
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Examples:**
|
|
248
|
+
|
|
249
|
+
Basic search:
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
Search "my-docs" for information about vector databases
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
With single filter:
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
Search "my-docs" for "vector databases" with filter {"must": [{"key": "category", "match": {"value": "technical"}}]}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
With multiple filters (AND):
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
Search "knowledge-base" for "machine learning" with filter {"must": [{"key": "category", "match": {"value": "ml"}}, {"key": "level", "match": {"value": "advanced"}}]}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### `list_collections`
|
|
268
|
+
|
|
269
|
+
List all available collections.
|
|
270
|
+
|
|
271
|
+
### `get_collection_info`
|
|
272
|
+
|
|
273
|
+
Get detailed information about a collection.
|
|
274
|
+
|
|
275
|
+
**Parameters:**
|
|
276
|
+
|
|
277
|
+
- `name` (string, required): Collection name
|
|
278
|
+
|
|
279
|
+
### `delete_collection`
|
|
280
|
+
|
|
281
|
+
Delete a collection and all its documents.
|
|
282
|
+
|
|
283
|
+
**Parameters:**
|
|
284
|
+
|
|
285
|
+
- `name` (string, required): Collection name
|
|
286
|
+
|
|
287
|
+
### `delete_documents`
|
|
288
|
+
|
|
289
|
+
Delete specific documents from a collection.
|
|
290
|
+
|
|
291
|
+
**Parameters:**
|
|
292
|
+
|
|
293
|
+
- `collection` (string, required): Collection name
|
|
294
|
+
- `ids` (array, required): Array of document IDs to delete (string IDs are automatically normalized to UUID format)
|
|
295
|
+
|
|
296
|
+
**Note:** String IDs will be normalized to the same UUID format used when adding documents.
|
|
297
|
+
|
|
298
|
+
## Available Resources
|
|
299
|
+
|
|
300
|
+
- `qdrant://collections` - List all collections
|
|
301
|
+
- `qdrant://collection/{name}` - Collection details and statistics
|
|
302
|
+
|
|
303
|
+
## Project Structure
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
qdrant-mcp-server/
|
|
307
|
+
├── src/
|
|
308
|
+
│ ├── index.ts # MCP server implementation
|
|
309
|
+
│ ├── qdrant/
|
|
310
|
+
│ │ └── client.ts # Qdrant client wrapper
|
|
311
|
+
│ └── embeddings/
|
|
312
|
+
│ ├── base.ts # Provider interface and types
|
|
313
|
+
│ ├── factory.ts # Provider factory
|
|
314
|
+
│ ├── openai.ts # OpenAI embeddings provider
|
|
315
|
+
│ ├── cohere.ts # Cohere embeddings provider
|
|
316
|
+
│ ├── voyage.ts # Voyage AI embeddings provider
|
|
317
|
+
│ └── ollama.ts # Ollama embeddings provider
|
|
318
|
+
├── docker-compose.yml # Qdrant Docker setup
|
|
319
|
+
├── .env.example # Environment configuration template
|
|
320
|
+
├── package.json
|
|
321
|
+
├── tsconfig.json
|
|
322
|
+
└── README.md
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Example Workflow
|
|
326
|
+
|
|
327
|
+
1. **Create a collection:**
|
|
328
|
+
|
|
329
|
+
```
|
|
330
|
+
Create a collection called "knowledge-base"
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
2. **Add documents:**
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
Add these documents to knowledge-base:
|
|
337
|
+
- id: "doc1", text: "MCP is a protocol for AI model context", metadata: {"type": "definition", "category": "protocol"}
|
|
338
|
+
- id: "doc2", text: "Vector databases store embeddings for semantic search", metadata: {"type": "definition", "category": "database"}
|
|
339
|
+
- id: "doc3", text: "Qdrant provides high-performance vector similarity search", metadata: {"type": "product", "category": "database"}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
3. **Search without filters:**
|
|
343
|
+
|
|
344
|
+
```
|
|
345
|
+
Search knowledge-base for "how does semantic search work"
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
4. **Search with filters:**
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
Search knowledge-base for "vector database" with filter {"must": [{"key": "category", "match": {"value": "database"}}]}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
5. **Get collection information:**
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
Get info about "knowledge-base" collection
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
6. **View all collections:**
|
|
361
|
+
```
|
|
362
|
+
What collections do I have?
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## Configuration Options
|
|
366
|
+
|
|
367
|
+
### Environment Variables
|
|
368
|
+
|
|
369
|
+
#### Common Configuration
|
|
370
|
+
|
|
371
|
+
- `EMBEDDING_PROVIDER` (optional): Embedding provider to use - "openai", "cohere", "voyage", or "ollama" (default: "ollama")
|
|
372
|
+
- `QDRANT_URL` (optional): Qdrant server URL (default: http://localhost:6333)
|
|
373
|
+
- `EMBEDDING_MODEL` (optional): Model name for the selected provider (provider-specific defaults apply)
|
|
374
|
+
- `EMBEDDING_DIMENSIONS` (optional): Custom embedding dimensions (overrides model defaults)
|
|
375
|
+
- `EMBEDDING_BASE_URL` (optional): Custom API base URL (for Voyage AI and Ollama)
|
|
376
|
+
- `EMBEDDING_MAX_REQUESTS_PER_MINUTE` (optional): Rate limit (provider-specific defaults)
|
|
377
|
+
- `EMBEDDING_RETRY_ATTEMPTS` (optional): Retry attempts for rate limit errors (default: 3)
|
|
378
|
+
- `EMBEDDING_RETRY_DELAY` (optional): Initial retry delay in ms with exponential backoff (default: 1000)
|
|
379
|
+
|
|
380
|
+
#### Provider-Specific API Keys
|
|
381
|
+
|
|
382
|
+
- `OPENAI_API_KEY`: Required for OpenAI provider
|
|
383
|
+
- `COHERE_API_KEY`: Required for Cohere provider
|
|
384
|
+
- `VOYAGE_API_KEY`: Required for Voyage AI provider
|
|
385
|
+
- Ollama: No API key required
|
|
386
|
+
|
|
387
|
+
### Embedding Models
|
|
388
|
+
|
|
389
|
+
#### OpenAI Models
|
|
390
|
+
|
|
391
|
+
- `text-embedding-3-small` (1536 dims, default) - Faster, more cost-effective
|
|
392
|
+
- `text-embedding-3-large` (3072 dims) - Higher quality
|
|
393
|
+
- `text-embedding-ada-002` (1536 dims) - Legacy model
|
|
394
|
+
|
|
395
|
+
Default rate limit: 3500 requests/minute (paid tier)
|
|
396
|
+
|
|
397
|
+
#### Cohere Models
|
|
398
|
+
|
|
399
|
+
- `embed-english-v3.0` (1024 dims, default) - English-optimized
|
|
400
|
+
- `embed-multilingual-v3.0` (1024 dims) - Multi-language support
|
|
401
|
+
- `embed-english-light-v3.0` (384 dims) - Lightweight English model
|
|
402
|
+
- `embed-multilingual-light-v3.0` (384 dims) - Lightweight multilingual model
|
|
403
|
+
|
|
404
|
+
Default rate limit: 100 requests/minute
|
|
405
|
+
|
|
406
|
+
#### Voyage AI Models
|
|
407
|
+
|
|
408
|
+
- `voyage-2` (1024 dims, default) - General purpose
|
|
409
|
+
- `voyage-large-2` (1536 dims) - Enhanced quality
|
|
410
|
+
- `voyage-code-2` (1536 dims) - Code-specialized
|
|
411
|
+
- `voyage-lite-02-instruct` (1024 dims) - Instruction-tuned
|
|
412
|
+
|
|
413
|
+
Default rate limit: 300 requests/minute
|
|
414
|
+
|
|
415
|
+
#### Ollama Models (Local)
|
|
416
|
+
|
|
417
|
+
- `nomic-embed-text` (768 dims, default) - High-quality local embeddings
|
|
418
|
+
- `mxbai-embed-large` (1024 dims) - Larger context window
|
|
419
|
+
- `all-minilm` (384 dims) - Lightweight option
|
|
420
|
+
|
|
421
|
+
Default rate limit: 1000 requests/minute (local, can be adjusted)
|
|
422
|
+
|
|
423
|
+
**Note:** Ollama models must be downloaded first using `ollama pull <model-name>`
|
|
424
|
+
|
|
425
|
+
## Advanced Features
|
|
426
|
+
|
|
427
|
+
### Rate Limiting and Error Handling
|
|
428
|
+
|
|
429
|
+
The server implements robust rate limiting for all embedding providers:
|
|
430
|
+
|
|
431
|
+
**Features:**
|
|
432
|
+
|
|
433
|
+
- **Request Throttling**: Queues requests to stay within provider rate limits (provider-specific defaults)
|
|
434
|
+
- **Exponential Backoff**: Automatically retries failed requests with increasing delays (1s, 2s, 4s, 8s...)
|
|
435
|
+
- **Retry-After Header Support**: Respects provider retry guidance (OpenAI) with validation fallback
|
|
436
|
+
- **Typed Error Handling**: Provider-specific error interfaces for type-safe error detection
|
|
437
|
+
- **Smart Error Detection**: Identifies rate limit errors (429 status) vs other failures
|
|
438
|
+
- **User Feedback**: Clear console messages during retry attempts with estimated wait times
|
|
439
|
+
|
|
440
|
+
**Configuration:**
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
# Common settings (apply to all providers)
|
|
444
|
+
EMBEDDING_MAX_REQUESTS_PER_MINUTE=3500 # Adjust based on your provider tier
|
|
445
|
+
EMBEDDING_RETRY_ATTEMPTS=3 # Number of retries before failing
|
|
446
|
+
EMBEDDING_RETRY_DELAY=1000 # Initial delay (doubles each retry)
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
**Provider-Specific Defaults:**
|
|
450
|
+
|
|
451
|
+
- OpenAI: 3500 requests/minute (paid tier)
|
|
452
|
+
- Cohere: 100 requests/minute
|
|
453
|
+
- Voyage AI: 300 requests/minute
|
|
454
|
+
- Ollama: 1000 requests/minute (local, configurable)
|
|
455
|
+
|
|
456
|
+
**Benefits:**
|
|
457
|
+
|
|
458
|
+
- Prevents failed operations during high-volume usage
|
|
459
|
+
- Automatic recovery from temporary API issues
|
|
460
|
+
- Optimized for batch document processing
|
|
461
|
+
- Works seamlessly with both single and batch embedding operations
|
|
462
|
+
- Consistent behavior across all providers
|
|
463
|
+
|
|
464
|
+
### Metadata Filtering
|
|
465
|
+
|
|
466
|
+
The server supports Qdrant's powerful filtering capabilities for refined search results. Filters can be applied to any metadata field stored with your documents.
|
|
467
|
+
|
|
468
|
+
**Supported filter types:**
|
|
469
|
+
|
|
470
|
+
- **Match filters**: Exact value matching for strings, numbers, and booleans
|
|
471
|
+
- **Logical operators**: `must` (AND), `should` (OR), `must_not` (NOT)
|
|
472
|
+
- **Range filters**: Greater than, less than, between (for numeric values)
|
|
473
|
+
- **Nested filters**: Complex boolean expressions
|
|
474
|
+
|
|
475
|
+
See the `semantic_search` tool documentation for filter syntax examples.
|
|
476
|
+
|
|
477
|
+
## Troubleshooting
|
|
478
|
+
|
|
479
|
+
### Qdrant connection errors
|
|
480
|
+
|
|
481
|
+
Make sure Qdrant is running:
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
docker compose ps
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
If not running:
|
|
488
|
+
|
|
489
|
+
```bash
|
|
490
|
+
docker compose up -d
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Collection doesn't exist
|
|
494
|
+
|
|
495
|
+
Create the collection first before adding documents:
|
|
496
|
+
|
|
497
|
+
```
|
|
498
|
+
Create a collection named "my-collection"
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### Embedding Provider Errors
|
|
502
|
+
|
|
503
|
+
**OpenAI:**
|
|
504
|
+
|
|
505
|
+
- Verify your API key is correct in `.env`
|
|
506
|
+
- Check your OpenAI account has available credits
|
|
507
|
+
- Ensure you have access to the embedding models
|
|
508
|
+
|
|
509
|
+
**Cohere:**
|
|
510
|
+
|
|
511
|
+
- Verify your Cohere API key is correct
|
|
512
|
+
- Check your Cohere account status and credits
|
|
513
|
+
- Ensure you're using a valid model name
|
|
514
|
+
|
|
515
|
+
**Voyage AI:**
|
|
516
|
+
|
|
517
|
+
- Verify your Voyage API key is correct
|
|
518
|
+
- Check your Voyage AI account status
|
|
519
|
+
- Ensure the base URL is correct (default: https://api.voyageai.com/v1)
|
|
520
|
+
|
|
521
|
+
**Ollama:**
|
|
522
|
+
|
|
523
|
+
- Ensure Ollama is running: `curl http://localhost:11434`
|
|
524
|
+
- Pull the required model: `ollama pull nomic-embed-text`
|
|
525
|
+
- Check the base URL matches your Ollama installation
|
|
526
|
+
|
|
527
|
+
### Rate limit errors
|
|
528
|
+
|
|
529
|
+
The server automatically handles rate limits, but if you see persistent rate limit errors:
|
|
530
|
+
|
|
531
|
+
- Reduce `EMBEDDING_MAX_REQUESTS_PER_MINUTE` to match your provider's tier
|
|
532
|
+
- OpenAI free: 500/min, paid: 3500+/min
|
|
533
|
+
- Cohere: 100/min (adjust based on your plan)
|
|
534
|
+
- Voyage AI: 300/min (adjust based on your plan)
|
|
535
|
+
- Ollama: No limits (local), but adjust based on system capacity
|
|
536
|
+
- Increase `EMBEDDING_RETRY_ATTEMPTS` for more resilient retries
|
|
537
|
+
- Check your provider's dashboard for current usage and limits
|
|
538
|
+
|
|
539
|
+
### Filter errors
|
|
540
|
+
|
|
541
|
+
If you encounter "Bad Request" errors with filters:
|
|
542
|
+
|
|
543
|
+
- Ensure you're using Qdrant's native filter format
|
|
544
|
+
- Check that field names match your metadata exactly
|
|
545
|
+
- Verify the filter structure has proper nesting
|
|
546
|
+
|
|
547
|
+
## Development
|
|
548
|
+
|
|
549
|
+
### Development Mode
|
|
550
|
+
|
|
551
|
+
Run in development mode with auto-reload:
|
|
552
|
+
|
|
553
|
+
```bash
|
|
554
|
+
npm run dev
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### Build
|
|
558
|
+
|
|
559
|
+
Build for production:
|
|
560
|
+
|
|
561
|
+
```bash
|
|
562
|
+
npm run build
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
### Type Checking
|
|
566
|
+
|
|
567
|
+
Run TypeScript type checking without emitting files:
|
|
568
|
+
|
|
569
|
+
```bash
|
|
570
|
+
npm run type-check
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
### Continuous Integration
|
|
574
|
+
|
|
575
|
+
The project uses GitHub Actions for CI/CD:
|
|
576
|
+
|
|
577
|
+
- **Build**: Compiles TypeScript to JavaScript
|
|
578
|
+
- **Type Check**: Validates TypeScript types with strict mode
|
|
579
|
+
- **Test**: Runs all 376 unit tests with 98.27% coverage
|
|
580
|
+
- **Multi-version**: Tests on Node.js 20 and 22
|
|
581
|
+
|
|
582
|
+
The CI workflow runs on every push and pull request to the main branch.
|
|
583
|
+
|
|
584
|
+
## Testing
|
|
585
|
+
|
|
586
|
+
The project includes comprehensive unit and integration tests using Vitest.
|
|
587
|
+
|
|
588
|
+
### Run Tests
|
|
589
|
+
|
|
590
|
+
```bash
|
|
591
|
+
# Run all tests
|
|
592
|
+
npm test
|
|
593
|
+
|
|
594
|
+
# Run tests in watch mode
|
|
595
|
+
npm test -- --watch
|
|
596
|
+
|
|
597
|
+
# Run tests with UI
|
|
598
|
+
npm run test:ui
|
|
599
|
+
|
|
600
|
+
# Run tests with coverage
|
|
601
|
+
npm run test:coverage
|
|
602
|
+
|
|
603
|
+
# Run provider verification tests
|
|
604
|
+
npm run test:providers
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
### Test Coverage
|
|
608
|
+
|
|
609
|
+
The test suite includes **422 tests** (376 unit + 46 functional/interactive) covering:
|
|
610
|
+
|
|
611
|
+
**Unit Tests:**
|
|
612
|
+
|
|
613
|
+
- **QdrantManager** (21 tests): Collection management, point operations, and search functionality
|
|
614
|
+
- **OllamaEmbeddings** (31 tests): Local embedding generation, batch processing, rate limiting - DEFAULT PROVIDER
|
|
615
|
+
- **OpenAIEmbeddings** (25 tests): Cloud embedding generation, batch processing, rate limiting with Retry-After header
|
|
616
|
+
- **CohereEmbeddings** (29 tests): Cohere API integration, batch processing, rate limiting
|
|
617
|
+
- **VoyageEmbeddings** (31 tests): Voyage AI integration, batch processing, rate limiting
|
|
618
|
+
- **Factory Pattern** (32 tests): Provider instantiation, configuration, error handling
|
|
619
|
+
- **MCP Server** (19 tests): Tool schemas, resource URI patterns, and MCP protocol compliance
|
|
620
|
+
|
|
621
|
+
**Functional/Interactive Tests:**
|
|
622
|
+
|
|
623
|
+
- **Live API Integration** (46 tests): Real embedding APIs, production MCP server validation, rate limiting behavior, and end-to-end workflows with real documents
|
|
624
|
+
|
|
625
|
+
**Coverage Highlights:**
|
|
626
|
+
|
|
627
|
+
- ✅ 100% function coverage across all modules
|
|
628
|
+
- ✅ Comprehensive rate limiting tests with timing validation
|
|
629
|
+
- ✅ Typed error handling with OpenAIError interface
|
|
630
|
+
- ✅ Invalid Retry-After header fallback to exponential backoff
|
|
631
|
+
- ✅ Real-world validation with live OpenAI API
|
|
632
|
+
- ✅ Both source and compiled code tested
|
|
633
|
+
|
|
634
|
+
See [`docs/test_report.md`](docs/test_report.md) for detailed test results and coverage analysis.
|
|
635
|
+
|
|
636
|
+
### Writing Tests
|
|
637
|
+
|
|
638
|
+
Tests are located next to the files they test with a `.test.ts` extension:
|
|
639
|
+
|
|
640
|
+
- `src/qdrant/client.test.ts` - Qdrant client wrapper tests
|
|
641
|
+
- `src/embeddings/openai.test.ts` - OpenAI embeddings provider tests
|
|
642
|
+
- `src/index.test.ts` - MCP server integration tests
|
|
643
|
+
|
|
644
|
+
Run tests before committing:
|
|
645
|
+
|
|
646
|
+
```bash
|
|
647
|
+
npm test -- --run
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
## License
|
|
651
|
+
|
|
652
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
653
|
+
|
|
654
|
+
## Contributing
|
|
655
|
+
|
|
656
|
+
Contributions are welcome! Please read our [Contributing Guidelines](CONTRIBUTING.md) for detailed information about:
|
|
657
|
+
|
|
658
|
+
- Code of conduct
|
|
659
|
+
- Development workflow
|
|
660
|
+
- Commit message conventions (Conventional Commits)
|
|
661
|
+
- Pull request process
|
|
662
|
+
- Testing requirements
|
|
663
|
+
|
|
664
|
+
### Quick Start for Contributors
|
|
665
|
+
|
|
666
|
+
1. **Run tests**: Ensure all tests pass
|
|
667
|
+
|
|
668
|
+
```bash
|
|
669
|
+
npm test -- --run
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
2. **Type check**: Verify no TypeScript errors
|
|
673
|
+
|
|
674
|
+
```bash
|
|
675
|
+
npm run type-check
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
3. **Build**: Confirm the project builds successfully
|
|
679
|
+
|
|
680
|
+
```bash
|
|
681
|
+
npm run build
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
4. **Commit**: Use conventional commit format
|
|
685
|
+
```bash
|
|
686
|
+
git commit -m "feat: add new feature"
|
|
687
|
+
git commit -m "fix: resolve bug"
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
All pull requests will automatically run through CI checks that validate:
|
|
691
|
+
|
|
692
|
+
- TypeScript compilation
|
|
693
|
+
- Type checking
|
|
694
|
+
- Test suite (376 tests, 98.27% coverage)
|
|
695
|
+
- Compatibility with Node.js 20 and 22
|
|
696
|
+
- Conventional commit format
|
|
697
|
+
|
|
698
|
+
### Automated Releases
|
|
699
|
+
|
|
700
|
+
This project uses semantic-release for automated versioning and releases based on conventional commits. Version numbers follow Semantic Versioning based on your commit types:
|
|
701
|
+
|
|
702
|
+
- `feat:` commits trigger minor version bumps (1.x.0)
|
|
703
|
+
- `fix:` commits trigger patch version bumps (1.0.x)
|
|
704
|
+
- Commits with `BREAKING CHANGE:` trigger major version bumps (x.0.0)
|
|
705
|
+
|
|
706
|
+
### Note for Repository Owners
|
|
707
|
+
|
|
708
|
+
After forking or cloning, update the CI badge URL in README.md:
|
|
709
|
+
|
|
710
|
+
```markdown
|
|
711
|
+
[](https://github.com/mhalder/qdrant-mcp-server/actions/workflows/ci.yml)
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
Replace `YOUR_USERNAME` with your GitHub username or organization name.
|