---
title: Prompting well for Quilium
description: Give an AI agent what it needs to build a Quilium site correctly, and phrase the request so it does not have to guess.
updated: 2026-07-25
---

An agent connected to Quilium's [MCP server](/en/docs/mcp-tools) can do everything you can do in the backoffice, and it does it well when the request names the right objects and states the constraints. This guide is about the request.

<div class="q-callout q-callout-note"><i class="fa-solid fa-flask lead"></i>
  <div><b>Live examples.</b> The prompts below are written against the demo sites used throughout this documentation: <b>Méridienne</b> (coffee roaster), <b>Cairn</b> (hiking guides) and <b>Oscilla</b> (observability SaaS). Swap the names and the collection keys for your own.</div></div>

## 1. Make it load the skills before it acts

Quilium ships a **skills library** through the MCP server: task-oriented guides on field types, schema shapes, routing, translations, batching. It is served live, so it is always current, and it is the difference between an agent that writes plausible YAML and one that writes correct YAML.

Agents do not always reach for it on their own. Say so once, at the start of the session:

```prompt
Before any CMS operation, call get-skills, load every skill relevant to the task
(a real task needs several, not one), then call get-site-settings for this site.
Don't infer this site's structure from another project.
```

Two skills earn their place in almost every session: `meta-getting-started` once, and `practices-ops-mcp-batching` as soon as you go past a handful of write calls. You never install these — the server serves them and the agent pulls them. See the [MCP skill library](/en/docs/skills) if you want to know how it is organised.

## 2. Install the Quilium skills for your agent

The MCP library covers the CMS. It does not cover what sits around it: the order a whole site gets built in, the CLI loop (`init`, `run`, `push`, `dictionary`), and the Liquid layer. Two companion skills carry that part, `quilium-builder` for structure and templates, `quilium-webmaster` for running the site day to day.

