From 2bccc3dad9dd837b15ed349c347e67666ea0ca62 Mon Sep 17 00:00:00 2001 From: "renovate-bot-cbcoutinho[bot]" <210269379+renovate-bot-cbcoutinho[bot]@users.noreply.github.com> Date: Sat, 22 Nov 2025 23:04:40 +0000 Subject: [PATCH 1/7] chore(deps): update docker.io/library/python:3.12-slim-trixie docker digest to b43ff04 --- Dockerfile | 2 +- Dockerfile.smithery | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 91bc485..0cba525 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/python:3.12-slim-trixie@sha256:2e683fc3e18a248aa23b8022f2a3474b072b04fb851efe9b49f6b516a8944939 +FROM docker.io/library/python:3.12-slim-trixie@sha256:b43ff04d5df04ad5cabb80890b7ef74e8410e3395b19af970dcd52d7a4bff921 COPY --from=ghcr.io/astral-sh/uv:0.9.11@sha256:5aa820129de0a600924f166aec9cb51613b15b68f1dcd2a02f31a500d2ede568 /uv /uvx /bin/ diff --git a/Dockerfile.smithery b/Dockerfile.smithery index 9be7ac6..9f20375 100644 --- a/Dockerfile.smithery +++ b/Dockerfile.smithery @@ -12,7 +12,7 @@ # - Per-session app password authentication # - Multi-user support via Smithery session config -FROM docker.io/library/python:3.12-slim-trixie@sha256:2e683fc3e18a248aa23b8022f2a3474b072b04fb851efe9b49f6b516a8944939 +FROM docker.io/library/python:3.12-slim-trixie@sha256:b43ff04d5df04ad5cabb80890b7ef74e8410e3395b19af970dcd52d7a4bff921 WORKDIR /app From 1f3c35f162362d659c456c972f02f30e45ccddf5 Mon Sep 17 00:00:00 2001 From: "renovate-bot-cbcoutinho[bot]" <210269379+renovate-bot-cbcoutinho[bot]@users.noreply.github.com> Date: Sat, 22 Nov 2025 23:04:43 +0000 Subject: [PATCH 2/7] chore(deps): update ghcr.io/astral-sh/uv docker tag to v0.9.11 --- Dockerfile.smithery | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.smithery b/Dockerfile.smithery index 9be7ac6..3236399 100644 --- a/Dockerfile.smithery +++ b/Dockerfile.smithery @@ -17,7 +17,7 @@ FROM docker.io/library/python:3.12-slim-trixie@sha256:2e683fc3e18a248aa23b8022f2 WORKDIR /app # Install uv for fast dependency management -COPY --from=ghcr.io/astral-sh/uv:0.9.10@sha256:29bd45092ea8902c0bbb7f0a338f0494a382b1f4b18355df5be270ade679ff1d /uv /uvx /bin/ +COPY --from=ghcr.io/astral-sh/uv:0.9.11@sha256:5aa820129de0a600924f166aec9cb51613b15b68f1dcd2a02f31a500d2ede568 /uv /uvx /bin/ # Install dependencies # 1. git (required for caldav dependency from git) From e86b6e83ae387b6592191406c38767d636f1d7a0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 23 Nov 2025 00:23:47 +0000 Subject: [PATCH 3/7] =?UTF-8?q?bump:=20version=200.46.2=20=E2=86=92=200.47?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++++++ charts/nextcloud-mcp-server/Chart.yaml | 4 ++-- pyproject.toml | 2 +- uv.lock | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 568dbfd..ecbc514 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v0.47.0 (2025-11-23) + +### Feat + +- Add OpenAI provider support for embeddings and generation + ## v0.46.2 (2025-11-22) ### Fix diff --git a/charts/nextcloud-mcp-server/Chart.yaml b/charts/nextcloud-mcp-server/Chart.yaml index a53bb77..dcfe611 100644 --- a/charts/nextcloud-mcp-server/Chart.yaml +++ b/charts/nextcloud-mcp-server/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: nextcloud-mcp-server description: A Helm chart for Nextcloud MCP Server - enables AI assistants to interact with Nextcloud type: application -version: 0.46.2 -appVersion: "0.46.2" +version: 0.47.0 +appVersion: "0.47.0" keywords: - nextcloud - mcp diff --git a/pyproject.toml b/pyproject.toml index 57d822a..da0540b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "nextcloud-mcp-server" -version = "0.46.2" +version = "0.47.0" 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"} diff --git a/uv.lock b/uv.lock index 0de8ebd..ed610fe 100644 --- a/uv.lock +++ b/uv.lock @@ -1936,7 +1936,7 @@ wheels = [ [[package]] name = "nextcloud-mcp-server" -version = "0.46.2" +version = "0.47.0" source = { editable = "." } dependencies = [ { name = "aiosqlite" }, From 626c4bf562f30bb3ce7a4311fc6e995814625c55 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 23 Nov 2025 00:53:24 +0000 Subject: [PATCH 4/7] =?UTF-8?q?bump:=20version=200.47.0=20=E2=86=92=200.48?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++++++ charts/nextcloud-mcp-server/Chart.yaml | 4 ++-- pyproject.toml | 2 +- uv.lock | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecbc514..a6daa67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v0.48.0 (2025-11-23) + +### Feat + +- Add tag management methods to WebDAV client + ## v0.47.0 (2025-11-23) ### Feat diff --git a/charts/nextcloud-mcp-server/Chart.yaml b/charts/nextcloud-mcp-server/Chart.yaml index dcfe611..c927e3e 100644 --- a/charts/nextcloud-mcp-server/Chart.yaml +++ b/charts/nextcloud-mcp-server/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: nextcloud-mcp-server description: A Helm chart for Nextcloud MCP Server - enables AI assistants to interact with Nextcloud type: application -version: 0.47.0 -appVersion: "0.47.0" +version: 0.48.0 +appVersion: "0.48.0" keywords: - nextcloud - mcp diff --git a/pyproject.toml b/pyproject.toml index da0540b..6b2fea0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "nextcloud-mcp-server" -version = "0.47.0" +version = "0.48.0" 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"} diff --git a/uv.lock b/uv.lock index ed610fe..2994efb 100644 --- a/uv.lock +++ b/uv.lock @@ -1936,7 +1936,7 @@ wheels = [ [[package]] name = "nextcloud-mcp-server" -version = "0.47.0" +version = "0.48.0" source = { editable = "." } dependencies = [ { name = "aiosqlite" }, From 852606ec8ba6346de32aa4a4e84d062cfc0f24dc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 23 Nov 2025 03:03:55 +0000 Subject: [PATCH 5/7] =?UTF-8?q?bump:=20version=200.48.0=20=E2=86=92=200.48?= =?UTF-8?q?.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 10 ++++++++++ charts/nextcloud-mcp-server/Chart.yaml | 4 ++-- pyproject.toml | 2 +- uv.lock | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6daa67..e68320c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## v0.48.1 (2025-11-23) + +### Fix + +- Use WebDAV for tag creation and add LLM-as-a-judge for RAG tests + +### Refactor + +- Move background tasks to server lifespan and deprecate SSE transport + ## v0.48.0 (2025-11-23) ### Feat diff --git a/charts/nextcloud-mcp-server/Chart.yaml b/charts/nextcloud-mcp-server/Chart.yaml index c927e3e..9d01c4e 100644 --- a/charts/nextcloud-mcp-server/Chart.yaml +++ b/charts/nextcloud-mcp-server/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: nextcloud-mcp-server description: A Helm chart for Nextcloud MCP Server - enables AI assistants to interact with Nextcloud type: application -version: 0.48.0 -appVersion: "0.48.0" +version: 0.48.1 +appVersion: "0.48.1" keywords: - nextcloud - mcp diff --git a/pyproject.toml b/pyproject.toml index 6b2fea0..0502c7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "nextcloud-mcp-server" -version = "0.48.0" +version = "0.48.1" 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"} diff --git a/uv.lock b/uv.lock index 2994efb..b2b51b4 100644 --- a/uv.lock +++ b/uv.lock @@ -1936,7 +1936,7 @@ wheels = [ [[package]] name = "nextcloud-mcp-server" -version = "0.48.0" +version = "0.48.1" source = { editable = "." } dependencies = [ { name = "aiosqlite" }, From 6df58af0c3aff7a9566df9cad966c7e924305a94 Mon Sep 17 00:00:00 2001 From: Chris Coutinho Date: Sun, 23 Nov 2025 04:09:37 +0100 Subject: [PATCH 6/7] ci: Decrease polling interval to 5s --- .github/workflows/rag-evaluation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rag-evaluation.yml b/.github/workflows/rag-evaluation.yml index 148321d..a5446b5 100644 --- a/.github/workflows/rag-evaluation.yml +++ b/.github/workflows/rag-evaluation.yml @@ -49,7 +49,7 @@ jobs: env: # Override MCP container environment for OpenAI + vector sync VECTOR_SYNC_ENABLED: "true" - VECTOR_SYNC_SCAN_INTERVAL: "30" + VECTOR_SYNC_SCAN_INTERVAL: "5" OPENAI_API_KEY: ${{ secrets.GITHUB_TOKEN }} OPENAI_BASE_URL: "https://models.github.ai/inference" OPENAI_EMBEDDING_MODEL: ${{ inputs.embedding_model }} From a134a0fc08da2cfbcb37df406a64ebc227d9da0e Mon Sep 17 00:00:00 2001 From: Chris Coutinho Date: Sun, 23 Nov 2025 04:20:09 +0100 Subject: [PATCH 7/7] fix: Share vector sync state with FastMCP session lifespan via module singleton MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The refactor in fafeaf3 moved background tasks to Starlette server lifespan but broke nc_get_vector_sync_status because it still looked for streams in FastMCP's AppContext (lifespan_context). Add VectorSyncState module singleton to bridge the lifespans: - starlette_lifespan sets the singleton when starting background tasks - app_lifespan_basic reads from singleton and includes in AppContext - MCP tools can now access document_receive_stream for pending count 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- nextcloud_mcp_server/app.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/nextcloud_mcp_server/app.py b/nextcloud_mcp_server/app.py index b4ab820..f1185d6 100644 --- a/nextcloud_mcp_server/app.py +++ b/nextcloud_mcp_server/app.py @@ -243,6 +243,25 @@ def validate_pkce_support(discovery: dict, discovery_url: str) -> None: click.echo(f"✓ PKCE support validated: {code_challenge_methods}") +@dataclass +class VectorSyncState: + """ + Module-level state for vector sync background tasks. + + This singleton bridges the Starlette server lifespan (where background tasks run) + and FastMCP session lifespans (where MCP tools need access to the streams). + """ + + document_send_stream: Optional[MemoryObjectSendStream] = None + document_receive_stream: Optional[MemoryObjectReceiveStream] = None + shutdown_event: Optional[anyio.Event] = None + scanner_wake_event: Optional[anyio.Event] = None + + +# Module-level singleton for vector sync state +_vector_sync_state = VectorSyncState() + + @dataclass class AppContext: """Application context for BasicAuth mode.""" @@ -580,8 +599,16 @@ async def app_lifespan_basic(server: FastMCP) -> AsyncIterator[AppContext]: initialize_document_processors() # Yield client context - scanner runs at server level (starlette_lifespan) + # Include vector sync state from module singleton (set by starlette_lifespan) try: - yield AppContext(client=client, storage=storage) + yield AppContext( + client=client, + storage=storage, + document_send_stream=_vector_sync_state.document_send_stream, + document_receive_stream=_vector_sync_state.document_receive_stream, + shutdown_event=_vector_sync_state.shutdown_event, + scanner_wake_event=_vector_sync_state.scanner_wake_event, + ) finally: logger.info("Shutting down BasicAuth session") await client.close() @@ -1228,6 +1255,13 @@ def get_app(transport: str = "streamable-http", enabled_apps: list[str] | None = app.state.shutdown_event = shutdown_event app.state.scanner_wake_event = scanner_wake_event + # Also store in module singleton for FastMCP session lifespans + _vector_sync_state.document_send_stream = send_stream + _vector_sync_state.document_receive_stream = receive_stream + _vector_sync_state.shutdown_event = shutdown_event + _vector_sync_state.scanner_wake_event = scanner_wake_event + logger.info("Vector sync state stored in module singleton") + # Also share with browser_app for /app route for route in app.routes: if isinstance(route, Mount) and route.path == "/app":