Handle parameters with environmental variables only (#24)
* Switch to Typer to read the CLI parameters and options * Rely on environmental variables only * Fix tests * Update README
This commit is contained in:
106
README.md
106
README.md
@@ -1,7 +1,10 @@
|
|||||||
# mcp-server-qdrant: A Qdrant MCP server
|
# mcp-server-qdrant: A Qdrant MCP server
|
||||||
[](https://smithery.ai/protocol/mcp-server-qdrant)
|
[](https://smithery.ai/protocol/mcp-server-qdrant)
|
||||||
|
|
||||||
> The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open protocol that enables seamless integration between LLM applications and external data sources and tools. Whether you’re building an AI-powered IDE, enhancing a chat interface, or creating custom AI workflows, MCP provides a standardized way to connect LLMs with the context they need.
|
> The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open protocol that enables
|
||||||
|
> seamless integration between LLM applications and external data sources and tools. Whether you’re building an
|
||||||
|
> AI-powered IDE, enhancing a chat interface, or creating custom AI workflows, MCP provides a standardized way to
|
||||||
|
> connect LLMs with the context they need.
|
||||||
|
|
||||||
This repository is an example of how to create a MCP server for [Qdrant](https://qdrant.tech/), a vector search engine.
|
This repository is an example of how to create a MCP server for [Qdrant](https://qdrant.tech/), a vector search engine.
|
||||||
|
|
||||||
@@ -27,18 +30,18 @@ It acts as a semantic memory layer on top of the Qdrant database.
|
|||||||
- `query` (string): Query to retrieve a memory
|
- `query` (string): Query to retrieve a memory
|
||||||
- Returns: Memories stored in the Qdrant database as separate messages
|
- Returns: Memories stored in the Qdrant database as separate messages
|
||||||
|
|
||||||
## Installation
|
## Installation in Claude Desktop
|
||||||
|
|
||||||
### Using uv (recommended)
|
### Using mcp (recommended)
|
||||||
|
|
||||||
When using [`uv`](https://docs.astral.sh/uv/) no specific installation is needed to directly run *mcp-server-qdrant*.
|
When using [`mcp`](https://github.com/modelcontextprotocol/python-sdk) no specific installation is needed to directly run *mcp-server-qdrant*.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
uv run mcp-server-qdrant \
|
mcp install src/mcp_server_qdrant/server.py \
|
||||||
--qdrant-url "http://localhost:6333" \
|
-v QDRANT_URL="http://localhost:6333" \
|
||||||
--qdrant-api-key "your_api_key" \
|
-v QDRANT_API_KEY="your_api_key" \
|
||||||
--collection-name "my_collection" \
|
-v COLLECTION_NAME="my_collection" \
|
||||||
--embedding-model "sentence-transformers/all-MiniLM-L6-v2"
|
-v EMBEDDING_MODEL="sentence-transformers/all-MiniLM-L6-v2"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Installing via Smithery
|
### Installing via Smithery
|
||||||
@@ -49,70 +52,68 @@ To install Qdrant MCP Server for Claude Desktop automatically via [Smithery](htt
|
|||||||
npx @smithery/cli install mcp-server-qdrant --client claude
|
npx @smithery/cli install mcp-server-qdrant --client claude
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage with Claude Desktop
|
### Manual configuration
|
||||||
|
|
||||||
To use this server with the Claude Desktop app, add the following configuration to the "mcpServers" section of your `claude_desktop_config.json`:
|
To use this server with the Claude Desktop app, add the following configuration to the "mcpServers" section of your
|
||||||
|
`claude_desktop_config.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"qdrant": {
|
"qdrant": {
|
||||||
"command": "uvx",
|
"command": "uvx",
|
||||||
"args": [
|
"args": ["mcp-server-qdrant"],
|
||||||
"mcp-server-qdrant",
|
"env": {
|
||||||
"--qdrant-url",
|
"QDRANT_URL": "http://localhost:6333",
|
||||||
"http://localhost:6333",
|
"QDRANT_API_KEY": "your_api_key",
|
||||||
"--qdrant-api-key",
|
"COLLECTION_NAME": "your_collection_name",
|
||||||
"your_api_key",
|
"EMBEDDING_MODEL": "sentence-transformers/all-MiniLM-L6-v2"
|
||||||
"--collection-name",
|
}
|
||||||
"your_collection_name"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace `http://localhost:6333`, `your_api_key` and `your_collection_name` with your Qdrant server URL, Qdrant API key
|
For local Qdrant mode:
|
||||||
and collection name, respectively. The use of API key is optional, but recommended for security reasons, and depends on
|
|
||||||
the Qdrant server configuration.
|
```json
|
||||||
|
{
|
||||||
|
"qdrant": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": ["mcp-server-qdrant"],
|
||||||
|
"env": {
|
||||||
|
"QDRANT_LOCAL_PATH": "/path/to/qdrant/database",
|
||||||
|
"COLLECTION_NAME": "your_collection_name",
|
||||||
|
"EMBEDDING_MODEL": "sentence-transformers/all-MiniLM-L6-v2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
This MCP server will automatically create a collection with the specified name if it doesn't exist.
|
This MCP server will automatically create a collection with the specified name if it doesn't exist.
|
||||||
|
|
||||||
By default, the server will use the `sentence-transformers/all-MiniLM-L6-v2` embedding model to encode memories.
|
By default, the server will use the `sentence-transformers/all-MiniLM-L6-v2` embedding model to encode memories.
|
||||||
For the time being, only [FastEmbed](https://qdrant.github.io/fastembed/) models are supported, and you can change it
|
For the time being, only [FastEmbed](https://qdrant.github.io/fastembed/) models are supported.
|
||||||
by passing the `--embedding-model` argument to the server.
|
|
||||||
|
|
||||||
### Using the local mode of Qdrant
|
### Support for other tools
|
||||||
|
|
||||||
To use a local mode of Qdrant, you can specify the path to the database using the `--qdrant-local-path` argument:
|
This MCP server can be used with any MCP-compatible client. For example, you can use it with
|
||||||
|
[Cursor](https://docs.cursor.com/context/model-context-protocol), which provides built-in support for the Model Context
|
||||||
```json
|
Protocol.
|
||||||
{
|
|
||||||
"qdrant": {
|
|
||||||
"command": "uvx",
|
|
||||||
"args": [
|
|
||||||
"mcp-server-qdrant",
|
|
||||||
"--qdrant-local-path",
|
|
||||||
"/path/to/qdrant/database",
|
|
||||||
"--collection-name",
|
|
||||||
"your_collection_name"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
It will run Qdrant local mode inside the same process as the MCP server. Although it is not recommended for production.
|
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
||||||
The configuration of the server can be also done using environment variables:
|
The configuration of the server is done using environment variables:
|
||||||
|
|
||||||
- `QDRANT_URL`: URL of the Qdrant server, e.g. `http://localhost:6333`
|
- `QDRANT_URL`: URL of the Qdrant server, e.g. `http://localhost:6333`
|
||||||
- `QDRANT_API_KEY`: API key for the Qdrant server
|
- `QDRANT_API_KEY`: API key for the Qdrant server (optional, depends on Qdrant server configuration)
|
||||||
- `COLLECTION_NAME`: Name of the collection to use
|
- `COLLECTION_NAME`: Name of the collection to use (required)
|
||||||
- `EMBEDDING_MODEL`: Name of the embedding model to use
|
- `EMBEDDING_MODEL`: Name of the embedding model to use (default: `sentence-transformers/all-MiniLM-L6-v2`)
|
||||||
- `EMBEDDING_PROVIDER`: Embedding provider to use (currently only "fastembed" is supported)
|
- `EMBEDDING_PROVIDER`: Embedding provider to use (currently only "fastembed" is supported)
|
||||||
- `QDRANT_LOCAL_PATH`: Path to the local Qdrant database
|
- `QDRANT_LOCAL_PATH`: Path to the local Qdrant database (alternative to `QDRANT_URL`)
|
||||||
|
|
||||||
You cannot provide `QDRANT_URL` and `QDRANT_LOCAL_PATH` at the same time.
|
Note: You cannot provide both `QDRANT_URL` and `QDRANT_LOCAL_PATH` at the same time.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> Command-line arguments are not supported anymore! Please use environment variables for all configuration.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -126,9 +127,8 @@ servers. It runs both a client UI (default port 5173) and an MCP proxy server (d
|
|||||||
your browser to use the inspector.
|
your browser to use the inspector.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
npx @modelcontextprotocol/inspector uv run mcp-server-qdrant \
|
QDRANT_URL=":memory:" COLLECTION_NAME="test" \
|
||||||
--collection-name test \
|
mcp dev src/mcp_server_qdrant/server.py
|
||||||
--qdrant-local-path /tmp/qdrant-local-test
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Once started, open your browser to http://localhost:5173 to access the inspector interface.
|
Once started, open your browser to http://localhost:5173 to access the inspector interface.
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ dependencies = [
|
|||||||
"mcp[cli]>=1.3.0",
|
"mcp[cli]>=1.3.0",
|
||||||
"fastembed>=0.6.0",
|
"fastembed>=0.6.0",
|
||||||
"qdrant-client>=1.12.0",
|
"qdrant-client>=1.12.0",
|
||||||
"typer>=0.15.2",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
@@ -26,7 +25,7 @@ dev-dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
mcp-server-qdrant = "mcp_server_qdrant:main"
|
mcp-server-qdrant = "mcp_server_qdrant.main:main"
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
testpaths = ["tests"]
|
testpaths = ["tests"]
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
from . import server
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Main entry point for the package."""
|
|
||||||
server.mcp.run()
|
|
||||||
|
|
||||||
|
|
||||||
# Optionally expose other important items at package level
|
|
||||||
__all__ = ["main", "server"]
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
from .base import EmbeddingProvider
|
|
||||||
from .factory import create_embedding_provider
|
|
||||||
from .fastembed import FastEmbedProvider
|
|
||||||
|
|
||||||
__all__ = ["EmbeddingProvider", "FastEmbedProvider", "create_embedding_provider"]
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from mcp_server_qdrant.embeddings import EmbeddingProvider
|
from mcp_server_qdrant.embeddings import EmbeddingProvider
|
||||||
|
from mcp_server_qdrant.embeddings.types import EmbeddingProviderType
|
||||||
from mcp_server_qdrant.settings import EmbeddingProviderSettings
|
from mcp_server_qdrant.settings import EmbeddingProviderSettings
|
||||||
|
|
||||||
|
|
||||||
@@ -8,7 +9,7 @@ def create_embedding_provider(settings: EmbeddingProviderSettings) -> EmbeddingP
|
|||||||
:param settings: The settings for the embedding provider.
|
:param settings: The settings for the embedding provider.
|
||||||
:return: An instance of the specified embedding provider.
|
:return: An instance of the specified embedding provider.
|
||||||
"""
|
"""
|
||||||
if settings.provider_type.lower() == "fastembed":
|
if settings.provider_type == EmbeddingProviderType.FASTEMBED:
|
||||||
from mcp_server_qdrant.embeddings.fastembed import FastEmbedProvider
|
from mcp_server_qdrant.embeddings.fastembed import FastEmbedProvider
|
||||||
|
|
||||||
return FastEmbedProvider(settings.model_name)
|
return FastEmbedProvider(settings.model_name)
|
||||||
|
|||||||
5
src/mcp_server_qdrant/embeddings/types.py
Normal file
5
src/mcp_server_qdrant/embeddings/types.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class EmbeddingProviderType(Enum):
|
||||||
|
FASTEMBED = "fastembed"
|
||||||
9
src/mcp_server_qdrant/main.py
Normal file
9
src/mcp_server_qdrant/main.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
from mcp_server_qdrant.server import mcp
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""
|
||||||
|
Main entry point for the mcp-server-qdrant script defined
|
||||||
|
in pyproject.toml. It runs the MCP server.
|
||||||
|
"""
|
||||||
|
mcp.run()
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from typing import AsyncIterator, List
|
from typing import AsyncIterator, List
|
||||||
|
|
||||||
@@ -8,27 +7,18 @@ from mcp.server.fastmcp import Context, FastMCP
|
|||||||
|
|
||||||
from mcp_server_qdrant.embeddings.factory import create_embedding_provider
|
from mcp_server_qdrant.embeddings.factory import create_embedding_provider
|
||||||
from mcp_server_qdrant.qdrant import QdrantConnector
|
from mcp_server_qdrant.qdrant import QdrantConnector
|
||||||
from mcp_server_qdrant.settings import (
|
from mcp_server_qdrant.settings import EmbeddingProviderSettings, QdrantSettings
|
||||||
EmbeddingProviderSettings,
|
|
||||||
QdrantSettings,
|
|
||||||
parse_args,
|
|
||||||
)
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Parse command line arguments and set them as environment variables.
|
|
||||||
# This is done for backwards compatibility with the previous versions
|
|
||||||
# of the MCP server.
|
|
||||||
env_vars = parse_args()
|
|
||||||
for key, value in env_vars.items():
|
|
||||||
os.environ[key] = value
|
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def server_lifespan(server: Server) -> AsyncIterator[dict]: # noqa
|
async def server_lifespan(server: Server) -> AsyncIterator[dict]: # noqa
|
||||||
"""
|
"""
|
||||||
Context manager to handle the lifespan of the server.
|
Context manager to handle the lifespan of the server.
|
||||||
This is used to configure the embedding provider and Qdrant connector.
|
This is used to configure the embedding provider and Qdrant connector.
|
||||||
|
All the configuration is now loaded from the environment variables.
|
||||||
|
Settings handle that for us.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Embedding provider is created with a factory function so we can add
|
# Embedding provider is created with a factory function so we can add
|
||||||
@@ -63,7 +53,7 @@ async def server_lifespan(server: Server) -> AsyncIterator[dict]: # noqa
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
mcp = FastMCP("Qdrant", lifespan=server_lifespan)
|
mcp = FastMCP("mcp-server-qdrant", lifespan=server_lifespan)
|
||||||
|
|
||||||
|
|
||||||
@mcp.tool(
|
@mcp.tool(
|
||||||
@@ -116,7 +106,3 @@ async def find(query: str, ctx: Context) -> List[str]:
|
|||||||
for entry in entries:
|
for entry in entries:
|
||||||
content.append(f"<entry>{entry}</entry>")
|
content.append(f"<entry>{entry}</entry>")
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
mcp.run()
|
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
import argparse
|
from typing import Optional
|
||||||
from typing import Any, Dict, Optional
|
|
||||||
|
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
from pydantic_settings import BaseSettings
|
from pydantic_settings import BaseSettings
|
||||||
|
|
||||||
|
from mcp_server_qdrant.embeddings.types import EmbeddingProviderType
|
||||||
|
|
||||||
|
|
||||||
class EmbeddingProviderSettings(BaseSettings):
|
class EmbeddingProviderSettings(BaseSettings):
|
||||||
"""
|
"""
|
||||||
Configuration for the embedding provider.
|
Configuration for the embedding provider.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
provider_type: str = Field(
|
provider_type: EmbeddingProviderType = Field(
|
||||||
default="fastembed", validation_alias="EMBEDDING_PROVIDER"
|
default=EmbeddingProviderType.FASTEMBED,
|
||||||
|
validation_alias="EMBEDDING_PROVIDER",
|
||||||
)
|
)
|
||||||
model_name: str = Field(
|
model_name: str = Field(
|
||||||
default="sentence-transformers/all-MiniLM-L6-v2",
|
default="sentence-transformers/all-MiniLM-L6-v2",
|
||||||
@@ -36,66 +38,3 @@ class QdrantSettings(BaseSettings):
|
|||||||
Get the Qdrant location, either the URL or the local path.
|
Get the Qdrant location, either the URL or the local path.
|
||||||
"""
|
"""
|
||||||
return self.location or self.local_path
|
return self.location or self.local_path
|
||||||
|
|
||||||
|
|
||||||
def parse_args() -> Dict[str, Any]:
|
|
||||||
"""
|
|
||||||
Parse command line arguments for the MCP server.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dict[str, Any]: Dictionary of parsed arguments
|
|
||||||
"""
|
|
||||||
parser = argparse.ArgumentParser(description="Qdrant MCP Server")
|
|
||||||
|
|
||||||
# Qdrant connection options
|
|
||||||
connection_group = parser.add_mutually_exclusive_group()
|
|
||||||
connection_group.add_argument(
|
|
||||||
"--qdrant-url",
|
|
||||||
help="URL of the Qdrant server, e.g. http://localhost:6333",
|
|
||||||
)
|
|
||||||
connection_group.add_argument(
|
|
||||||
"--qdrant-local-path",
|
|
||||||
help="Path to the local Qdrant database",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Other Qdrant settings
|
|
||||||
parser.add_argument(
|
|
||||||
"--qdrant-api-key",
|
|
||||||
help="API key for the Qdrant server",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--collection-name",
|
|
||||||
help="Name of the collection to use",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Embedding settings
|
|
||||||
parser.add_argument(
|
|
||||||
"--embedding-provider",
|
|
||||||
help="Embedding provider to use (currently only 'fastembed' is supported)",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--embedding-model",
|
|
||||||
help="Name of the embedding model to use",
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# Convert to dictionary and filter out None values
|
|
||||||
args_dict = {k: v for k, v in vars(args).items() if v is not None}
|
|
||||||
|
|
||||||
# Convert argument names to environment variable format
|
|
||||||
env_vars = {}
|
|
||||||
if "qdrant_url" in args_dict:
|
|
||||||
env_vars["QDRANT_URL"] = args_dict["qdrant_url"]
|
|
||||||
if "qdrant_api_key" in args_dict:
|
|
||||||
env_vars["QDRANT_API_KEY"] = args_dict["qdrant_api_key"]
|
|
||||||
if "collection_name" in args_dict:
|
|
||||||
env_vars["COLLECTION_NAME"] = args_dict["collection_name"]
|
|
||||||
if "embedding_model" in args_dict:
|
|
||||||
env_vars["EMBEDDING_MODEL"] = args_dict["embedding_model"]
|
|
||||||
if "embedding_provider" in args_dict:
|
|
||||||
env_vars["EMBEDDING_PROVIDER"] = args_dict["embedding_provider"]
|
|
||||||
if "qdrant_local_path" in args_dict:
|
|
||||||
env_vars["QDRANT_LOCAL_PATH"] = args_dict["qdrant_local_path"]
|
|
||||||
|
|
||||||
return env_vars
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from mcp_server_qdrant.embeddings.types import EmbeddingProviderType
|
||||||
from mcp_server_qdrant.settings import EmbeddingProviderSettings, QdrantSettings
|
from mcp_server_qdrant.settings import EmbeddingProviderSettings, QdrantSettings
|
||||||
|
|
||||||
|
|
||||||
@@ -47,15 +48,15 @@ class TestEmbeddingProviderSettings:
|
|||||||
def test_default_values(self):
|
def test_default_values(self):
|
||||||
"""Test default values are set correctly."""
|
"""Test default values are set correctly."""
|
||||||
settings = EmbeddingProviderSettings()
|
settings = EmbeddingProviderSettings()
|
||||||
assert settings.provider_type == "fastembed"
|
assert settings.provider_type == EmbeddingProviderType.FASTEMBED
|
||||||
assert settings.model_name == "sentence-transformers/all-MiniLM-L6-v2"
|
assert settings.model_name == "sentence-transformers/all-MiniLM-L6-v2"
|
||||||
|
|
||||||
@patch.dict(
|
@patch.dict(
|
||||||
os.environ,
|
os.environ,
|
||||||
{"EMBEDDING_PROVIDER": "custom_provider", "EMBEDDING_MODEL": "custom_model"},
|
{"EMBEDDING_MODEL": "custom_model"},
|
||||||
)
|
)
|
||||||
def test_custom_values(self):
|
def test_custom_values(self):
|
||||||
"""Test loading custom values from environment variables."""
|
"""Test loading custom values from environment variables."""
|
||||||
settings = EmbeddingProviderSettings()
|
settings = EmbeddingProviderSettings()
|
||||||
assert settings.provider_type == "custom_provider"
|
assert settings.provider_type == EmbeddingProviderType.FASTEMBED
|
||||||
assert settings.model_name == "custom_model"
|
assert settings.model_name == "custom_model"
|
||||||
|
|||||||
2
uv.lock
generated
2
uv.lock
generated
@@ -498,7 +498,6 @@ dependencies = [
|
|||||||
{ name = "fastembed" },
|
{ name = "fastembed" },
|
||||||
{ name = "mcp", extra = ["cli"] },
|
{ name = "mcp", extra = ["cli"] },
|
||||||
{ name = "qdrant-client" },
|
{ name = "qdrant-client" },
|
||||||
{ name = "typer" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dev-dependencies]
|
[package.dev-dependencies]
|
||||||
@@ -515,7 +514,6 @@ requires-dist = [
|
|||||||
{ name = "fastembed", specifier = ">=0.6.0" },
|
{ name = "fastembed", specifier = ">=0.6.0" },
|
||||||
{ name = "mcp", extras = ["cli"], specifier = ">=1.3.0" },
|
{ name = "mcp", extras = ["cli"], specifier = ">=1.3.0" },
|
||||||
{ name = "qdrant-client", specifier = ">=1.12.0" },
|
{ name = "qdrant-client", specifier = ">=1.12.0" },
|
||||||
{ name = "typer", specifier = ">=0.15.2" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata.requires-dev]
|
[package.metadata.requires-dev]
|
||||||
|
|||||||
Reference in New Issue
Block a user