---
title: "quario — declarative reports for the agentic age"
description: "Declarative reporting for AI agents. The model drafts a JSON report, quario computes every total from your data, and nothing the model writes can run."
url: "https://getquario.com/"
---

REPORTING FOR THE AGENTIC AGE

Agents draft the pages.\
quario does the folding.
========================

Reports are data, not code. An LLM drafts the definition; quario computes every number from your data and runs nothing the model writes.

[Getting started](https://getquario.com/docs/getting-started.md) [View docs](https://getquario.com/docs.md)

npm install quario

Free to evaluate, no time limit · one license per production deployment · users, agents, and renders never counted

agent · quario-reports Replay

Invoice for Acme — line items for the March work, total in dollars.

1. `validate_report` 2 problems

   - sort\[0].dir: unknown sort direction "descending"
   - detail.columns\[1].value \[{{ round(@.qty \* @.unitPrice }}]: Unexpected end of expression

2. `validate_report` revised 0 problems

3. `render_report` invoice-1042.pdf

Invoice No. 1042

| Item                | Amount      |
| ------------------- | ----------- |
| Typesetting         | US$1,440.00 |
| Folding & gathering | US$320.00   |
| Total               | US$1,760.00 |

The model wrote the formula. The total came from the data.

Renders wherever JavaScript runs

- Browser
- Node
- Edge
- Workers

NO DESIGNER, NO SANDBOX

## Three steps from a definition to a document.

1. 01 · DEFINE

   ### An agent — or you — drafts JSON

   Sections, bindings, expressions. A format a model can write and a person can read.

2. 02 · VALIDATE

   ### Check it before it renders

   `plan()` rejects a malformed definition and hands back every problem at its path.

3. 03 · RENDER

   ### HTML, PDF, a workbook, or Word

   quario computes every total from your data, then renders it wherever JavaScript runs — browser, Node, edge, workers.

## One definition, four document shapes.

The same definition gives HTML, PDF, a workbook, or Word.

`@quario/html`

### A page

`@quario/pdf`

### A PDF, no headless browser

`@quario/xlsx`

### A workbook, numbers stay numbers

`@quario/docx`

### A Word document, and Word paginates

SAFE BY CONSTRUCTION

## Untrusted input by design.

An agent's output is untrusted, because a prompt injection can hide in it. Engines that compile templates run that output through `eval`. quario parses expressions into safe closures. It generates no code and evaluates none.

And the model never writes a number. It declares the formula for each figure, and quario computes it from your data. If the model picks the wrong formula, you'll see it in the definition — not buried in the output.

- eval / new Function 0 uses
- numbers typed by the model 0
- script-src 'self' — strict CSP passes
- code injection via definition impossible by construction
- markup in a definition escaped as text

BUILT FOR TOOL CALLS

## A reporting tool for agents.

Connect the quario MCP server, or register a tool of your own. The agent passes a definition and gets back every problem at the path it sits at, so it fixes the definition before anything renders.

The server's configuration stays yours: query budgets, link schemes, the data it may read and where it writes. Because the data comes from your side of the boundary, every figure traces back to your systems, not to the model.

- MCP server
- Skill
- JSON Schema
- llms.txt

[Read the agent guide](https://getquario.com/guides/ai-report-generator.md)

The loop The skill MCP Function calling

```
→ validate_report  { definition }
← 2 problems
    sort[0].dir: unknown sort direction "descending"
    detail.columns[1].value [{{ round(@.qty * @.unitPrice }}]: Unexpected end of expression
→ validate_report  { definition }  revised
← {"problems":[],"warnings":[]}
→ render_report  { definition, target: "pdf", dataPath: "invoices/1042.json", filename: "invoice-1042" }
← Wrote invoice-1042.pdf (1.8 kB): /srv/reports/invoice-1042.pdf
```

Two problems, one retry, nothing rendered until it passed.

You

Make the March invoice for Acme, totals in dollars.

Agent

- Using skill: `quario-reports`
- `validate_report` — 1 problem, fixed
- `render_report`

Done — saved invoice-1042.pdf

The skill teaches the loop: declare, validate, render. [Get the skill](https://github.com/getquario/skills)

claude\_desktop\_config.json

```
{
  "mcpServers": {
    "quario": {
      "command": "npx",
      "args": ["-y", "@quario/mcp"],
      "env": { "QUARIO_LICENSE": "quario_..." }
    }
  }
}
```

tools: validate\_report, render\_report one key per deployment · every agent that calls it is covered

tool.ts

```
import { writeFile } from 'node:fs/promises'
import { generateText, jsonSchema, stepCountIs, tool } from 'ai'
import { anthropic } from '@ai-sdk/anthropic'
import { quario } from 'quario'
import { pdf } from '@quario/pdf'
import schema from 'quario/schema.json' with { type: 'json' }

const q = quario()

// The agent writes the definition; your code supplies the data.
const draftInvoice = tool({
  description: 'Write a quario report definition for an invoice.',
  inputSchema: jsonSchema(schema),
  execute: async (definition) => {
    const { report, problems } = q.plan(definition)
    if (!report) return { ok: false, problems } // back to the agent

    await writeFile('invoice.pdf', await report.render(pdf(), await getInvoice()))
    return { ok: true }
  },
})

await generateText({
  model: anthropic('claude-sonnet-5'),
  tools: { draft_invoice: draftInvoice },
  stopWhen: stepCountIs(5),
  prompt: 'Make the March invoice for Acme, totals in dollars.',
})
```

The AI SDK's tool(), the same validate-then-render loop.

worker.ts · no agent required

```
import { quario } from 'quario'
import { pdf } from '@quario/pdf'
import definition from './reports/statement.report.json' with {
  type: 'json',
}

const q = quario({ locale: 'en-GB', currency: 'EUR' })
const report = q.report(definition)          // once, at startup

export async function renderStatement(accountId: string) {
  const data = await db.statements.forAccount(accountId)
  return report.render(pdf(), data)          // HTML · PDF · XLSX · DOCX
}
```

SDK FIRST

## No agent required.

Compile a definition once and render it from a scheduled job, a queue worker, or an API route. The same definition gives HTML, PDF, a workbook, or Word.

If you know bands, groups, and running totals from classic report designers, you already know quario.

[How quario lays out bands](https://getquario.com/docs/diving-deeper/bands.md)

## Report templates for JavaScript

A growing set of production-ready quario reports. Each one is a declarative definition — copy it, point it at your data, and render to HTML, PDF, Excel, or Word.

[All templates](https://getquario.com/templates.md)

- [Certificate](https://getquario.com/templates/certificate.md)
- [Event ticket](https://getquario.com/templates/event-ticket.md)
- [Expense report](https://getquario.com/templates/expense-breakdown.md)
- [Invoice](https://getquario.com/templates/invoice.md)
- [JSON Resume](https://getquario.com/templates/json-resume.md)
- [KPI scorecard](https://getquario.com/templates/kpi-scorecard.md)
- [Packing slip](https://getquario.com/templates/packing-slip.md)
- [Purchase order](https://getquario.com/templates/purchase-order.md)
- [Receipt](https://getquario.com/templates/receipt.md)
- [Revenue report](https://getquario.com/templates/revenue-report.md)
- [Shipping label](https://getquario.com/templates/shipping-label.md)
- [Statement](https://getquario.com/templates/statement.md)
- [Summary report](https://getquario.com/templates/summary-report.md)
- [Timesheet](https://getquario.com/templates/timesheet.md)
- [Work order](https://getquario.com/templates/work-order.md)

BANDS WITHOUT THE BAGGAGE

## Where it fits.

Safer than letting the model write HTML. Lighter than the heavyweight suites. More of a real engine than a PDF hack.

- Heavyweight suites

  The same banded model, without the designer runtime, per-server licensing, or `eval` in the template engine.

- PDF hacks

  Screenshot a webpage and hope. No structure, no bindings, no future.

- Model writes HTML

  The model types every number itself. Needs a sandbox, impossible to validate, different every run.

- quario

  The model declares, the engine computes. Validated before it renders, and safe by construction — whoever writes the definition.

COLOPHON

quario takes its name from the *quarto* and the *quire* — the folded sheet and the gathering of leaves that make a book. Whoever drafts the pages, quario does the folding.

*quarto*, a sheet folded into four leaves · *quire*, a gathering of folded sheets · *‑ario*, a place that gathers. Net meaning: a place where pages come together.

PER DEPLOYMENT, NOT PER PERSON

Free to start.\
Fair to ship.
-------------

Commercial software with readable source. Evaluate it free for as long as you like. License each production deployment when you ship, then let every user and every agent render without limit.

Agents and users are never counted. You license the deployment, not the people or the bots that use it.

### Evaluation

$0

- Full engine
- no key
- no time limit
- every runtime
- output carries a watermark

[Getting started](https://getquario.com/docs/getting-started.md)

### Deployment

Per deployment / year

- Unlimited users, agents, and renders
- unmarked output
- development, staging, and CI free
- annual, and the versions you paid for stay yours

[See commercial terms](https://getquario.com/pricing.md)

```json
{"@context":"https://schema.org","@type":"Organization","name":"quario","description":"Builds a declarative reporting engine for JavaScript: one JSON report definition renders to a page, a PDF, a workbook and a Word document.","url":"https://getquario.com/","logo":"https://getquario.com/logo.png","sameAs":["https://github.com/getquario","https://www.crunchbase.com/organization/quario-82fd"]}
```
