Qdrant MCP

io.github.avaazquezz由 GitHub 账号 avaazquezz 发布v2.12.0更新于 Nov 5, 2026

The full Qdrant API as 58 MCP tools: plain-text semantic/BM25/hybrid search and a search advisor.

已验证STDIO仅桌面数据库知识与记忆

概览

AI 生成的概览

把 Qdrant 向量数据库 API 封装为 58 个 MCP 工具,让助手管理集合、数据点、payload、快照,并执行向量、文本与混合检索。

可以做什么
  • 检查连通性,创建、更新、列出、查看或删除集合
  • 写入、读取、分页、计数和删除数据点,支持直接写入纯文本
  • 执行向量、语义文本、BM25 与混合查询,以及批量、分组、推荐、发现和距离矩阵检索
  • 编辑 payload、创建 payload 索引、统计分面值,并管理命名向量与批量操作
  • 通过快照备份与恢复单个集合或整个存储,读取遥测、指标与配额
  • 诊断集合、测量检索召回率与延迟,并提供调优与零停机重建的引导式提示词
适用场景
适合需要让助手端到端操作 Qdrant 部署的场景,例如搭建与维护集合、调优检索质量,或对向量与文本进行查询,而不只是存取文档。
运行要求
通过 uvx 或 pip 以 stdio 在本地运行(需 Python 3.12+),也可用 Docker 镜像或 Claude Desktop 安装包。需要可访问的 Qdrant 服务器(v1.19.0 以上,已在 v1.20.0 测试),通过 QDRANT_URL 指定,或用 QDRANT_LOCAL_PATH 使用嵌入式实例;实例需要时提供 QDRANT_API_KEY。语义文本检索需安装 embeddings 附加组件,模型会下载到 FASTEMBED_CACHE_PATH。网络模式必须设置 QDRANT_MCP_SHARED_SECRET。
安装前请注意
工具可写入和删除:集合、数据点、payload 与快照都可变更,部分删除被标记为破坏性操作。可设置 QDRANT_MCP_READ_ONLY 从注册表中移除所有写入类工具。QDRANT_API_KEY 是经环境变量传入的密钥。快照恢复会让 Qdrant 服务器自行抓取指定位置,应通过 QDRANT_MCP_SNAPSHOT_ALLOWED_ORIGINS 限制来源。streamable-http 模式下缺少 QDRANT_MCP_SHARED_SECRET 时服务器拒绝启动,客户端以 bearer 令牌发送该密钥。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Qdrant MCP,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

Qdrant MCP

[PyPI version] [CI] [Python versions] [License: MIT]

[Qdrant MCP server]

A Model Context Protocol (MCP) server that exposes the full Qdrant vector database API as tools — collection management, advanced hybrid search, payload and vector editing, snapshots, and server observability. Not just store/find.

Table of Contents

Overview

Qdrant MCP is a thin MCP server that wraps the Qdrant API one-to-one: it registers a tool per Qdrant operation, validates the input with Pydantic, calls the official qdrant-client SDK, and returns the result. It never parses documents and never decides how to chunk text — it is not a RAG pipeline, on purpose. A client can bring its own vectors, or — with the optional embeddings extra — send plain text and search by meaning or by keywords (see Text Search).

That is what sets it apart from the official Qdrant MCP server, which exposes exactly two tools (store/find). This server covers the rest of Qdrant's surface — everything under collections, points, search, payload, indexing, snapshots, and observability — so an LLM client can manage a Qdrant deployment end to end, and query it in plain text too.

See ROADMAP.md for the full phase-by-phase design history, including every finding that shaped a decision (in Spanish).

