diff --git a/toolhive/Chart.yaml b/toolhive/Chart.yaml new file mode 100644 index 0000000..82008cd --- /dev/null +++ b/toolhive/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v2 +name: toolhive + +type: application + +version: 0.1.0 + +icon: https://raw.githubusercontent.com/stacklok/toolhive/refs/heads/main/docs/images/toolhive.png diff --git a/toolhive/templates/clusterrole.yaml b/toolhive/templates/clusterrole.yaml new file mode 100644 index 0000000..94b60d0 --- /dev/null +++ b/toolhive/templates/clusterrole.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: toolhive + app.kubernetes.io/name: toolhive + name: {{ .Release.Name }} +rules: + - apiGroups: + - "*" + resources: + - "*" + verbs: + - "*" diff --git a/toolhive/templates/clusterrolebinding.yaml b/toolhive/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..abb5b6a --- /dev/null +++ b/toolhive/templates/clusterrolebinding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app: toolhive + app.kubernetes.io/name: toolhive + name: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }} +subjects: + - kind: ServiceAccount + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} diff --git a/toolhive/templates/deployment.yaml b/toolhive/templates/deployment.yaml new file mode 100644 index 0000000..ba01568 --- /dev/null +++ b/toolhive/templates/deployment.yaml @@ -0,0 +1,56 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }} +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: mcpserver + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: mcpserver + toolhive: "true" + toolhive-name: {{ .Release.Name }} + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + app: mcpserver + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: mcpserver + toolhive: "true" + toolhive-name: {{ .Release.Name }} + spec: + serviceAccount: {{ .Release.Name }} + serviceAccountName: {{ .Release.Name }} + containers: + - args: + - run + - --foreground=true + - --port={{ .Values.port }} + - --name={{ .Release.Name }} + - --transport={{ .Values.transport }} + - --host=0.0.0.0 + - --k8s-pod-patch={"metadata":{"creationTimestamp":null},"spec":{"containers":[{"name":"mcp","resources":{"limits":{"cpu":"500m","memory":"512Mi"},"requests":{"cpu":"100m","memory":"128Mi"}},"securityContext":{"capabilities":{"drop":["ALL"]},"runAsUser":0,"runAsGroup":0,"runAsNonRoot":false,"allowPrivilegeEscalation":false}}],"securityContext":{"runAsUser":0,"runAsGroup":0,"runAsNonRoot":false,"seccompProfile":{"type":"RuntimeDefault"}}}} + - --permission-profile=network + - {{ .Values.image }} + image: ghcr.io/stacklok/toolhive:latest + imagePullPolicy: Always + name: toolhive + ports: + - containerPort: {{ .Values.port }} + name: http + protocol: TCP + resources: + limits: + cpu: {{ .Values.resources.limits.cpu }} + memory: {{ .Values.resources.limits.memory }} + requests: + cpu: {{ .Values.resources.requests.cpu }} + memory: {{ .Values.resources.requests.cpu }} diff --git a/toolhive/templates/serviceaccount.yaml b/toolhive/templates/serviceaccount.yaml new file mode 100644 index 0000000..0b502a9 --- /dev/null +++ b/toolhive/templates/serviceaccount.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: toolhive + app.kubernetes.io/name: toolhive + name: {{ .Release.Name }} diff --git a/toolhive/templates/services.yaml b/toolhive/templates/services.yaml new file mode 100644 index 0000000..08c0c11 --- /dev/null +++ b/toolhive/templates/services.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: mcp-{{ .Release.Name }}-proxy +spec: + internalTrafficPolicy: Cluster + ports: + - name: http + port: {{ .Values.port }} + protocol: TCP + targetPort: {{ .Values.port }} + selector: + app: mcpserver + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: mcpserver + toolhive: "true" + toolhive-name: {{ .Release.Name }} + type: ClusterIP diff --git a/toolhive/values.schema.json b/toolhive/values.schema.json new file mode 100644 index 0000000..34d5bae --- /dev/null +++ b/toolhive/values.schema.json @@ -0,0 +1,168 @@ +{ + "properties": { + "image": { + "title": "Image", + "description": "Docker image of your MCP server", + "type": "string" + }, + "podTemplateSpec": { + "properties": { + "spec": { + "properties": { + "containers": { + "items": { + "properties": { + "name": { + "title": "Name", + "description": "Container name", + "type": "string" + }, + "resources": { + "properties": { + "limits": { + "properties": { + "cpu": { + "title": "cpu", + "type": "string" + }, + "memory": { + "title": "memory", + "type": "string" + } + }, + "required": [ + "cpu", + "memory" + ], + "title": "limits", + "type": "object" + }, + "requests": { + "properties": { + "cpu": { + "title": "cpu", + "type": "string" + }, + "memory": { + "title": "memory", + "type": "string" + } + }, + "required": [ + "cpu", + "memory" + ], + "title": "requests", + "type": "object" + } + }, + "required": [ + "limits", + "requests" + ], + "title": "resources", + "type": "object" + } + }, + "required": [ + "name" + ], + "order": [ + "name", + "resources" + ], + "type": "object" + }, + "title": "Containers", + "type": "array" + } + }, + "required": [ + "containers" + ], + "title": "spec", + "type": "object" + } + }, + "required": [ + "spec" + ], + "title": "podTemplateSpec", + "type": "object" + }, + "port": { + "title": "Port", + "description": "Port to expose the MCP on", + "type": "integer" + }, + "resources": { + "properties": { + "limits": { + "properties": { + "cpu": { + "title": "cpu", + "type": "string" + }, + "memory": { + "title": "memory", + "type": "string" + } + }, + "required": [ + "cpu", + "memory" + ], + "title": "limits", + "type": "object" + }, + "requests": { + "properties": { + "cpu": { + "title": "cpu", + "type": "string" + }, + "memory": { + "title": "memory", + "type": "string" + } + }, + "required": [ + "cpu", + "memory" + ], + "title": "requests", + "type": "object" + } + }, + "required": [ + "limits", + "requests" + ], + "title": "resources", + "type": "object" + }, + "transport": { + "title": "Transport", + "description": "Set the transport for your MCP server", + "enum": [ + "stdio", + "sse" + ], + "type": "string" + } + }, + "order": [ + "image", + "permissionProfile", + "podTemplateSpec", + "port", + "resources", + "transport" + ], + "required": [ + "image", + "port", + "transport" + ], + "type": "object" +} \ No newline at end of file diff --git a/toolhive/values.yaml b/toolhive/values.yaml new file mode 100644 index 0000000..c41f049 --- /dev/null +++ b/toolhive/values.yaml @@ -0,0 +1,24 @@ +image: docker.io/mcp/fetch +permissionProfile: + name: network + type: builtin +podTemplateSpec: + spec: + containers: + - name: mcp + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 128Mi +port: 8080 +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 50m + memory: 64Mi +transport: sse