@mhalder/qdrant-mcp-server 3.3.2 → 3.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/.github/workflows/ci.yml +0 -2
  2. package/.github/workflows/claude-code-review.yml +1 -1
  3. package/CHANGELOG.md +12 -0
  4. package/README.md +1 -1
  5. package/biome.json +3 -2
  6. package/build/code/chunker/tree-sitter-chunker.d.ts.map +1 -1
  7. package/build/code/chunker/tree-sitter-chunker.js +2 -12
  8. package/build/code/chunker/tree-sitter-chunker.js.map +1 -1
  9. package/build/code/indexer.d.ts.map +1 -1
  10. package/build/code/indexer.js +12 -18
  11. package/build/code/indexer.js.map +1 -1
  12. package/build/code/scanner.js +1 -1
  13. package/build/code/scanner.js.map +1 -1
  14. package/build/embeddings/cohere.d.ts +1 -1
  15. package/build/embeddings/cohere.d.ts.map +1 -1
  16. package/build/embeddings/cohere.js +2 -2
  17. package/build/embeddings/cohere.js.map +1 -1
  18. package/build/embeddings/cohere.test.js +1 -5
  19. package/build/embeddings/cohere.test.js.map +1 -1
  20. package/build/embeddings/factory.d.ts +1 -1
  21. package/build/embeddings/factory.d.ts.map +1 -1
  22. package/build/embeddings/factory.js +7 -9
  23. package/build/embeddings/factory.js.map +1 -1
  24. package/build/embeddings/factory.test.js +3 -3
  25. package/build/embeddings/factory.test.js.map +1 -1
  26. package/build/embeddings/ollama.d.ts +1 -1
  27. package/build/embeddings/ollama.d.ts.map +1 -1
  28. package/build/embeddings/ollama.js +6 -8
  29. package/build/embeddings/ollama.js.map +1 -1
  30. package/build/embeddings/ollama.test.js +2 -6
  31. package/build/embeddings/ollama.test.js.map +1 -1
  32. package/build/embeddings/openai.d.ts +1 -1
  33. package/build/embeddings/openai.d.ts.map +1 -1
  34. package/build/embeddings/openai.js +4 -7
  35. package/build/embeddings/openai.js.map +1 -1
  36. package/build/embeddings/openai.test.js +3 -12
  37. package/build/embeddings/openai.test.js.map +1 -1
  38. package/build/embeddings/sparse.test.js +12 -2
  39. package/build/embeddings/sparse.test.js.map +1 -1
  40. package/build/embeddings/voyage.d.ts +1 -1
  41. package/build/embeddings/voyage.d.ts.map +1 -1
  42. package/build/embeddings/voyage.js +2 -3
  43. package/build/embeddings/voyage.js.map +1 -1
  44. package/build/embeddings/voyage.test.js +2 -6
  45. package/build/embeddings/voyage.test.js.map +1 -1
  46. package/build/git/chunker.d.ts.map +1 -1
  47. package/build/git/chunker.js +2 -2
  48. package/build/git/chunker.js.map +1 -1
  49. package/build/git/chunker.test.js +1 -1
  50. package/build/git/chunker.test.js.map +1 -1
  51. package/build/git/extractor.d.ts.map +1 -1
  52. package/build/git/extractor.integration.test.js +9 -5
  53. package/build/git/extractor.integration.test.js.map +1 -1
  54. package/build/git/extractor.js +1 -1
  55. package/build/git/extractor.js.map +1 -1
  56. package/build/git/extractor.test.js +2 -2
  57. package/build/git/extractor.test.js.map +1 -1
  58. package/build/git/index.d.ts +4 -4
  59. package/build/git/index.d.ts.map +1 -1
  60. package/build/git/index.js +3 -3
  61. package/build/git/index.js.map +1 -1
  62. package/build/git/indexer.d.ts.map +1 -1
  63. package/build/git/indexer.js +9 -21
  64. package/build/git/indexer.js.map +1 -1
  65. package/build/git/indexer.test.js +4 -8
  66. package/build/git/indexer.test.js.map +1 -1
  67. package/build/git/sync/synchronizer.d.ts.map +1 -1
  68. package/build/git/sync/synchronizer.js.map +1 -1
  69. package/build/git/sync/synchronizer.test.js +4 -2
  70. package/build/git/sync/synchronizer.test.js.map +1 -1
  71. package/build/index.js +5 -9
  72. package/build/index.js.map +1 -1
  73. package/build/index.test.js +3 -3
  74. package/build/index.test.js.map +1 -1
  75. package/build/logger.d.ts.map +1 -1
  76. package/build/logger.js +1 -9
  77. package/build/logger.js.map +1 -1
  78. package/build/prompts/register.d.ts.map +1 -1
  79. package/build/prompts/register.js.map +1 -1
  80. package/build/qdrant/client.d.ts.map +1 -1
  81. package/build/qdrant/client.js.map +1 -1
  82. package/build/qdrant/client.test.js +10 -34
  83. package/build/qdrant/client.test.js.map +1 -1
  84. package/build/resources/index.d.ts +1 -1
  85. package/build/resources/index.d.ts.map +1 -1
  86. package/build/resources/index.js +1 -1
  87. package/build/resources/index.js.map +1 -1
  88. package/build/tools/code.d.ts.map +1 -1
  89. package/build/tools/code.js +3 -9
  90. package/build/tools/code.js.map +1 -1
  91. package/build/tools/collection.d.ts.map +1 -1
  92. package/build/tools/collection.js +1 -3
  93. package/build/tools/collection.js.map +1 -1
  94. package/build/tools/document.d.ts.map +1 -1
  95. package/build/tools/document.js +1 -1
  96. package/build/tools/document.js.map +1 -1
  97. package/build/tools/federated.d.ts.map +1 -1
  98. package/build/tools/federated.js +15 -6
  99. package/build/tools/federated.js.map +1 -1
  100. package/build/tools/federated.test.js +18 -22
  101. package/build/tools/federated.test.js.map +1 -1
  102. package/build/tools/git-history.d.ts.map +1 -1
  103. package/build/tools/git-history.js +3 -7
  104. package/build/tools/git-history.js.map +1 -1
  105. package/build/tools/index.d.ts.map +1 -1
  106. package/build/tools/index.js.map +1 -1
  107. package/build/tools/logging.d.ts.map +1 -1
  108. package/build/tools/logging.js +1 -3
  109. package/build/tools/logging.js.map +1 -1
  110. package/build/tools/logging.test.js +1 -1
  111. package/build/tools/logging.test.js.map +1 -1
  112. package/build/tools/schemas.d.ts.map +1 -1
  113. package/build/tools/schemas.js +17 -64
  114. package/build/tools/schemas.js.map +1 -1
  115. package/build/tools/search.d.ts.map +1 -1
  116. package/build/tools/search.js +1 -1
  117. package/build/tools/search.js.map +1 -1
  118. package/commitlint.config.js +12 -23
  119. package/package.json +1 -1
  120. package/scripts/verify-providers.js +12 -32
  121. package/src/code/chunker/tree-sitter-chunker.ts +9 -35
  122. package/src/code/indexer.ts +45 -107
  123. package/src/code/scanner.ts +1 -1
  124. package/src/embeddings/cohere.test.ts +17 -45
  125. package/src/embeddings/cohere.ts +10 -17
  126. package/src/embeddings/factory.test.ts +18 -18
  127. package/src/embeddings/factory.ts +18 -25
  128. package/src/embeddings/ollama.test.ts +38 -67
  129. package/src/embeddings/ollama.ts +15 -27
  130. package/src/embeddings/openai.test.ts +17 -53
  131. package/src/embeddings/openai.ts +11 -22
  132. package/src/embeddings/sparse.test.ts +12 -2
  133. package/src/embeddings/voyage.test.ts +39 -80
  134. package/src/embeddings/voyage.ts +9 -13
  135. package/src/git/chunker.test.ts +1 -1
  136. package/src/git/chunker.ts +6 -22
  137. package/src/git/extractor.integration.test.ts +12 -16
  138. package/src/git/extractor.test.ts +21 -35
  139. package/src/git/extractor.ts +14 -36
  140. package/src/git/index.ts +9 -10
  141. package/src/git/indexer.test.ts +29 -57
  142. package/src/git/indexer.ts +38 -86
  143. package/src/git/sync/synchronizer.test.ts +6 -9
  144. package/src/git/sync/synchronizer.ts +2 -5
  145. package/src/index.test.ts +7 -9
  146. package/src/index.ts +34 -80
  147. package/src/logger.ts +3 -14
  148. package/src/prompts/register.ts +3 -10
  149. package/src/qdrant/client.test.ts +63 -169
  150. package/src/qdrant/client.ts +19 -45
  151. package/src/resources/index.ts +4 -10
  152. package/src/tools/code.ts +43 -66
  153. package/src/tools/collection.ts +19 -38
  154. package/src/tools/document.ts +10 -19
  155. package/src/tools/federated.test.ts +34 -57
  156. package/src/tools/federated.ts +88 -108
  157. package/src/tools/git-history.ts +32 -60
  158. package/src/tools/index.ts +1 -4
  159. package/src/tools/logging.test.ts +10 -10
  160. package/src/tools/logging.ts +8 -18
  161. package/src/tools/schemas.ts +23 -78
  162. package/src/tools/search.ts +77 -94
  163. package/tests/code/chunker/tree-sitter-chunker.test.ts +6 -19
  164. package/tests/code/indexer.test.ts +100 -192
  165. package/tests/code/integration.test.ts +61 -117
  166. package/tests/code/scanner.test.ts +12 -39
  167. package/tests/code/sync/snapshot.test.ts +4 -14
  168. package/tests/code/sync/synchronizer.test.ts +10 -40
