How it works is the story of an edit. This is the wiring behind it: what each piece is, who runs it, which secrets it holds, and how long they live. Nothing here is a diagram of an ideal. It is what the code does.
There is no application server anywhere in this list. Your site is compiled to files ahead of time, and the only thing that ever runs on a request is Cloudflare handing one over.
| Piece | What it actually is | Who runs it | Holds secrets |
|---|---|---|---|
| Your repository | Markdown and HTML files on GitHub. The source of truth for every word on your site. | You | No |
| Your site | An Astro static build, served by Cloudflare Pages. Plain HTML by the time a visitor sees it. | You | No |
| Lanza, the CMS | A Vue app at /admin. Static files, with no backend of its own. | You | No |
| lanza-site | The npm package holding the render code and the site's server functions. You pin a version. | You | No |
| The broker | connect.lanzacms.com, which handles onboarding, login, and minting short-lived tokens. | Lanza | Yes, all of them |
| /api/mcp | The endpoint an AI agent connects to in order to edit your site. | You | No |
The CMS never writes to your live site. It writes to a staging branch, and publishing is an ordinary git merge, which is why every change is reversible and nothing is ever half-applied.
PUT → stagingThe CMS commits to the staging branch through its own /admin/api/gh proxy. Your browser never holds a GitHub token: the proxy attaches one per request, scoped to this one repository, and it expires in about an hour.
staging.<project>.pages.devCloudflare builds the staging branch too, so there is a real URL showing exactly what you just wrote, before anyone else can see it.
merge staging → mainOne merge. No separate deploy step and no copy of your content living anywhere else.
astro build → distThe push to main triggers a static build. Entries marked draft never render, whether or not they were merged.
git revertEvery version is a commit. Rolling back is the same operation a developer would use, and the CMS keeps theme history for the same reason.
Your site holds no signing secret. It verifies with a public key baked into the package, which means the thing that proves who you are lives somewhere it cannot be stolen from you.
The useful question about a credential is not whether it is encrypted. It is what an attacker reaches if they hold it, and for how long.
| Credential | Reaches | Lifetime |
|---|---|---|
| Your session cookie | Your site's /admin only. HttpOnly, Secure, and scoped so it is never sent on public pages | 7 days |
| The GitHub token behind a save | One repository, contents only. Minted per request; never sent to the browser | ~1 hour |
| An agent's access token | The sites you ticked on the consent screen, and nothing else | 1 hour, refreshable |
| A token minted for one agent call | Exactly one site. The audience is pinned to it | 5 minutes |
| Your site's own key material | Nothing. It holds a public key and can only verify | none |
Your site exposes an MCP endpoint. An agent that connects to it goes through the same OAuth round-trip you do: authorization code with PKCE, discovery over the standard well-known documents, and a GitHub login for identity. If you own several Lanza sites, one consent screen asks which of them this agent may touch, and that choice is carried on the token itself; a tampered response can only narrow the grant, never widen it. The agent is given a token bound to one site's endpoint. It never receives a GitHub token, and there is no personal access token to create, paste, or leak.
Read the agent contractPage views on Cloudflare Pages are unmetered, so there is no per-visit cost and no traffic level at which your bill starts moving. There is no database to pay for and no server sitting idle, because there is no server. The only recurring cost is your domain name, which you buy from whoever you like and point wherever you like.
Your site depends on a published package at a version you choose, so an improvement we ship does not change your site until you take it, from Settings, when it suits you. And the exit is not a feature we had to build: your content is already a folder of ordinary files in a repository you own. The broker is a convenience layered on top of a CMS that works without it: supply your own GitHub credentials and owner list and you can run the whole thing yourself, with us removed from the picture entirely.