From 7f23cbd2364c726910f66bde7c950ee7b7d9a68f Mon Sep 17 00:00:00 2001 From: Kyle Petryszak <6314611+ProjectInitiative@users.noreply.github.com> Date: Sat, 6 Jun 2026 20:17:58 +0000 Subject: [PATCH 1/2] adding k8s mcp server --- apps.yaml | 7 ++ .../config/debug-clusterrole.yaml | 26 ++++++ .../mcp-kubernetes/config/deployment.yaml | 56 ++++++++++++ .../mcp-kubernetes/config/kustomization.yaml | 7 ++ apps/base/mcp-kubernetes/config/rbac.yaml | 87 +++++++++++++++++++ apps/base/mcp-kubernetes/config/service.yaml | 15 ++++ clusters/cc.yaml | 3 + clusters/mc.yaml | 3 + 8 files changed, 204 insertions(+) create mode 100644 apps/base/mcp-kubernetes/config/debug-clusterrole.yaml create mode 100644 apps/base/mcp-kubernetes/config/deployment.yaml create mode 100644 apps/base/mcp-kubernetes/config/kustomization.yaml create mode 100644 apps/base/mcp-kubernetes/config/rbac.yaml create mode 100644 apps/base/mcp-kubernetes/config/service.yaml diff --git a/apps.yaml b/apps.yaml index 1ccc83c..174ed1e 100644 --- a/apps.yaml +++ b/apps.yaml @@ -442,6 +442,13 @@ catalog: privateer: path: apps/base/privateer/config + mcp-kubernetes: + path: apps/base/mcp-kubernetes/config + syncPolicy: + syncOptions: + - CreateNamespace=true + - ServerSideApply=true + # nixos-remote-builder: # path: apps/base/nixos-remote-builder/config # vaultSecrets: diff --git a/apps/base/mcp-kubernetes/config/debug-clusterrole.yaml b/apps/base/mcp-kubernetes/config/debug-clusterrole.yaml new file mode 100644 index 0000000..c8ae450 --- /dev/null +++ b/apps/base/mcp-kubernetes/config/debug-clusterrole.yaml @@ -0,0 +1,26 @@ +--- +# This ClusterRole is ready for granting debug/exec access on-demand. +# It is NOT bound by default — to activate it for a namespace: +# kubectl create rolebinding mcp-debug- \ +# --clusterrole=mcp-namespace-debugger \ +# --serviceaccount=mcp-system:mcp-agent-sa \ +# -n +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: mcp-namespace-debugger +rules: + - apiGroups: [""] + resources: + - pods/exec + - pods/attach + - pods/portforward + verbs: ["create"] + - apiGroups: [""] + resources: + - pods/ephemeralcontainers + verbs: ["update", "patch"] + - apiGroups: [""] + resources: + - pods + verbs: ["create", "get", "list", "watch"] diff --git a/apps/base/mcp-kubernetes/config/deployment.yaml b/apps/base/mcp-kubernetes/config/deployment.yaml new file mode 100644 index 0000000..130f150 --- /dev/null +++ b/apps/base/mcp-kubernetes/config/deployment.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mcp-kubernetes-server + labels: + app: mcp-kubernetes +spec: + replicas: 1 + selector: + matchLabels: + app: mcp-kubernetes + template: + metadata: + labels: + app: mcp-kubernetes + spec: + serviceAccountName: mcp-agent-sa + containers: + - name: mcp-server + image: ghcr.io/azure/mcp-kubernetes:v0.0.14 + args: + - "--transport" + - "sse" + - "--port" + - "8080" + - "--access-level" + - "readonly" + ports: + - containerPort: 8080 + name: http-sse + livenessProbe: + tcpSocket: + port: http-sse + initialDelaySeconds: 10 + periodSeconds: 15 + readinessProbe: + tcpSocket: + port: http-sse + initialDelaySeconds: 3 + periodSeconds: 5 + resources: + limits: + cpu: "500m" + memory: "256Mi" + requests: + cpu: "100m" + memory: "128Mi" + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 10001 + securityContext: + seccompProfile: + type: RuntimeDefault diff --git a/apps/base/mcp-kubernetes/config/kustomization.yaml b/apps/base/mcp-kubernetes/config/kustomization.yaml new file mode 100644 index 0000000..e3bad62 --- /dev/null +++ b/apps/base/mcp-kubernetes/config/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - rbac.yaml + - debug-clusterrole.yaml + - deployment.yaml + - service.yaml diff --git a/apps/base/mcp-kubernetes/config/rbac.yaml b/apps/base/mcp-kubernetes/config/rbac.yaml new file mode 100644 index 0000000..fa20451 --- /dev/null +++ b/apps/base/mcp-kubernetes/config/rbac.yaml @@ -0,0 +1,87 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: mcp-agent-sa +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: mcp-cluster-reader +rules: + - apiGroups: [""] + resources: + - pods + - pods/log + - pods/status + - services + - endpoints + - configmaps + - namespaces + - nodes + - nodes/status + - events + - persistentvolumes + - persistentvolumeclaims + - replicationcontrollers + - resourcequotas + - limitranges + - serviceaccounts + verbs: ["get", "list", "watch"] + - apiGroups: ["apps"] + resources: + - deployments + - deployments/status + - daemonsets + - daemonsets/status + - statefulsets + - statefulsets/status + - replicasets + verbs: ["get", "list", "watch"] + - apiGroups: ["batch"] + resources: + - jobs + - jobs/status + - cronjobs + - cronjobs/status + verbs: ["get", "list", "watch"] + - apiGroups: ["networking.k8s.io"] + resources: + - ingresses + - ingresses/status + - networkpolicies + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: + - storageclasses + - csidrivers + - csidnodes + - volumeattachments + - volumeattachments/status + verbs: ["get", "list", "watch"] + - apiGroups: ["metrics.k8s.io"] + resources: + - pods + - nodes + verbs: ["get", "list", "watch"] + - apiGroups: ["apiextensions.k8s.io"] + resources: + - customresourcedefinitions + verbs: ["get", "list", "watch"] + - apiGroups: ["coordination.k8s.io"] + resources: + - leases + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: mcp-cluster-reader-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: mcp-cluster-reader +subjects: + - kind: ServiceAccount + name: mcp-agent-sa + namespace: mcp-system diff --git a/apps/base/mcp-kubernetes/config/service.yaml b/apps/base/mcp-kubernetes/config/service.yaml new file mode 100644 index 0000000..4bf9c4b --- /dev/null +++ b/apps/base/mcp-kubernetes/config/service.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: mcp-kubernetes-svc + labels: + app: mcp-kubernetes +spec: + type: ClusterIP + ports: + - port: 8080 + targetPort: 8080 + name: http-sse + selector: + app: mcp-kubernetes diff --git a/clusters/cc.yaml b/clusters/cc.yaml index c87234c..aa67ff1 100644 --- a/clusters/cc.yaml +++ b/clusters/cc.yaml @@ -108,3 +108,6 @@ apps: serviceCIDR: "10.43.0.0/16" brokerK8sSecret: "submariner-broker-info" brokerK8sApiServer: "https://kubernetes.default.svc:443" + + - name: mcp-kubernetes + namespace: mcp-system diff --git a/clusters/mc.yaml b/clusters/mc.yaml index 11197b6..db69ae2 100644 --- a/clusters/mc.yaml +++ b/clusters/mc.yaml @@ -146,3 +146,6 @@ apps: serviceCIDR: "10.43.0.0/16" brokerK8sSecret: "submariner-broker-info" brokerK8sApiServer: "https://100.95.205.21:443" + + - name: mcp-kubernetes + namespace: mcp-system From 897437d41de48796821ee122e6c53a66686d5a3a Mon Sep 17 00:00:00 2001 From: Kyle Petryszak <6314611+ProjectInitiative@users.noreply.github.com> Date: Sat, 6 Jun 2026 21:09:27 +0000 Subject: [PATCH 2/2] feat(mcp): add NetworkPolicy and Tailscale LB service --- .../mcp-kubernetes/config/kustomization.yaml | 2 ++ .../mcp-kubernetes/config/network-policy.yaml | 18 ++++++++++++++++++ .../mcp-kubernetes/config/tailscale-lb.yaml | 17 +++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 apps/base/mcp-kubernetes/config/network-policy.yaml create mode 100644 apps/base/mcp-kubernetes/config/tailscale-lb.yaml diff --git a/apps/base/mcp-kubernetes/config/kustomization.yaml b/apps/base/mcp-kubernetes/config/kustomization.yaml index e3bad62..6c834ff 100644 --- a/apps/base/mcp-kubernetes/config/kustomization.yaml +++ b/apps/base/mcp-kubernetes/config/kustomization.yaml @@ -5,3 +5,5 @@ resources: - debug-clusterrole.yaml - deployment.yaml - service.yaml + - tailscale-lb.yaml + - network-policy.yaml diff --git a/apps/base/mcp-kubernetes/config/network-policy.yaml b/apps/base/mcp-kubernetes/config/network-policy.yaml new file mode 100644 index 0000000..937ec37 --- /dev/null +++ b/apps/base/mcp-kubernetes/config/network-policy.yaml @@ -0,0 +1,18 @@ +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: mcp-allow-tailscale-only +spec: + podSelector: + matchLabels: + app: mcp-kubernetes + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: tailscale + ports: + - port: 8080 diff --git a/apps/base/mcp-kubernetes/config/tailscale-lb.yaml b/apps/base/mcp-kubernetes/config/tailscale-lb.yaml new file mode 100644 index 0000000..f3a2985 --- /dev/null +++ b/apps/base/mcp-kubernetes/config/tailscale-lb.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: mcp-kubernetes-tailscale + labels: + app: mcp-kubernetes +spec: + type: LoadBalancer + loadBalancerClass: tailscale + ports: + - name: http-sse + protocol: TCP + port: 8080 + targetPort: 8080 + selector: + app: mcp-kubernetes