@mhalder/qdrant-mcp-server 1.1.0 → 1.2.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/README.md CHANGED
@@ -3,97 +3,51 @@
3
3
  [![CI](https://github.com/mhalder/qdrant-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/mhalder/qdrant-mcp-server/actions/workflows/ci.yml)
4
4
  [![codecov](https://codecov.io/gh/mhalder/qdrant-mcp-server/branch/main/graph/badge.svg)](https://codecov.io/gh/mhalder/qdrant-mcp-server)
5
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).
6
+ A Model Context Protocol (MCP) server providing semantic search capabilities using Qdrant vector database with multiple embedding providers.
7
7
 
8
8
  ## Features
9
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
10
+ - **Zero Setup**: Works out of the box with Ollama - no API keys required
11
+ - **Privacy-First**: Local embeddings and vector storage - data never leaves your machine
12
+ - **Multiple Providers**: Ollama (default), OpenAI, Cohere, and Voyage AI
13
+ - **Hybrid Search**: Combine semantic and keyword search for better results
14
+ - **Semantic Search**: Natural language search with metadata filtering
15
+ - **Rate Limiting**: Intelligent throttling with exponential backoff
16
+ - **Full CRUD**: Create, search, and manage collections and documents
27
17
 
28
- **Optional** (for alternative embedding providers):
18
+ ## Quick Start
29
19
 
30
- - OpenAI API key
31
- - Cohere API key
32
- - Voyage AI API key
20
+ ### Prerequisites
33
21
 
34
- ## Installation
22
+ - Node.js 20+
23
+ - Docker and Docker Compose
35
24
 
36
- 1. Clone the repository:
25
+ ### Installation
37
26
 
38
27
  ```bash
39
- git clone <your-repo-url>
28
+ # Clone and install
29
+ git clone https://github.com/mhalder/qdrant-mcp-server.git
40
30
  cd qdrant-mcp-server
41
- ```
42
-
43
- 2. Install dependencies:
44
-
45
- ```bash
46
31
  npm install
47
- ```
48
32
 
49
- 3. Start Qdrant and Ollama:
50
-
51
- ```bash
33
+ # Start services and pull model
52
34
  docker compose up -d
53
- ```
54
-
55
- 4. Pull the Ollama embedding model:
56
-
57
- ```bash
58
35
  docker exec ollama ollama pull nomic-embed-text
59
- ```
60
-
61
- 5. Build the project:
62
36
 
63
- ```bash
37
+ # Build
64
38
  npm run build
65
39
  ```
66
40
 
67
- ## Usage
68
-
69
- ### Running the Server
41
+ ### Configuration
70
42
 
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):**
43
+ Add to `~/.claude/claude_code_config.json`:
88
44
 
89
45
  ```json
90
46
  {
91
47
  "mcpServers": {
92
48
  "qdrant": {
93
49
  "command": "node",
94
- "args": [
95
- "/home/YOUR_USERNAME/projects/active/qdrant-mcp-server/build/index.js"
96
- ],
50
+ "args": ["/path/to/qdrant-mcp-server/build/index.js"],
97
51
  "env": {
98
52
  "QDRANT_URL": "http://localhost:6333",
99
53
  "EMBEDDING_BASE_URL": "http://localhost:11434"
@@ -103,612 +57,123 @@ Add this to your Claude Code configuration file at `~/.claude/claude_code_config
103
57
  }
104
58
  ```
105
59
 
106
- **With OpenAI (Alternative):**
60
+ **Using a different provider:**
107
61
 
108
62
  ```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
- }
63
+ "env": {
64
+ "EMBEDDING_PROVIDER": "openai", // or "cohere", "voyage"
65
+ "OPENAI_API_KEY": "sk-...", // provider-specific API key
66
+ "QDRANT_URL": "http://localhost:6333"
163
67
  }
164
68
  ```
165
69
 
166
- Replace `YOUR_USERNAME` and the path with your actual username and installation path.
70
+ Restart after making changes.
167
71
 
168
- Restart Claude Code after making this change.
72
+ See [Advanced Configuration](#advanced-configuration) section below for all options.
169
73
 
170
- ## Available Tools
74
+ ## Tools
171
75
 
172
- ### `create_collection`
76
+ ### Collection Management
173
77
 
174
- Create a new vector collection.
78
+ | Tool | Description |
79
+ | --------------------- | -------------------------------------------------------------------- |
80
+ | `create_collection` | Create collection with specified distance metric (Cosine/Euclid/Dot) |
81
+ | `list_collections` | List all collections |
82
+ | `get_collection_info` | Get collection details and statistics |
83
+ | `delete_collection` | Delete collection and all documents |
175
84
 
176
- **Parameters:**
85
+ ### Document Operations
177
86
 
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
- ```
87
+ | Tool | Description |
88
+ | ------------------ | ----------------------------------------------------------------------------- |
89
+ | `add_documents` | Add documents with automatic embedding (supports string/number IDs, metadata) |
90
+ | `semantic_search` | Natural language search with optional metadata filtering |
91
+ | `hybrid_search` | Hybrid search combining semantic and keyword (BM25) search with RRF |
92
+ | `delete_documents` | Delete specific documents by ID |
186
93
 
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
94
+ ### Resources
299
95
 
