What's actually under the hood.
You've read the pitch. You're here for receipts. This page is the receipts — the data model, the deploy pipeline, the protocol layer, and the answer to the question every other platform's architecture page ducks: what happens if we want to leave?
Six things a Lanlan site is made of.
Files. Structured content. Form submissions. Live values. Page-level settings. Snapshots. Plus the brand guide that travels with all of them. Each is its own primitive with its own tools.
| primitive | what's stored | how you reach it | where it lives |
|---|---|---|---|
files |
HTML, CSS, JS, images, fonts | get_site_files, update_file, patch_file, edit_element |
object storage |
collections |
structured content with editable schemas (blogs, team pages, portfolios) | collection (action-based) |
a database |
forms |
submissions to the site's contact forms | form (action-based) |
a database |
live_data |
single live JSON values per key (counters, statuses, totals) | live_data (action-based) |
a database |
page_settings |
per-page status, preview links, PWA toggle (the site password lives on the site, set with protect) |
page_settings (action-based) |
a database |
snapshots |
the last 20 published versions, each restorable | list_snapshots, restore_snapshot |
object storage |
brand |
design tokens — colors, fonts, voice notes — at /_brand/brief.md |
design_consultation, get_design_brief |
object storage (markdown file) |
Everything except the database tables is a file in object storage. The database holds metadata, schemas, and the things that need to be queryable.
What happens when you call update_file.
The walk from tool call to live URL. Sub-15-second deploys, end to end.
-
01
tool call
agent→mcp.lanlan.siteYour agent serializes the call as JSON-RPC and sends it over Streamable HTTP. Single round-trip.
-
02
validate & write
MCP server→object storageServer checks auth and the site pin, runs path validation, and writes the new source bytes to object storage.
-
03
deploy
object storage→global CDN⁰The site is built into a new, immutable version — partials and collections resolved — and the live pointer flips to it atomically. Every published version is kept for restore. On a site set to publish manually, the new version waits as a draft until someone presses Publish (or calls
publish_site). -
04
serve
edge cache→live URLCDN edge invalidates, the new bytes serve. HTTPS automatic, no build step.
⁰ The CDN and object-storage stack are Cloudflare's. Happy to share specifics on a sales call — info@lanlan.site.
How the agent and the server talk.
Streamable HTTP. JSON-RPC. No server-side state except the session and your default site pin. Everything else is one round-trip.
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "patch_file",
"arguments": {
"site_id": "33b69e87-...",
"path": "index.html",
"patches": [{
"find": "Welcome to my site",
"replace": "Studio days. Wedding nights."
}]
}
},
"id": 47
}
{
"jsonrpc": "2.0",
"result": {
"content": [{
"type": "text",
"text": "{\"success\": true,
\"patches_applied\": 1,
\"deploy_id\": \"...\"}"
}]
},
"id": 47
}
- Stateful
- The session (auth) and the default site pin from
select_site. - Stateless
- Every tool call carries everything it needs. You can drop and resume mid-session and lose nothing.
- Transport
- Streamable HTTP. Older MCP clients on stdio need a transport bridge — most are on HTTP now.
Five questions every other platform ducks.
If you ever want to leave, here's exactly what that looks like. Answered honestly, including the question with the awkward answer.
Can I export my sites? Yes.
get_site_files returns every file. One bash loop and you have a folder of HTML/CSS/JS on your machine. No proprietary block model to translate. The bytes you wrote are the bytes you get back.
The shape of an export — this is pseudocode for now. A real REST export endpoint is on the way; today this runs through your MCP client.
# pseudocode — the MCP equivalent today, REST export coming
for path in $(lanlan list-files --site $SITE); do
lanlan get-file --site $SITE --path $path \
> "./export/$path"
done
Are the files mine? Yes.
They're HTML, CSS, JS, and your media in standard object storage. Same shape any static site host expects. Drop them on Vercel, Netlify, S3, your own server. They work.
Can I keep my domain? Yes — with one step.
A domain you bring stays at your registrar the whole time; to leave, point the DNS somewhere else. A domain you buy with register_domain is registered through our Cloudflare Registrar account (ICANN-accredited, WHOIS privacy on). To take it with you, unlock it and get its transfer code — dns_records with unlock and auth_code — then start the transfer at any registrar. We don't hold it hostage.
Can I self-host the engine? Not today, honestly.
The engine is small — a few thousand lines — but it's tied to Cloudflare's edge in ways that make a one-button self-host non-trivial. If you're a team with a strong reason to host it yourselves, write to us. We'll have a real conversation.
What if Lanlan goes away? You keep what you built.
Sites keep serving for the duration of the CDN cache. After that, you have your files (export above), your domains (transfer them out with their auth codes), your Stripe account (in your client's name), and your form submissions (export them via the dashboard). No platform can promise to exist forever. We can promise that the day we stop, you don't lose your work.
We want you to stay because the product is good, not because leaving is hard.
The receipts hold up. Want to build?
Two lines of config and you're connected to the engine.