diff --git a/charts/nextcloud-mcp-server/.gitignore b/charts/nextcloud-mcp-server/.gitignore new file mode 100644 index 0000000..ee3892e --- /dev/null +++ b/charts/nextcloud-mcp-server/.gitignore @@ -0,0 +1 @@ +charts/ diff --git a/charts/nextcloud-mcp-server/Chart.lock b/charts/nextcloud-mcp-server/Chart.lock new file mode 100644 index 0000000..08b5e13 --- /dev/null +++ b/charts/nextcloud-mcp-server/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: qdrant + repository: https://qdrant.github.io/qdrant-helm + version: 0.9.0 +- name: ollama + repository: https://otwld.github.io/ollama-helm + version: 1.33.0 +digest: sha256:c53b7a604d202460f60408a62025ae837cad8d4da970b1e5bb404e2b41289f94 +generated: "2025-11-08T23:44:59.709689907+01:00" diff --git a/charts/nextcloud-mcp-server/Chart.yaml b/charts/nextcloud-mcp-server/Chart.yaml index e16c754..8505981 100644 --- a/charts/nextcloud-mcp-server/Chart.yaml +++ b/charts/nextcloud-mcp-server/Chart.yaml @@ -21,3 +21,12 @@ home: https://github.com/cbcoutinho/nextcloud-mcp-server sources: - https://github.com/cbcoutinho/nextcloud-mcp-server icon: https://raw.githubusercontent.com/nextcloud/server/master/core/img/logo/logo.svg +dependencies: + - name: qdrant + version: "0.9.0" + repository: https://qdrant.github.io/qdrant-helm + condition: qdrant.enabled + - name: ollama + version: "1.33.0" + repository: https://otwld.github.io/ollama-helm + condition: ollama.enabled diff --git a/charts/nextcloud-mcp-server/README.md b/charts/nextcloud-mcp-server/README.md index e6b120e..3082bbb 100644 --- a/charts/nextcloud-mcp-server/README.md +++ b/charts/nextcloud-mcp-server/README.md @@ -202,6 +202,67 @@ The application exposes HTTP health check endpoints: | `documentProcessing.unstructured.apiUrl` | Unstructured API URL | `http://unstructured:8000` | | `documentProcessing.tesseract.enabled` | Enable Tesseract OCR | `false` | +#### Vector Search & Semantic Capabilities (Optional) + +Enable semantic search capabilities by deploying a vector database (Qdrant) and embedding service (Ollama or OpenAI). + +**Vector Sync Configuration:** + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `vectorSync.enabled` | Enable background vector synchronization | `false` | +| `vectorSync.scanInterval` | Scan interval in seconds | `3600` | +| `vectorSync.processorWorkers` | Number of concurrent processor workers | `3` | +| `vectorSync.queueMaxSize` | Maximum queue size for pending documents | `10000` | + +**Qdrant Vector Database:** + +Qdrant is deployed as a subchart when `qdrant.enabled` is `true`. All configuration values are passed through to the [qdrant/qdrant](https://github.com/qdrant/qdrant-helm) chart. + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `qdrant.enabled` | Deploy Qdrant as a subchart | `false` | +| `qdrant.replicaCount` | Number of Qdrant replicas | `1` | +| `qdrant.image.tag` | Qdrant version | `v1.12.5` | +| `qdrant.apiKey` | Optional API key for authentication | `""` | +| `qdrant.persistence.size` | Storage size for vector data | `10Gi` | +| `qdrant.persistence.storageClass` | Storage class | `""` | +| `qdrant.resources.requests.cpu` | CPU request | `200m` | +| `qdrant.resources.requests.memory` | Memory request | `512Mi` | +| `qdrant.resources.limits.cpu` | CPU limit | `1000m` | +| `qdrant.resources.limits.memory` | Memory limit | `2Gi` | + +**Ollama Embedding Service:** + +Ollama is deployed as a subchart when `ollama.enabled` is `true`. All configuration values are passed through to the [ollama/ollama](https://github.com/otwld/ollama-helm) chart. Alternatively, set `ollama.url` to use an external Ollama instance. + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `ollama.enabled` | Deploy Ollama as a subchart | `false` | +| `ollama.url` | External Ollama URL (use with `enabled: false`) | `""` | +| `ollama.embeddingModel` | Embedding model to use | `nomic-embed-text` | +| `ollama.verifySsl` | Verify SSL certificates | `true` | +| `ollama.replicaCount` | Number of Ollama replicas | `1` | +| `ollama.ollama.models.pull` | Models to pull on startup | `["nomic-embed-text"]` | +| `ollama.persistentVolume.enabled` | Enable persistent storage | `true` | +| `ollama.persistentVolume.size` | Storage size for models | `20Gi` | +| `ollama.resources.requests.cpu` | CPU request | `500m` | +| `ollama.resources.requests.memory` | Memory request | `1Gi` | +| `ollama.resources.limits.cpu` | CPU limit | `2000m` | +| `ollama.resources.limits.memory` | Memory limit | `4Gi` | + +**OpenAI Embedding Provider (Alternative):** + +Use OpenAI or any OpenAI-compatible API instead of Ollama. + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `openai.enabled` | Enable OpenAI embedding provider | `false` | +| `openai.apiKey` | OpenAI API key | `""` | +| `openai.existingSecret` | Use existing secret for API key | `""` | +| `openai.secretKey` | Key in secret containing API key | `api-key` | +| `openai.baseUrl` | Custom API endpoint (optional) | `""` | + ## Examples ### Example 1: Basic Auth with Ingress @@ -379,6 +440,90 @@ affinity: topologyKey: kubernetes.io/hostname ``` +### Example 5: Semantic Search with Qdrant and Ollama + +Deploy with vector search capabilities using embedded Qdrant and Ollama: + +```yaml +nextcloud: + host: https://cloud.example.com + +auth: + mode: basic + basic: + username: admin + password: secure-password + +# Enable vector sync +vectorSync: + enabled: true + scanInterval: 1800 # Scan every 30 minutes + processorWorkers: 5 + +# Deploy Qdrant as a subchart +qdrant: + enabled: true + persistence: + size: 20Gi + storageClass: fast-ssd + resources: + requests: + cpu: 500m + memory: 1Gi + limits: + cpu: 2000m + memory: 4Gi + +# Deploy Ollama as a subchart +ollama: + enabled: true + embeddingModel: nomic-embed-text + persistentVolume: + size: 30Gi + storageClass: standard + resources: + requests: + cpu: 1000m + memory: 2Gi + limits: + cpu: 4000m + memory: 8Gi +``` + +Or use an external Ollama instance: + +```yaml +vectorSync: + enabled: true + +qdrant: + enabled: true + +# Use external Ollama instead of deploying subchart +ollama: + enabled: false + url: "http://ollama.ai-services.svc.cluster.local:11434" + embeddingModel: nomic-embed-text +``` + +Or use OpenAI for embeddings: + +```yaml +vectorSync: + enabled: true + +qdrant: + enabled: true + +# Use OpenAI instead of Ollama +openai: + enabled: true + apiKey: "sk-..." + # Or use existing secret: + # existingSecret: openai-api-key + # secretKey: api-key +``` + ## Upgrading ### To upgrade an existing deployment: diff --git a/charts/nextcloud-mcp-server/templates/NOTES.txt b/charts/nextcloud-mcp-server/templates/NOTES.txt index fdc5e15..2ab528f 100644 --- a/charts/nextcloud-mcp-server/templates/NOTES.txt +++ b/charts/nextcloud-mcp-server/templates/NOTES.txt @@ -69,6 +69,33 @@ Your Nextcloud MCP Server has been deployed in {{ .Values.auth.mode }} authentic {{- end }} {{- end }} +{{- if .Values.vectorSync.enabled }} + +5. Vector Search & Semantic Capabilities: + - Vector Sync: Enabled + - Scan Interval: {{ .Values.vectorSync.scanInterval }}s + - Processor Workers: {{ .Values.vectorSync.processorWorkers }} + {{- if .Values.qdrant.enabled }} + - Qdrant: Deployed as subchart ({{ .Release.Name }}-qdrant:6333) + {{- else }} + - Qdrant: Not deployed (configure external instance) + {{- end }} + {{- if .Values.ollama.enabled }} + - Ollama: Deployed as subchart ({{ .Release.Name }}-ollama:11434) + - Embedding Model: {{ .Values.ollama.embeddingModel }} + {{- else if .Values.ollama.url }} + - Ollama: Using external instance at {{ .Values.ollama.url }} + - Embedding Model: {{ .Values.ollama.embeddingModel }} + {{- else if .Values.openai.enabled }} + - OpenAI: Enabled for embeddings + {{- else }} + - WARNING: No embedding provider configured (Ollama or OpenAI required) + {{- end }} + + Check vector sync status: + kubectl --namespace {{ .Release.Namespace }} exec -it deploy/{{ include "nextcloud-mcp-server.fullname" . }} -- curl -s http://localhost:{{ include "nextcloud-mcp-server.port" . }}/user/page | grep "Vector Sync" +{{- end }} + For more information and documentation: - GitHub: https://github.com/cbcoutinho/nextcloud-mcp-server - Documentation: https://github.com/cbcoutinho/nextcloud-mcp-server#readme diff --git a/charts/nextcloud-mcp-server/templates/deployment.yaml b/charts/nextcloud-mcp-server/templates/deployment.yaml index 09e21b1..51a4fbb 100644 --- a/charts/nextcloud-mcp-server/templates/deployment.yaml +++ b/charts/nextcloud-mcp-server/templates/deployment.yaml @@ -140,6 +140,52 @@ spec: value: {{ .Values.documentProcessing.custom.types | quote }} {{- end }} {{- end }} + # Vector Sync + - name: VECTOR_SYNC_ENABLED + value: {{ .Values.vectorSync.enabled | quote }} + {{- if .Values.vectorSync.enabled }} + - name: VECTOR_SYNC_SCAN_INTERVAL + value: {{ .Values.vectorSync.scanInterval | quote }} + - name: VECTOR_SYNC_PROCESSOR_WORKERS + value: {{ .Values.vectorSync.processorWorkers | quote }} + - name: VECTOR_SYNC_QUEUE_MAX_SIZE + value: {{ .Values.vectorSync.queueMaxSize | quote }} + {{- end }} + # Qdrant Vector Database + {{- if .Values.qdrant.enabled }} + - name: QDRANT_URL + value: "http://{{ .Release.Name }}-qdrant:6333" + - name: QDRANT_COLLECTION + value: "nextcloud_content" + {{- if .Values.qdrant.apiKey }} + - name: QDRANT_API_KEY + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-qdrant + key: api-key + {{- end }} + {{- end }} + # Ollama Embedding Service + {{- if or .Values.ollama.enabled .Values.ollama.url }} + - name: OLLAMA_BASE_URL + value: {{ .Values.ollama.url | default (printf "http://%s-ollama:11434" .Release.Name) | quote }} + - name: OLLAMA_EMBEDDING_MODEL + value: {{ .Values.ollama.embeddingModel | quote }} + - name: OLLAMA_VERIFY_SSL + value: {{ .Values.ollama.verifySsl | quote }} + {{- end }} + # OpenAI Embedding Provider (alternative to Ollama) + {{- if .Values.openai.enabled }} + - name: OPENAI_API_KEY + valueFrom: + secretKeyRef: + name: {{ .Values.openai.existingSecret | default (printf "%s-openai" (include "nextcloud-mcp-server.fullname" .)) }} + key: {{ .Values.openai.secretKey }} + {{- if .Values.openai.baseUrl }} + - name: OPENAI_BASE_URL + value: {{ .Values.openai.baseUrl | quote }} + {{- end }} + {{- end }} {{- with .Values.extraEnv }} {{- toYaml . | nindent 12 }} {{- end }} diff --git a/charts/nextcloud-mcp-server/templates/openai-secret.yaml b/charts/nextcloud-mcp-server/templates/openai-secret.yaml new file mode 100644 index 0000000..d8514a3 --- /dev/null +++ b/charts/nextcloud-mcp-server/templates/openai-secret.yaml @@ -0,0 +1,11 @@ +{{- if and .Values.openai.enabled (not .Values.openai.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "nextcloud-mcp-server.fullname" . }}-openai + labels: + {{- include "nextcloud-mcp-server.labels" . | nindent 4 }} +type: Opaque +data: + {{ .Values.openai.secretKey }}: {{ .Values.openai.apiKey | b64enc | quote }} +{{- end }} diff --git a/charts/nextcloud-mcp-server/values.yaml b/charts/nextcloud-mcp-server/values.yaml index ab4361a..b407591 100644 --- a/charts/nextcloud-mcp-server/values.yaml +++ b/charts/nextcloud-mcp-server/values.yaml @@ -264,3 +264,98 @@ extraEnvFrom: [] # name: my-configmap # - secretRef: # name: my-secret + +# Vector Sync Configuration +# Background synchronization of Nextcloud content into vector database for semantic search +vectorSync: + # Enable background vector synchronization + enabled: false + # Scan interval in seconds (how often to check for changes) + scanInterval: 3600 + # Number of concurrent processor workers + processorWorkers: 3 + # Maximum queue size for documents pending indexing + queueMaxSize: 10000 + +# Qdrant Vector Database +# Deployed as a subchart when enabled. All values are passed through to the qdrant/qdrant chart. +# See https://github.com/qdrant/qdrant-helm for full configuration options. +qdrant: + # Enable Qdrant subchart deployment + enabled: false + # Number of Qdrant replicas + replicaCount: 1 + image: + # Qdrant version + tag: v1.12.5 + # Optional API key for Qdrant authentication + apiKey: "" + config: + cluster: + # Enable distributed cluster mode + enabled: false + # Persistent storage for vector data + persistence: + size: 10Gi + storageClass: "" + accessModes: + - ReadWriteOnce + # Resource limits and requests + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + cpu: 1000m + memory: 2Gi + +# Ollama Embedding Service +# Deployed as a subchart when enabled. All values are passed through to the ollama/ollama chart. +# See https://github.com/otwld/ollama-helm for full configuration options. +ollama: + # Enable Ollama subchart deployment + # Set to true to deploy Ollama as a subchart, or false to use an external Ollama instance + enabled: false + # External Ollama URL (use this if you have Ollama deployed elsewhere) + # When set, use enabled: false to prevent deploying the subchart + # Example: "http://ollama.default.svc.cluster.local:11434" + url: "" + # Embedding model to use + embeddingModel: "nomic-embed-text" + # Verify SSL certificates when connecting to Ollama + verifySsl: true + # Number of Ollama replicas (only used when subchart is deployed) + replicaCount: 1 + # Ollama configuration (only used when subchart is deployed) + ollama: + # Models to automatically pull on startup + models: + pull: + - nomic-embed-text + # Persistent storage for models (only used when subchart is deployed) + persistentVolume: + enabled: true + size: 20Gi + storageClass: "" + # Resource limits and requests (only used when subchart is deployed) + resources: + requests: + cpu: 500m + memory: 1Gi + limits: + cpu: 2000m + memory: 4Gi + +# OpenAI-compatible Embedding Provider +# Alternative to Ollama for embedding generation. Can be used with OpenAI or any compatible API. +openai: + # Enable OpenAI embedding provider + enabled: false + # OpenAI API key (only used if existingSecret is not set) + apiKey: "" + # Name of existing secret containing the API key + existingSecret: "" + # Key in the secret that contains the API key + secretKey: "api-key" + # Optional custom API endpoint (e.g., for Azure OpenAI or local compatible services) + baseUrl: ""