300
96
  - `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:**
97
+ - `qdrant://collection/{name}` - Collection details
334
98
 
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
- ```
99
+ ## Examples
341
100
 
342
- 3. **Search without filters:**
101
+ See [examples/](examples/) directory for detailed guides:
343
102
 
344
- ```
345
- Search knowledge-base for "how does semantic search work"
346
- ```
103
+ - **[Basic Usage](examples/basic/)** - Create collections, add documents, search
104
+ - **[Knowledge Base](examples/knowledge-base/)** - Structured documentation with metadata
105
+ - **[Advanced Filtering](examples/filters/)** - Complex boolean filters
106
+ - **[Rate Limiting](examples/rate-limiting/)** - Batch processing with cloud providers
347
107
 
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
108
+ ## Advanced Configuration
366
109
 
367
110
  ### Environment Variables
368
111
 
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.
112
+ | Variable | Description | Default |
113
+ | ----------------------------------- | -------------------------------------- | --------------------- |
114
+ | `EMBEDDING_PROVIDER` | "ollama", "openai", "cohere", "voyage" | ollama |
115
+ | `QDRANT_URL` | Qdrant server URL | http://localhost:6333 |
116
+ | `EMBEDDING_MODEL` | Model name | Provider-specific |
117
+ | `EMBEDDING_BASE_URL` | Custom API URL | Provider-specific |
118
+ | `EMBEDDING_MAX_REQUESTS_PER_MINUTE` | Rate limit | Provider-specific |
119
+ | `EMBEDDING_RETRY_ATTEMPTS` | Retry count | 3 |
120
+ | `EMBEDDING_RETRY_DELAY` | Initial retry delay (ms) | 1000 |
121
+ | `OPENAI_API_KEY` | OpenAI API key | - |
122
+ | `COHERE_API_KEY` | Cohere API key | - |
123
+ | `VOYAGE_API_KEY` | Voyage AI API key | - |
124
+
125
+ ### Provider Comparison
126
+
127
+ | Provider | Models | Dimensions | Rate Limit | Notes |
128
+ | ---------- | --------------------------------------------------------------- | -------------- | ---------- | -------------------- |
129
+ | **Ollama** | `nomic-embed-text` (default), `mxbai-embed-large`, `all-minilm` | 768, 1024, 384 | None | Local, no API key |
130
+ | **OpenAI** | `text-embedding-3-small` (default), `text-embedding-3-large` | 1536, 3072 | 3500/min | Cloud API |
131
+ | **Cohere** | `embed-english-v3.0` (default), `embed-multilingual-v3.0` | 1024 | 100/min | Multilingual support |
132
+ | **Voyage** | `voyage-2` (default), `voyage-large-2`, `voyage-code-2` | 1024, 1536 | 300/min | Code-specialized |
133
+
134
+ **Note:** Ollama models require `docker exec ollama ollama pull <model-name>` before use.
476
135
 
477
136
  ## Troubleshooting
478
137
 
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
138
+ | Issue | Solution |
139
+ | ---------------------- | ---------------------------------------------------------------------------- |
140
+ | **Qdrant not running** | `docker compose up -d` |
141
+ | **Collection missing** | Create collection first before adding documents |
142
+ | **Ollama not running** | Verify with `curl http://localhost:11434`, start with `docker compose up -d` |
143
+ | **Model missing** | `docker exec ollama ollama pull nomic-embed-text` |
144
+ | **Rate limit errors** | Adjust `EMBEDDING_MAX_REQUESTS_PER_MINUTE` to match your provider tier |
145
+ | **API key errors** | Verify correct API key in environment configuration |
146
+ | **Filter errors** | Ensure Qdrant filter format, check field names match metadata |
546
147
 
547
148
  ## Development
548
149
 
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
150
  ```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
151
+ npm run dev # Development with auto-reload
152
+ npm run build # Production build
153
+ npm run type-check # TypeScript validation
154
+ npm test # Run test suite
155
+ npm run test:coverage # Coverage report
605
156
  ```
606
157
 
607
- ### Test Coverage
158
+ ### Testing
608
159
 
609
- The test suite includes **422 tests** (376 unit + 46 functional/interactive) covering:
160
+ **422 tests** (376 unit + 46 functional) with **98%+ coverage**:
610
161
 
611
- **Unit Tests:**
162
+ - **Unit Tests**: QdrantManager (21), Ollama (31), OpenAI (25), Cohere (29), Voyage (31), Factory (32), MCP Server (19)
163
+ - **Functional Tests**: Live API integration, end-to-end workflows (46)
612
164
 
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.
165
+ **CI/CD**: GitHub Actions runs build, type-check, and tests on Node.js 20 & 22 for every push/PR.
653
166
 
654
167
  ## Contributing
655
168
 
656
- Contributions are welcome! Please read our [Contributing Guidelines](CONTRIBUTING.md) for detailed information about:
169
+ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for:
657
170
 
658
- - Code of conduct
659
171
  - Development workflow
660
- - Commit message conventions (Conventional Commits)
661
- - Pull request process
662
- - Testing requirements
663
-
664
- ### Quick Start for Contributors
172
+ - Conventional commit format (`feat:`, `fix:`, `BREAKING CHANGE:`)
173
+ - Testing requirements (run `npm test`, `npm run type-check`, `npm run build`)
665
174
 
666
- 1. **Run tests**: Ensure all tests pass
175
+ **Automated releases**: Semantic versioning via conventional commits - `feat:` → minor, `fix:` → patch, `BREAKING CHANGE:` → major.
667
176
 
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
- [![CI](https://github.com/mhalder/qdrant-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/mhalder/qdrant-mcp-server/actions/workflows/ci.yml)
712
- ```
177
+ ## License
713
178
 
714
- Replace `YOUR_USERNAME` with your GitHub username or organization name.
179
+ MIT - see [LICENSE](LICENSE) file.