lanlan / dev / architecture

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?

the primitives

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.

the pipeline

What happens when you call update_file.

The walk from tool call to live URL. Sub-15-second deploys, end to end.

  1. 01

    tool call

    agent mcp.plinth.page

    Your agent serializes the call as JSON-RPC and sends it over Streamable HTTP. Single round-trip.

  2. 02

    validate & write

    MCP server object storage

    Server checks auth and the site pin, runs path validation, writes the new bytes to object storage. Snapshots the previous version in the same transaction.

  3. 03

    deploy

    object storage global CDN

    Storage write triggers an edge deploy. Files land at every region's CDN node within seconds.

  4. 04

    serve

    edge cache live URL

    CDN 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.

the protocol

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.

tool call — agent → server
{
  "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
}
response — server → agent
{
  "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.
the escape hatches

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.