@@ -39,9 +39,7 @@ describe("QdrantManager", () => {
39
39
  // Reset mocks and restore default implementations
40
40
  mockClient.createCollection.mockReset().mockResolvedValue({});
41
41
  mockClient.getCollection.mockReset().mockResolvedValue({});
42
- mockClient.getCollections
43
- .mockReset()
44
- .mockResolvedValue({ collections: [] });
42
+ mockClient.getCollections.mockReset().mockResolvedValue({ collections: [] });
45
43
  mockClient.deleteCollection.mockReset().mockResolvedValue({});
46
44
  mockClient.upsert.mockReset().mockResolvedValue({});
47
45
  mockClient.search.mockReset().mockResolvedValue([]);
@@ -76,50 +74,41 @@ describe("QdrantManager", () => {
76
74
  it("should create a collection with default distance metric", async () => {
77
75
  await manager.createCollection("test-collection", 1536);
78
76
 
79
- expect(mockClient.createCollection).toHaveBeenCalledWith(
80
- "test-collection",
81
- {
82
- vectors: {
83
- size: 1536,
84
- distance: "Cosine",
85
- },
77
+ expect(mockClient.createCollection).toHaveBeenCalledWith("test-collection", {
78
+ vectors: {
79
+ size: 1536,
80
+ distance: "Cosine",
86
81
  },
87
- );
82
+ });
88
83
  });
89
84
 
90
85
  it("should create a collection with custom distance metric", async () => {
91
86
  await manager.createCollection("test-collection", 1536, "Euclid");
92
87
 
93
- expect(mockClient.createCollection).toHaveBeenCalledWith(
94
- "test-collection",
95
- {
96
- vectors: {
97
- size: 1536,
98
- distance: "Euclid",
99
- },
88
+ expect(mockClient.createCollection).toHaveBeenCalledWith("test-collection", {
89
+ vectors: {
90
+ size: 1536,
91
+ distance: "Euclid",
100
92
  },
101
- );
93
+ });
102
94
  });
103
95
 
104
96
  it("should create a hybrid collection with sparse vectors enabled", async () => {
105
97
  await manager.createCollection("test-collection", 1536, "Cosine", true);
106
98
 
107
- expect(mockClient.createCollection).toHaveBeenCalledWith(
108
- "test-collection",
109
- {
110
- vectors: {
111
- dense: {
112
- size: 1536,
113
- distance: "Cosine",
114
- },
99
+ expect(mockClient.createCollection).toHaveBeenCalledWith("test-collection", {
100
+ vectors: {
101
+ dense: {
102
+ size: 1536,
103
+ distance: "Cosine",
115
104
  },
116
- sparse_vectors: {
117
- text: {
118
- modifier: "idf",
119
- },
105
+ },
106
+ sparse_vectors: {
107
+ text: {
108
+ modifier: "idf",
120
109
  },
121
110
  },
122
- );
111
+ });
123
112
  });
124
113
  });
125
114
 
@@ -145,20 +134,12 @@ describe("QdrantManager", () => {
145
134
  describe("listCollections", () => {
146
135
  it("should return list of collection names", async () => {
147
136
  mockClient.getCollections.mockResolvedValue({
148
- collections: [
149
- { name: "collection1" },
150
- { name: "collection2" },
151
- { name: "collection3" },
152
- ],
137
+ collections: [{ name: "collection1" }, { name: "collection2" }, { name: "collection3" }],
153
138
  });
154
139
 
155
140
  const collections = await manager.listCollections();
156
141
 
157
- expect(collections).toEqual([
158
- "collection1",
159
- "collection2",
160
- "collection3",
161
- ]);
142
+ expect(collections).toEqual(["collection1", "collection2", "collection3"]);
162
143
  });
163
144
 
164
145
  it("should return empty array when no collections exist", async () => {
@@ -253,9 +234,7 @@ describe("QdrantManager", () => {
253
234
  it("should delete a collection", async () => {
254
235
  await manager.deleteCollection("test-collection");
255
236
 
256
- expect(mockClient.deleteCollection).toHaveBeenCalledWith(
257
- "test-collection",
258
- );
237
+ expect(mockClient.deleteCollection).toHaveBeenCalledWith("test-collection");
259
238
  });
260
239
  });
261
240
 
@@ -304,7 +283,7 @@ describe("QdrantManager", () => {
304
283
  const normalizedId = calls[0][1].points[0].id;
305
284
  // Check that it's a valid UUID format
306
285
  expect(normalizedId).toMatch(
307
- /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
286
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
308
287
  );
309
288
  // Ensure it's not the original ID
310
289
  expect(normalizedId).not.toBe("my-custom-id");
@@ -312,9 +291,7 @@ describe("QdrantManager", () => {
312
291
 
313
292
  it("should preserve UUID format IDs without modification", async () => {
314
293
  const uuidId = "123e4567-e89b-12d3-a456-426614174000";
315
- const points = [
316
- { id: uuidId, vector: [0.1, 0.2, 0.3], payload: { text: "test" } },
317
- ];
294
+ const points = [{ id: uuidId, vector: [0.1, 0.2, 0.3], payload: { text: "test" } }];
318
295
 
319
296
  await manager.addPoints("test-collection", points);
320
297
 
@@ -342,10 +319,8 @@ describe("QdrantManager", () => {
342
319
  },
343
320
  });
344
321
 
345
- await expect(
346
- manager.addPoints("test-collection", points),
347
- ).rejects.toThrow(
348
- 'Failed to add points to collection "test-collection": Vector dimension mismatch',
322
+ await expect(manager.addPoints("test-collection", points)).rejects.toThrow(
323
+ 'Failed to add points to collection "test-collection": Vector dimension mismatch'
349
324
  );
350
325
  });
351
326
 
@@ -354,10 +329,8 @@ describe("QdrantManager", () => {
354
329
 
355
330
  mockClient.upsert.mockRejectedValue(new Error("Network error"));
356
331
 
357
- await expect(
358
- manager.addPoints("test-collection", points),
359
- ).rejects.toThrow(
360
- 'Failed to add points to collection "test-collection": Network error',
332
+ await expect(manager.addPoints("test-collection", points)).rejects.toThrow(
333
+ 'Failed to add points to collection "test-collection": Network error'
361
334
  );
362
335
  });
363
336
 
@@ -366,10 +339,8 @@ describe("QdrantManager", () => {
366
339
 
367
340
  mockClient.upsert.mockRejectedValue("Unknown error");
368
341
 
369
- await expect(
370
- manager.addPoints("test-collection", points),
371
- ).rejects.toThrow(
372
- 'Failed to add points to collection "test-collection": Unknown error',
342
+ await expect(manager.addPoints("test-collection", points)).rejects.toThrow(
343
+ 'Failed to add points to collection "test-collection": Unknown error'
373
344
  );
374
345
  });
375
346
  });
@@ -397,11 +368,7 @@ describe("QdrantManager", () => {
397
368
  { id: 2, score: 0.85, payload: { text: "result2" } },
398
369
  ]);
399
370
 
400
- const results = await manager.search(
401
- "test-collection",
402
- [0.1, 0.2, 0.3],
403
- 5,
404
- );
371
+ const results = await manager.search("test-collection", [0.1, 0.2, 0.3], 5);
405
372
 
406
373
  expect(results).toEqual([
407
374
  { id: 1, score: 0.95, payload: { text: "result1" } },
@@ -500,9 +467,7 @@ describe("QdrantManager", () => {
500
467
  });
501
468
 
502
469
  it("should handle null payload in results", async () => {
503
- mockClient.search.mockResolvedValue([
504
- { id: 1, score: 0.95, payload: null },
505
- ]);
470
+ mockClient.search.mockResolvedValue([{ id: 1, score: 0.95, payload: null }]);
506
471
 
507
472
  const results = await manager.search("test-collection", [0.1, 0.2, 0.3]);
508
473
 
@@ -531,19 +496,11 @@ describe("QdrantManager", () => {
531
496
  },
532
497
  });
533
498
 
534
- mockClient.search.mockResolvedValue([
535
- { id: 1, score: 0.95, payload: { text: "result1" } },
536
- ]);
499
+ mockClient.search.mockResolvedValue([{ id: 1, score: 0.95, payload: { text: "result1" } }]);
537
500
 
538
- const results = await manager.search(
539
- "hybrid-collection",
540
- [0.1, 0.2, 0.3],
541
- 5,
542
- );
501
+ const results = await manager.search("hybrid-collection", [0.1, 0.2, 0.3], 5);
543
502
 
544
- expect(results).toEqual([
545
- { id: 1, score: 0.95, payload: { text: "result1" } },
546
- ]);
503
+ expect(results).toEqual([{ id: 1, score: 0.95, payload: { text: "result1" } }]);
547
504
  expect(mockClient.search).toHaveBeenCalledWith("hybrid-collection", {
548
505
  vector: { name: "dense", vector: [0.1, 0.2, 0.3] },
549
506
  limit: 5,
@@ -566,19 +523,11 @@ describe("QdrantManager", () => {
566
523
  },
567
524
  });
568
525
 
569
- mockClient.search.mockResolvedValue([
570
- { id: 1, score: 0.95, payload: { text: "result1" } },
571
- ]);
526
+ mockClient.search.mockResolvedValue([{ id: 1, score: 0.95, payload: { text: "result1" } }]);
572
527
 
573
- const results = await manager.search(
574
- "standard-collection",
575
- [0.1, 0.2, 0.3],
576
- 5,
577
- );
528
+ const results = await manager.search("standard-collection", [0.1, 0.2, 0.3], 5);
578
529
 
579
- expect(results).toEqual([
580
- { id: 1, score: 0.95, payload: { text: "result1" } },
581
- ]);
530
+ expect(results).toEqual([{ id: 1, score: 0.95, payload: { text: "result1" } }]);
582
531
  expect(mockClient.search).toHaveBeenCalledWith("standard-collection", {
583
532
  vector: [0.1, 0.2, 0.3],
584
533
  limit: 5,
@@ -589,9 +538,7 @@ describe("QdrantManager", () => {
589
538
 
590
539
  describe("getPoint", () => {
591
540
  it("should retrieve a point by id", async () => {
592
- mockClient.retrieve.mockResolvedValue([
593
- { id: 1, payload: { text: "test" } },
594
- ]);
541
+ mockClient.retrieve.mockResolvedValue([{ id: 1, payload: { text: "test" } }]);
595
542
 
596
543
  const point = await manager.getPoint("test-collection", 1);
597
544
 
@@ -691,11 +638,7 @@ describe("QdrantManager", () => {
691
638
  ],
692
639
  });
693
640
 
694
- const results = await manager.hybridSearch(
695
- "test-collection",
696
- denseVector,
697
- sparseVector,
698
- );
641
+ const results = await manager.hybridSearch("test-collection", denseVector, sparseVector);
699
642
 
700
643
  expect(results).toEqual([
701
644
  { id: 1, score: 0.95, payload: { text: "result1" } },
@@ -731,12 +674,7 @@ describe("QdrantManager", () => {
731
674
 
732
675
  mockClient.query.mockResolvedValue({ points: [] });
733
676
 
734
- await manager.hybridSearch(
735
- "test-collection",
736
- denseVector,
737
- sparseVector,
738
- 10,
739
- );
677
+ await manager.hybridSearch("test-collection", denseVector, sparseVector, 10);
740
678
 
741
679
  expect(mockClient.query).toHaveBeenCalledWith(
742
680
  "test-collection",
@@ -745,7 +683,7 @@ describe("QdrantManager", () => {
745
683
  expect.objectContaining({ limit: 40 }), // 10 * 4
746
684
  ]),
747
685
  limit: 10,
748
- }),
686
+ })
749
687
  );
750
688
  });
751
689
 
@@ -756,13 +694,7 @@ describe("QdrantManager", () => {
756
694
 
757
695
  mockClient.query.mockResolvedValue({ points: [] });
758
696
 
759
- await manager.hybridSearch(
760
- "test-collection",
761
- denseVector,
762
- sparseVector,
763
- 5,
764
- filter,
765
- );
697
+ await manager.hybridSearch("test-collection", denseVector, sparseVector, 5, filter);
766
698
 
767
699
  expect(mockClient.query).toHaveBeenCalledWith("test-collection", {
768
700
  prefetch: [
@@ -804,13 +736,7 @@ describe("QdrantManager", () => {
804
736
 
805
737
  mockClient.query.mockResolvedValue({ points: [] });
806
738
 
807
- await manager.hybridSearch(
808
- "test-collection",
809
- denseVector,
810
- sparseVector,
811
- 5,
812
- filter,
813
- );
739
+ await manager.hybridSearch("test-collection", denseVector, sparseVector, 5, filter);
814
740
 
815
741
  const call = mockClient.query.mock.calls[0][1];
816
742
  expect(call.prefetch[0].filter).toEqual(filter);
@@ -826,13 +752,7 @@ describe("QdrantManager", () => {
826
752
 
827
753
  mockClient.query.mockResolvedValue({ points: [] });
828
754
 
829
- await manager.hybridSearch(
830
- "test-collection",
831
- denseVector,
832
- sparseVector,
833
- 5,
834
- filter,
835
- );
755
+ await manager.hybridSearch("test-collection", denseVector, sparseVector, 5, filter);
836
756
 
837
757
  const call = mockClient.query.mock.calls[0][1];
838
758
  expect(call.prefetch[0].filter).toEqual(filter);
@@ -848,13 +768,7 @@ describe("QdrantManager", () => {
848
768
 
849
769
  mockClient.query.mockResolvedValue({ points: [] });
850
770
 
851
- await manager.hybridSearch(
852
- "test-collection",
853
- denseVector,
854
- sparseVector,
855
- 5,
856
- filter,
857
- );
771
+ await manager.hybridSearch("test-collection", denseVector, sparseVector, 5, filter);
858
772
 
859
773
  const call = mockClient.query.mock.calls[0][1];
860
774
  expect(call.prefetch[0].filter).toEqual(filter);
@@ -867,13 +781,7 @@ describe("QdrantManager", () => {
867
781
 
868
782
  mockClient.query.mockResolvedValue({ points: [] });
869
783
 
870
- await manager.hybridSearch(
871
- "test-collection",
872
- denseVector,
873
- sparseVector,
874
- 5,
875
- {},
876
- );
784
+ await manager.hybridSearch("test-collection", denseVector, sparseVector, 5, {});
877
785
 
878
786
  const call = mockClient.query.mock.calls[0][1];
879
787
  expect(call.prefetch[0].filter).toBeUndefined();
@@ -888,11 +796,7 @@ describe("QdrantManager", () => {
888
796
  points: [{ id: 1, score: 0.95, payload: null }],
889
797
  });
890
798
 
891
- const results = await manager.hybridSearch(
892
- "test-collection",
893
- denseVector,
894
- sparseVector,
895
- );
799
+ const results = await manager.hybridSearch("test-collection", denseVector, sparseVector);
896
800
 
897
801
  expect(results).toEqual([{ id: 1, score: 0.95, payload: undefined }]);
898
802
  });
@@ -910,9 +814,9 @@ describe("QdrantManager", () => {
910
814
  });
911
815
 
912
816
  await expect(
913
- manager.hybridSearch("test-collection", denseVector, sparseVector),
817
+ manager.hybridSearch("test-collection", denseVector, sparseVector)
914
818
  ).rejects.toThrow(
915
- 'Hybrid search failed on collection "test-collection": Named vector not found',
819
+ 'Hybrid search failed on collection "test-collection": Named vector not found'
916
820
  );
917
821
  });
918
822
 
@@ -923,10 +827,8 @@ describe("QdrantManager", () => {
923
827
  mockClient.query.mockRejectedValue(new Error("Network timeout"));
924
828
 
925
829
  await expect(
926
- manager.hybridSearch("test-collection", denseVector, sparseVector),
927
- ).rejects.toThrow(
928
- 'Hybrid search failed on collection "test-collection": Network timeout',
929
- );
830
+ manager.hybridSearch("test-collection", denseVector, sparseVector)
831
+ ).rejects.toThrow('Hybrid search failed on collection "test-collection": Network timeout');
930
832
  });
931
833
 
932
834
  it("should throw error with String(error) fallback", async () => {
@@ -936,10 +838,8 @@ describe("QdrantManager", () => {
936
838
  mockClient.query.mockRejectedValue("Unknown error");
937
839
 
938
840
  await expect(
939
- manager.hybridSearch("test-collection", denseVector, sparseVector),
940
- ).rejects.toThrow(
941
- 'Hybrid search failed on collection "test-collection": Unknown error',
942
- );
841
+ manager.hybridSearch("test-collection", denseVector, sparseVector)
842
+ ).rejects.toThrow('Hybrid search failed on collection "test-collection": Unknown error');
943
843
  });
944
844
  });
945
845
 
@@ -1030,7 +930,7 @@ describe("QdrantManager", () => {
1030
930
  const normalizedId = calls[0][1].points[0].id;
1031
931
  // Check that it's a valid UUID format
1032
932
  expect(normalizedId).toMatch(
1033
- /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
933
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
1034
934
  );
1035
935
  expect(normalizedId).not.toBe("my-doc-id");
1036
936
  });
@@ -1080,10 +980,8 @@ describe("QdrantManager", () => {
1080
980
  },
1081
981
  });
1082
982
 
1083
- await expect(
1084
- manager.addPointsWithSparse("test-collection", points),
1085
- ).rejects.toThrow(
1086
- 'Failed to add points with sparse vectors to collection "test-collection": Sparse vector not configured',
983
+ await expect(manager.addPointsWithSparse("test-collection", points)).rejects.toThrow(
984
+ 'Failed to add points with sparse vectors to collection "test-collection": Sparse vector not configured'
1087
985
  );
1088
986
  });
1089
987
 
@@ -1098,10 +996,8 @@ describe("QdrantManager", () => {
1098
996
 
1099
997
  mockClient.upsert.mockRejectedValue(new Error("Connection refused"));
1100
998
 
1101
- await expect(
1102
- manager.addPointsWithSparse("test-collection", points),
1103
- ).rejects.toThrow(
1104
- 'Failed to add points with sparse vectors to collection "test-collection": Connection refused',
999
+ await expect(manager.addPointsWithSparse("test-collection", points)).rejects.toThrow(
1000
+ 'Failed to add points with sparse vectors to collection "test-collection": Connection refused'
1105
1001
  );
1106
1002
  });
1107
1003
 
@@ -1116,10 +1012,8 @@ describe("QdrantManager", () => {
1116
1012
 
1117
1013
  mockClient.upsert.mockRejectedValue("Unexpected error");
1118
1014
 
1119
- await expect(
1120
- manager.addPointsWithSparse("test-collection", points),
1121
- ).rejects.toThrow(
1122
- 'Failed to add points with sparse vectors to collection "test-collection": Unexpected error',
1015
+ await expect(manager.addPointsWithSparse("test-collection", points)).rejects.toThrow(
1016
+ 'Failed to add points with sparse vectors to collection "test-collection": Unexpected error'
1123
1017
  );
1124
1018
  });
1125
1019
  });
@@ -39,8 +39,7 @@ export class QdrantManager {
39
39
  }
40
40
 
41
41
  // Check if already a valid UUID (8-4-4-4-12 format)
42
- const uuidRegex =
43
- /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
42
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
44
43
  if (uuidRegex.test(id)) {
45
44
  return id;
46
45
  }
@@ -54,12 +53,9 @@ export class QdrantManager {
54
53
  name: string,
55
54
  vectorSize: number,
56
55
  distance: "Cosine" | "Euclid" | "Dot" = "Cosine",
57
- enableSparse: boolean = false,
56
+ enableSparse: boolean = false
58
57
  ): Promise<void> {
59
- this.log.debug(
60
- { collection: name, vectorSize, distance, enableSparse },
61
- "createCollection",
62
- );
58
+ this.log.debug({ collection: name, vectorSize, distance, enableSparse }, "createCollection");
63
59
  const config: any = {};
64
60
 
65
61
  // When hybrid search is enabled, use named vectors
@@ -147,12 +143,9 @@ export class QdrantManager {
147
143
  id: string | number;
148
144
  vector: number[];
149
145
  payload?: Record<string, any>;
150
- }>,
146
+ }>
151
147
  ): Promise<void> {
152
- this.log.debug(
153
- { collection: collectionName, count: points.length },
154
- "addPoints",
155
- );
148
+ this.log.debug({ collection: collectionName, count: points.length }, "addPoints");
156
149
  try {
157
150
  // Normalize all IDs to ensure string IDs are in UUID format
158
151
  const normalizedPoints = points.map((point) => ({
@@ -165,11 +158,8 @@ export class QdrantManager {
165
158
  points: normalizedPoints,
166
159
  });
167
160
  } catch (error: any) {
168
- const errorMessage =
169
- error?.data?.status?.error || error?.message || String(error);
170
- throw new Error(
171
- `Failed to add points to collection "${collectionName}": ${errorMessage}`,
172
- );
161
+ const errorMessage = error?.data?.status?.error || error?.message || String(error);
162
+ throw new Error(`Failed to add points to collection "${collectionName}": ${errorMessage}`);
173
163
  }
174
164
  }
175
165
 
@@ -177,7 +167,7 @@ export class QdrantManager {
177
167
  collectionName: string,
178
168
  vector: number[],
179
169
  limit: number = 5,
180
- filter?: Record<string, any>,
170
+ filter?: Record<string, any>
181
171
  ): Promise<SearchResult[]> {
182
172
  this.log.debug({ collection: collectionName, limit }, "search");
183
173
  // Convert simple key-value filter to Qdrant filter format
@@ -218,7 +208,7 @@ export class QdrantManager {
218
208
 
219
209
  async getPoint(
220
210
  collectionName: string,
221
- id: string | number,
211
+ id: string | number
222
212
  ): Promise<{ id: string | number; payload?: Record<string, any> } | null> {
223
213
  try {
224
214
  const normalizedId = this.normalizeId(id);
@@ -239,14 +229,8 @@ export class QdrantManager {
239
229
  }
240
230
  }
241
231
 
242
- async deletePoints(
243
- collectionName: string,
244
- ids: (string | number)[],
245
- ): Promise<void> {
246
- this.log.debug(
247
- { collection: collectionName, count: ids.length },
248
- "deletePoints",
249
- );
232
+ async deletePoints(collectionName: string, ids: (string | number)[]): Promise<void> {
233
+ this.log.debug({ collection: collectionName, count: ids.length }, "deletePoints");
250
234
  // Normalize IDs to ensure string IDs are in UUID format
251
235
  const normalizedIds = ids.map((id) => this.normalizeId(id));
252
236
 
@@ -260,10 +244,7 @@ export class QdrantManager {
260
244
  * Deletes points matching a filter condition.
261
245
  * Useful for deleting all chunks associated with a specific file path.
262
246
  */
263
- async deletePointsByFilter(
264
- collectionName: string,
265
- filter: Record<string, any>,
266
- ): Promise<void> {
247
+ async deletePointsByFilter(collectionName: string, filter: Record<string, any>): Promise<void> {
267
248
  this.log.debug({ collection: collectionName }, "deletePointsByFilter");
268
249
  await this.client.delete(collectionName, {
269
250
  wait: true,
@@ -281,7 +262,7 @@ export class QdrantManager {
281
262
  sparseVector: SparseVector,
282
263
  limit: number = 5,
283
264
  filter?: Record<string, any>,
284
- _semanticWeight: number = 0.7,
265
+ _semanticWeight: number = 0.7
285
266
  ): Promise<SearchResult[]> {
286
267
  this.log.debug({ collection: collectionName, limit }, "hybridSearch");
287
268
  // Convert simple key-value filter to Qdrant filter format
@@ -332,11 +313,8 @@ export class QdrantManager {
332
313
  payload: result.payload || undefined,
333
314
  }));
334
315
  } catch (error: any) {
335
- const errorMessage =
336
- error?.data?.status?.error || error?.message || String(error);
337
- throw new Error(
338
- `Hybrid search failed on collection "${collectionName}": ${errorMessage}`,
339
- );
316
+ const errorMessage = error?.data?.status?.error || error?.message || String(error);
317
+ throw new Error(`Hybrid search failed on collection "${collectionName}": ${errorMessage}`);
340
318
  }
341
319
  }
342
320
 
@@ -350,12 +328,9 @@ export class QdrantManager {
350
328
  vector: number[];
351
329
  sparseVector: SparseVector;
352
330
  payload?: Record<string, any>;
353
- }>,
331
+ }>
354
332
  ): Promise<void> {
355
- this.log.debug(
356
- { collection: collectionName, count: points.length },
357
- "addPointsWithSparse",
358
- );
333
+ this.log.debug({ collection: collectionName, count: points.length }, "addPointsWithSparse");
359
334
  try {
360
335
  // Normalize all IDs to ensure string IDs are in UUID format
361
336
  const normalizedPoints = points.map((point) => ({
@@ -372,10 +347,9 @@ export class QdrantManager {
372
347
  points: normalizedPoints,
373
348
  });
374
349
  } catch (error: any) {
375
- const errorMessage =
376
- error?.data?.status?.error || error?.message || String(error);
350
+ const errorMessage = error?.data?.status?.error || error?.message || String(error);
377
351
  throw new Error(
378
- `Failed to add points with sparse vectors to collection "${collectionName}": ${errorMessage}`,
352
+ `Failed to add points with sparse vectors to collection "${collectionName}": ${errorMessage}`
379
353
  );
380
354
  }
381
355
  }
@@ -2,19 +2,13 @@
2
2
  * Resource registration module
3
3
  */
4
4
 
5
- import {
6
- McpServer,
7
- ResourceTemplate,
8
- } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { type McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
9
6
  import type { QdrantManager } from "../qdrant/client.js";
10
7
 
11
8
  /**
12
9
  * Register all MCP resources on the server
13
10
  */
14
- export function registerAllResources(
15
- server: McpServer,
16
- qdrant: QdrantManager,
17
- ): void {
11
+ export function registerAllResources(server: McpServer, qdrant: QdrantManager): void {
18
12
  // Static resource: list all collections
19
13
  server.registerResource(
20
14
  "collections",
@@ -35,7 +29,7 @@ export function registerAllResources(
35
29
  },
36
30
  ],
37
31
  };
38
- },
32
+ }
39
33
  );
40
34
 
41
35
  // Dynamic resource: individual collection info
@@ -74,6 +68,6 @@ export function registerAllResources(
74
68
  },
75
69
  ],
76
70
  };
77
- },
71
+ }
78
72
  );
79
73
  }