Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
FROM python:3.11-slim
FROM python:3.13-slim

WORKDIR /app
# Copy uv from official image
COPY --from=ghcr.io/astral-sh/uv:0.8.3 /uv /uvx /bin/

# Install uv for package management
RUN pip install --no-cache-dir uv
WORKDIR /app

# Install the mcp-server-qdrant package
RUN uv pip install --system --no-cache-dir mcp-server-qdrant
RUN uv tool install --no-cache mcp-server-qdrant

# Expose the default port for SSE transport
EXPOSE 8000
Expand All @@ -16,6 +16,7 @@ ENV QDRANT_URL=""
ENV QDRANT_API_KEY=""
ENV COLLECTION_NAME="default-collection"
ENV EMBEDDING_MODEL="sentence-transformers/all-MiniLM-L6-v2"
ENV FASTMCP_HOST="0.0.0.0"

# Run the server with SSE transport
CMD uvx mcp-server-qdrant --transport sse
CMD ["uvx", "--no-cache", "mcp-server-qdrant", "--transport", "sse"]
25 changes: 25 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.PHONY: up down logs ps rebuild clean

# Launch containers in detached mode
up:
docker compose up -d --build

# Stop and remove containers
down:
docker compose down

# Stream logs from the mcp-server-qdrant service
logs:
docker compose logs -f mcp-server-qdrant

# Display active container status
ps:
docker compose ps

# Rebuild the mcp-server-qdrant image without cache
rebuild:
docker compose build --no-cache mcp-server-qdrant

# Terminate containers and remove volumes
clean:
docker compose down -v
217 changes: 201 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,90 @@ It acts as a semantic memory layer on top of the Qdrant database.
- Input:
- `information` (string): Information to store
- `metadata` (JSON): Optional metadata to store
- `collection_name` (string): Name of the collection to store the information in. This field is required if there are no default collection name.
If there is a default collection name, this field is not enabled.
- `collection_name` (string, optional): Name of the collection to store the information in
- Returns: Confirmation message

2. `qdrant-find`
- Retrieve relevant information from the Qdrant database
- Retrieve relevant information from the Qdrant database using semantic search
- Input:
- `query` (string): Query to use for searching
- `collection_name` (string): Name of the collection to store the information in. This field is required if there are no default collection name.
If there is a default collection name, this field is not enabled.
- `collection_name` (string, optional): Name of the collection to search in
- Returns: Information stored in the Qdrant database as separate messages

3. `qdrant-hybrid-find`
- Retrieve information using hybrid search (combining dense and sparse vectors)
- Input:
- `query` (string): Query to use for searching
- `collection_name` (string, optional): Name of the collection to search in
- `fusion_method` (string): Fusion method - 'rrf' or 'dbsf' (default: 'rrf')
- `dense_limit` (int): Limit for dense vector prefetch (default: 10)
- `sparse_limit` (int): Limit for sparse vector prefetch (default: 10)
- `final_limit` (int): Final limit after fusion (default: 10)
- Returns: Hybrid search results

4. `qdrant-get-point`
- Retrieve a specific point by ID from a collection
- Input:
- `point_id` (string): The ID of the point to retrieve
- `collection_name` (string, optional): Name of the collection
- Returns: Point data with content and metadata

5. `qdrant-delete-point`
- Delete a specific point by ID from a collection
- Input:
- `point_id` (string): The ID of the point to delete
- `collection_name` (string, optional): Name of the collection
- Returns: Confirmation message

6. `qdrant-update-point-payload`
- Update the metadata/payload for a specific point
- Input:
- `point_id` (string): The ID of the point to update
- `metadata` (JSON): The new metadata to set
- `collection_name` (string, optional): Name of the collection
- Returns: Confirmation message

7. `qdrant-list-points`
- List points in a collection with pagination
- Input:
- `collection_name` (string, optional): Name of the collection
- `limit` (int): Maximum number of points to return (default: 10)
- `offset` (int): Number of points to skip (default: 0)
- Returns: List of points with IDs, content, and metadata

8. `qdrant-get-collections`
- List all available collections in Qdrant
- Returns: List of collection names

9. `qdrant-get-collection-details`
- Get detailed information about a specific collection
- Input:
- `collection_name` (string): Name of the collection
- Returns: Collection details including status, vector count, and configuration

## Environment Variables

The configuration of the server is done using environment variables:

