Last 12 weeks · 1 commit
4 of 6 standards met
🤖 Proof of concept authored by Claude. This is an exploratory draft for maintainer review, not a production-ready change. I cannot run / (GCP + Pulumi passphrase are maintainer-only secrets), so this is validated only by the secret-free checks below — please treat the chosen defaults as starting points for discussion. Motivation The registry's read-heavy list endpoint has a throughput problem. In registry issue #1323, maintainer @pree-dew load-tested ~19k server entries and reported that above ~300 RPS, CPU, goroutines (8k–12k at peak) and heap spike sharply and requests time out waiting on the Postgres queue — the DB queries aren't the bottleneck, the service just can't absorb the request volume. The recommended fix is a CDN caching layer in front of the registry. Three options were floated (Google Cloud CDN, Cloudflare, Fastly); Cloudflare is the natural fit because DNS is already managed here via the Cloudflare provider. This PR is a POC of the Cloudflare option, as IaC in this repo, to give maintainers something concrete to evaluate. What this changes Two pieces: 1. Proxy the registry hostname through Cloudflare. Records here default to DNS-only (grey cloud); Cloudflare can only cache traffic for a proxied (orange-cloud) record. I added a per-record flag to the record config ( now honors , preserving today's grey-cloud default for every other record) and set on the CNAME — the public hostname that serves . stays grey so the origin/staging remain directly reachable; the proxied CNAME flattens onto its in-zone A record at the edge. 2. Add a Cloudflare cache rule (, new in the phase) that makes cacheable at the edge: Match scope: — only the list endpoint, GET only. Detail routes () and writes are untouched. Edge TTL: , 60s (the origin sends no today, so we override it). Error responses (4xx/5xx) are explicitly never served from cache. Cache key: restricted to exactly the query params that change the response body — , , , , , (these mirror the endpoint's ), order-insensitive. Distinct pages/filters cache separately; unknown/tracking query params don't fragment the cache (or let someone blow past it with junk params). Defaults chosen (and the knobs to tune) Open questions / considerations for reviewers Proxying the hostname (not just the cache rule) introduces a few things worth weighing: Origin TLS: once proxied, Cloudflare terminates TLS at the edge and re-connects to origin. The zone SSL mode should be Full (strict) with the origin presenting a valid cert for ; otherwise expect TLS errors. This is a zone-level setting not managed in this repo. Real client IP: the origin will see Cloudflare IPs. Any IP-based logging/rate-limiting in the registry must read (or ) instead of the socket peer. Cache invalidation on writes: with a 60s TTL, a freshly published server can be invisible in the cached list for up to the TTL. Options: keep the TTL short (this POC), or have the registry issue a targeted Cloudflare cache purge on publish. Worth a follow-up discussion. One ruleset per phase: a zone can hold only one ruleset; this resource owns it. If other cache rules are added later they should live in the same ruleset. Verification I could not run cloud-auth'd steps ( / ) — those need / , which aren't available to a fork draft. The workflow only runs on push to , so it does not run on this PR. I ran the same secret-free checks runs: [x] — clean install (260 packages) [x] (, strict) — clean, exit 0. This typechecks the Pulumi program against the v6.13.0 resource schema, so the / cache-key / edge-TTL shapes are validated. [x] () — clean, "All matched files use Prettier code style!" [x] CI green on this PR — the job (no secrets) passed in ~31s. [x] Independent fresh-eyes review performed (separate adversarial pass against the provider v6 schema and the registry's actual endpoint). It verified the Ruleset shape, enum values, and Wirefilter expression are correct, and caught one real bug: the cache key originally keyed only on /, which would conflate responses that differ by ///. Fixed** by keying on all six response-affecting params (commit in this PR); re-ran / clean and re-confirmed CI. Cloud-auth CI jobs are expected to be skipped/absent for a fork draft. 🤖 Generated with Claude Code
Restores the and CNAMEs that were removed in #20 and #18 after takeover. Safety status as of this PR: — repo has set as its Pages custom domain, so the CNAME is claimed on deploy. ✅ — repo currently has . Before merging this**, either set as that repo's Pages custom domain, or confirm the Pages-verification from #22 shows Verified in Org Settings → Pages. Otherwise this re-creates the dangling state. ⚠️
Adds the TXT record for GitHub Pages domain verification (Org Settings → Pages → Add a verified domain). Once this deploys and is verified in org settings, it protects and all immediate subdomains from being claimed as a Pages custom domain by any account outside the modelcontextprotocol org — the durable fix for the takeovers that prompted #18 and #20. This is distinct from the records (org-profile "Verified" badge), which do not provide Pages takeover protection. Additional Pages-verification records (apex, ) can be appended to this PR as the codes are generated.
Repository: modelcontextprotocol/dns. Description: Infrastructure as Code for MCP domains / DNS management Stars: 10, Forks: 9. Primary language: TypeScript. Languages: TypeScript (92.6%), Makefile (7.4%). Open PRs: 2, open issues: 0. Last activity: 2w ago. Community health: 75%. Top contributors: localden, dsp-ant, domdomegg, dependabot[bot], chr-hertel, DaleSeo, dsp, koic.