How Cloudflare helps us run NetProjects
Alex Michalas, Founder & Director
NetProjects is a small team that runs several long-lived websites with the help of about 30 AI agents. Our last article described how that works: one job per agent, drafts by default, changes we can undo, and a person who decides. This companion piece is about where the work actually lands. Our public sites, our domains, our inbound email, a small internal tool and one of the AI models our agents use all run on Cloudflare, in a single company account.
As before, this is a plain account of what we do and what we've learned. There are no traffic charts and no claims about how fast our sites are. Where we give a time, it comes from a log or a timestamp you could check.
One account, one place to look
NetProjects (the trading name of Internet Projects Ltd) runs GreekMythology.com, Airportia.com, NetScores.com and the company site, netprojects.com. All of them are served through Cloudflare. Our company domains sit as zones in one account, and new domains are registered with Cloudflare Registrar by default. We only use another registrar for endings Cloudflare doesn't sell.
That matters more once agents are involved. An agent that needs to check DNS, read a Worker's settings or list our databases has one place to look, and so do we when we review what it did. For read-only questions the agents use Cloudflare's MCP server. On 5 October it listed 29 Workers, 9 D1 databases, 8 KV namespaces and 4 R2 buckets in the account. Many of those Workers are previews and prototypes, which is what cheap, disposable environments are for.
The company site is a Worker
netprojects.com is a Next.js site on Cloudflare Workers, built with the OpenNext adapter. Beta is password-protected and asks search engines not to index it. Production serves the main domain and www. Neither has a public workers.dev address or preview URLs. Every request, static files included, goes through our own Worker code first, so one small file sets the security headers (including a one-year HSTS header) and the beta-only rules. Workers observability is on, so when something looks odd there are logs to read.
Deploys: one command, measured in seconds
A deploy is a single command: one script for beta and one for production. It builds the site and hands it to Wrangler. The agents run it in the background, save the output to a log and run the automated tests first. Code reaches that point the way our last article describes, through Cursor, a pull request and a person's review.
Because every deploy leaves a log, we can say how long the Cloudflare part takes. Between the launch on 2 October and the evening of 4 October we made 19 production deploys of netprojects.com. In Wrangler's own output, uploading the Worker and activating it took between 6.5 and 20 seconds, and 18 of the 19 took under 10 seconds. On the evening of 2 October we shipped eight small changes in under an hour. For each one, the deploy log was finished between 60 and 84 seconds after the commit. Going back is one command too: Wrangler can roll production back to an earlier version.
From idea to a live domain in one morning
A new market data project shows the platform best. It is a market-cap and price data site, planned for 2027. On 4 October it went from an idea to a registered domain with a live teaser page before lunch. These are the timestamps, in Athens time:
- 08:30: an agent starts checking names and domains for the idea.
- 08:40: the project's main domain is confirmed as unregistered.
- 08:52: the list of domains to register for the new market data project is written. The files don't record the exact minute the name was chosen, but it was chosen by then.
- 08:54: the main domain is registered through Cloudflare Registrar, and the zone is active on Cloudflare's nameservers the same minute.
- 09:36: a dedicated agent for the project starts from a written handover.
- 10:51: the teaser and sign-up page is ready as a pull request, not yet deployed.
- 12:36: one minute after my yes, the agent uses the cf CLI to harden the zone: strict SSL, HTTPS only, a minimum of TLS 1.2, DNSSEC enabled, and a strict DMARC record. It also creates the forwarding rules for hello@ and security@.
- 12:49 to 12:50: the D1 database is created, and the teaser Worker goes live on the domain and its www version, two minutes after my yes. Wrangler's upload and activation took under seven seconds.
- 12:51: the agent checks the live pages, the redirects and HTTPS.
- 07:59 the next morning (5 October): I switch Email Routing on in the dashboard. A minute later, public DNS shows Cloudflare's mail records for the domain.
So the domain was registered about two minutes after the list was written. The site went live 3 hours 55 minutes after registration, and most of that time went on deciding what the product is. Each Cloudflare step took minutes or less. Email took longer, but not because of Cloudflare. The forwarding rules were ready at 12:36 on 4 October, and switching routing on is a dashboard click that none of our agents' credentials can do. I made that click at about 07:59 the next morning, roughly 19 hours later. Email routing is now on and tested: I sent a test message at about 08:03, and it arrived.
Two command-line tools
Wrangler is still how we build, deploy and roll back Workers, and how Workers get their custom domains. On 4 October, for the new market data project's zone, we started using Cloudflare's new cf CLI (version 1.0.0-beta.12) for everything around the code: DNS records, zone settings, DNSSEC and Email Routing rules.
Two features made it a good fit for agents. Its help output tells agents to discover commands by describing the task, not by guessing. And --dry-run prints the exact request it would send without sending it. Our agents show me the dry run, I approve, they apply it, and then they read the setting back to prove it changed. On 4 October every change was read back, nothing failed, and no other zone was touched. We found some rough edges, which is fair for a beta. There is no command yet for Workers custom domains, and a delete you haven't confirmed prints "Aborted." but still reports success. We wrote both down so the next agent doesn't trip on them.
Retiring a domain without breaking it
When netprojects.com replaced internetprojects.com, the old domain still had email on it, so we didn't touch its DNS. Two Worker routes on the old zone send web requests to the new site's Worker, which answers with a permanent (301) redirect: terms and privacy go to their new pages, and everything else goes to the homepage. The agent saved and diffed the DNS records before and after to show that nothing else had moved. The old "coming soon" teaser was kept as a Worker, ready to put back with one command.
GreekMythology.com: content at the edge
GreekMythology.com is a Next.js app on Workers, with its content in D1 and its images in R2. Pages are served from Workers Cache. Because a page render makes several trips to the database, Smart Placement runs the Worker near the database rather than near the visitor. A cron trigger every five minutes clears the cache for pages whose scheduled video has just gone public. The editing area sits behind Cloudflare Access, and the app's API has Workers rate limiting. Each of those is a setting or a few lines of code.
Email we receive, not email we send
Company addresses such as hello@ and security@ use Cloudflare Email Routing, so incoming mail is forwarded to an inbox we already read and we run no mail server. We don't send from the domain yet, so SPF allows only Cloudflare's routing and DMARC tells receivers to reject anything else. Nobody, person or agent, may set up "send as" until a proper sender exists.
A small hub of our own
For partner relations we built a company hub: a task board, notes on each partner and weekly reports. It is one Worker with a D1 database behind a login. It has its own agent, and the site agent has a standing rule never to touch it.
Busy sites, scrapers and the firewall
On one of our high-traffic sites, Cloudflare's WAF sits in front of everything. When a scraper shows up, real-time visitors jump, "Not Found" becomes the top page and one unusual source leads the traffic. A written skill tells the agent what to do. First it looks, read-only, at the analytics and at Cloudflare's security events. Then it proposes adding the specific addresses to an existing custom rule. It doesn't block whole countries, because real visitors live there too. Nothing is saved until a person says yes, and afterwards the agent logs what it saw and what changed.
A fast, cheap classifier on Workers AI
Some agent work is a long run of small yes-or-no questions. Does this screenshot show a working page or an error? Does this draft mention something it shouldn't? For those, our agents use Clef-flash on Workers AI. It takes the item and a few typed questions and returns a probability for each answer. It writes no prose. It is a first pass only: anything uncertain goes to open models on our own hardware and then to a person. On a trial of 50 labelled screenshots from one of our QA checks it was 94% right with no false alarms. It missed three pages stuck on a loading screen, so it may never pass a screenshot showing a loading bar on its own.
How agents get access
Agents never get one all-powerful Cloudflare key. Credentials are narrow and named by job. The default one on the agents' computer can do little beyond clearing the cache, DNS changes need a different one, and Workers AI uses its own. Handovers say where a credential lives, never what it is. Agents may not change Workers, routes, redirect rules or firewall rules on a live site without an explicit yes. After any problem on a live zone, they stay signed out until I sign them back in.
What can go wrong
Stale caches. After one deploy a site served old cached files until a person purged the cache. "Purge, then check the live page" is now on every deploy checklist.
Changes that take effect for everyone at once. Edge settings are live as soon as they are saved, so live changes need a person's yes, and the rollback path is written before launch, not after.
Credentials that do too much. A key that can edit every zone will eventually be used on the wrong one. A narrow key fails loudly with "not allowed", and that is the better failure.
What we'd tell you
- Keep every domain in one account you can see in one place.
- Put your own code in front of every request, so headers and rules live in one file.
- Make a deploy one command that leaves a log, so you can measure it.
- Give agents narrow, named credentials, never one key for everything.
- Dry-run first, approve, then read the change back.
- Keep the old version running until the new one has proved itself.
That's how a small team runs several long-lived sites, an inbox and a fleet of agents on one platform, and starts a new project before lunch. It isn't finished: it is a set of written-down habits we adjust as we go.
Alex Michalas is the founder and director of Internet Projects Ltd, which trades as NetProjects. You can read more about how we use AI at https://netprojects.com/standards/ai, and our earlier article at https://netprojects.com/insights/how-we-run-netprojects-with-ai-agents.