Skip to content

Commit f644185

Browse files
Merge pull request #15 from qdrant/fix/collection-compatibility
Fix compatibility with the previous versions
2 parents f252489 + 8afd738 commit f644185

File tree

5 files changed

+57
-11
lines changed

5 files changed

+57
-11
lines changed

Diff for: src/mcp_server_qdrant/embeddings/base.py

+5
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ async def embed_documents(self, documents: List[str]) -> List[List[float]]:
1414
async def embed_query(self, query: str) -> List[float]:
1515
"""Embed a query into a vector."""
1616
pass
17+
18+
@abstractmethod
19+
def get_vector_name(self) -> str:
20+
"""Get the name of the vector for the Qdrant collection."""
21+
pass

Diff for: src/mcp_server_qdrant/embeddings/fastembed.py

+8
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,11 @@ async def embed_query(self, query: str) -> List[float]:
3535
None, lambda: list(self.embedding_model.query_embed([query]))
3636
)
3737
return embeddings[0].tolist()
38+
39+
def get_vector_name(self) -> str:
40+
"""
41+
Return the name of the vector for the Qdrant collection.
42+
Important: This is compatible with the FastEmbed logic used before 0.6.0.
43+
"""
44+
model_name = self.embedding_model.model_name.split("/")[-1].lower()
45+
return f"fast-{model_name}"

Diff for: src/mcp_server_qdrant/qdrant.py

+14-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import uuid
12
from typing import Optional
23

34
from qdrant_client import AsyncQdrantClient, models
@@ -40,12 +41,16 @@ async def _ensure_collection_exists(self):
4041
sample_vector = await self._embedding_provider.embed_query("sample text")
4142
vector_size = len(sample_vector)
4243

44+
# Use the vector name as defined in the embedding provider
45+
vector_name = self._embedding_provider.get_vector_name()
4346
await self._client.create_collection(
4447
collection_name=self._collection_name,
45-
vectors_config=models.VectorParams(
46-
size=vector_size,
47-
distance=models.Distance.COSINE,
48-
),
48+
vectors_config={
49+
vector_name: models.VectorParams(
50+
size=vector_size,
51+
distance=models.Distance.COSINE,
52+
)
53+
},
4954
)
5055

5156
async def store_memory(self, information: str):
@@ -59,12 +64,13 @@ async def store_memory(self, information: str):
5964
embeddings = await self._embedding_provider.embed_documents([information])
6065

6166
# Add to Qdrant
67+
vector_name = self._embedding_provider.get_vector_name()
6268
await self._client.upsert(
6369
collection_name=self._collection_name,
6470
points=[
6571
models.PointStruct(
66-
id=hash(information), # Simple hash as ID
67-
vector=embeddings[0],
72+
id=uuid.uuid4().hex,
73+
vector={vector_name: embeddings[0]},
6874
payload={"document": information},
6975
)
7076
],
@@ -82,11 +88,12 @@ async def find_memories(self, query: str) -> list[str]:
8288

8389
# Embed the query
8490
query_vector = await self._embedding_provider.embed_query(query)
91+
vector_name = self._embedding_provider.get_vector_name()
8592

8693
# Search in Qdrant
8794
search_results = await self._client.search(
8895
collection_name=self._collection_name,
89-
query_vector=query_vector,
96+
query_vector=models.NamedVector(name=vector_name, vector=query_vector),
9097
limit=10,
9198
)
9299

Diff for: src/mcp_server_qdrant/server.py

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
import importlib.metadata
23
from typing import Optional
34

45
import click
@@ -11,6 +12,15 @@
1112
from .qdrant import QdrantConnector
1213

1314

15+
def get_package_version() -> str:
16+
"""Get the package version using importlib.metadata."""
17+
try:
18+
return importlib.metadata.version("mcp-server-qdrant")
19+
except importlib.metadata.PackageNotFoundError:
20+
# Fall back to a default version if package is not installed
21+
return "0.0.0"
22+
23+
1424
def serve(
1525
qdrant_url: Optional[str],
1626
qdrant_api_key: Optional[str],
@@ -140,6 +150,13 @@ async def handle_tool_call(
140150
required=True,
141151
help="Collection name",
142152
)
153+
@click.option(
154+
"--fastembed-model-name",
155+
envvar="FASTEMBED_MODEL_NAME",
156+
required=False,
157+
help="FastEmbed model name",
158+
default="sentence-transformers/all-MiniLM-L6-v2",
159+
)
143160
@click.option(
144161
"--embedding-provider",
145162
envvar="EMBEDDING_PROVIDER",
@@ -165,6 +182,7 @@ def main(
165182
qdrant_url: Optional[str],
166183
qdrant_api_key: str,
167184
collection_name: Optional[str],
185+
fastembed_model_name: Optional[str],
168186
embedding_provider: str,
169187
embedding_model: str,
170188
qdrant_local_path: Optional[str],
@@ -175,6 +193,14 @@ def main(
175193
"Exactly one of qdrant-url or qdrant-local-path must be provided"
176194
)
177195

196+
# Warn if fastembed_model_name is provided, as this is going to be deprecated
197+
if fastembed_model_name:
198+
click.echo(
199+
"Warning: --fastembed-model-name parameter is deprecated and will be removed in a future version. "
200+
"Please use --embedding-provider and --embedding-model instead",
201+
err=True,
202+
)
203+
178204
async def _run():
179205
async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
180206
server = serve(
@@ -190,7 +216,7 @@ async def _run():
190216
write_stream,
191217
InitializationOptions(
192218
server_name="qdrant",
193-
server_version="0.5.1",
219+
server_version=get_package_version(),
194220
capabilities=server.get_capabilities(
195221
notification_options=NotificationOptions(),
196222
experimental_capabilities={},

Diff for: uv.lock

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)