< cd ../work[01]CASE> cat fwrd-studio.mdlive, in active development

Websites that maintain themselves

FWRD Studio builds a small business a website from a short description, then keeps working on it. The site watches how visitors use it and proposes changes the owner approves, and every site has its own MCP endpoint so it can be managed from Claude.

role
founder / product & AI systems engineering
year
2026 — now
status
live, in active development
stack
SvelteKitAstro + SanityCloudflare WorkersSupabaseStripeMCP / LLM agents
Two browser windows on a dark backdrop: the fwrd.digital homepage hero, 'Describe your business. Get a website that maintains itself.' above a prompt box, and in front of it the FWRD Studio start screen at app.fwrd.digital/start, with a prompt box under 'Your site should be working as hard as you. Let's fix that.'
fig.01The fwrd.digital homepage and the FWRD Studio start screen, captured live on 5 October 2026.

[CASE]fwrd-studio.md07 CHAPTERS ·5 MIN READ

The problem

For a small business, launching the website is the easy part. Afterwards pages go stale, the call to action stops fitting, and nobody has time to look at how visitors use the site. FWRD is my Dutch web company, and FWRD Studio is its product. It treats a website as something that keeps being worked on after launch.

FWRD homepage hero reading ‘Describe your business. Get a website that maintains itself.’ above a prompt box with a ‘Build my site for free’ button
fig.02The pitch is one prompt box: describe the business and get a website that maintains itself.

How it works

A visitor describes their business in a chat box. An LLM pipeline turns that description into a structured site config, and the config renders into a client template that is then provisioned on Cloudflare. Building is free. You pay when the site goes live.

The system has three parts:

  • The marketing site, fwrd.digital. Astro on Cloudflare Pages, with Sanity as a block-based page builder that includes two scroll-pinned storytelling blocks. It is also written for machine readers: a custom Astro integration generates llms.txt and llms-full.txt from Sanity, and every page has a Markdown twin. The blog runs in six languages, translated by a model with parity checks against the Dutch source.
  • The hub, app.fwrd.digital. A SvelteKit app on Cloudflare Pages, plus a separate Cloudflare Worker for generation, chat, Stripe webhooks and crons, and a dedicated MCP worker. Data lives in Supabase Postgres with deny-by-default row-level security, and cross-tenant tests run in CI. Stripe handles subscriptions, credits, top-ups and dunning.
  • Client sites. Each site is built from the “Maple & Stone” template, which uses Astro and Sanity and is driven by tokens. Brand theming is done with Tailwind v4 @theme CSS variables that are overridden per client at build time. Every document carries a siteId, and the template emits JSON-LD, including LocalBusiness. The builder warns when a colour choice fails WCAG contrast.
FWRD Studio start screen: ‘Your site should be working as hard as you. Let’s fix that.’ with a prompt box and ‘Attach files’ and ‘Improve prompt’ buttons
fig.03FWRD Studio’s starting point: a business name and what you do, and the agent takes it from there.

Provisioning is a durable Cloudflare Workflow: a GA4 property, a Pages project and a Turnstile widget per site, a GitHub Actions build of the template, then DNS and, for custom domains, a Cloudflare for SaaS hostname. Every step is get-or-create, so a failed run resumes where it failed. A cron watchdog flags sites that stay stuck in provisioning.

After launch

The site watches how visitors behave and turns that into suggestions, such as a sharper CTA, a new page for a search intent people keep arriving with, or archiving a page nobody reads. The owner approves each suggestion, or turns on autopilot and sets the limits on what it may change by itself.

Step 05 ‘Your site evolves on its own’ next to a suggestions panel with an autopilot toggle and three approvable suggestions
fig.04After launch the site proposes its own improvements. The owner approves each one or lets autopilot handle them.

Every FWRD site also gets its own MCP endpoint with four tools: generate_page, edit_page, publish_site and run_report. The owner connects it to Claude and asks for changes in plain Dutch. Each edit comes back as a card that shows its credit cost, and nothing goes live until it has been approved.

Section ‘Claude now knows your website’ listing generate_page, edit_page, publish_site and run_report beside a Claude chat showing a costed edit_page card
fig.05Every FWRD site gets its own MCP endpoint, so changes can be requested from Claude and published only after approval.

One of the first internal tools was mcp-page-gen, an MCP server of about 520 lines with three tools: Claude writes a schema-exact Sanity document, the server saves it as a draft, and it scaffolds the Astro page. After every Claude call the server estimates the cost from the reported token usage and throws the result away if it crosses a ceiling (50 cents by default), so page generation can’t run up the bill unnoticed.

Decisions worth explaining

  • Receipts over model claims. A September audit showed that replies like “here is what I changed” were model-written free text, never checked against the actual diff. The fix renders the factual half of each reply from a server-side change receipt, adds no-op detection to the shared edit functions so an edit that changed nothing isn’t billed, and adds a claim guard that strips sentences the receipt can’t support. Its first version was overfit to the sentences it was tuned on; after a rework, a fresh test corpus showed it catching 43 of 50 rephrased false claims and keeping all 40 true sentences.
  • Fail closed. If the Turnstile secret is missing, the form pipeline returns 403 on every submission. Other layers: a honeypot, size caps, an allow-list of fields declared on the Sanity form document, and a Sanity token that can only create submissions. Secrets never go into Sanity, because the dataset is publicly readable through GROQ.
  • Deterministic gates for untrusted input. The prompt-injection check for the Coordinator agent, which reads inbound client messages, is deterministic: regex, keywords, length, and encoding checks after NFKC normalisation. A planned LLM classifier may only add advisory flags, because an injection that fools the agent can fool an LLM judge too.

Built with agents, reviewed by agents

FWRD started in May 2026 as a marketing site, an internal boilerplate and the page-generation server. For the first stretch I ran the company as a Paperclip organisation of 12 Claude agents. It had a CEO, a CTO, engineers, marketing roles and a Risk & Compliance council (cybersecurity, legal, accessibility) that could sign off, ask for fixes or block a release. I was “the board”, and a question only reached me when it was blocking, irreversible, needed human judgement and had no internal owner. The first commits in the hub repository are authored by the frontend engineer agent.

From June on, most of the build ran through Claude Code sessions that I directed. I made the product calls, approved merges, and handled the parts that need a human, like live payments and DNS. By September the hub was about 200k lines, with 122 migrations and 182 test files. A deep review that month sent about 60 finder agents across 30 subsystems and gave every finding two independent refuters, so only findings that survived both went onto the fix list.

My role

Founder and the only human engineer. I decide what the product does and how the system fits together, from the prompt box down to the Cloudflare and Supabase setup. I designed and ran the agent setup that builds and audits it, and I approve what ships.

Status

It is live. fwrd.digital serves the landing page, and app.fwrd.digital runs the Studio builder. Development is ongoing: in early October the hub was at v2.58, and a migration gate on deploys had just gone live. In June an audit of the go-live checklist against the code found the backend well ahead of the UI, so the launch plan became a concierge pilot in which I handled publishing by hand.

[NEXT]cd ../sponsorboard02 / 03

Next case: Sponsorboard

Creator sponsorships, matched in both directions

A two-sided marketplace that matches content creators with brands whose audiences fit, then runs the deal in one app. I founded it, designed it, and rebuilt it in 2026 as an Expo and Supabase app with a reciprocal matching pipeline built on pgvector and a Claude rerank. It is built, but not launched yet.

EVOLUTION 0034