They live in one public repository — [`quiliumio/quilium-skills`](https://github.com/quiliumio/quilium-skills) — and install in a line:

```bash
npx skills add quiliumio/quilium-skills
```

Run it from the project root. It asks which agents to wire up and writes the skills into the directory each one actually reads; `-y` takes every agent already on the machine and skips a selection screen where nothing is ticked the first time. `--agent codex` targets one explicitly, `-g` installs at user level rather than per project, `-l` only lists what the repository holds.

They are plain `SKILL.md` packages with nothing Claude-specific in them, so Codex, Cursor, Copilot, Gemini CLI, Zed and the rest read the same files. Claude Code can also load the repository directly as a plugin, and the manual path always works: clone it and copy the two directories under `skills/` wherever your agent looks.

Two consequences worth knowing. The install is **per project**, so it runs again in the next one. And skills are discovered at startup, so one installed mid-session does not load until the agent restarts.

The step-by-step version, with the installer's output and where the files land, is in [Set up the project](/en/docs/ai-setup), section 4.

## 3. Name things the way Quilium names them

The single biggest quality jump comes from using the platform's own vocabulary. "Add a section" is ambiguous. "Add a content-type" is not.

| Instead of | Ask for |
|---|---|
| "add a section to the page" | "add a **content-type** `mediaText` and drop a block of it on the home page" |
| "make a list of products" | "create an **collection** `flavors` with a detail **route**" |
| "the page needs the latest three articles" | "add a **query** on the page-type: `itemSet: articles`, `limit: 3`, sorted by `date` desc" |
| "put the address in the footer" | "add a **global field** `address` and read it as `globals.address`" |
| "make the article page" | "add a **page-type** with a query resolving the current item by `{{route.article.slug}}`" |

The vocabulary is in [The content model](/en/docs/content-model). An agent that receives the right noun loads the right skill.

## 4. Decide the shape, or ask for the decision explicitly

Most modelling mistakes are made in the first thirty seconds, when a repeating thing gets stored as the wrong kind of field. Either state the shape or make the agent justify one:

```prompt
The story on a coffee entry alternates paragraphs, pull quotes and full-width images,
in an order the editor picks. Which shape do you recommend: wysiwyg, repeat, or choice?
Give me the trade-off in three lines, then wait for my go before writing anything.
```

Asking for the trade-off first costs one exchange and saves a migration. When you already know, say it outright: "use a `choice` field with four variants" leaves nothing to interpret.

## 5. Give the order, or let the skill give it

Dependencies between Quilium objects are real, and getting them wrong produces errors that look like something else. A collection must exist before the `save` that targets it. Page-types must exist before the pages that use them, because a page freezes its template at creation.

```prompt
Build in this order: collections, then content-types and page-types, then routes,
then the base layout, then one template per type, then the content.
```

## 6. State the guardrails in the prompt

These are the ones worth repeating, because each failure they prevent is silent or misleading.

```prompt
Rules for this session:
- Templates are .liquid, always the full path (elements/hero.liquid).
- Never hardcode a URL path or a page UUID in a template. Use a named route.
- Create pages with the default state: active. `state` means routable, not published.
  An inactive page 404s everywhere, including locally.
- update-settings-partial replaces the whole target block: read it, merge, write it back entire.
- One locale per write call.
- Pages: leave them unpublished and tell me what to review. Never set a page inactive.
- Collection entries have no draft, they are live once saved. Show me the first one
  before writing the rest.
```

<div class="q-callout q-callout-warn"><i class="fa-solid fa-triangle-exclamation lead"></i>
  <div><b>"Leave it in draft" is the one that gets misread, twice.</b> An agent told to keep pages in draft may set <code>state: inactive</code>, and the whole site returns 404, locally included. Draft means "do not publish a live revision", never "deactivate the page". And it only applies to pages: a collection entry has no draft state, so asking for one silently gets you live content. Spell both out.</div></div>

## 7. Ask for verification, not just execution

An agent that reports "done" has usually written the calls, not checked the result. Make the check part of the task:

```prompt
When you're finished, run `quilium run`, then curl each page and confirm:
HTTP 200, no unrendered Liquid ({{ or {% in the output), no [object Object],
and every image returning 200. Paste what you checked.
```

For a template that renders empty for no obvious reason, the useful instruction is to probe rather than theorise: drop a `<!--DBG x=[{{ … }}]-->` comment into the partial, `curl | grep DBG`, then remove it. Some filters return empty without erroring, and an assumption there costs an afternoon.

## 8. Hand over real material

An agent with a prototype, a brand and a page blueprint produces a site. An agent with a paragraph produces a guess. Point at files rather than describing them:

```prompt
The static prototype is in prototype/. Match its markup and its classes.
The design tokens are in brand/. The page intent is in BLUEPRINT_accueil.md.
Convert the prototype into content-types; do not invent sections it does not have.
```

## A complete request

Everything above, in the shape of one real task on an existing site:

```prompt
Site: Cairn (bilingual FR/EN hiking guides). Load the Quilium skills for this task first,
then get-site-settings.

Goal: visitors should be able to filter the itineraries list by massif, in the browser,
on top of the existing query.

Constraints:
- No new page and no new route. The list block already exists.
- Store the key in the data attribute, never the translated label.
- Interface strings go through the translate filter so they follow the locale.
- Templates are .liquid; keep the existing class names.

Deliver: the YAML diff, the modified element template, the JS, and the curl output
proving the page still returns 200 with all cards present when JS is off.
```

Short, specific, and it names the objects. That is the whole technique.

## Related

<div class="q-cards">
  <a class="q-card reco" href="/en/docs/ai-mcp-skills"><span class="k">Recommended</span><span class="t">AI, MCP and skills</span><span class="d">Why Quilium exposes a skills library at all.</span></a>
  <a class="q-card" href="/en/docs/skills"><span class="t">MCP skill library</span><span class="d">How the served library is organised and discovered.</span></a>
  <a class="q-card" href="/en/docs/mcp-tools"><span class="t">MCP tools</span><span class="d">Every operation an agent can call.</span></a>
</div>