Key Features

  • Text search — semantic search with plain text (query_text, embedded locally with fastembed using the model the collection declares), BM25 keyword search with stemming and stopwords (bm25_query, Qdrant 1.20, no embeddings needed), and both fused in one hybrid query. Upserts accept text too. Works on collections built elsewhere once their model is declared.
  • Full collection & point lifecycle — create/update/delete collections, CRUD on points, scrolling, counting.
  • Every Qdrant search mode — plain vector search over dense, sparse and multivectors, hybrid search (RRF — optionally weighted — and DBSF fusion), nested multi-stage prefetch (fuse dense+sparse, then rerank with a multivector), MMR diversity, custom score formulas (payload boosts, recency and geo decay), ordering by a payload field, random sampling, grouped queries, recommend, discover, and pairwise distance matrices. Search accuracy knobs (search_params, score_threshold, paging, timeouts) are accepted by every search tool.
  • Payload & vector editing — set/overwrite/delete/clear payload, payload indexes, facet counting, named (dense/sparse) vector management, ordered batch operations.
  • Snapshots — per-collection and full-storage backup/restore.
  • A search advisor — qdrant_collection_doctor checks a collection (status, index, memory, aliases, text setup) and answers each finding with the exact tool call that fixes it; qdrant_search_quality_eval measures recall@k of the approximate search against an exact one, and latency, for any search_params variants — so tuning HNSW or quantization is judged by numbers, e.g. "quantized without rescoring: recall 0.97; with rescoring: 1.0".
  • Guided workflows — MCP prompts that walk a model through a whole task: tune a collection's search (diagnose, measure, propose, wait for approval), rebuild a collection without downtime, or add text search to an existing collection. In Claude Code they're slash commands, e.g. /mcp__qdrant__tune_search docs. The server also hands the model a short orientation (its MCP instructions), built from the toolsets you enabled.
  • Aliases, reindexing & introspection — switch the collection a name points to without downtime, copy points between collections server-side (vectors never pass through the model), check shard layout and whether the optimizer has finished indexing, and profile the payload keys a collection actually has before writing a filter.
  • Observability — telemetry, Prometheus metrics endpoint, resource quotas, self-diagnosed issues.
  • Opt-in tool surface — the 58 tools are grouped into toolsets you enable explicitly, so a client isn't handed all of them by default (only the 13-tool core toolset is on).
  • Read-only guard — one flag removes every mutating tool from the registry entirely.
  • Easy on the model's context — the schemas the server advertises are compact (Qdrant's verbose Filter and configuration models are summarized, validation unchanged), so the default toolset costs ~47 KB of schema instead of ~150 KB; with_payload can name just the keys to return (["title", "url"]), since payload is most of what a model reads back; and a per-call result cap (QDRANT_MCP_MAX_LIMIT) stops one mistaken limit from flooding the conversation.
  • Resilient by default — every Qdrant call goes through retry-with-backoff and returns Qdrant's own error message on failure, never a generic exception.

