---
title: "quario over MCP — quario"
description: "Running quario for an agent through its MCP server: adding it to a client, the line between host and author, render data, and the file a render writes."
url: "https://getquario.com/docs/diving-deeper/mcp"
---

# quario over MCP

## Intent

`@quario/mcp` gives an agent two tools: `validate_report` checks a definition
and returns its problems, and `render_report` renders one to a file. Use it
when an agent client such as Claude Code or Claude Desktop should write
reports for you. You wire no tool of your own.

## Design decisions

**The launch configuration is the host, and the agent is an author.** Whoever
writes the server’s configuration decides what the server may touch. The
agent calling the tools writes the definition and chooses the data, and the
engine treats an author as untrusted. So no tool argument reaches a host
setting. The query budgets, the `href` schemes, the license key, the data root
and the output directory come from the environment alone. An agent can’t raise
a budget to finish a large render, or point `dataPath` outside the directory you
granted it.

**How a report looks is the author’s to choose.** `locale`, `currency`,
`timeZone` and a target’s `page` and `meta` may come from a call. They change
the document, not what the server can reach.

**A problem is an answer, not a failure.** `validate_report` returns problems as
a successful result, each at the path it sits at, so the agent reads what to fix
and tries again. `render_report` plans against its target first and returns the
same problems, marked as an error, instead of rendering a broken document.

**A render returns a path, never the document.** Every target writes a file into
the output directory and returns its location. Clients handle embedded binary
results badly or not at all. A path is the one shape that reaches you in every
client quario tested the server against.

**The engine checks the definition.** The `definition` field carries the full JSON
Schema of the report document, so an agent reads what a definition may hold from
the tool itself. The server still passes the definition to the engine unchecked.
One located problem helps an agent more than a list of every schema rule that
failed.

## API walkthrough

### Adding it to a client

In Claude Code, one command adds the server:

```bash title="terminal"
claude mcp add quario -e QUARIO_LICENSE=quario_... -- npx -y @quario/mcp
```

In Claude Desktop, add it to `claude_desktop_config.json`:

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

Without `QUARIO_LICENSE` the server runs unlicensed, and every file it writes
carries the watermark. The server is a deployment: one key on it covers
every agent that calls it, and no agent holds a license of its own.

### Where render data comes from

A call gives exactly one of `data` and `dataPath`. Inline `data` suits a small
payload the agent already holds. `dataPath` names a JSON file inside the data
root, `QUARIO_DATA_ROOT`, or Claude Code’s project directory when that’s unset.
The server resolves symlinks before it tests the path, so a link can’t leave the
root, and without a data root it refuses `dataPath` entirely.

An image arrives in the data as an object with one key. `{ "$image":
"assets/logo.png" }` names a PNG or JPEG inside the data root, so an agent
doesn’t paste a picture into every call. `{ "$base64": "…" }` carries the bytes
inline. Either decodes to bytes before the render, and the definition reads it
as usual. The server tests an `$image` path after symlinks resolve, reads only
a PNG or JPEG, and refuses `$image` without a data root.

### The file a render writes

The file lands in `QUARIO_OUT_DIR`, or a `quario-mcp` directory under the
system’s temporary directory. A call may suggest a `filename`, a name without a
directory, and the server gives it the target’s extension. The server never overwrites a file, so a
name that exists gets a numbered suffix instead.

### What this release leaves out

This release leaves out registered functions, host fonts, and remote transport.
A report that needs a registered function renders through your own code, where
you register it. The [AI report generator](https://getquario.com/guides/ai-report-generator.md) guide
wires that loop with function calling.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://getquario.com/"},{"@type":"ListItem","position":2,"name":"Docs","item":"https://getquario.com/docs"},{"@type":"ListItem","position":3,"name":"quario over MCP","item":"https://getquario.com/docs/diving-deeper/mcp"}]}
```
