Chapter 7
Sites, Domains & the Web
From the vhost on your Mac to the registrar, the DNS, the CDN and the search engines — one pane that tells you whether a domain is actually healthy, and a set of tools to fix it when it is not.
A working website is more than a running Apache. The domain has to resolve, the certificate has to be valid, the right machine has to answer, the CDN has to be in front of it, and the search engines have to know it exists. FrontierStack gathers all of that into the Sites pane and a small family of companion tools, so the whole chain — registrar, DNS, TLS, CDN, host, SEO — is visible and fixable from one window. This chapter covers the web above the stack; for the vhosts and certificates themselves see Chapter 4.
7.1The Sites pane and Domain Health
Open Sites from the sidebar. At the top sits the Domain Health section, a live dashboard that collects every hostname FrontierStack knows about: the local Apache and Nginx vhosts you have defined, the vhosts on linked servers, every Cloudflare zone on your token, and every domain in the registrar monitor. Each domain gets a row with a set of status badges; press Check on a row, or Check All in the header, and the app probes the domain end to end and colours the badges green or amber.
The point of the dashboard is to answer one question reliably: is this domain actually serving, and from where? Because the checks run against the public internet (a real DNS lookup, a real HTTP request, a real TLS handshake), they catch the failures a local config check never sees — a record that points at the wrong IP, an expired certificate, a Cloudflare zone stuck in "pending", a site that resolves but returns a 502.
| Check | How it is measured | What a problem looks like |
|---|---|---|
| DNS | A real resolver lookup of the hostname (host/dig) and the IP it returns. | No record, or an address that is not your server. |
| HTTP | A live request that records the status code (curl -w %{http_code}). | Anything outside 200–399 — a 404, a 502, a redirect loop. |
| SSL / TLS | A TLS handshake reading the certificate end date (openssl s_client → x509 -enddate); the badge shows days remaining. | Expired, expiring soon, or a name that does not match. |
| HTTP/3 | A teal badge when the server advertises HTTP/3 in its Alt-Svc header. Apache has no HTTP/3 of its own — the usual way to earn this badge on an Apache site is the HTTP/3 toggle in the domain's Cloudflare zone pane (browsers then speak QUIC to the edge while the origin stays h1/h2). Remember HTTP/3 rides on UDP 443: a TCP-only firewall makes browsers silently fall back to HTTP/2. | No badge on a site you expected to serve h3 — the edge setting is off, or UDP 443 is blocked. |
| Cloudflare | Zone status and plan from your token, shown as e.g. active · Pro. | A zone "pending" because the nameservers were never switched at the registrar. |
| Serving host | Derived from the answering IP and the Server header. | "This Mac (Apache)" when you expected a remote box, or "Cloudflare" masking the origin. |
7.2Search Console, Analytics and Ahrefs on each site
Under its health badges, every Domain Health row has a short line with three chips: Search Console, GA4 and Ahrefs. Grey means the service isn't set up for that site, green means it is on and nothing is wrong, yellow means there is something worth a look, and orange means a problem that also raises an alert. Hover over a chip to see what was found, or click it to open that service's pane. This line doesn't copy the vendors' consoles. It answers two questions for each site: is the service on, and is there anything the owner should know?
The checks build up depending on what you have connected:
- With no keys at all, FrontierStack reads the live home page,
robots.txtand the domain's TXT records. It finds the Google Analytics and Tag Manager tags, the Ahrefs Web Analytics script, and the Google and Ahrefs verification tokens. It warns when the home page carries anoindex(in a meta tag or anX-Robots-Tagheader), or whenrobots.txtshuts Googlebot, AhrefsBot or AhrefsSiteAudit out of the whole site. An old Universal Analytics (UA-) tag is pointed out too, because it no longer collects anything. - With Google signed in (the Search Console pane's Sign in with Google, or a service-account key), each site is matched to its Search Console property. FrontierStack then checks:
- whether you are still verified for the property;
- whether submitted sitemaps report errors;
- what Google's URL Inspection says about the home page: whether it could be fetched, whether robots.txt or a noindex blocks it, and whether it is indexed;
- whether search impressions have collapsed week on week.
- With a Cloudflare token, the zone's firewall events are read for Googlebot, AhrefsBot and AhrefsSiteAudit requests that a WAF, rate-limit or bot rule blocked in the last day, and the rule responsible is named. Only requests from Google's and Ahrefs' own networks count. When Cloudflare blocks an impostor that merely claims to be Googlebot, it is doing its job, so that isn't reported.
Everything is rechecked every six hours, and also whenever you press Check or Check All. Problems are sent to Alerts under the Search & Analytics group, one item per site and service, so a fixed problem sends a recovery. Ahrefs problems are only raised for sites where Ahrefs is actually in use, because blocking a crawler you don't use is a choice, not a fault.
7.3ChatGPT Sites: monitor, use your domain, or self-host
The ChatGPT Sites section uses one shared registry everywhere it appears in FrontierStack. Paste a public name.openai.chatgpt.site URL and it joins Domain Health, SEO and Alerts like any other site. Mark a workspace- or owner-only Site private and outside probes pause, because its sign-in page is not an outage.
Import or Move offers two owner-authorised routes. Use my domain keeps the Site on ChatGPT: first add the domain in the Site's ChatGPT settings, then copy the exact DNS records ChatGPT supplies. FrontierStack validates that every record belongs to the selected Cloudflare zone and publishes it DNS-only; for another DNS provider, add the records there and use Save Domain. Both paths keep the original Sites address and the custom domain in the registry. Return to ChatGPT and refresh the domain status after DNS propagates.
Self-host starts from the Site's local project folder. FrontierStack reads .openai/hosting.json and package.json, identifies the framework and ready output folder, shows D1/R2 bindings and the names of example environment variables, and copies the reviewed web output into a managed Apache domain. The importer never runs package scripts, never reads secret values, skips links and source-control metadata, limits the copy to 50,000 files or 5 GB, and uses a staging folder so a failed replacement can be rolled back. Build the project first, then import dist, build, out, public, or another folder containing index.html.
7.4Proving domain ownership
Vendors verify that a domain is yours by asking you to publish a DNS TXT record only its owner could create — the same proof-by-DNS idea as ACME's DNS-01 challenge, but every vendor has its own record format. The Verify button on a Domain Health row keeps those formats in one place: pick the service — Google (Search Console / Workspace), Microsoft 365, Meta, Apple Business Manager, Atlassian, OpenAI, Stripe, GitHub organizations, or a custom record — paste the token from the vendor's console, and FrontierStack publishes the TXT record straight into the domain's Cloudflare zone. If the domain isn't on your Cloudflare token, it hands you the exact record to add at your DNS host instead. A bare token is completed automatically (paste abc123 for Google and the record becomes google-site-verification=abc123).
The sheet also shows the verification records already published on the apex — a quick audit of who this domain is currently proven to — and Check DNS queries public DNS (1.1.1.1) for the new record, so you know the proof is visible before you press "Verify" on the vendor's side.
For certificates, the Let's Encrypt service pane (Security & Secrets category) is a standing health check on the other kind of domain proof: it watches the ACME API, Let's Encrypt's status page and a domain's live certificate, and — because ACME clients renew when 30 days remain — alerts when a certificate is overdue for renewal, catching broken certbot/acme.sh automation weeks before visitors ever see an expiry warning.
7.5Spam blocklists: domains, mail servers and your network's public IP
Receivers decide whether to accept mail partly by asking public blocklists. Blocklists on a Domain Health row (the same section appears on a Cloudflare zone's pane and in the Mail Server pane) looks the domain up on the domain lists — Spamhaus DBL, SURBL, URIBL — and its mail servers (MX hosts and single SPF addresses) on the IP lists — Spamhaus ZEN, SpamCop, Barracuda, PSBL, Mailspike. Each answer is decoded per list, so the result says why a listing exists, with a Look Up button for the list's removal page. The row then shows the last result.
| Result | Meaning | Alert |
|---|---|---|
| Listed | Spam, phishing or malicious domains; SBL, CSS or XBL address; SpamCop, Barracuda, PSBL or Mailspike listing | Alert (down) under Spam Blocklists |
| Caution | Spamhaus PBL (an end-user range) or URIBL grey (bulk sender) | Warning only |
| No answer | The list refused this Mac's resolver, even when asked at its own nameservers, or did not answer | Never — the last real answer is kept |
Regular check in the same section puts a domain on a schedule: Off, Daily, Weekly, Every 2 weeks or Monthly. Only a domain on a regular check raises Alerts. The lists rate-limit busy resolvers, so checks run one target at a time with a pause in between, never on the Alerts sweep, and the result is kept across launches. The Spam Blocklists section under Domain Health lists every watched domain with its rate and last result, and has a switch for the Alerts.
Network public IPs, in the same section, checks the public (WAN) address of every pinned router or firewall — the External IP set in its device details — on the IP lists, on a schedule of its own. A machine on guest Wi-Fi or the LAN that sends spam does it through that NAT address, and a listing there is often the first sign from outside, long before anyone inside notices.
The Mail Server Policy survey on a linked server's pane (see Chapter 10) runs the same lookups for that server's public address and the domains it receives mail for, and reports a listing as a failure, a caution entry as a warning, and an unanswered list as information. It reuses answers for six hours, so reopening the pane does not query the lists again.
7.6AI SEO and "Fix My Site"
Two of the badges on a domain row are not just diagnostics — they are buttons that hand the problem to the AI Administrator. Fix My Site takes a broken or misbehaving site and runs the assistant through a fixed playbook: reproduce the fault by curling the site locally with its Host header, read the relevant logs, check that Apache, PHP and the database are running, and then state the single most likely root cause with concrete next steps. With Allow changes off it only advises; with it on it may apply the reversible fixes (restart a service, correct a wrong value in a config file, repair the database). There is a WordPress-aware variant for the classic white screen, "Error establishing a database connection", broken permalinks and stuck maintenance mode.
The SEO action runs an on-device read-only audit: the assistant fetches the home page, robots.txt and the sitemap, scores the site out of 100 and writes a short report (titles, meta descriptions, headings, crawlability, structured data). The result opens in an SEO report sheet so you can read the findings and act on them.
7.7One-click CMS installs (Apps & CMS)
WordPress gets a single pane that both installs new sites and runs the ones you already have — on this Mac or on any fleet server. That merge matters: the old installer pane could only ever write to This Mac, whereas everything here runs through WP-CLI on whichever host you pick, so a remote server is a first-class target for a new install. Install a new WordPress site, at the foot of the pane, downloads WordPress onto the selected host, writes wp-config.php, creates the database and completes setup with the administrator account you name. Nothing is copied up from your Mac, and an install already sitting at that path is refused rather than overwritten. Serving the new folder still needs a virtual host — create one in the Sites pane for a local site, or on the server's own web server. Installing a CMS is only the first day of its life, and the same pane covers the rest. Choose a host — This Mac or any fleet server — and scan for wp-config.php under the usual web roots, and every WordPress install on that machine appears with its core, plugin and theme versions and whatever is waiting to be updated. Update all exports the database before it touches anything, because a bad plugin update is recoverable and a lost database is not. Check integrity compares the core files against the checksums WordPress.org publishes, which is the quickest way to find a defaced or backdoored install; add a free WPScan token and the pane also checks your installed plugins and core against the vulnerability database, marking anything with no published fix. Multisite networks list their subsites. Each site also carries an Add a plugin list — a curated catalogue covering booking, commerce, mail delivery, backups, caching and security — which installs straight onto that site, local or remote, with an option to activate it once installed. The list is deliberately not a mirror of the WordPress.org directory: every entry either fails visibly when it breaks or produces something FrontierStack already monitors elsewhere, and each says what the app can tell you about it once it is running, so an install never implies monitoring that does not exist. Anything already on the site shows as installed rather than being offered twice, and a premium plugin with no WordPress.org slug links to its own page instead. On a host with no WordPress site yet — or without WP-CLI — the catalogue is still shown, greyed out and not selectable, so you can see what will be on offer instead of meeting an empty pane. The remaining jobs are the ones that otherwise mean an SSH session and a half-remembered command: resetting the password of a locked-out administrator, search-replace to move a site between domains (WP-CLI rewrites URLs buried in serialized PHP, where a plain SQL replace corrupts them — so always dry-run first), cloning a site to staging, and exporting or optimising the database. A clone copies the files, gives the copy its own database, rewrites the URLs inside it and sets it to discourage search engines, so staging can never write to production or outrank it. Everything runs through WP-CLI over SSH, and the pane offers to install WP-CLI on any host that lacks it. Pin a site and Alerts will tell you about pending updates, a failed integrity check or a new vulnerability.
Sites moved from GoDaddy. GoDaddy’s Managed WordPress puts a must-use system plugin and a Memcached object-cache.php into every site, and its older hosting adds a gd-config.php include to wp-config.php. None of them work anywhere else — a restored GoDaddy backup typically stops at a white screen or a database-connection error. The pane spots them on refresh and offers Remove GoDaddy Leftovers…: the files move to ~/frontierstack-godaddy-leftovers on the server with a copy of wp-config.php, the include is commented out, and after a database export into the same folder, links still on the temporary *.myftpupload.com address are pointed at the site’s own. It won’t run on GoDaddy’s own servers, where those files are the platform.
If your WordPress lives on managed hosting rather than your own machines, the hosting panes now list those sites too: WP Engine, Kinsta, Cloudways and Pressable each pull your installs through their API — environment, primary domain and status — and they roll up into Cloud Servers alongside your VPS instances, so one inventory covers everything you run. These are sites rather than machines, so they carry no power controls.
The Apps & CMS section installs the other self-hosted CMS onto your Apache/PHP/MySQL stack in a single flow, each with its own pane: Drupal, Joomla, Statamic, Grav, Kirby, Craft CMS and FreshRSS — plus Magento Open Source, which uses the same installer but is filed under E-Commerce. The installer downloads the app (or runs composer create-project for the Composer-based Statamic and Craft), extracts it into the document root, and — for the ones that need a database (Drupal, Joomla, Craft) — creates the database and user and writes the config where the app expects it. The flat-file CMS (Grav, Kirby, Statamic) need no database at all. It then opens the app's setup or admin page so you can create your account (/admin, /panel, /cp, /admin/install…), while FrontierStack wires the virtual host, PHP and trusted HTTPS around it. For the install folder you can pick a site Apache already manages — a menu prefills its domain, document root and port — or Choose… a new empty folder; a matching Apache vhost is created for a new folder, or updated when the domain is an existing site. If an install misbehaves, Fix My Site (AI) above debugs it.
FreshRSS is the exception that finishes the job. It is a self-hosted RSS and Atom reader, and unlike the CMS above it leaves you no setup wizard at all: name an account and password in the pane, and the installer downloads the release, creates the database, runs FreshRSS's own command-line installer to write its configuration and build the schema, creates that account, and registers a virtual host pointing at p/ — the subfolder FreshRSS actually serves from, with the rest of its code left outside the web root where it belongs. The browser then opens on the login screen of a working reader rather than on step one of an installation. Because its API is Google Reader-compatible, mobile clients such as Reeder and NetNewsWire can sync against it once you expose it, which makes it a natural companion to the HTTPS and remote-access work elsewhere in this book.
Magento Open Source also installs completely, for a different reason: Magento removed its browser installer, so the only way in is its command line. The pane gathers what bin/magento setup:install needs — an admin username, password, email and name, the store currency, and the address of a running OpenSearch (or Elasticsearch 8) server — and checks the slow-to-discover problems first: a PHP older than 8.2 or missing one of Magento's extensions, a search server that does not answer, and the MySQL version. Only then does it run composer create-project, from the keyless Mage-OS mirror by default or from Adobe's repo.magento.com with your Marketplace access keys, which are used for that one download and not stored. That download is several hundred packages and usually takes 5–15 minutes. The installer then creates the database, runs the setup with your account, makes the folders Magento writes to at runtime writable by the web server, and registers a virtual host that serves pub/. The admin lives at a random path such as /admin_k3x9qz/, which the log shows and the browser opens. Magento normally makes every admin set up two-factor sign-in through an emailed link; for a local test store that cannot send mail, a toggle turns this off (it starts off for .local and .test names). If setup fails after the download, fix the cause and press Install again: the pane resumes from the database step without downloading again. Finally, Magento does its indexing and email from cron, so run bin/magento cron:install in the install folder once the store is up.
The same pane installs the licensed Adobe Commerce (on-premises) edition: set Edition to Adobe Commerce and enter the Marketplace access keys of the account that holds the licence, since that edition downloads only from repo.magento.com. Its MySQL settings for Magento section reads three values from the chosen instance — log_bin_trust_function_creators, which must be on while binary logging is (MySQL 8’s default), or MySQL refuses the triggers Magento’s indexers create with error 1419; max_allowed_packet, at least 64 MB; and, if you tick it, an InnoDB buffer pool of 1 GB. Apply sets them at once with SET GLOBAL, then writes them under [mysqld] in the instance’s my.cnf, after saving a timestamped backup beside it, so a restart does not quietly undo them. Sizes are only ever raised, and a server on another host gets the lines to add rather than an edit. Install runs the same step. Once the store is installed, the pane also shows its live sales monitor. Adobe’s hosted editions — Adobe Commerce on Cloud Infrastructure, Adobe Commerce as a Cloud Service and Adobe Commerce Optimizer — are services in the catalog, each with a monitor of its own.
The pane is called Magento and has three tabs. This Mac is the installer described above. Stores manages every Magento store FrontierStack knows about, on this Mac or on any server in the fleet — Find Stores scans a server’s web roots. For each store it reports the version and whether a newer security patch exists, the deploy mode, whether the storefront answers, maintenance mode, whether cron is installed and when its last job finished, stale indexers, disabled caches, a default /admin/ path or missing two-factor sign-in on a server, and today’s exceptions, worst first. Its buttons flush the cache, reindex, switch indexer modes, toggle maintenance, change the deploy mode, run setup:upgrade safely behind the maintenance page, install cron, unlock an admin and tail the logs, always as the owner of the store’s files. Fix My Store (AI) passes the store to the AI Agent, which reads the same evidence through its ecommerce tool and proposes changes you approve one by one.
Host on a Server is the one-click route to a live store. Choose an Ubuntu 24.04+ or Debian 12+ server, a domain and the admin account, and FrontierStack works through eleven stages, showing each as it goes: check the server (memory, disk, nothing else on port 80); install Nginx, PHP-FPM, MySQL or MariaDB, Composer and Redis; install a loopback-only OpenSearch; create the database with Magento’s MySQL settings; create a magento user with its own PHP-FPM pool; download Magento with Composer; run setup:install; build the Nginx site from Magento’s own nginx.conf.sample; switch to production mode; install cron; and get a Let’s Encrypt certificate. Expect 20–40 minutes. It needs root on the server, and the passwords it generates travel in a private file that is deleted at the end. A failed stage stops the job with its reason; fix it and press Host Store again, and finished stages are skipped. The new store joins the Stores tab with alerts turned on.
7.8The Domain Registrar monitor
Sites tells you whether a domain works today; the Domain Registrars pane (in the DNS category) tells you whether it will keep working. Add a domain and FrontierStack watches three things on a schedule and raises an alert when any of them drifts:
- Expiry — the registration end date, registrar and nameservers, pulled over RDAP (with a
whoisfallback). Works for any domain, whatever the registrar. - DNS — whether the domain still resolves (
dig). - SSL — the certificate expiry, checked directly with
openssl.
A renewal warning fires when the expiry is within your reminder window, already past, or when auto-renew is off. For supported registrars the pane can import your domain list and auto-renew status by API — GoDaddy, Porkbun, Gandi, Value Domain, Route 53 (via the AWS CLI) and Cloudflare (reusing the Cloudflare token — this one needs a user API token, as Cloudflare Registrar does not accept account-owned cfat_ tokens). Registrars without a usable list API (Namecheap, Squarespace, Onamae, Muumuu Domain) you add by hand; RDAP still monitors them.
7.14.1Domain companies: registrar uptime
A Cloudflare zone tells you nothing about who holds the registration. FrontierStack looks each pinned zone up over RDAP and shows its registrar and live nameservers in a Domain Company section of the zone pane; in the Cloudflare pane each zone's line reads e.g. active · Pro · registered at GoDaddy. Every registrar and DNS host behind your domains — GoDaddy, Namecheap, Porkbun, Gandi, Squarespace, DNSimple, Route 53, Value Domain, Onamae, Name.com, Hover, Dynadot, IONOS, OVHcloud, Sakura and Cloudflare itself — is checked every five minutes on three signals:
- Official status — the company's status page (Statuspage or Instatus JSON; AWS's Route 53 RSS), including each of its services — domains, DNS, email, hosting, SSL, website builder — where the page lists them.
- Reachability — its website and API host answer.
- Nameservers — for domains still delegated to it, its nameservers answer for them.
A yellow building icon next to a zone in the sidebar means its registrar or DNS host is degraded; red means down. Pin a company (from the zone pane, the zone's context menu or the Domain Companies list in Domain Registrars) and it gets its own sidebar row with a pulsing dot when down. A company going down raises a Domain company alert. Companies without a status page are judged on reachability alone, and when this Mac can reach none of them the check reports offline rather than a false outage.
7.14.2Moving a domain to Cloudflare
With a Cloudflare token set, two moves are one click where the registrar has an API:
- DNS only — for a domain not yet on Cloudflare, Add to Cloudflare DNS… in Domain Registrars creates the zone, copies its current public records in and pins it. Review the records, then use Switch Nameservers in the zone's Domain Company section: FrontierStack sets Cloudflare's two nameservers at GoDaddy, Porkbun, Gandi, DNSimple or Route 53 and asks Cloudflare to re-check activation. For other registrars it shows the two nameservers to copy.
- The registration — Transfer to Cloudflare… opens a checklist that reads the domain's live state: DNS active on Cloudflare, outside the 60-day lock, transfer lock off (with Unlock for GoDaddy, DNSimple and Route 53), and the authorization code (fetched from Route 53 or Gandi, emailed by DNSimple). The last step opens Cloudflare's transfer page, where you confirm and pay one year's renewal — Cloudflare has no API for starting a transfer.
domain tool: check (read-only), suggest (finds available names from keywords or a business description) and register, the last gated behind an explicit confirmation. Without a Porkbun or Namecheap key, checks and suggestions use GoDaddy’s public search, which needs no key but gives no prices and can’t buy. Registration reuses your stored registrar credentials and a registrant-contact profile you fill in once.7.9Cloudflare: zones, DNS, cache, tunnels and protection
The Cloudflare pane is where you paste an API token and choose which zones appear in the sidebar. Each zone you Pin to sidebar becomes its own pane with that zone's Cloudflare/DNS/HTTP/SSL health, DDoS and bot protection, WAF rules, Workers, CDN analytics, development mode and cache purging (everything, a list of URLs, or by prefix). Scope the token carefully: a read-only token lists zones, but DNS edits, certificate DNS-01 validation, Dev Mode, cache purge and zone creation each need their own permission, and creating a brand-new zone needs the account-level Zone · Zone · Edit permission. The Create Token… buttons open Cloudflare's token form with every permission the app uses already filled in (only that optional account-level zone-creation row must still be added by hand), a Test Token button probes the live API and lists exactly which of those abilities the token has or lacks (reads are exercised directly; writes are probed with deliberately-invalid requests, so nothing is changed), and a Dashboard button deep-links into the Cloudflare web console for the current zone.
When a pinned zone shows a warning or its HTTP check has stopped answering, the pane's Diagnose button finds out why instead of leaving you with a coloured dot. It probes each layer of the serving path in order — the zone's state at Cloudflare, the public nameservers, DNS resolution, HTTPS through the edge (decoding Cloudflare's 52x errors: 521 origin down, 522 timeout, 524 the app or its database hanging, 525/526 origin TLS), the origin server's ports 80 and 443 directly, and finally the machine FrontierStack knows serves the domain: the local web server if that is this Mac, or a linked server's on-host monitor service states (a stopped mysql surfaces right in the report). When the public path is broken it also sweeps the fleet: which linked servers are up, which binds the origin IP, and which already serves this domain's vhost — so a host that went offline and took the sites' front-door IP with it is named directly, together with the server that could take over. Each layer is shown pass/fail, ending with a plain-language conclusion — which layer broke and what to do about it.
Cloudflare turns up across the app: the AI's dns_record tool writes records into a zone you manage and updates existing ones in place — including flipping a subdomain between proxied (orange cloud) and DNS-only — issue_certificate can validate over Cloudflare DNS-01, and email_auth_dns can publish SPF/DMARC for you (see Chapter 13). The same account also powers Cloudflare DDNS and the Cloudflare Tunnel for exposing a local site — both covered in Chapter 9.
7.14.3When a site is under attack: Under Attack Mode
Every pinned zone's pane opens with an I'm Being Attacked button. It switches the zone to Cloudflare's Under Attack Mode (security level under_attack): every visitor gets a browser check of a few seconds before reaching the origin, which stops most request floods. You confirm before it turns on, because while it is on, anything that cannot run JavaScript — API clients, webhooks, mobile apps, uptime monitors — is blocked too. The same command sits on the zone's sidebar right-click menu (I'm Being Attacked…) and in the Cloudflare Zones mini palette, so you can reach it without hunting for the pane. A red shield in the sidebar and an ATTACK badge in the palette mark zones in the mode. Stand Down turns it off with no prompt and restores the security level the zone had before (or medium if the mode was switched on outside FrontierStack). The token needs Zone · Zone Settings · Edit; the AI Administrator can do the same with cloudflare_dev_mode action=under_attack.
7.14.4Email Routing and Email Service
The zone pane's Email section shows whether Email Routing is on and ready, its routing rules and catch-all, any destination address that is still unverified (mail forwarded there is dropped until it is confirmed), the last seven days of Email Service events with failures highlighted, and the zone's MX targets. It also warns when a mail hostname is orange-clouded: Cloudflare's proxy carries only web traffic, so SMTP and IMAP to a proxied host fail — set it to DNS-only. The Email Delivery monitor has a matching Cloudflare Email Service section listing every pinned zone, read with the same token. The token needs Zone · Email Routing Rules · Read (and Account · Email Routing Addresses · Read for destinations); the AI reads the same picture with cloudflare_dev_mode action=email_status.
7.14.5Core Web Vitals
The zone pane's Core Web Vitals section reports what real visitors experienced over the last seven days, from Cloudflare's free Web Analytics, with bots excluded:
| Metric | Measures | Good |
|---|---|---|
| LCP | Largest Contentful Paint — when the main content appears | ≤ 2.5 s |
| INP | Interaction to Next Paint — how quickly the page responds to input | ≤ 200 ms |
| CLS | Cumulative Layout Shift — how much the layout jumps | ≤ 0.1 |
| FCP · TTFB | First paint and server response time, shown for context | — |
Each value is the 75th percentile, with the share of page loads that were "good" and a green, orange or red rating. Web Analytics must be on for the site, and the token needs Account · Account Analytics · Read — now pre-filled by the Create Token… buttons. AI: cloudflare_dev_mode action=web_vitals.
7.14.6Rate-limiting and WAF rules
The zone pane's Rules section lists the zone's rate-limiting and custom WAF rules, each with its action, its limits (for example "block, more than 20 requests / 10 s per IP") and its expression. The switch turns a rule off and on. Edit changes the name, expression, action and limits. The … menu offers Revert to Previous Version — FrontierStack keeps the version from before its last edit — and Delete Rule, which the app cannot undo. Changes are live on Cloudflare as soon as you apply them, and Cloudflare rejects an expression it cannot parse without changing anything.
Watch for the orange warning. A rule with no hostname condition applies to every hostname in the zone, not only your website. A rule that matches a URL path such as /djs/ also matches a media or image host whose paths contain the same segment, so a visitor loading one page can be blocked with error 1015 (HTTP 429) partway through its images — and a cached image does not help, because rate limits run before the cache. The editor offers one-click Exclude <host> buttons that wrap the expression as (http.host ne "host") and (…).
New Rule… creates a rate limit, a custom WAF rule, a cache rule (cache for a set time, or bypass the cache) or a redirect. It asks for a hostname, with an optional path prefix, instead of a bare path, so a new rule cannot silently cover every host; a hand-written expression gets the same warning. Managed WAF, URL rewrite and request/response header rules are listed when the zone has them. They can be switched on and off, renamed and deleted, but their parameters (cache TTL, redirect target, headers) are shown rather than edited — recreate the rule to change them.
Each kind needs its own token permission — Zone WAF, Cache Rules, Single Redirect or Transform Rules — Read to view and Edit to change; the pane names whichever is missing. Rules in Cloudflare opens the dashboard. AI: cloudflare_dev_mode action=rules lists the rules, action=rule_create adds one and action=rule_update changes one (each needs Allow changes and your confirmation). It can disable a rule but never delete one.
7.14.7Security events and Bot Fight Mode
The zone pane's Security Events section shows what Cloudflare blocked, challenged or logged on the zone in the last 24 hours, grouped by source (rate limiting, custom rule, managed rules, DDoS, browser integrity check…), rule and hostname. Custom and rate-limit rule ids are shown by name. An orange triangle means visitors were stopped on a hostname other than the main site — typically a media or image host caught by a rule meant for pages. Start here when images go missing or visitors report error 1015 or 429, then fix the rule under Rules.
Below the list, Bot Fight Mode shows and switches Cloudflare's free bot challenge. Turning it on asks first: it can block legitimate bots, feeds, webhooks and monitors, and on the free plan a rule cannot exempt them. Needs Zone · Analytics · Read. AI: action=security_events and action=bot_fight.
7.14.8Cache by hostname
The zone pane's Cache by Hostname section shows, for the last 24 hours, each hostname's requests and the share of cacheable requests served from Cloudflare's cache (HTML and API responses are left out), plus the top files that were not served from cache. A zone-wide hit rate hides an image host that never caches; this does not. A host well below 100% usually has no cache rule, an origin sending Set-Cookie or Cache-Control: no-store, or a rule blocking requests before they reach the cache. AI: action=cache_hosts.
7.14.9Workers
The account pane's Workers section lists every Worker with the routes that point at it, the last day's requests, errors and 99th-percentile CPU time, and a bar showing usage against the plan's published allowance — 10 million requests a month on Workers Paid, 100,000 a day on Free — turning orange at 70% and red at 90%. Needs Account · Workers Scripts · Read, Workers Routes · Read and Account Analytics · Read, all pre-filled by Create Token…. AI: action=workers.
7.14.10Plan and notifications
The account pane's Plan & Notifications section lists the account's subscriptions (plan, price, state, renewal date) and its notification policies, and warns when there are none — nothing would then tell you about an outage, an expiring certificate or Workers usage. It is read-only; Billing and Notifications open the dashboard. Needs Account · Billing · Read (pre-filled) and Account · Notifications · Read, which has no token-template shortcut and must be added by hand. AI: action=plan_usage.
7.14.11Turnstile widgets
Turnstile is Cloudflare's free CAPTCHA replacement for sign-up, login and contact forms. The Cloudflare pane's Turnstile section lists your widgets with a Copy Site Key button each. New Widget… asks for a name, up to ten hostnames and a mode (Managed, recommended; Non-interactive; Invisible). The new widget's secret is shown with Copy and Save Secret to Script Secrets, which stores it as $TURNSTILE_SECRET_<NAME> for your scripts. Each row's ⋯ menu reaches an existing widget's secret too: Copy Secret Key (the clipboard clears after 60 seconds), Save Secret to Script Secrets and Rotate Secret…. Rotating has Cloudflare issue a new secret while the old one keeps working for two hours, so put the new one on every server that verifies the widget before then; a copy already in Script Secrets is updated for you. The site key goes in the page; the secret stays on your server, which checks each visitor's token with Cloudflare's siteverify endpoint. Delete Widget… lives in the same menu.
cfat_). It needs a user token with Account · Turnstile · Edit. Test Token now probes this and the other optional account-level permissions, tells a network failure or a Cloudflare 5xx apart from a bad token, and says which account a multi-account token acts on.7.14.12Named tunnels: health, alerts and Access
Each named tunnel row (see Chapter 9) carries a status line: Cloudflare's view of its connectors — healthy, degraded, down or inactive — and, for a tunnel this Mac runs, whether the local port answers, since a healthy tunnel in front of a stopped service still fails. The bell opts that tunnel into an alert if it or its service goes down (Alerts group Network & Routing). Protect… puts a Cloudflare Access sign-in in front of the hostname: list email addresses and/or @domains, choose how long a sign-in lasts (one hour to 30 days), and visitors sign in with a one-time PIN sent to their email or through your identity provider. FrontierStack creates a reusable allow policy and a self-hosted Access application; a blue lock marks protected tunnels, and Remove Access takes it off. Access needs Zero Trust set up on the account once (the free plan covers 50 users) and Account · Access: Apps and Policies · Edit.
7.14.13AI access through Cloudflare MCP
The AI Access (Cloudflare MCP) section lets the AI Administrator use Cloudflare's official MCP server at mcp.cloudflare.com with the token you already saved — useful for products FrontierStack has no pane for (WAF rules, Workers, R2, KV, D1, Access). Turn on Let the AI Administrator use Cloudflare MCP and press Test Connection. Out of the box it is read-only: the AI can search Cloudflare's documentation and its full API specification. Allow API calls (execute), off by default, lets it run JavaScript against the live API; every run needs Allow changes and your approval. MCP clients connected to FrontierStack reach the same server through the hosted_mcp tool with provider=cloudflare (see the tools table in Chapter 13). Other MCP clients ▸ Copy Config gives a token-free entry for Claude, Cursor and similar apps, which sign in to Cloudflare themselves with OAuth.
mcp.cloudflare.com as a header and is never shown to the AI; credential values in responses (tunnel tokens, Turnstile secrets) are redacted. With execute on, the AI can do anything the token allows — keep the token's permissions narrow.7.14.14Cloudflare developer tools
The Cloudflare pane's Developer Tools section installs Cloudflare's own tooling from its agent-setup guide. Install adds the Cloudflare CLI (cf, beta) with npm in the in-app console, adding Node through Homebrew first if needed; Sign In… runs cf auth login and opens your browser to authorize your account (it does not use the saved API token). The Claude Code plugin row adds the cloudflare/skills marketplace and installs the cloudflare plugin, Cloudflare's skills plus its API, docs, bindings, builds and observability MCP servers. That installs third-party plugin code, so run /reload-plugins in Claude Code afterwards. It needs Claude Code on this Mac.
7.10Hosting providers
Not everything you run lives on a Mac. The Hosting category brings VPS and managed providers into the same window. VPS providers — DigitalOcean, Vultr, Linode, Hetzner, Sakura and others — expose their servers through an API token: paste it, and the pane lists each server with plan, location, status and IP, and lets you power one on, off or restart with a confirmation. Dashboard-style providers store their token and surface quick links to the control panel, docs and sign-up. Hostinger goes further: with an API token from hPanel ▸ Account ▸ API the pane lists and powers your VPSs, takes a VPS snapshot (Hostinger keeps one per VPS, so a new one replaces it), lists your domain portfolio with expiry dates and your hosting websites, and lets the AI Administrator read and set DNS records with dns_record (provider=hostinger). Its AI Access (Hostinger MCP) section connects the AI to Hostinger's official MCP server with the same token — read tools only, until you turn on Allow writes. Either way the credential lives in the Keychain, and the servers you can reach over SSH become part of your fleet (Chapter 8). ConoHa signs in with three values from its control panel’s API page — the API user, its password and the tenant ID — lists and powers your VPS 3.0 (or legacy 2.0) servers, and adds a DNS section for ConoHa DNS zones: add, edit and delete records here, or let the AI do it with dns_record (provider=conoha). ConoHa DNS is free for ConoHa customers and is the usual API-managed home for a domain registered at Onamae.com, which has no DNS API of its own. Tencent Cloud signs every request with an API key pair (SecretId and SecretKey from CAM ▸ API Keys; the SecretKey never leaves the Mac). It lists and powers your CVM and Lighthouse servers in every region, manages DNSPod records (or the AI does, with provider=dnspod), and shows your SSL certificates by expiry, COS storage buckets (flagging any an ACL leaves publicly readable), CDN and EdgeOne sites, and this month’s charges. Set the account’s site — international or China — because the two keep separate accounts. Domains registered at Tencent Cloud are imported in Domain Registrars like any other registrar’s, and new ones can be bought there: Tencent quotes its price, registers to a registrant profile on the account and pays from the balance, after a preview and a confirmation.
Xserver (エックスサーバー) takes one API key from the XServer account (API キー管理) — read-only is enough except for setting up SSH for a move — and covers its rental servers, XServer Business, Xserver Domain, Xserver VPS, Xserver VPS Cloud and Xserver for WordPress. The pane lists every contract with its plan and renewal date — VPS Cloud VPSs, DB servers, load balancers, NFS volumes and additional IPs included — and powers the VPSs and VPS Cloud resources, shows each rental server's disk and file use and any certificate that has expired or is about to, copies the contracts into Spend & Billing with Xserver's published 12-month list price, and imports Xserver Domain renewals into Domain Registrars; a live monitor raises an alert for a suspended contract, a renewal due with auto-renew off, a quota at 90%, an expired certificate or an expiring key. Move to This Mac… brings a rental server's sites home: FrontierStack reads the domains, document roots, databases and WordPress installs from the API, registers its own SSH key there, rsyncs each document root and copies each database — live with mysqldump, using the password from the site's wp-config.php, or from last night's automatic backup — into Homebrew MySQL. It rewrites the /home/xs… paths, gives each WordPress its own local MySQL user, adds the sites to Apache (on 127.0.0.1 until you choose to serve them publicly) and writes XSERVER-IMPORT.md with the DNS zones, cron jobs, mail accounts and the cut-over steps. Mail is not moved: Xserver exports neither mailboxes nor their passwords. Running the move needs a licence; the inventory does not.
7.11IndexNow: instant search-engine submission
When a page changes, you do not have to wait for a crawler to notice. IndexNow Manager (in SEO & Marketing) tells the participating engines — Bing, Yandex, Seznam, Naver and others — immediately. Pick one of your managed sites, press Install Key File, and FrontierStack writes the <key>.txt file into the site's document root so the engines can confirm you own the key; Verify checks it is being served. Then submit a single URL, fire off the pending queue, or feed it from a sitemap, and it can auto-submit on a schedule. Everything goes to api.indexnow.org, which fans out to all participating engines; the URL's host must match the selected site and its key.
gsc_verify_domain and index_site tools, hands-off when you are signed in to Google. The Index button on each Domain Health row drives both paths at once.7.12OpenSEO and DataForSEO: your own SEO toolkit
OpenSEO (SEO & Marketing) is an open-source alternative to Semrush and Ahrefs — keyword research, rank tracking, competitor insights, backlinks, site audits and AI visibility — with an MCP server so your AI agent can use the same data. Its pane starts with one question: where does it run?
- Hosted — app.openseo.so. Free to try, $10/month to support the project; SEO data is billed through OpenSEO credits (DataForSEO's price plus 28%), so you do not need your own DataForSEO account.
- Docker on this Mac — Set Up & Start pulls
ghcr.io/every-app/open-seoand starts it onhttp://localhost:3001. Your projects live in theopen_seo_datavolume, so Apply Settings & Restart (after changing a key or the port) and Update (latest image) keep them. OpenSEO's telemetry is off by default, and you can share your OpenRouter key to enable its SAM agent. - Self-hosted elsewhere — enter the URL of an existing instance, or press Deploy to Cloudflare…. FrontierStack clones the repository, writes an owner-only
.env.selfhostwith your DataForSEO key and the email addresses allowed through Cloudflare Access, and runspnpm deploy:selfhostin the in-app console. The first run signs you in to Cloudflare; answer yes to customising the OAuth scopes and enableaccess:write. Paste the Worker URL it prints back into Instance URL.
The live monitor reads the instance's /api/health endpoint, which lists the setup checks for the DataForSEO key, database, auth mode, AI and Search Console. Pin Alert me and a failing check raises an alert. If you paste an oseo_ API key, it is checked against the MCP endpoint, so a revoked key is flagged too. The AI agents section copies the MCP URL, a claude mcp add command and a Claude Desktop/Cursor config. The API-key variant reads $OPENSEO_API_KEY from your shell, so FrontierStack never puts the key on the clipboard.
DataForSEO is the data source behind OpenSEO, and it has its own live monitor, which the OpenSEO pane embeds. Enter the API login and password from app.dataforseo.com ▸ API Access (not your dashboard password), or leave the login empty and paste the longer Base64 credential. The monitor shows your prepaid balance, today's spend and API calls, and it can alert you when today's spend passes a threshold or the balance drops below a floor you set. Self-hosted OpenSEO installs take the same credential, so you enter it once.
7.13Site Clone: copying sites between machines
The Site Clone pane (Setup & Migration) copies a website — its files and its MySQL database — from where it is now to somewhere else, in four numbered steps. Pick where the site is now (This Mac, one of your pinned servers, or a hosting account reached over SFTP/FTPS) and where the copy goes (This Mac, a pinned server, A new server… or a hosting account). Find Sites & Databases lists the folders a server's web server serves and its databases, so you pick rather than type. A new server is linked over SSH when the clone starts; Pin it to the sidebar keeps it with your other servers afterwards. The database can be copied once, or kept in sync as a MySQL replica: FrontierStack creates a replication login on the source, loads a dump taken at a known binary-log position, and starts a replication channel on the copy that carries only that database. Check tests both ends first, without changing anything, and names whatever stops a replica (MySQL older than 8.0.23, binary logging off, a source that only listens on 127.0.0.1).
Two more tools move a site without a manual rsync dance. Copy Websites Between Apache handles the local case: when you have more than one Apache install on the Mac (say a Homebrew one and an old Server.app one), choose the source install, tick the sites you want, and FrontierStack copies their document roots and vhost definitions into the currently selected Apache. Sites with the same domain are overwritten, so it is also how you re-import after a migration.
To move a site to another machine, the AI's promote_site tool clones a local site to one named fleet host: it uploads the document root, writes the vhost (Apache or Nginx) on the far side, reloads the web server, and can add the Cloudflare A record pointing at the new host — the same steps as a manual fleet push, in one call.
7.14Provisioning a new web project
The pieces above combine into a single flow for standing up a project's infrastructure from nothing. The idea is a clean division of labour: your AI tool (over MCP) owns the code; FrontierStack owns the infrastructure. The built-in Provision Web Project skill walks the assistant through the recipe in order:
- Discover — inventory the target, its privilege access, installed Apache/Nginx and connected DNS provider; identify or install missing prerequisites before making a public change.
- Zone —
cloudflare_zone_createmakes the Cloudflare zone and returns the nameservers to set at the registrar (and tells you plainly if the token lacks account-level zone-create rights). - Vhost + folder —
vhost_createdefines the Apache/Nginx site. If you did not provide a document root, FrontierStack creates an empty platform-appropriate folder and reports its path. It does not design or generate site content. - DNS —
dns_recordpoints the name at the host. - TLS —
issue_certificateissues a Let's Encrypt certificate. - Preview — a temporary share for a localhost test point (Chapter 9).
- Promote — optionally
promote_siteclones it onto a fleet host.
Domain registration can join the front of this recipe through domain_register, so an agent can in principle buy the name, create the zone, stand up the vhost, issue the certificate and clone to the fleet — with every money-spending or system-changing step previewed for your approval first.
FrontierStack User Manual · Version 1.0.0 · Chapter 7