diff --git a/deploy/k8s/cert-manager-issuer.yaml b/deploy/k8s/cert-manager-issuer.yaml new file mode 100644 index 00000000..ba20e5ee --- /dev/null +++ b/deploy/k8s/cert-manager-issuer.yaml @@ -0,0 +1,18 @@ +# Let's Encrypt ClusterIssuer for TLS certificates +# Requires cert-manager to be installed first: +# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod +spec: + acme: + server: https://acme-v2.api.letsencrypt.org/directory + email: scott@shorashim.ch + privateKeySecretRef: + name: letsencrypt-prod-key + solvers: + - http01: + ingress: + class: nginx diff --git a/deploy/k8s/gitea-mcp-deployment.yaml b/deploy/k8s/gitea-mcp-deployment.yaml new file mode 100644 index 00000000..fa598ce5 --- /dev/null +++ b/deploy/k8s/gitea-mcp-deployment.yaml @@ -0,0 +1,80 @@ +# Gitea MCP Server — public connector for claude.ai +# +# Deploys the official Gitea MCP server (gitea.com/gitea/gitea-mcp) +# in HTTP mode, exposing /mcp endpoint for Streamable HTTP transport. +# +# The MCP server connects to the Gitea backend at 185.19.29.94 +# using a Personal Access Token stored in gitea-mcp-secrets. +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gitea-mcp + namespace: shorashim + labels: + app.kubernetes.io/name: gitea-mcp +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: gitea-mcp + template: + metadata: + labels: + app.kubernetes.io/name: gitea-mcp + spec: + containers: + - name: gitea-mcp + image: gitea/gitea-mcp-server:latest + args: + - "-t" + - "http" + - "--host" + - "http://185.19.29.94" + - "--port" + - "8080" + env: + - name: GITEA_TOKEN + valueFrom: + secretKeyRef: + name: gitea-mcp-secrets + key: GITEA_TOKEN + ports: + - containerPort: 8080 + name: http + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "256Mi" + cpu: "250m" + livenessProbe: + httpGet: + path: /mcp + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 30 + readinessProbe: + httpGet: + path: /mcp + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + name: gitea-mcp + namespace: shorashim + labels: + app.kubernetes.io/name: gitea-mcp +spec: + type: ClusterIP + selector: + app.kubernetes.io/name: gitea-mcp + ports: + - port: 8080 + targetPort: 8080 + protocol: TCP + name: http diff --git a/deploy/k8s/gitea-mcp-ingress.yaml b/deploy/k8s/gitea-mcp-ingress.yaml new file mode 100644 index 00000000..10987125 --- /dev/null +++ b/deploy/k8s/gitea-mcp-ingress.yaml @@ -0,0 +1,37 @@ +# Ingress for Gitea MCP Server — public HTTPS endpoint +# Routes mcp.shorashim.ch to the gitea-mcp service +# TLS via cert-manager (Let's Encrypt) +# +# Prerequisites: +# 1. nginx-ingress controller installed +# 2. cert-manager installed +# 3. ClusterIssuer letsencrypt-prod applied +# 4. DNS: mcp.shorashim.ch → Ingress external IP +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: gitea-mcp + namespace: shorashim + labels: + app.kubernetes.io/name: gitea-mcp + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/ssl-redirect: "true" +spec: + ingressClassName: nginx + tls: + - hosts: + - mcp.shorashim.ch + secretName: gitea-mcp-tls + rules: + - host: mcp.shorashim.ch + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: gitea-mcp + port: + number: 8080 diff --git a/deploy/k8s/gitea-mcp-secret.yaml b/deploy/k8s/gitea-mcp-secret.yaml new file mode 100644 index 00000000..dd4b4f05 --- /dev/null +++ b/deploy/k8s/gitea-mcp-secret.yaml @@ -0,0 +1,22 @@ +# Gitea MCP Server — secrets template +# NEVER commit actual values. Fill in and apply manually. +# +# Two secrets needed: +# 1. GITEA_TOKEN: Personal Access Token from Gitea +# Create at: http://185.19.29.94/user/settings/applications +# Permissions: repo (read/write) +# +# 2. OAuth Client ID/Secret: Registered OAuth app in Gitea +# Create at: http://185.19.29.94/user/settings/applications +# Redirect URI: https://claude.ai/api/mcp/auth_callback +# (These go into claude.ai connector settings, not this secret) +--- +apiVersion: v1 +kind: Secret +metadata: + name: gitea-mcp-secrets + namespace: shorashim +type: Opaque +stringData: + # Gitea Personal Access Token for backend API access + GITEA_TOKEN: "REPLACE_WITH_GITEA_PAT"