---
title: Quilium architecture
description: Get a map of the whole system, the parts a Quilium site is made of and how content turns into a served page, so the rest of the Explanation pages have somewhere to anchor.
updated: 2026-06-22
prev: what-is-quilium
next: content-model
---

## The shape of the system

Quilium is a structured SaaS CMS with a templating layer on top and a native [MCP](/en/docs/ai-mcp-skills) server beside it. Those three facts explain almost everything about how it is put together.

The core idea is a clean split between **what the content is** and **how it looks**. You model your content once as typed objects in a data store. You write templates that read those objects and render HTML. From then on the two evolve on their own clocks: editors and agents change content without touching code, and you change templates without migrating data. The published site is the output of pressing one against the other.

What makes Quilium unusual is that both a human and an [AI agent](/en/docs/ai-mcp-skills) drive the same machine. There is no separate "automation API" bolted to the side. The [CLI](/en/docs/cli) and the MCP server operate on the very same model, types and templates a person edits by hand. An agent that scaffolds a content-type is doing exactly what a developer does, through a different door.

<div class="q-ph"><i class="fa-regular fa-image"></i><span><b>Placeholder:</b> architecture diagram. Show the seven components (CMS data store, structured types, render layer, CLI, MCP server, skills library, published site), the left-to-right flow content → render → served site, and the two driver lanes (human via CMS/CLI, agent via MCP) both feeding the same model. To produce from the fil-rouge demo site.</span></div>

## The building blocks

A Quilium project is a handful of parts, each with one job. Knowing which part owns what is most of understanding the system.

| Component | What it is | What it owns |
|---|---|---|
| CMS data store | The backing store for everything editable | Pages, content blocks, collection entries, `global fields`, media |
| Structured types | The schemas your content conforms to | `page-type`, `content-type`, collection type definitions |
| Render layer | The Liquid templating engine | Turning a page plus its data into HTML, server-side |
| CLI | The local developer tool | Auth, scaffolding, running the site locally, the i18n dictionary |
| MCP server | The agent-facing interface | The same operations as the CLI and CMS, exposed to agents |
| skills library | Task-oriented guides for agents | Canonical patterns an agent loads before acting |
| Published site | The output | The static HTML served to visitors |

### The data store and the types

The data store holds the editable substance of a site. The types describe its shape. We keep these two distinct on purpose: a `page-type` is a schema, a page is an instance of it; a `content-type` is the definition of a reusable block, a **content block** is one such block dropped onto a page.

Three structured types do most of the modelling, and telling them apart prevents most mistakes:

| Object | Role | Example |
|---|---|---|
| `page-type` | The template and content zones for a single kind of page | `home`, `article` |
| `content-type` | A reusable block dropped into a page's sections | `hero`, `gallery`, `quote` |
| `collection` | A managed set of structured, listable entries | articles, members, events |

One convention is worth stating once and obeying everywhere: a **content block**'s data lives under `custom: {}`, a collection entry's under `data: {}`. The wrapper is the single most common source of modelling errors. [The content model](/en/docs/content-model) covers when to reach for each of these, with a decision table.

Two smaller pieces round out the data layer. `global fields` hold the rare site-wide singleton, the kind of value that is genuinely unique to the whole site rather than to a page. We use them sparingly, a logo being the canonical case; most footer, contact and social data belongs in a **content block**, not a global. And a **query** is a route-aware data fetch declared on a `page-type`: it is how a detail page pulls in the one collection entry, or the list, it needs to render.

### The render layer

Templates are plain Liquid files. There is no client-side framework in the picture: a template renders server-side to HTML, and the data it reads comes from two places, the **content blocks** placed on the page and the **queries** declared on its `page-type`.

```liquid
{% layout "layout.liquid" %}

{% block content %}
  <article>
    {% include '_contents', section: page.contents['main'] %}
  </article>
{% endblock %}
```

The mechanics of this, the context objects a template can read, how a **route** resolves into `page.custom`, what gets rendered when, are the subject of [How Quilium renders the site](/en/docs/how-quilium-builds) and [Templating philosophy](/en/docs/templating-philosophy). The one fact to carry forward from here is the direction of flow: the model is the source of truth, and the template is a pure function of it.

### The CLI, the MCP server and the skills library

These three are the surfaces you and your agents act through. They sit in front of the same model, which is exactly the point.

