5b484c9226
Refactored LLM provider infrastructure to support sustainable additions of new providers with both embedding and text generation capabilities.
## Major Changes
### Unified Provider Architecture (ADR-015)
- Created `nextcloud_mcp_server/providers/` with unified Provider ABC
- Providers now support optional capabilities (embeddings and/or generation)
- Auto-detection registry with priority: Bedrock → Ollama → Simple
- Backward compatible - existing code continues to work
### New Providers
- **BedrockProvider**: Full Amazon Bedrock integration
- Embeddings: Titan Embed, Cohere Embed models
- Generation: Claude, Llama, Titan Text, Mistral models
- Model-specific request/response handling
- AWS credential chain integration
- **OllamaProvider**: Migrated with both capabilities support
- **AnthropicProvider**: Moved from test code to production providers
- **SimpleProvider**: Migrated in-memory fallback provider
### Breaking Changes
None - full backward compatibility maintained:
- `embedding.get_embedding_service()` still works
- RAG evaluation tests updated to use unified providers
- All existing tests pass (127 unit tests)
### Testing
- Added 9 comprehensive Bedrock unit tests with mocked boto3
- All existing unit tests pass
- Type checking (ty) and linting (ruff) pass
- Verified backward compatibility
### Documentation
- `docs/ADR-015-unified-provider-architecture.md`: Comprehensive ADR
- `docs/bedrock-setup.md`: AWS setup guide with IAM permissions
- `CLAUDE.md`: Updated with provider architecture section
### Dependencies
- Added `boto3>=1.35.0` to dev dependencies (optional)
## Environment Variables
### Bedrock
- `AWS_REGION`: AWS region (e.g., "us-east-1")
- `BEDROCK_EMBEDDING_MODEL`: Model ID for embeddings
- `BEDROCK_GENERATION_MODEL`: Model ID for generation
- `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`: Optional credentials
### Ollama
- `OLLAMA_BASE_URL`: API URL
- `OLLAMA_EMBEDDING_MODEL`: Embedding model (default: "nomic-embed-text")
- `OLLAMA_GENERATION_MODEL`: Generation model
## AWS Bedrock Permissions Required
Minimal IAM policy:
```json
{
"Effect": "Allow",
"Action": ["bedrock:InvokeModel"],
"Resource": ["arn:aws:bedrock:*::foundation-model/*"]
}
```
See `docs/bedrock-setup.md` for detailed setup instructions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
130 lines
4.4 KiB
TOML
130 lines
4.4 KiB
TOML
[project]
|
|
name = "nextcloud-mcp-server"
|
|
version = "0.36.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"}
|
|
]
|
|
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 (>=10.3.0,<12.0.0)", # Compatible with fastembed
|
|
"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",
|
|
"fastembed>=0.4.2", # BM25 sparse vector embeddings for hybrid search
|
|
# Observability dependencies
|
|
"prometheus-client>=0.21.0", # Prometheus metrics
|
|
"opentelemetry-api>=1.28.2", # OpenTelemetry API
|
|
"opentelemetry-sdk>=1.28.2", # OpenTelemetry SDK
|
|
"opentelemetry-instrumentation-asgi>=0.49b2", # Auto-instrument ASGI/Starlette
|
|
"opentelemetry-instrumentation-httpx>=0.49b2", # Auto-instrument httpx client
|
|
"opentelemetry-instrumentation-logging>=0.49b2", # Logging integration
|
|
"opentelemetry-exporter-otlp-proto-grpc>=1.28.2", # OTLP gRPC exporter
|
|
"python-json-logger>=3.2.0", # Structured JSON logging
|
|
]
|
|
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 = [
|
|
"anthropic>=0.42.0", # For RAG evaluation with Anthropic LLMs
|
|
"boto3>=1.35.0", # For Amazon Bedrock provider (optional)
|
|
"commitizen>=4.8.2",
|
|
"datasets>=3.3.0", # For BeIR nfcorpus dataset loading
|
|
"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.cli:run"
|
|
|
|
[[tool.uv.index]]
|
|
name = "testpypi"
|
|
url = "https://test.pypi.org/simple/"
|
|
publish-url = "https://test.pypi.org/legacy/"
|
|
explicit = true
|