commit d6f607c8e1c052899137bd52824a137e83aa6cf9 Author: Nick Gorse Date: Fri May 29 14:05:41 2026 +0100 Install ToolHive operator via ArgoCD Co-Authored-By: Claude Opus 4.8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2a241f3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.ci-schemas/ +.ci-rendered/ +.ci-chart-cache/ +.helm-cache/ +.helm-config/ +.helm-data/ +.DS_Store +.kube/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..45f0bc6 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# toolhive + +Installs the [ToolHive](https://docs.stacklok.com/toolhive) Kubernetes operator +via Argo CD, so MCP servers can be declared as `MCPServer` custom resources +(see the `mcp-services` app). Runs in the `toolhive-system` namespace. + +## What it deploys + +A multi-source Argo CD Application renders two OCI Helm charts plus this repo's +values: + +| Source | Purpose | +|---------------------------------------------------------|----------------------------------| +| `oci://ghcr.io/stacklok/toolhive/toolhive-operator-crds`| CRDs (MCPServer, MCPRegistry, …) | +| `oci://ghcr.io/stacklok/toolhive/toolhive-operator` | operator Deployment + RBAC | +| this repo (`ref: values`) | operator Helm values | + +Both charts share a unified version, pinned via `chartVersion` in +`bootstrap/applicationset.yaml` (currently `0.28.3`). RBAC scope is left +`cluster` (chart default) so the operator can reconcile MCPServers in +`mcp-services`. + +## Deploy + +```bash +# validate the operator chart renders with our values +helm template toolhive-operator oci://ghcr.io/stacklok/toolhive/toolhive-operator \ + --version 0.28.3 -n toolhive-system \ + -f manifest/overlays/production/helm-values/values.yaml >/dev/null + +# enable bootstrap/config.yaml (enabled: true), commit, push to main, then: +kubectl get pods -n toolhive-system +kubectl get crd | grep toolhive.stacklok.dev +``` + +Deploy this app **before** `mcp-services` — the MCPServer CRs depend on the CRDs +installed here. + +## Bumping the version + +```bash +curl -s 'https://api.github.com/repos/stacklok/toolhive/releases?per_page=10' \ + | grep tag_name +``` + +Update `chartVersion` in `bootstrap/applicationset.yaml` and push. (The CRDs and +operator charts are released together under the same version number.) diff --git a/bootstrap/applicationset.yaml b/bootstrap/applicationset.yaml new file mode 100644 index 0000000..72b98e9 --- /dev/null +++ b/bootstrap/applicationset.yaml @@ -0,0 +1,51 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: toolhive + namespace: argocd +spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] + generators: + - list: + elements: + - environment: production + namespace: toolhive-system + overlay: production + chartVersion: 0.28.3 + template: + metadata: + name: 'toolhive-{{ .environment }}' + labels: + app.kubernetes.io/managed-by: argocd + app.kubernetes.io/name: toolhive + spec: + project: default + sources: + # 1. ToolHive CRDs (MCPServer, MCPRegistry, ...). No values needed. + - repoURL: ghcr.io/stacklok/toolhive + chart: toolhive-operator-crds + targetRevision: '{{ .chartVersion }}' + # 2. ToolHive operator, values pulled from this repo via $values. + - repoURL: ghcr.io/stacklok/toolhive + chart: toolhive-operator + targetRevision: '{{ .chartVersion }}' + helm: + releaseName: toolhive-operator + valueFiles: + - $values/manifest/overlays/{{ .overlay }}/helm-values/values.yaml + # 3. Values source ref for the operator chart above. + - repoURL: http://gitea-ha-http.apps:3000/olb42/toolhive.git + targetRevision: main + ref: values + destination: + server: https://kubernetes.default.svc + namespace: '{{ .namespace }}' + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + # CRD schemas are large; SSA avoids the last-applied-config annotation limit. + - ServerSideApply=true diff --git a/bootstrap/config.yaml b/bootstrap/config.yaml new file mode 100644 index 0000000..5e77a0b --- /dev/null +++ b/bootstrap/config.yaml @@ -0,0 +1,3 @@ +enabled: false +target_namespace: argocd +apply_from_branch: main diff --git a/manifest/overlays/production/helm-values/values.yaml b/manifest/overlays/production/helm-values/values.yaml new file mode 100644 index 0000000..9f680a4 --- /dev/null +++ b/manifest/overlays/production/helm-values/values.yaml @@ -0,0 +1,13 @@ +# Values for the toolhive-operator Helm chart +# (oci://ghcr.io/stacklok/toolhive/toolhive-operator), supplied to the Argo CD +# multi-source ApplicationSet via $values. Validated as Helm values, not as a +# Kubernetes manifest. +# +# The operator runs in toolhive-system but must watch + reconcile MCPServer +# resources in the mcp-services namespace, so RBAC stays cluster-scoped (the +# chart default). To restrict it, set scope: namespace and list namespaces. + +operator: + rbac: + scope: cluster + allowedNamespaces: []