MCP server for retrieving context from a Qdrant vector database
Project description
MADPANDA3D QDRANT MCP
Manage your Vector Database how you see fit
MADPANDA3D QDRANT MCP is a production-ready Model Context Protocol server for Qdrant. It turns your vector store into a managed memory layer with structured controls for ingest, retrieval, validation, and ongoing cleanup.
Use it to keep memories clean, deduped, and relevance-tuned over time. The toolkit includes safe dry-run previews, bulk maintenance jobs with progress reporting, and operational guardrails so agents can manage your database at scale without chaos.
Overview
This server is designed for production workloads and supports hosted header-auth access for clients like n8n, Claude Desktop, and other MCP-capable agents.
Hosted MCP (Header Auth)
Use the MADPANDA3D hosted endpoint:
https://qdrant-mcp.madpanda3d.com/mcp
n8n setup:
- Add MCP tool node to your agent.
- Add the MCP endpoint URL.
- Set Server transport to HTTP streamable.
- Set Auth to Multiple Headers Auth.
- Add headers:
X-Qdrant-UrlX-Collection-NameX-Qdrant-Api-Key(required for private Qdrant)
- Save the auth credentials.
- Set Tools to include → All.
n8n Setup
Screenshots below show the MCP node configuration in n8n.
Deploy
Quickstart
Install (pip)
pip install mad-mcp-qdrant
Run with Docker
docker build -t mcp-server-qdrant .
docker run -d --name mcp-qdrant \
--env-file .env \
mcp-server-qdrant mcp-server-qdrant --transport streamable-http
Run locally (uvx)
QDRANT_URL=... COLLECTION_NAME=... uvx mad-mcp-qdrant
Prefer mad-mcp-qdrant; mcp-server-qdrant remains as a compatible alias.
Tools
Most mutating tools support dry_run + confirm and return a dry_run_diff preview for safer approvals.
Core Memory Tools
qdrant-store: store a single memory point with metadata.qdrant-cache-memory: store short-term memory with a TTL in a cache collection.qdrant-promote-short-term: promote short-term memories into the long-term collection.qdrant-ingest-with-validation: validate inputs, optionally quarantine, then store.qdrant-ingest-document: chunk a document and store as multiple points.qdrant-find: query vectors with filters and return matches.qdrant-find-short-term: query the short-term memory cache collection.qdrant-recommend-memories: recommend memories using positive/negative examples.qdrant-update-point: update payload fields for a point id.qdrant-patch-payload: patch specific payload keys for a point id.qdrant-tag-memories: append or replace labels for a set of points.qdrant-link-memories: link memories via related ids and optional associations.qdrant-list-points: scroll point ids in a collection with filters.qdrant-get-points: fetch points by id list with payload/vectors.qdrant-count-points: count points that match optional filters.
Housekeeping + Quality
qdrant-audit-memories: scan for missing fields, bad payloads, and duplicates.qdrant-backfill-memory-contract: populate missing metadata fields at scale.qdrant-bulk-patch: patch payloads in bulk by filter or ids (dry-run supported).qdrant-dedupe-memories: dedupe exact matches by hash.qdrant-find-near-duplicates: cluster semantic near-duplicates.qdrant-merge-duplicates: merge duplicate groups into a canonical point.qdrant-reembed-points: recompute embeddings for selected points.qdrant-expire-memories: delete/archive memories pastexpires_at_ts.qdrant-expire-short-term: delete expired memories from the short-term cache.qdrant-delete-points: delete points by id list.qdrant-delete-by-filter: delete points that match a filter.qdrant-delete-document: delete all chunks for a document id.
Jobs + Progress
qdrant-submit-job: start a background maintenance job.qdrant-job-status: get job status and summary.qdrant-job-progress: read progress counters and phase.qdrant-job-logs: tail recent logs for a job.qdrant-job-result: fetch the final job result.qdrant-cancel-job: cancel a running job.
Collection + Admin
qdrant-health-check: validate collection health and expected indexes.qdrant-metrics-snapshot: capture collection stats and index coverage.qdrant-ensure-payload-indexes: create missing payload indexes.qdrant-optimizer-status: report optimizer and segment status.qdrant-update-optimizer-config: update optimizer settings (admin).qdrant-list-collections: list all collections.qdrant-collection-exists: check if a collection exists.qdrant-collection-info: fetch collection config and metadata.qdrant-collection-stats: read collection stats (points, segments).qdrant-collection-vectors: show vector config for the collection.qdrant-collection-payload-schema: list payload schema + indexed fields.qdrant-get-vector-name: resolve the active vector name.qdrant-list-aliases: list all aliases.qdrant-collection-aliases: list aliases for a collection.qdrant-collection-cluster-info: cluster and shard info.qdrant-list-snapshots: list collection snapshots.qdrant-list-full-snapshots: list full snapshots on the server.qdrant-list-shard-snapshots: list shard snapshots for a collection.qdrant-create-snapshot: create a new collection snapshot.qdrant-restore-snapshot: restore a snapshot into a collection.
Configuration
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_VECTOR_NAME |
Override vector name used by the MCP server | None |
QDRANT_LOCAL_PATH |
Path to the local Qdrant database (alternative to QDRANT_URL) |
None |
EMBEDDING_PROVIDER |
Embedding provider to use (fastembed or openai) |
fastembed |
EMBEDDING_MODEL |
Name of the embedding model to use | sentence-transformers/all-MiniLM-L6-v2 |
EMBEDDING_VECTOR_SIZE |
Vector size override (required for unknown OpenAI models) | unset |
EMBEDDING_VERSION |
Embedding version label stored with each memory | unset |
OPENAI_API_KEY |
OpenAI API key (required for openai provider) |
unset |
OPENAI_BASE_URL |
OpenAI-compatible base URL (optional) | unset |
OPENAI_ORG |
OpenAI organization ID (optional) | unset |
OPENAI_PROJECT |
OpenAI project ID (optional) | unset |
TOOL_STORE_DESCRIPTION |
Custom description for the store tool | See default in src/mcp_server_qdrant/settings.py |
TOOL_FIND_DESCRIPTION |
Custom description for the find tool | See default in src/mcp_server_qdrant/settings.py |
MCP_ADMIN_TOOLS_ENABLED |
Enable admin-only tools (optimizer updates) | false |
MCP_MUTATIONS_REQUIRE_ADMIN |
Require admin access for mutating tools | false |
MCP_MAX_BATCH_SIZE |
Max batch size for bulk operations | 500 |
MCP_MAX_POINT_IDS |
Max point id list size | 500 |
MCP_STRICT_PARAMS |
Reject unknown keys/filters and oversized text | false |
MCP_MAX_TEXT_LENGTH |
Max text length before chunking | 8000 |
MCP_DEDUPE_ACTION |
Dedupe behavior (update or skip) |
update |
MCP_INGEST_VALIDATION_MODE |
Validation mode (allow, reject, quarantine) |
allow |
MCP_QUARANTINE_COLLECTION |
Collection name for quarantined memories | jarvis-quarantine |
MCP_HEALTH_CHECK_COLLECTION |
Default collection for health check | unset |
MCP_SHORT_TERM_COLLECTION |
Collection name for short-term memory cache | jarvis-short-term |
MCP_SHORT_TERM_TTL_DAYS |
Default TTL (days) for short-term memory cache | 7 |
MCP_SERVER_VERSION |
Optional git SHA for telemetry | unset |
MCP_ALLOW_REQUEST_OVERRIDES |
Allow per-request Qdrant headers | false |
MCP_REQUIRE_REQUEST_QDRANT_URL |
Require X-Qdrant-Url when overrides enabled |
true |
MCP_REQUIRE_REQUEST_COLLECTION |
Require X-Collection-Name when overrides enabled |
true |
MCP_QDRANT_URL_HEADER |
Header name for Qdrant URL | x-qdrant-url |
MCP_QDRANT_API_KEY_HEADER |
Header name for Qdrant API key | x-qdrant-api-key |
MCP_COLLECTION_NAME_HEADER |
Header name for collection name | x-collection-name |
MCP_QDRANT_VECTOR_NAME_HEADER |
Header name for vector name | x-qdrant-vector-name |
MCP_QDRANT_HOST_ALLOWLIST |
Comma/space-separated allowed Qdrant hostnames | unset |
Note: You cannot provide both QDRANT_URL and QDRANT_LOCAL_PATH at the same time.
Example .env templates
Base (Qdrant + hosted overrides):
QDRANT_URL=https://your-qdrant-host:6333
QDRANT_API_KEY=your-qdrant-api-key
COLLECTION_NAME=your-collection
# Hosted MCP: require client headers (recommended for public endpoints)
MCP_ALLOW_REQUEST_OVERRIDES=true
MCP_REQUIRE_REQUEST_QDRANT_URL=true
MCP_REQUIRE_REQUEST_COLLECTION=true
MCP_QDRANT_HOST_ALLOWLIST=["*.qdrant.io"]
FastEmbed (local embeddings, no external API):
EMBEDDING_PROVIDER=fastembed
EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
OpenAI embeddings:
EMBEDDING_PROVIDER=openai
EMBEDDING_MODEL=text-embedding-3-large
OPENAI_API_KEY=your-openai-key
OpenAI-compatible embeddings (custom base URL):
EMBEDDING_PROVIDER=openai
EMBEDDING_MODEL=your-model-id
OPENAI_API_KEY=your-openai-compatible-key
OPENAI_BASE_URL=https://your-openai-compatible-host/v1
# Optional:
OPENAI_ORG=
OPENAI_PROJECT=
Hosted MCP (Bring Your Own Qdrant)
If you run a public MCP endpoint and want users to supply their own Qdrant credentials (e.g., in n8n), enable per-request overrides and send headers.
Server env:
MCP_ALLOW_REQUEST_OVERRIDES=true
MCP_REQUIRE_REQUEST_QDRANT_URL=true
MCP_REQUIRE_REQUEST_COLLECTION=true
# Optional hardening
MCP_QDRANT_HOST_ALLOWLIST=*.qdrant.io
Client headers (n8n MCP node):
X-Qdrant-Url: user Qdrant URL (required)X-Qdrant-Api-Key: user Qdrant API key (optional if public)X-Collection-Name: user collection (required)X-Qdrant-Vector-Name: optional vector name override
If you want to keep server defaults and only allow optional overrides, set
MCP_REQUIRE_REQUEST_QDRANT_URL=false and MCP_REQUIRE_REQUEST_COLLECTION=false.
Tip: If you enable request overrides for a public endpoint, do not rely on
server-side QDRANT_* defaults. Require user headers and keep your own
Qdrant instance network-restricted.
Memory Contract
Stored memories are normalized to include at least:
text, type, entities, source, created_at, updated_at, scope, confidence, and text_hash.
Optional fields include expires_at / ttl_days, labels, related_ids, associations,
validation metadata (validation_status, validation_errors), merge markers
(merged_into, merged_from), plus embedding metadata
(embedding_model, embedding_dim, embedding_provider, embedding_version).
Document ingestion stores additional fields such as doc_id, doc_title, doc_hash,
source_url, file_name, file_type, page_start, page_end, and section_heading.
When a duplicate text_hash is found in the same scope, the server updates
last_seen_at and reinforcement_count instead of inserting a duplicate.
Maintenance Playbooks
See docs/MAINTENANCE_PLAYBOOKS.md for recommended maintenance flows.
Release & Versioning
This repo uses conventional commits and semantic-release. Every push to main runs the
release workflow, and a release is created only when commit messages warrant a version bump.
License
Apache-2.0.
Support
Affiliate Links
Services I use (affiliate)
Using these links helps support continued development.
Hostinger VPS
Cloud Hosting
Web Hosting
Website Builder
Agency Hosting
Reach
Contact
Open an issue in MADPANDA3D/QDRANT-MCP.
MADPANDA3D
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mad_mcp_qdrant-1.4.0.tar.gz.
File metadata
- Download URL: mad_mcp_qdrant-1.4.0.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a4fd68d0788723619271c3231a8b9b55ab1fed280645f048d9ed0b9bea4839e
|
|
| MD5 |
b59a3166ca97aef1013ec41f3ce2f5ac
|
|
| BLAKE2b-256 |
3178f9b31183ffbee1b25a1dc121b0faf5d92aa00de84de8adb3c0663898aac1
|
File details
Details for the file mad_mcp_qdrant-1.4.0-py3-none-any.whl.
File metadata
- Download URL: mad_mcp_qdrant-1.4.0-py3-none-any.whl
- Upload date:
- Size: 74.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74cb5003a17199b73741245dc80cc53c170e596178d491ee6535a8daac4b2d23
|
|
| MD5 |
ae61057330897197d52dab84531a291a
|
|
| BLAKE2b-256 |
c80bcb76b1aff624baa6bb72e7015b5069327640cb4d09905ee59f116dd8e16f
|