8f45e996e8
Implements background vector database synchronization using anyio TaskGroups for BasicAuth mode with single-user credentials. Scanner Implementation: - Periodic document discovery (hourly, configurable) - Timestamp-based change detection (Nextcloud vs Qdrant) - Wake event for immediate scanning on-demand - Supports both initial sync (all docs) and incremental sync (changes only) - Detects deleted documents and queues for removal Processor Implementation: - Concurrent document processing pool (3 workers default) - I/O-bound embedding generation via Ollama API - Retry logic with exponential backoff (3 retries) - Document chunking (512 words, 50-word overlap) - Handles both index and delete operations - Upserts vectors to Qdrant with rich metadata App Lifespan Integration: - Extended AppContext with background task state - Modified app_lifespan_basic() to start tasks via anyio TaskGroups - Graceful shutdown with coordinated task cancellation - Only activates when VECTOR_SYNC_ENABLED=true Embedding Service: - OllamaEmbeddingProvider with TLS support - Singleton pattern for shared client instances - Batch embedding support for efficiency - Auto-detects embedding dimension (768 for nomic-embed-text) Qdrant Client: - Async client wrapper with singleton pattern - Auto-creates collection on first use - COSINE distance metric for semantic similarity - Integrates with embedding service for dimension detection Health Check Enhancement: - Added Qdrant status check to /health/ready endpoint - Only checks when VECTOR_SYNC_ENABLED=true - 2-second timeout for health probe - Reports connection errors with details Configuration: - VECTOR_SYNC_ENABLED: Enable background sync - VECTOR_SYNC_SCAN_INTERVAL: Scanner frequency (3600s default) - VECTOR_SYNC_PROCESSOR_WORKERS: Concurrent processors (3 default) - QDRANT_URL, QDRANT_API_KEY, QDRANT_COLLECTION: Vector DB config - OLLAMA_BASE_URL, OLLAMA_EMBEDDING_MODEL: Embedding service config Dependencies Added: - qdrant-client>=1.7.0: Vector database client Docker Compose: - Added Qdrant service with health check - Exposed ports 6333 (REST) and 6334 (gRPC) - Configured MCP service with vector sync environment - Added qdrant-data volume for persistence Known Issue: - FastMCP lifespan not triggering for streamable-http transport - Background tasks will start once lifespan integration is complete - Lifespan triggers on MCP session establishment, not server startup Related: ADR-007 Background Vector Database Synchronization 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
117 lines
3.6 KiB
TOML
117 lines
3.6 KiB
TOML
[project]
|
|
name = "nextcloud-mcp-server"
|
|
version = "0.26.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"}
|
|
]
|
|
readme = "README.md"
|
|
license = {text = "AGPL-3.0-only"}
|
|
requires-python = ">=3.11"
|
|
keywords = ["nextcloud", "mcp", "model-context-protocol", "llm", "ai", "claude", "webdav", "caldav", "carddav"]
|
|
dependencies = [
|
|
"mcp[cli] (>=1.21,<1.22)",
|
|
"httpx (>=0.28.1,<0.29.0)",
|
|
"pillow (>=12.0.0,<12.1.0)",
|
|
"icalendar (>=6.0.0,<7.0.0)",
|
|
"pythonvcard4>=0.2.0",
|
|
"pydantic>=2.11.4",
|
|
"click>=8.1.8",
|
|
"caldav",
|
|
"pyjwt[crypto]>=2.8.0",
|
|
"aiosqlite>=0.20.0", # Async SQLite for refresh token storage
|
|
"authlib>=1.6.5",
|
|
"qdrant-client>=1.7.0", # Vector database for semantic search
|
|
]
|
|
classifiers = [
|
|
"Development Status :: 4 - Beta",
|
|
"Intended Audience :: Developers",
|
|
"License :: OSI Approved :: GNU Affero General Public License v3",
|
|
"Programming Language :: Python :: 3",
|
|
"Programming Language :: Python :: 3.11",
|
|
"Programming Language :: Python :: 3.12",
|
|
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
"Topic :: Communications",
|
|
"Topic :: Internet :: WWW/HTTP",
|
|
]
|
|
|
|
[project.urls]
|
|
Homepage = "https://github.com/cbcoutinho/nextcloud-mcp-server"
|
|
Documentation = "https://github.com/cbcoutinho/nextcloud-mcp-server#readme"
|
|
Repository = "https://github.com/cbcoutinho/nextcloud-mcp-server"
|
|
"Bug Tracker" = "https://github.com/cbcoutinho/nextcloud-mcp-server/issues"
|
|
Changelog = "https://github.com/cbcoutinho/nextcloud-mcp-server/blob/master/CHANGELOG.md"
|
|
|
|
[tool.pytest.ini_options]
|
|
anyio_mode = "auto"
|
|
addopts = "-p no:asyncio -x" # Disable pytest-asyncio plugin, use only anyio
|
|
log_cli = 1
|
|
log_cli_level = "ERROR"
|
|
log_level = "ERROR"
|
|
markers = [
|
|
"unit: Fast unit tests with mocked dependencies",
|
|
"integration: Integration tests requiring Docker containers",
|
|
"oauth: OAuth tests requiring Playwright (slowest)",
|
|
"smoke: Critical path smoke tests for quick validation",
|
|
"keycloak: OAuth tests that utilize keycloak external identity provider",
|
|
]
|
|
testpaths = [
|
|
"tests",
|
|
]
|
|
# Timeout settings to prevent tests from hanging indefinitely
|
|
timeout = 180 # 3 minutes default timeout per test (includes fixture setup)
|
|
timeout_func_only = false # Timeout includes fixture setup/teardown
|
|
|
|
[tool.commitizen]
|
|
name = "cz_conventional_commits"
|
|
tag_format = "v$version"
|
|
version_scheme = "pep440"
|
|
version_provider = "uv"
|
|
update_changelog_on_bump = true
|
|
major_version_zero = true
|
|
version_files = [
|
|
"charts/nextcloud-mcp-server/Chart.yaml:appVersion",
|
|
"charts/nextcloud-mcp-server/Chart.yaml:version"
|
|
]
|
|
ignored_tag_formats = [
|
|
"nextcloud-mcp-server-*"
|
|
]
|
|
|
|
[tool.ruff.lint]
|
|
extend-select = ["I"]
|
|
|
|
[tool.uv.sources]
|
|
caldav = { git = "https://github.com/cbcoutinho/caldav", branch = "feature/httpx" }
|
|
|
|
[build-system]
|
|
requires = ["uv_build>=0.9.4,<0.10.0"]
|
|
build-backend = "uv_build"
|
|
|
|
[tool.uv.build-backend]
|
|
module-name = "nextcloud_mcp_server"
|
|
module-root = ""
|
|
|
|
[dependency-groups]
|
|
dev = [
|
|
"commitizen>=4.8.2",
|
|
"ipython>=9.2.0",
|
|
"playwright>=1.49.1",
|
|
"pytest>=8.3.5",
|
|
"pytest-cov>=6.1.1",
|
|
"pytest-mock>=3.15.1",
|
|
"pytest-playwright-asyncio>=0.7.1",
|
|
"pytest-timeout>=2.3.1",
|
|
"ruff>=0.11.13",
|
|
"reportlab>=4.0.0",
|
|
"ty>=0.0.1a25",
|
|
]
|
|
|
|
[project.scripts]
|
|
nextcloud-mcp-server = "nextcloud_mcp_server.app:run"
|
|
|
|
[[tool.uv.index]]
|
|
name = "testpypi"
|
|
url = "https://test.pypi.org/simple/"
|
|
publish-url = "https://test.pypi.org/legacy/"
|
|
explicit = true
|