- The **CLI** is the local developer tool. It authenticates with an [access token](/en/docs/cli), scaffolds and runs the site on your machine, and drives the i18n dictionary. Commands are code-styled in this doc, for example `quilium init` and `quilium run`.
- The **MCP server** exposes those same operations to an [AI agent](/en/docs/ai-mcp-skills) over the Model Context Protocol. Anything the CLI or the CMS can do, an agent can do through the MCP, under your review.
- The **skills library** is what keeps an agent honest. Skills are small, task-oriented guides encoding the canonical Quilium patterns, the wrapper rule, the route-versus-`page-type` distinction, the field-type choices. An agent loads the relevant skills before it acts, so it builds with real conventions instead of plausible guesses.

[AI, MCP and skills](/en/docs/ai-mcp-skills) goes into why Quilium ships an MCP server and a curated skills library rather than leaving agents to improvise.

<div class="q-callout q-callout-note"><i class="fa-solid fa-circle-info lead"></i>
  <div><b>One model, two doors.</b> The CLI and the MCP server are not separate products with separate data. They are two interfaces onto one data store and one set of types. That symmetry is why a site can be built by hand, by an agent, or by both in turn, with the same result.</div></div>

## How a request becomes a page

Put the parts in motion and the global flow is short. Someone, a person in the CMS, a developer at the CLI, or an agent through the MCP, models content against the types. A visitor requests a URL. Quilium matches the URL to a page, resolves the **queries** the page's `page-type` declares (this is where a **route** turns a `/segment/{{param}}` into concrete data), and renders the page's templates against that data. The result is HTML, served.

Read it as a pipeline:

1. **Model.** Content blocks and collection entries are created and edited against their types, by humans or agents.
2. **Resolve.** On a request, the matched page's `page-type` runs its route-aware **queries**; results land in `page.custom`.
3. **Render.** The Liquid render layer reads the page's content blocks and query results and produces HTML.
4. **Serve.** The published site returns that HTML to the visitor.

The seam between steps one and three is the whole design. Content can change a hundred times without a template edit, and a template can be rewritten without touching a single content block, because neither step reaches across the seam. Multilingual works the same way: one model, rendered per locale, which [The multilingual model](/en/docs/multilingual-model) unpacks. The URL-matching half of step two, route patterns and link generation, is the subject of [Routing and URLs](/en/docs/routing-and-urls).

## Where each thing lives

A quick orientation for where these parts physically sit:

| Thing | Where it lives |
|---|---|
| Types (`page-type`, `content-type`, collection), routes, `global fields`, settings | Site configuration, edited through the CMS, the CLI or the MCP |
| Pages, content blocks, collection entries, media | The CMS data store |
| Liquid templates and partials | <span>Plain `.liquid` files at the site root, in your local project</span> |
| The i18n dictionary | <span>Managed via the CLI and the MCP, per locale</span> |
| The skills library | Served by Quilium, loaded on demand by agents |

<div class="q-ph"><i class="fa-solid fa-folder-open"></i><span><b>Placeholder:</b> the exact on-disk project layout (which directories hold <code>layout.liquid</code>, <code>layouts/</code>, <code>elements/</code>, partials, and where settings/types are stored locally versus remotely). Confirm against a fresh <code>quilium init</code> project and the Reference page on project structure.</span></div>

## The core vocabulary

These are the words the rest of the doc leans on. The pages below are the deeper zoom on each.

| Term | In one line |
|---|---|
| `page-type` | The schema for a kind of page; a page is an instance of it. |
| `content-type` | The definition of a reusable block; a **content block** is an instance. |
| `collection` | A managed set of structured, listable entries. |
| **content block** | One block of a `content-type` placed on a page; its data sits in `custom: {}`. |
| **query** | A route-aware data fetch declared on a `page-type`. |
| **route** | The `/segment/{{param}}` pattern that maps a URL to a detail page. |
| `global fields` | Site-wide singletons, read as `globals.<field>` in templates; used sparingly. |
| **CLI** | The local developer tool (`quilium init`, `quilium run`). |
| **MCP** | The Model Context Protocol server exposing the same operations to agents. |
| **skill** | A task-oriented guide an agent loads before acting. |

## Where to go next

<div class="q-cards">
  <a class="q-card reco" href="/en/docs/content-model"><span class="k">Recommended</span><span class="t">The content model</span><span class="d">When to use each building block, with a decision table.</span></a>
  <a class="q-card" href="/en/docs/how-quilium-builds"><span class="t">How Quilium renders the site</span><span class="d">Queries on the page-type, server-side render.</span></a>
  <a class="q-card" href="/en/docs/ai-mcp-skills"><span class="t">AI, MCP and skills</span><span class="d">Why Quilium exposes an MCP server and a skills library.</span></a>
</div>
