Merge remote-tracking branch 'origin/master' into fix/qdrant-doc-id-keyword-index

# Conflicts:
#	nextcloud_mcp_server/vector/qdrant_client.py
This commit is contained in:
Chris Coutinho
2026-05-10 17:55:53 +02:00
4 changed files with 36 additions and 8 deletions
+12
View File
@@ -5,6 +5,18 @@ All notable changes to the Nextcloud MCP Server will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [PEP 440](https://peps.python.org/pep-0440/).
## v0.83.4 (2026-05-10)
### Fix
- **qdrant**: use get_collection for startup probe (multi-tenant safe, take 2)
## v0.83.3 (2026-05-10)
### Fix
- **qdrant**: use collection_exists for startup probe (multi-tenant safe)
## v0.83.2 (2026-05-09)
### Fix
+22 -6
View File
@@ -559,17 +559,33 @@ async def get_qdrant_client() -> AsyncQdrantClient:
expected_dimension = embedding_service.get_dimension()
# Explicitly check if collection exists
logger.debug(f"Checking if collection '{collection_name}' exists...")
collections = await provisional.get_collections()
collection_names = [c.name for c in collections.collections]
# Existence check folded into the get_collection() call.
#
# In managed multi-tenant Qdrant Cloud setups, per-tenant JWTs are
# scoped to a single collection (`access: [{"collection": "...",
# "access": "rw"}]`) and Qdrant denies the cluster-level meta
# endpoints `GET /collections` (used by `get_collections()`) and
# `GET /collections/{name}/exists` (used by `collection_exists()`)
# with 403 Forbidden — by design, since listing or probing
# collections cluster-wide is a tenant-isolation boundary.
# `GET /collections/{name}` (the underlying call for
# `get_collection()`) is the only existence-probe permitted on a
# collection-scoped JWT — it returns 200 with the collection
# detail on hit and 404 on miss.
logger.debug(f"Fetching collection '{collection_name}' details...")
collection_info = None
try:
collection_info = await provisional.get_collection(collection_name)
except UnexpectedResponse as exc:
if exc.status_code != 404:
raise
logger.debug(f"Collection '{collection_name}' not found (404).")
if collection_name in collection_names:
if collection_info is not None:
# Collection exists - validate dimensions
logger.debug(
f"Collection '{collection_name}' found, validating dimensions..."
)
collection_info = await provisional.get_collection(collection_name)
# Handle both named vectors (dict) and legacy single vector
vectors = collection_info.config.params.vectors
if isinstance(vectors, dict):
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "nextcloud-mcp-server"
version = "0.83.2"
version = "0.83.4"
description = "Model Context Protocol (MCP) server for Nextcloud integration - enables AI assistants to interact with Nextcloud data"
authors = [
{name = "Chris Coutinho", email = "chris@coutinho.io"}
Generated
+1 -1
View File
@@ -2123,7 +2123,7 @@ wheels = [
[[package]]
name = "nextcloud-mcp-server"
version = "0.83.2"
version = "0.83.4"
source = { editable = "." }
dependencies = [
{ name = "aiosqlite" },