Requirements

  • Python 3.12+
  • Qdrant server v1.19.0 or newer; tested against v1.20.0. Two tools (qdrant_collection_vector_create/qdrant_collection_vector_delete) depend on an endpoint that returns 404 on older Qdrant servers (verified against v1.13.6 and v1.15.1) — everything else works on older versions. Tool descriptions state the behavior verified on v1.20.0, and say so where v1.19 differed (alias batches, MMR with offset). Text search needs v1.16+ (it keeps the model in the collection's metadata), and its BM25 mode v1.20+.

Installation

PyPI

bash
# Run without installing (recommended for Claude Desktop/Code configs)uvx mcp-qdrant
# Or install into your environmentpip install mcp-qdrant
# With text search (adds fastembed; models are downloaded on first use)uvx --from 'mcp-qdrant[embeddings]' mcp-qdrant

Docker

bash
docker run --rm -p 8000:8000 \  -e QDRANT_URL=http://host.docker.internal:6333 \  -e QDRANT_MCP_TRANSPORT=streamable-http \  -e QDRANT_MCP_HTTP_HOST=0.0.0.0 \  -e QDRANT_MCP_SHARED_SECRET=<a long random secret> \  -v mcp-qdrant-models:/models \  ghcr.io/avaazquezz/qdrant-mcp:latest

The image only makes sense with streamable-http — stdio needs a client to own the process's stdin/stdout directly, which a detached container can't provide. The server binds 127.0.0.1 by default, so QDRANT_MCP_HTTP_HOST=0.0.0.0 is required for the port to be reachable from outside the container. Images are published on every tagged release as {version}, {major}.{minor}, and latest.

Claude Desktop bundle (.mcpb)

Download mcp-qdrant.mcpb from the latest release and double-click it. Claude Desktop installs the server via uv (resolving dependencies on your machine, no Python installation required) and prompts for Qdrant URL, API key, local path, toolsets, and read-only mode through its own settings form — no JSON to edit.

Quick Start

Point the server at a local Qdrant instance over stdio and confirm it's reachable:

bash
QDRANT_URL=http://localhost:6333 mcp-qdrant

Once connected from an MCP client, a typical first exchange looks like:

  1. qdrant_health_check — confirms the configured Qdrant instance is reachable before doing anything else.
  2. qdrant_collection_create — {"collection_name": "docs", "vector_size": 4, "distance": "Cosine"}.
  3. qdrant_points_upsert — {"collection_name": "docs", "points": [{"id": 1, "vector": [0.1, 0.2, 0.3, 0.4], "payload": {"title": "hello"}}]}.
  4. qdrant_query — {"collection_name": "docs", "query_vector": [0.1, 0.2, 0.3, 0.4], "limit": 5}.

The full parameter shape of every tool is described in its own MCP schema — an LLM client reads those directly via tools/list; the table in Available Tools below is a human-readable summary of the same data.

Connecting to Claude

Claude Desktop / Claude Code (local, stdio)

claude_desktop_config.json (Claude Desktop) or .mcp.json (Claude Code):

json
{  "mcpServers": {    "qdrant": {      "command": "uvx",      "args": ["mcp-qdrant"],      "env": {        "QDRANT_URL": "http://localhost:6333",        "QDRANT_MCP_TOOLSETS": "core,search"      }    }  }}

Or use the .mcpb bundle described in Installation — same result, no JSON to edit.

Remote (streamable-http)

For a server reachable over the network (e.g. added as a custom connector in Claude.ai) with a single, fixed backing Qdrant. QDRANT_MCP_SHARED_SECRET is required in this mode — the server refuses to start as streamable-http without one, to avoid serving an unauthenticated endpoint over the network (verified hands-on: an open streamable-http server is trivially usable by anyone with the URL).

bash
QDRANT_URL=http://localhost:6333 \QDRANT_MCP_TRANSPORT=streamable-http \QDRANT_MCP_HTTP_HOST=0.0.0.0 \QDRANT_MCP_SHARED_SECRET=<a long random secret> \mcp-qdrant

In Claude.ai (Customize → Connectors → Add custom connector, verified hands-on against a real account): enter the server's HTTPS URL, then on the detected authentication screen choose "None" and add a Request header — Authorization → Bearer <the same secret>. (Authorization is used here because it's one of the two header names Claude.ai's custom-connector UI accepts without requiring Anthropic's manual approval of a custom name.)

Text Search

Text search needs no extra configuration — the collection carries it. Its metadata records which model made each dense vector and which payload field holds the text, so every later query and upsert uses the same model (a query embedded with a different model would return plausible-looking nonsense with no error):