| Name | Description | Default Value |
|--------------------------|---------------------------------------------------------------------|-------------------------------------------------------------------|
| `QDRANT_URL` | URL of the Qdrant server | None |
| `QDRANT_API_KEY` | API key for the Qdrant server | None |
| `COLLECTION_NAME` | Name of the default collection to use. | None |
| `QDRANT_LOCAL_PATH` | Path to the local Qdrant database (alternative to `QDRANT_URL`) | None |
| `EMBEDDING_PROVIDER` | Embedding provider to use (currently only "fastembed" is supported) | `fastembed` |
| `EMBEDDING_MODEL` | Name of the embedding model to use | `sentence-transformers/all-MiniLM-L6-v2` |
| `TOOL_STORE_DESCRIPTION` | Custom description for the store tool | See default in [`settings.py`](src/mcp_server_qdrant/settings.py) |
| `TOOL_FIND_DESCRIPTION` | Custom description for the find tool | See default in [`settings.py`](src/mcp_server_qdrant/settings.py) |
| Name | Description | Default Value |
|---------------------------------|---------------------------------------------------------------------|-------------------------------------------------------------------|
| `QDRANT_URL` | URL of the Qdrant server | None |
| `QDRANT_API_KEY` | API key for the Qdrant server | None |
| `COLLECTION_NAME` | Name of the default collection to use | None |
| `COLLECTION_NAMES` | List of collection names for multiple collections support | None |
| `QDRANT_LOCAL_PATH` | Path to the local Qdrant database (alternative to `QDRANT_URL`) | None |
| `QDRANT_READ_ONLY` | Enable read-only mode (disables write operations) | `false` |
| `EMBEDDING_PROVIDER` | Embedding provider: "fastembed", "model2vec", "oai_compat", or "gemini" | `fastembed` |
| `EMBEDDING_MODEL` | Name of the embedding model to use | `sentence-transformers/all-MiniLM-L6-v2` |
| `USE_UNNAMED_VECTORS` | Use Qdrant's unnamed vector field instead of named vectors | `false` |
| `SPARSE_EMBEDDING_MODEL` | Sparse embedding model for hybrid search | None |
| `OAI_COMPAT_ENDPOINT` | OpenAI-compatible API endpoint URL | `https://api.openai.com/v1` |
| `OAI_COMPAT_API_KEY` | API key for OpenAI-compatible endpoint | None |
| `OAI_COMPAT_VEC_SIZE` | Vector size override for OpenAI-compatible embeddings | None (auto-detected) |
| `GEMINI_API_KEY` | API key for Google Gemini embeddings | None |
| `TOOL_STORE_DESCRIPTION` | Custom description for the store tool | See default in [`settings.py`](src/mcp_server_qdrant/settings.py) |
| `TOOL_FIND_DESCRIPTION` | Custom description for the find tool | See default in [`settings.py`](src/mcp_server_qdrant/settings.py) |
| `TOOL_HYBRID_FIND_DESCRIPTION` | Custom description for the hybrid find tool | See default in [`settings.py`](src/mcp_server_qdrant/settings.py) |

Note: You cannot provide both `QDRANT_URL` and `QDRANT_LOCAL_PATH` at the same time.

