From c90ffcd2eaea5d1b9b862d50f0167f94a70fa3ce Mon Sep 17 00:00:00 2001 From: xnoto Date: Wed, 26 Aug 2026 11:53:35 -0600 Subject: [PATCH] fix(mcp): move backend endpoints to first-level mcp- hostnames Cloudflare Universal SSL covers only *.makeitwork.cloud, so .mcp.makeitwork.cloud cannot present a certificate and the edge refuses the TLS handshake. Rename to mcp-.makeitwork.cloud and replace the wildcard Access app with one application per backend FQDN. --- README.md | 2 +- cf-access-mcp.tf | 15 ++++++++------- cf-tunnels.tf | 49 +++++++++++++++++++++++++++--------------------- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index a95a43c..dd87041 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ No modules. | [cloudflare_zero_trust_access_application.grafana_alerts](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | | [cloudflare_zero_trust_access_application.k3s](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | | [cloudflare_zero_trust_access_application.mcp_gateway](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | -| [cloudflare_zero_trust_access_application.mcp_gateway_backends](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | +| [cloudflare_zero_trust_access_application.mcp_gateway_backend](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | | [cloudflare_zero_trust_access_application.warp](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_application) | resource | | [cloudflare_zero_trust_access_group.admins](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_group) | resource | | [cloudflare_zero_trust_access_identity_provider.github](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_access_identity_provider) | resource | diff --git a/cf-access-mcp.tf b/cf-access-mcp.tf index 81bb0ad..aea292b 100644 --- a/cf-access-mcp.tf +++ b/cf-access-mcp.tf @@ -43,15 +43,16 @@ resource "cloudflare_zero_trust_access_application" "mcp_gateway" { ] } -# Per-backend MCP endpoints (.mcp.makeitwork.cloud) terminate on the -# same toolhive proxyrunners behind the same tunnel. Wildcard application so -# each integration gets its own FQDN without a new Access app per backend; -# same service-token + admins policies as the aggregate gateway above. -resource "cloudflare_zero_trust_access_application" "mcp_gateway_backends" { +# Per-backend MCP endpoints (mcp-.makeitwork.cloud) terminate on the +# same toolhive proxyrunners behind the same tunnel. One application per FQDN: +# Access domains cannot wildcard a name prefix, and first-level names are +# required anyway because Universal SSL only covers one subdomain level. +resource "cloudflare_zero_trust_access_application" "mcp_gateway_backend" { + for_each = toset(local.mcp_backends) account_id = local.account_id - name = "MCP Gateway Backends" + name = "MCP ${each.key}" type = "self_hosted" - domain = "*.mcp.makeitwork.cloud" + domain = "mcp-${each.key}.makeitwork.cloud" session_duration = "24h" allowed_idps = [ diff --git a/cf-tunnels.tf b/cf-tunnels.tf index 2a5c299..78afc7c 100644 --- a/cf-tunnels.tf +++ b/cf-tunnels.tf @@ -16,28 +16,35 @@ data "cloudflare_zero_trust_tunnel_cloudflared" "cluster_apps" { # kustomize-cluster picks up traffic for each FQDN; this CNAME just tells # Cloudflare's edge which tunnel to route requests through. locals { - cluster_apps_hostnames = [ - "api", - "argocd", - "forgejo", - "grafana", - "k3s", - "mcp", - # Per-backend MCP endpoints (toolhive proxyrunners); the aggregate - # VirtualMCPServer stays at the bare "mcp" hostname above. - "apify.mcp", - "argocd-makeitwork.mcp", - "aws-docs.mcp", - "context7.mcp", - "github.mcp", - "grafana-makeitwork.mcp", - "kubernetes.mcp", - "parallel-search.mcp", - "terraform-docs.mcp", - "opencode", - "status", - "alertmanager", + # Per-backend MCP endpoints (toolhive proxyrunners); the aggregate + # VirtualMCPServer stays at the bare "mcp" hostname. First-level names are + # required: Cloudflare Universal SSL only covers *.makeitwork.cloud, so + # .mcp.makeitwork.cloud cannot present a certificate. + mcp_backends = [ + "apify", + "argocd-makeitwork", + "aws-docs", + "context7", + "github", + "grafana-makeitwork", + "kubernetes", + "parallel-search", + "terraform-docs", ] + cluster_apps_hostnames = concat( + [ + "api", + "argocd", + "forgejo", + "grafana", + "k3s", + "mcp", + "opencode", + "status", + "alertmanager", + ], + [for backend in local.mcp_backends : "mcp-${backend}"], + ) } resource "cloudflare_dns_record" "cluster_apps" {