better-qdrant-mcp
by jtsang4
README.md
# better-qdrant-mcp
An MCP server implemented with `fastmcp`, OpenAI embeddings, and `qdrant-client`, providing long-term memory and semantic search on top of Qdrant.
## User Guide
### Features
- **MCP server** built with `fastmcp`
- **Hybrid search** in Qdrant (dense OpenAI embeddings + sparse BM25)
- **Chinese support** via jieba
- **Knowledge Base tools** (renamed from memory tools to avoid conflict):
- `store-knowledge`
- `store-knowledge-bulk`
- `search-knowledge`
- `get-knowledge-by-id`
- `inspect-knowledge-base`
- `delete-knowledge`
- **Multiple transports**: stdio, SSE, streamable HTTP
### Requirements
- Python 3.12+
- Qdrant reachable via HTTP
### Quick Start (published package)
The project is published as the `better-qdrant-mcp` package, so you can run it directly with `uvx` without cloning this repo.
#### 1. Environment variables (required for all transports)
Minimal env for typical use:
- `QDRANT_URL` – defaults to `http://localhost:6333`
- `QDRANT_API_KEY` – optional
- `COLLECTION_NAME` – optional default collection
- `OPENAI_API_KEY` (or `OPENAPI_API_KEY`) – required
- `OPENAI_BASE_URL` – optional
- `OPENAI_EMBEDDING_MODEL` – defaults to `text-embedding-3-small`
Advanced / transport-related env:
- `MCP_TRANSPORT` – `stdio` | `sse` | `streamable-http` (default: `stdio`)
- `MCP_HOST` – host for HTTP-based transports (default: `0.0.0.0`)
- `MCP_PORT` – port for HTTP-based transports (default: `8000`)
- `MCP_PATH` – path for HTTP transports (default: `/mcp`)
#### 2. Available MCP tools
Once the server is running, the MCP client will see these tools:
- `store-knowledge(content: str, title?: str, tags?: list[str], metadata?: dict, collection_name?: str) -> str`
- `store-knowledge-bulk(items: list[KnowledgeItem], collection_name?: str) -> str`
- `search-knowledge(query: str, limit?: int=5, collection_name?: str) -> str`
- `get-knowledge-by-id(ids: list[str] | str, collection_name?: str) -> str`
- `inspect-knowledge-base(collection_name?: str) -> str`
- `delete-knowledge(ids: list[str] | str, collection_name?: str) -> str`
**`store-knowledge`** automatically embeds the text using OpenAI and stores it in Qdrant (Knowledge Base), returning the stored point ID. The `title` and `tags` fields help improve search context and categorization.
**`store-knowledge-bulk`** efficiently stores multiple knowledge items at once using batch embedding. Each item in the list should include `content` (required), and optionally `title`, `tags`, and `metadata` fields. This is more efficient than calling `store-knowledge` multiple times.
**`search-knowledge`** uses hybrid search in Qdrant (dense + sparse). If the collection is configured with named vectors `dense` and `sparse`, queries are ranked by fusing dense OpenAI embeddings and sparse BM25 scores; otherwise it falls back to dense-only search.
**`get-knowledge-by-id`** retrieves the complete payload information for one or more knowledge items by their point IDs. Use this to inspect the full details of stored items (including `content`, `title`, `tags`, `metadata`, and `stored_at` timestamp). You can pass a single ID or a list of IDs (typically using the `id` field returned by `search-knowledge`).
**`inspect-knowledge-base`** shows the collection configuration and sample data points, useful for debugging and verification.
**`delete-knowledge`** deletes one or more stored knowledge items from Qdrant by their point IDs. You can pass a single ID or a list of IDs (typically using the `id` field returned by `search-knowledge`).
#### 3. Start the server
You can either specify the transport via CLI flags (recommended for quick start) or via env (`MCP_TRANSPORT`).
##### Standard IO (stdio) – default
```bash
uvx better-qdrant-mcp
```
In this mode, you configure your MCP client to use **stdio** transport and just invoke the binary; no HTTP URL is needed.
##### Server-Sent Events (SSE)
```bash
# Default host 0.0.0.0 and port 8000
uvx better-qdrant-mcp --transport sse
# Custom host and port
uvx better-qdrant-mcp --transport sse --host 0.0.0.0 --port 3000
```
Connection details for MCP clients:
- **Transport**: `sse`
- **URL**: `http://<host>:<port>/sse` (for example: `http://localhost:8000/sse`)
##### Streamable HTTP (recommended for web applications)
```bash
# Default host 0.0.0.0, port 8000 and path /mcp
uvx better-qdrant-mcp --transport streamable-http
# Custom host, port, and path
uvx better-qdrant-mcp --transport streamable-http --host 0.0.0.0 --port 3000 --path /api/mcp
```
Connection details for MCP clients:
- **Transport**: `streamable-http`
- **URL**: `http://<host>:<port><path>` (for example: `http://localhost:8000/mcp`)
## Development Guide
### Local installation (for development)
If you want to work on this repo locally instead of using the published package:
```bash
# using uv (recommended)
uv sync
# or with pip (editable install)
pip install -e .
```
### Local build
For local development, you can use the provided `Makefile`:
```bash
make build
```
This command will first clean the `dist` directory and then run `uv build` to produce fresh artifacts.
### Docker Deployment
Docker Compose provides Qdrant + this MCP server as a single service. Transport (`stdio`, `sse`, `streamable-http`) is selected via `MCP_TRANSPORT`.
The Docker image is built and published automatically to GitHub Container Registry as:
- `ghcr.io/jtsang4/better-qdrant-mcp:latest`
- Additional tags for branches, tags, and commit SHAs
The provided `docker-compose.yml` uses this published image directly, so you **do not need to build the image locally**.
```bash
# Start Qdrant + MCP using the published image
docker compose up -d
# Pull the latest published image and restart services
docker compose pull mcp && docker compose up -d
# Stop services
docker compose down
```
## License
[MIT](LICENSE)
TDQS
A4.1/5.0
Scored across 6 tools
Disambiguation5/5
Each tool has a distinct purpose: individual store, batch store, semantic search, get by ID, delete, and inspect. No overlap or ambiguity between them.
Naming Consistency4/5
Most tools follow a verb_knowledge pattern (store-knowledge, search-knowledge, delete-knowledge). store-knowledge-bulk is a minor deviation but still clear, and get-knowledge-by-id and inspect-knowledge-base are consistent with the verb_noun style.
Tool Count5/5
Six tools is well-scoped for a knowledge base server, covering the essential operations without bloat. Each tool earns its place.
Completeness4/5
Covers create (single and bulk), read (search, get by ID), delete, and inspect. No explicit update operation, but knowledge entries can be re-created; this is a minor gap.
Maintenance
ActivityInactive
ResponsivenessNo issues