Expand Down Expand Up @@ -179,7 +238,133 @@ For local Qdrant mode:
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.
For the time being, only [FastEmbed](https://qdrant.github.io/fastembed/) models are supported.

### Embedding Providers

The server supports multiple embedding providers:

1. **FastEmbed** (default) - Local embedding models via [FastEmbed](https://qdrant.github.io/fastembed/)
2. **Model2Vec** - Fast, lightweight static embeddings
3. **OpenAI-compatible** - Any OpenAI-compatible API endpoint
4. **Gemini** - Google's Gemini embedding models

#### Using Model2Vec

To use Model2Vec embeddings:

```shell
QDRANT_URL="http://localhost:6333" \
COLLECTION_NAME="my-collection" \
EMBEDDING_PROVIDER="model2vec" \
EMBEDDING_MODEL="minishlab/potion-base-8M" \
uvx mcp-server-qdrant
```

Popular Model2Vec models:
- `minishlab/potion-base-8M` - Efficient 8M parameter model
- `minishlab/potion-base-4M` - Compact 4M parameter model
- `minishlab/M2V_base_output` - Base output model

#### Using OpenAI-Compatible Embeddings

To use OpenAI or compatible API:

```shell
QDRANT_URL="http://localhost:6333" \
COLLECTION_NAME="my-collection" \
EMBEDDING_PROVIDER="oai_compat" \
EMBEDDING_MODEL="text-embedding-3-small" \
OAI_COMPAT_API_KEY="your-api-key" \
uvx mcp-server-qdrant
```

#### Using Google Gemini Embeddings

To use Google's Gemini embedding models:

```shell
QDRANT_URL="http://localhost:6333" \
COLLECTION_NAME="my-collection" \
EMBEDDING_PROVIDER="gemini" \
EMBEDDING_MODEL="text-embedding-004" \
GEMINI_API_KEY="your-gemini-api-key" \
uvx mcp-server-qdrant
```

The Gemini provider supports text-embedding-004 (768 dimensions) and other Gemini embedding models.

### Using Unnamed Vectors

Qdrant supports unnamed vectors as a simpler alternative to named vectors. To enable:

```shell
QDRANT_URL="http://localhost:6333" \
COLLECTION_NAME="my-collection" \
USE_UNNAMED_VECTORS="true" \
uvx mcp-server-qdrant
```

### Multiple Collections

You can configure the server to work with multiple collections by setting `COLLECTION_NAMES`:

```shell
QDRANT_URL="http://localhost:6333" \
COLLECTION_NAMES='["collection1", "collection2", "collection3"]' \
uvx mcp-server-qdrant
```

When using multiple collections, the `collection_name` parameter becomes available in all tools.

### Claude Desktop Configuration Example for Multiple Collections

```json
{
"qdrant": {
"command": "uvx",
"args": ["mcp-server-qdrant"],
"env": {
"QDRANT_URL": "https://xyz-example.eu-central.aws.cloud.qdrant.io:6333",
"QDRANT_API_KEY": "your_api_key",
"COLLECTION_NAMES": "[\"personal\", \"work\", \"research\"]",
"EMBEDDING_MODEL": "sentence-transformers/all-MiniLM-L6-v2"
}
}
}
```

### Hybrid Search

The server supports hybrid search combining dense and sparse vectors for improved accuracy. This requires configuring sparse embeddings in your Qdrant collection. The `qdrant-hybrid-find` tool supports two fusion methods:

- **RRF** (Reciprocal Rank Fusion) - Default method
- **DBSF** (Distribution-Based Score Fusion) - Alternative fusion strategy

## Docker Development

### Using Docker Compose

A `docker-compose.yml` file is provided for easy development:

```shell
make up # Start containers
make logs # View logs
make down # Stop containers
make clean # Remove containers and volumes
```

The compose file connects to an external `qdrantnet` network. Make sure you have a Qdrant instance running on this network.

### Makefile Commands

The provided `Makefile` includes convenient shortcuts:

- `make up` - Launch containers in detached mode
- `make down` - Stop and remove containers
- `make logs` - Stream logs from the mcp-server-qdrant service
- `make ps` - Display active container status
- `make rebuild` - Rebuild without cache
- `make clean` - Terminate containers and remove volumes

## Support for other tools

Expand Down
24 changes: 24 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: '3.8'

services:
mcp-server-qdrant:
build:
context: .
dockerfile: Dockerfile
image: mcp-server-qdrant:local
container_name: mcp-server-qdrant
environment:
FASTMCP_HOST: "0.0.0.0"
QDRANT_URL: "http://qdrant:6333"
COLLECTION_NAME: "qdrantdb"
EMBEDDING_MODEL: "sentence-transformers/all-MiniLM-L6-v2"
ports:
- "8000:8000"
command: ["uvx", "mcp-server-qdrant", "--transport", "streamable-http"]
restart: unless-stopped
networks:
- qdrantnet

networks:
qdrantnet:
external: true
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ dependencies = [
"qdrant-client>=1.12.0",
"pydantic>=2.10.6",
"fastmcp>=2.7.0",
"model2vec==0.6.0",
"openai>=1.109.1",
"google-generativeai>=0.8.3",
]

[build-system]
Expand Down
10 changes: 10 additions & 0 deletions src/mcp_server_qdrant/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""
Entry point for running mcp_server_qdrant as a module.

Usage: python -m mcp_server_qdrant
"""

from mcp_server_qdrant.main import main

if __name__ == "__main__":
main()
21 changes: 21 additions & 0 deletions src/mcp_server_qdrant/embeddings/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
Embeddings package with lazy imports for different embedding providers.
"""

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from mcp_server_qdrant.embeddings.fastembed import FastEmbedProvider
from mcp_server_qdrant.embeddings.model2vec import Model2VecProvider

from mcp_server_qdrant.embeddings.base import EmbeddingProvider
from mcp_server_qdrant.embeddings.factory import create_embedding_provider
from mcp_server_qdrant.embeddings.types import EmbeddingProviderType

__all__ = [
"EmbeddingProvider",
"EmbeddingProviderType",
"create_embedding_provider",
"FastEmbedProvider",
"Model2VecProvider",
]
Loading