json
{"mcp_qdrant": {"text_field": "text", "models": {"dense": "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"}}}
  • New collection — qdrant_collection_create with text_model (creates a dense vector of the model's size and records it) and/or text_language (adds a BM25 index on the text field: stemmed, accent-folded, stopwords removed).
  • Existing collection — qdrant_collection_update with text_models ({"<vector>": "<model>"}, "" for the unnamed vector) declares the model its vectors were made with; the size is checked against the vector. For BM25, create a text payload index with "scoring": true (and a stemmer) on the text field with qdrant_payload_index_create.
  • Write — qdrant_points_upsert with {"id": 1, "text": "..."} instead of a vector: one text is one point, nothing is split.
  • Query — qdrant_query with query_text (semantic), bm25_query (keywords), or both as prefetch stages fused with "rrf" (hybrid).

Guard rails: a text longer than the model reads (128 tokens, ~500 characters, for the multilingual MiniLM) is refused instead of silently cut — split it into several points; models that need query/document prefixes (e5, nomic, ...) aren't offered, since fastembed doesn't add them; a collection with points won't switch a vector to a different model (null in text_models removes a wrong declaration first); and text into a collection whose vectors have no declared model is refused rather than stored without a vector. BM25 with a language needs a Qdrant server — the embedded local mode only ranks default-tokenized indexes.

Semantic search needs the embeddings extra (the Docker image and the .mcpb bundle include it); BM25 needs Qdrant 1.20 but no extra. Models are downloaded on first use into FASTEMBED_CACHE_PATH — set it to a persistent directory (the Docker image uses /models, so mount a volume there) to download once.

Prompts

Guided workflows the user starts; each is offered only when the tools it uses are enabled and the server isn't read-only. In Claude Code they're slash commands with positional arguments.

PromptArgumentsNeeds toolsetsWhat it does
tune_searchcollectioncore, adminDoctor, then recall/latency for a few search_params variants, then the smallest change with its numbers — and waits for your approval.
zero_downtime_reindexcollection, aliascore, adminNew collection with the settings you choose, copy, compare counts, measure, switch the alias; the old collection is kept.
text_search_setupcollection, languagecore, payloadFind the text field, declare the embedding model you name (never guessed), add a BM25 index for the language, try semantic, keyword and hybrid queries.

Example: /mcp__qdrant__tune_search docs.

Configuration Reference

All configuration is via environment variables, read once at startup — a misconfiguration fails immediately instead of surfacing later as a confusing tool error.

VariableDefaultRequiredPurpose
QDRANT_URL—No¹URL of your Qdrant instance, e.g. http://localhost:6333 or a Qdrant Cloud URL.
QDRANT_API_KEY—NoAPI key for QDRANT_URL, if your instance requires one.
QDRANT_LOCAL_PATH—No¹Path to an embedded/on-disk Qdrant instance, instead of a URL.
QDRANT_MCP_READ_ONLYfalseNoRemoves every tool not marked read-only from the registry. See Read-Only Mode.
QDRANT_MCP_TRANSPORTstdioNostdio (local, for Claude Desktop/Code) or streamable-http (network).
QDRANT_MCP_TOOLSETScoreNoComma-separated list of toolsets to register. See Available Tools.
QDRANT_MCP_SHARED_SECRET—Yes, for streamable-httpBearer token clients must send in the Authorization header.
QDRANT_MCP_HTTP_HOST127.0.0.1NoBind host for streamable-http. Use 0.0.0.0 in a container.
QDRANT_MCP_HTTP_PORT8000NoBind port for streamable-http.
QDRANT_MCP_SNAPSHOT_ALLOWED_ORIGINS—NoComma-separated http(s) origins (e.g. https://backups.example.com) qdrant_snapshot_recover may restore from, besides file:// paths and QDRANT_URL's own origin. See Security.
QDRANT_MCP_MAX_LIMIT1000NoLargest number of points one tool call may ask for (minimum 30, so every tool's default request fits) (limit, groups' limit × group_size, a batch's total, the number of ids, ...). A bigger request is refused with a message saying to page, not silently cut.

¹ QDRANT_URL and QDRANT_LOCAL_PATH are mutually exclusive; if neither is set, the client falls back to the qdrant-client SDK's own default of localhost:6333.

Available Tools

Tools are grouped into toolsets, enabled via QDRANT_MCP_TOOLSETS (comma-separated). Only core is enabled by default — the rest are explicit opt-ins, so a client isn't handed every tool at once:

  • core — collection and point CRUD, plus qdrant_query and the qdrant_health_check smoke test. Enough for a fully working MCP on its own.
  • search — everything beyond plain vector search: batched/grouped queries, recommend, discover, and pairwise distance matrices.
  • payload — payload editing and indexing, named-vector management, ordered batch point operations.
  • snapshots — collection and full-storage backup/restore.
  • observability — telemetry, metrics, quotas, and self-diagnosed issues.
  • admin — collection aliases, per-collection shard layout and optimizer progress, composite operations that keep the data on the server (copying points between collections — the missing half of a zero-downtime reindex — and profiling the payload keys a collection really has), and the advisor: a collection doctor and a search-quality evaluation. Everything here works on a single node; distributed-cluster administration (shard keys, resharding) is out of scope — see ROADMAP.md, Fase 5 and Fase 12.

The table below is generated directly from the live tool registry — run uv run python scripts/gen_tools_doc.py after adding or changing a tool to keep it in sync (CI fails the build if it drifts).

ToolToolsetRead-onlyDestructiveIdempotentDescription
qdrant_health_checkcore✅❌✅Confirm the configured Qdrant instance is reachable and responding.
qdrant_collection_createcore❌❌❌Create a collection: a single unnamed vector (vector_size + distance), one or more named vectors (vectors, each a full VectorParams — size, distance, and optionally its own multivector_config for ColBERT-style multi-vectors or quantization_config), or a text collection (text_model) — exactly one of the three.
qdrant_collection_listcore✅❌✅List every collection name in the configured Qdrant instance.
qdrant_collection_infocore✅❌✅Return full config and status of one collection.
qdrant_collection_updatecore❌❌✅Update optimizer/HNSW/collection/vector params on an existing collection.
qdrant_collection_deletecore❌✅✅Delete a collection and all its points; a no-op if it doesn't exist.
qdrant_collection_existscore✅❌✅Check whether a collection exists, without raising if it doesn't.
qdrant_points_upsertcore❌✅✅Insert or replace points (id + vector or text + payload) in a collection.
qdrant_points_getcore✅❌✅Retrieve points by id; unknown ids are simply omitted, not an error.
qdrant_points_deletecore❌✅✅Delete points by id list or by payload filter — exactly one of the two.
qdrant_points_scrollcore✅❌✅Page through all points in a collection, optionally filtered.
qdrant_points_countcore✅❌✅Count points in a collection, optionally matching a filter.
qdrant_querycore✅❌✅Search a collection with Qdrant's unified Query API: vector similarity, hybrid fusion, multi-stage reranking, MMR diversity, payload-based score formulas, ordering by a payload field, or random sampling.
qdrant_query_batchsearch✅❌✅Run multiple independent queries against one collection in a single round trip — each item takes every query mode and tuning parameter of qdrant_query (vector, query_text, bm25_query, fusion over prefetch, MMR, formula, order_by, sample, search_params, score_threshold, offset); timeout_seconds and consistency apply to the whole batch.
qdrant_query_groupssearch✅❌✅Vector query grouped by a payload field, up to group_size hits per group — e.g. the best-matching chunks per source document.
qdrant_recommendsearch✅❌✅Find points similar to a set of positive examples and dissimilar to a set of negative ones (vectors or point ids) — Qdrant's recommendation API.
qdrant_recommend_batchsearch✅❌✅Run multiple independent recommend queries against one collection in a single round trip.
qdrant_recommend_groupssearch✅❌✅Recommend query grouped by a payload field, up to group_size hits per group.
qdrant_discoversearch✅❌✅Rank points by how well they fit a target within positive/negative context pairs (vectors or point ids) — Qdrant's discovery search, a finer-grained alternative to recommend.
qdrant_discover_batchsearch✅❌✅Run multiple independent discover queries against one collection in a single round trip.
qdrant_distance_matrix_pairssearch✅❌✅Pairwise distance matrix between a random sample of points: for each of sample points, its limit closest neighbors among that same sample — returned as a flat list of (a, b, score) pairs.
qdrant_distance_matrix_offsetssearch✅❌✅Same distance matrix as qdrant_distance_matrix_pairs, in a column-oriented shape (offsets into a shared id list + a parallel score array) — more compact for large samples.
qdrant_payload_setpayload❌❌✅Merge fields into the payload of selected points — exactly one of ids/points_filter.
qdrant_payload_overwritepayload❌✅✅Replace the entire payload of selected points with payload — exactly one of ids/points_filter.
qdrant_payload_deletepayload❌✅✅Delete specific payload keys from selected points — exactly one of ids/points_filter.
qdrant_payload_clearpayload❌✅✅Wipe the entire payload of selected points, keeping their vectors — exactly one of ids/points_filter.
qdrant_payload_facetpayload✅❌✅Count distinct values of a payload field across the collection (or a filtered subset) — e.g. how many points per city.
qdrant_payload_index_createpayload❌✅✅Create a payload index on field_name, speeding up filters that use it.
qdrant_payload_index_deletepayload❌✅✅Delete the payload index on field_name.
qdrant_collection_vector_createpayload❌❌✅Add a new named vector (dense or sparse) to a collection that already has points, without touching them.
qdrant_collection_vector_deletepayload❌✅✅Remove a named vector (dense or sparse) from a collection — points keep their other vectors and payload.
qdrant_points_batch_updatepayload❌✅❌Run multiple point operations (upsert, delete, set/overwrite/delete/clear payload, update/delete vectors) against one collection, in the order given, in a single request.
qdrant_vectors_updatepayload❌✅✅Replace the vector(s) of existing points by id — leaves their payload untouched.
qdrant_vectors_deletepayload❌✅✅Remove specific named vectors from selected points, keeping their payload and other vectors — exactly one of ids/points_filter.
qdrant_alias_listadmin✅❌✅List every alias on the server with the collection it points to.
qdrant_collection_aliasesadmin✅❌✅List the aliases that point to one collection (an empty list if it has none).
qdrant_alias_updateadmin❌✅❌Create, rename, re-point or delete aliases — the basis of a zero-downtime reindex: build the new collection, then switch the alias that clients use.
qdrant_collection_cluster_infoadmin✅❌✅Shard layout of a collection: how many shards it has and, for each local shard, its point count and replica state.
qdrant_collection_optimizationsadmin✅❌✅Progress of the background optimizer for a collection — answers "has it finished indexing?" and "why isn't the collection green?".
qdrant_collection_copyadmin❌✅✅Copy points (all vectors — dense, sparse and multivector — and payload) from one collection to another of the same Qdrant instance, entirely server-side: the vectors never pass through the model.
qdrant_payload_schema_inferadmin✅❌✅Profile the payload keys that actually occur in a collection, so filters can be written against real keys instead of guessed ones.
qdrant_collection_doctoradmin✅❌✅Diagnose one collection (or alias): read-only checks that each come with the exact tool call that acts on them, so you don't have to know Qdrant's internals.
qdrant_search_quality_evaladmin✅❌✅Measure how much a collection's approximate (HNSW, quantized) search loses against an exact one, and what each configuration costs in latency — so a tuning change is judged by numbers.
qdrant_snapshot_createsnapshots❌❌❌Create a snapshot of one collection's current state.
qdrant_snapshot_listsnapshots✅❌✅List the snapshots stored for one collection.
qdrant_snapshot_deletesnapshots❌✅✅Delete a collection snapshot, freeing its disk space on the server — does not touch the live collection.
qdrant_snapshot_recoversnapshots❌✅✅Restore the points (vectors and payload) captured in a snapshot into collection_name — points written since the snapshot are lost.
qdrant_snapshot_downloadsnapshots✅❌✅Confirm a collection snapshot exists and return where to fetch it from — this tool does not transfer the (potentially huge) snapshot file itself; download it yourself (e.g. curl) from the returned url.
qdrant_storage_snapshot_createsnapshots❌❌❌Create a snapshot of the whole storage: a snapshot of every collection plus the alias mapping (verified: no server configuration is included), not just one collection.
qdrant_storage_snapshot_listsnapshots✅❌✅List the full-storage snapshots stored on the server.
qdrant_storage_snapshot_deletesnapshots❌✅✅Delete a full-storage snapshot, freeing its disk space.
qdrant_storage_snapshot_downloadsnapshots✅❌✅Confirm a full-storage snapshot exists and return where to fetch it from — same caveat as qdrant_snapshot_download: this tool does not transfer the file itself.
qdrant_telemetryobservability✅❌✅Server-wide telemetry: build info, the number of collections and request counters by default; pass details_level 1 or more for per-collection stats, memory and hardware usage (verified: they are null at the default level).
qdrant_metrics_prometheusobservability✅❌✅Return the URL where Qdrant serves Prometheus-format metrics — this tool does not fetch the metrics themselves (they're plain text, not JSON); point your Prometheus scraper at the returned url instead.
qdrant_quotas_getobservability✅❌✅Current server-wide resource quotas (memory/disk limits) and actual usage.
qdrant_quotas_setobservability❌✅✅Replace the server-wide resource quotas.
qdrant_issues_listobservability✅❌✅List the issues Qdrant has detected about its own configuration (e.g. a heavily-filtered field with no payload index).
qdrant_issues_clearobservability❌✅✅Clear all accumulated issues.

Read-Only Mode

Setting QDRANT_MCP_READ_ONLY=1 removes every tool whose destructiveHint isn't explicitly false (i.e. anything that isn't readOnlyHint=true) from the registry itself — a client calling tools/list never sees them, rather than seeing them and having calls rejected. This is the mechanism to hand an LLM client safe, read-only access to a Qdrant deployment: point it at your database, set the flag, and there is no code path left for it to write anything.

Architecture

  • Single shared client. One AsyncQdrantClient is built once at startup and closed over by every tool.
  • One registration choke point. Every tool module calls into a single ToolRegistry, which is where the toolset filter and the read-only guard are both enforced — a tool can't bypass either by registering itself differently.
  • Resilience. Every Qdrant call is wrapped with tenacity-based retry and backoff (the qdrant-client SDK itself only exposes a timeout, not retries), and translated into an MCP ToolError carrying Qdrant's own error message instead of a generic failure — so "collection not found" reads as exactly that.
  • stdio-safe logging. All logging goes to stderr, configured before the MCP server object is even constructed — writing to stdout under the stdio transport would corrupt the JSON-RPC message framing.

Security

  • Mandatory authentication for streamable-http. The server refuses to start without QDRANT_MCP_SHARED_SECRET — verified hands-on that an unauthenticated instance is trivially usable by anyone with the URL. The bearer token is compared in constant time.
  • No server-side request forgery through snapshot restores. qdrant_snapshot_recover makes the Qdrant server itself fetch location, so it only accepts file:// paths, QDRANT_URL's own origin and the origins listed in QDRANT_MCP_SNAPSHOT_ALLOWED_ORIGINS — not, say, a cloud metadata endpoint on your internal network.
  • No blind retries of writes. A call is retried only when the request never reached Qdrant (connection refused, connect timeout). A timeout after sending is reported as "may have been applied" instead of being repeated, so a slow write can't run twice.
  • Input validation everywhere. Every tool's input is a Pydantic model — malformed input is rejected with a structured error before it reaches the Qdrant SDK.
  • Read-only guard. QDRANT_MCP_READ_ONLY removes every mutating tool from the registry — see Read-Only Mode.

Development

bash
git clone https://github.com/avaazquezz/Qdrant-MCP.gitcd Qdrant-MCPuv sync --dev --extra embeddingsuv run pre-commit install
bash
uv run ruff check .            # lintuv run ruff format --check .   # formattinguv run mypy .                  # type checking (strict)uv run pytest                  # unit testsuv run pytest -m integration   # integration tests — needs a running Qdrant (CI runs one as a Docker service)

If you add or change a tool, regenerate the table in Available Tools rather than hand-editing it:

bash
uv run python scripts/gen_tools_doc.py          # regenerateuv run python scripts/gen_tools_doc.py --check  # verify, no changes (what CI runs)

Versioning & Changelog

This project follows Semantic Versioning. See CHANGELOG.md for release notes and ROADMAP.md for the phased design history behind each version.

License

MIT

来源:README.md,提交 fdabeab

工具

0
SourceWeft 曾在隔离沙箱中以无凭据方式启动该软件包一次,以列出其工具,但未能完成:软件包安装失败。

版本历史

4
  1. v2.12.0最新Nov 5, 2026
  2. v2.8.0Nov 4, 2026
  3. v2.6.0Oct 20, 2026
  4. v1.0.1Sep 16, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分