mad-mcp-qdrant 1.4.0
MCP server for retrieving context from a Qdrant vector database
Requires Python: >=3.10

<p align="center">
  <img src="./assets/brand/header.jpg" alt="MADPANDA3D QDRANT MCP header" />
</p>

<p align="center">
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="Apache 2.0 License" /></a>
  <a href="https://www.python.org/"><img src="https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white" alt="Python 3.10+" /></a>
  <a href="https://modelcontextprotocol.io/"><img src="https://img.shields.io/badge/MCP-Server-000000" alt="MCP Server" /></a>
  <a href="https://qdrant.tech/"><img src="https://img.shields.io/badge/Qdrant-Connected-ff6f00" alt="Qdrant" /></a>
  <a href="https://github.com/MADPANDA3D/QDRANT-MCP/releases"><img src="https://img.shields.io/github/v/release/MADPANDA3D/QDRANT-MCP?display_name=tag&color=0e8a16" alt="release" /></a>
  <a href="https://github.com/MADPANDA3D/QDRANT-MCP/issues"><img src="https://img.shields.io/github/issues/MADPANDA3D/QDRANT-MCP?color=ff8c00" alt="open issues" /></a>
  <a href="https://github.com/MADPANDA3D/QDRANT-MCP"><img src="https://img.shields.io/github/stars/MADPANDA3D/QDRANT-MCP?color=f1c40f" alt="stars" /></a>
</p>

<h1 align="center"><strong>MADPANDA3D QDRANT MCP</strong></h1>
<p align="center"><strong>Manage your Vector Database how you see fit</strong></p>
<p align="center">
  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.
</p>
<p align="center">
  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.
</p>

## 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:

1. Add **MCP tool node** to your agent.
2. Add the MCP endpoint URL.
3. Set **Server transport** to **HTTP streamable**.
4. Set **Auth** to **Multiple Headers Auth**.
5. Add headers:
   - `X-Qdrant-Url`
   - `X-Collection-Name`
   - `X-Qdrant-Api-Key` (required for private Qdrant)
6. Save the auth credentials.
7. Set **Tools to include** → **All**.

## n8n Setup

Screenshots below show the MCP node configuration in n8n.

<p align="center">
  <img src="./assets/n8n/n8n-qdrant-mcp-setup-step1.jpg" alt="n8n MCP setup step 1" width="900" />
</p>
<p align="center">
  <img src="./assets/n8n/n8n-qdrant-mcp-setup-step2.jpg" alt="n8n MCP setup step 2" width="900" />
</p>
<p align="center">
  <img src="./assets/n8n/n8n-qdrant-mcp-setup-step3.jpg" alt="n8n MCP setup step 3" width="900" />
</p>

## Deploy

