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, passwords, preview links, PWA toggle | page_settings (action-based) |
a database |
snapshots |
every deploy, with point-in-time restore | snapshots |
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.plinth.pageYour 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, writes the new bytes to object storage. Snapshots the previous version in the same transaction.
-
03
deploy
object storage→global CDN⁰Storage write triggers an edge deploy. Files land at every region's CDN node within seconds.
-
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 — hi@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.
When you register_domain through Lanlan, the registration is in your name (or your client's) at the registrar. We're not the owner of record. To leave, you point the DNS somewhere else. 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 DNS (in your name), 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.