Escape

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:

terminal
claude mcp add quario -e QUARIO_LICENSE=quario_... -- npx -y @quario/mcp

In Claude Desktop, add it to claude_desktop_config.json:

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 guide wires that loop with function calling.