- [![Deploy to VPS](https://img.shields.io/badge/Deploy_to_VPS-Hostinger-blue?style=for-the-badge&logo=linux&logoColor=white)](https://www.hostinger.com/cart?product=vps%3Avps_kvm_4&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a492-531e-70d3-83f5-e28eb919466d)

## Quickstart

<details>
<summary>Install (pip)</summary>

```bash
pip install mad-mcp-qdrant
```

</details>

<details>
<summary>Run with Docker</summary>

```bash
docker build -t mcp-server-qdrant .
docker run -d --name mcp-qdrant \
  --env-file .env \
  mcp-server-qdrant mcp-server-qdrant --transport streamable-http
```

</details>

<details>
<summary>Run locally (uvx)</summary>

```bash
QDRANT_URL=... COLLECTION_NAME=... uvx mad-mcp-qdrant
```

Prefer `mad-mcp-qdrant`; `mcp-server-qdrant` remains as a compatible alias.

</details>

## Tools

Most mutating tools support `dry_run` + `confirm` and return a `dry_run_diff` preview for safer approvals.

<details>
<summary>Core Memory Tools</summary>

- `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.

</details>

<details>
<summary>Housekeeping + Quality</summary>

- `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 past `expires_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.

</details>

<details>
<summary>Jobs + Progress</summary>

- `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.

</details>

<details>
<summary>Collection + Admin</summary>

- `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.

</details>

## Configuration

<details>
<summary>Environment Variables</summary>

| 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.

</details>

### Example .env templates

Base (Qdrant + hosted overrides):

```bash
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):

```bash
EMBEDDING_PROVIDER=fastembed
EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
```

OpenAI embeddings:

```bash
EMBEDDING_PROVIDER=openai
EMBEDDING_MODEL=text-embedding-3-large
OPENAI_API_KEY=your-openai-key
```

OpenAI-compatible embeddings (custom base URL):

```bash
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:

```bash
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.

<details>
<summary>Memory Contract</summary>

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.

</details>

<details>
<summary>Maintenance Playbooks</summary>

See `docs/MAINTENANCE_PLAYBOOKS.md` for recommended maintenance flows.

</details>

## 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

[![Donate to the Project](https://img.shields.io/badge/Donate_to_the_Project-Support_Development-ff69b4?style=for-the-badge&logo=heart&logoColor=white)](https://donate.stripe.com/cNidRbdkAbdP8iU7SD4ko0b)

## Affiliate Links

<details>
<summary>Services I use (affiliate)</summary>

Using these links helps support continued development.

### Hostinger VPS
- [KVM 1](https://www.hostinger.com/cart?product=vps%3Avps_kvm_1&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a491-d783-7057-85d2-27de6e01e2c5)
- [KVM 2](https://www.hostinger.com/cart?product=vps%3Avps_kvm_2&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a492-26cf-7333-b6d7-692e17bf8ce1)
- [KVM 4](https://www.hostinger.com/cart?product=vps%3Avps_kvm_4&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a492-531e-70d3-83f5-e28eb919466d)
- [KVM 8](https://www.hostinger.com/cart?product=vps%3Avps_kvm_8&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a492-7ce9-70fb-b96c-2184abc56764)

### Cloud Hosting
- [Cloud Economy](https://www.hostinger.com/cart?product=hosting%3Acloud_economy&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a48f-e7fa-7358-9ff0-f9ba2e8d6e36)
- [Cloud Professional](https://www.hostinger.com/cart?product=hosting%3Acloud_professional&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a490-20fd-70bc-959e-a1f2cd9a69a6)
- [Cloud Enterprise](https://www.hostinger.com/cart?product=hosting%3Acloud_enterprise&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a490-5972-72e4-850f-40d618988dc1)

### Web Hosting
- [Premium](https://www.hostinger.com/cart?product=hosting%3Ahostinger_premium&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a48f-4c21-7199-9918-8f31a3f6a0d9)
- [Business](https://www.hostinger.com/cart?product=hosting%3Ahostinger_business&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a48f-1135-72ba-acbb-13e0e7550db0)

### Website Builder
- [Premium](https://www.hostinger.com/cart?product=hosting%3Ahostinger_premium&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a492-f240-7309-b3fe-9f6909fbc769&product_type=website-builder)
- [Business](https://www.hostinger.com/cart?product=hosting%3Ahostinger_business&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a492-7ce9-70fb-b96c-2184abc56764)

### Agency Hosting
- [Startup](https://www.hostinger.com/cart?product=hosting%3Aagency_startup&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a490-d03c-71de-9acf-08fd4fa911de)
- [Growth](https://www.hostinger.com/cart?product=hosting%3Aagency_growth&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a491-6af4-731f-8947-f1458f07fa5b)
- [Professional](https://www.hostinger.com/cart?product=hosting%3Aagency_professional&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a491-03fb-73f8-9910-044a0a33393a)

### Email
- [Business Pro](https://www.hostinger.com/cart?product=hostinger_mail%3Apro&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a493-5c27-727b-b7f9-8747ffb4e5ee)
- [Business Premium](https://www.hostinger.com/cart?product=hostinger_mail%3Apremium&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a493-a3fc-72b8-a961-94ed6e1c70e6)

### Reach
- [Reach 500](https://www.hostinger.com/cart?product=reach%3A500&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a494-3ebf-7367-b409-9948de50a297)
- [Reach 1000](https://www.hostinger.com/cart?product=reach%3A1000&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a494-8bb9-726e-bb8d-9de9a72a3c21)
- [Reach 2500](https://www.hostinger.com/cart?product=reach%3A2500&period=12&referral_type=cart_link&REFERRALCODE=ZUWMADPANOFE&referral_id=0199a494-c9c1-7191-b600-cafa2e9adafc)

</details>

## Contact

Open an issue in `MADPANDA3D/QDRANT-MCP`.

<p align="center">
  <img src="https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=316,fit=crop,q=95/dJo56xnDoJCnbgxg/official-logo-mxBMZGQ8Owc8p2M2.jpeg" width="160" alt="MADPANDA3D logo" />
  <br />
  <strong>MADPANDA3D</strong>
</p>