Driving Lolly from an AI agent

Give your model a deterministic, reviewable creative layer instead of asking it to hallucinate pixels. A tool invocation is just a URL with parameters - a few tokens that produce a press-quality file, the same way every time. No image model, no creative drift - and driven locally (URL or CLI), no data leaving the device. The hosted MCP endpoint is the one server-side path, covered below and inventoried on Server Surface.

Machine-readable entry points

Start here rather than scraping pages. Each file is generated by the docs build from the same sources the human pages come from, and each is served at the site root as well as under /info/.

FileWhat it is for
/agents.mdThe short version of this page for a machine reader: entry points, the URL grammar, how to get bytes and the rules that save a round trip.
/llms.txtThe docs index in the llms.txt convention - one line per page, linking its markdown twin.
/llms-full.txtEvery docs page in one file, in the index's order, for a reader that wants the whole corpus in one fetch.
/.well-known/lolly.jsonThe discovery record: where the catalog, the manifests, the render route, the MCP endpoints and the files above live on this deployment.
/openapi.jsonThe HTTP surface in OpenAPI 3.1 - the hot-link render route with its refusals, the catalog and manifest reads and the MCP endpoint's transport.
/info/capabilities.jsonFormat claims: what Lolly reads and writes per format and what each format's own metadata carries.
/catalog/tools/index.jsonThe generated tool index; /tools/<id>/tool.json is one tool's manifest with every input, default and format.
/info/skills/lolly/SKILL.mdThe agent skill: one page an agent loads to drive Lolly across every surface, with references for URL mode, the surfaces, the whole catalogue and the three document tools (chart, design, deck).

The same set exists on every deployment, so an agent pointed at a self-hosted instance discovers that instance's own endpoints from its own well-known record.

The model: a URL is the API

Every tool is fully described by its URL. The agent's job is to build that URL (or the equivalent CLI command) from structured inputs:

https://<host>/#/tool/<tool-id>?<input>=<value>&<input>=<value>

Open it and the tool renders with those inputs applied. Add reserved params to control output and trigger a download. Same inputs → same output, always - so results are reproducible, auditable and version-controllable.

What /#/tool/qr-code?url=https://suse.com renders - the bare canvas, no chrome, straight from the parameters in the linksigned by Lollyvector SVGखुद जाँचेंGet the signed file1 path~1.4k nodes12 KBTry it in the app

Use Lolly to generate the conference badge:
  tool: event-name-badge
  eventName: "KubeCon 2026"   firstname: "Ada"   lastname: "Lovelace"   company: "SUSE"
Return the file URL.

Discover a tool's inputs

Don't guess parameters - read them. The tool's manifest (tools/<id>/tool.json) lists every input id, type and default, or use the CLI:

npm run cli -- event-name-badge  # prints inputs, defaults, and supported formats
npm run cli                      # lists every available tool

Feed that schema to the model so it only emits valid inputs.

Reserved parameters

These are the common ones; anything outside the full reserved set is a tool input. (Full reference: URL Mode.)

ParamEffect
formatOutput format (png, svg, pdf, mp4, …)
exportPresence flag - render and download immediately on load
copyPresence flag - copy the result to the clipboard on load
width / w, height / hOutput size (value in unit)
unit, dpiPhysical sizing (mm/cm/in/pt) + raster resolution
bleed, marksPrint bleed and crop marks
profileColour profile - raster ICC (srgb/none) or CMYK press condition
filename, outputDownload filename / CLI output path
passwordLock the exported PDF
_vPin the tool version for stable output
slotOpen a saved session

The complete reserved set also includes full, options, c2pa, imprint, durable, meta, hdr, depth, cuts, lang, designv, template, nostage, z and zx; everything else is forwarded to the tool as an input. (The engine's RESERVED set in engine/src/url-mode.ts is the source of truth - see URL Mode.)

So a one-shot, ready-to-download link is just:

/#/tool/qr-code?url=https://suse.com&format=svg&export

Getting an actual file

``bash npm run cli -- qr-code --url=https://suse.com/kubecon --color=0c322c \ --export=svg --output=./qr.svg ``

(The lean node CLI renders SVG and text/data formats; raster/PDF/video need the desktop-bundled build - see CLI.)

Pipe stdout straight into another step in your pipeline.

A few tools won't hand back a file this way:

The MCP server (native endpoint)

Beyond building URLs by hand, Lolly ships an optional Model Context Protocol server - a native endpoint any MCP client (an agent runtime, an IDE, a CLI, a hosted assistant) connects to directly. It exposes the catalogue and the render path as callable tools, so an agent can discover a tool, fill its declared inputs and get back a finished file plus an editable lolly.tools link - with no app update, because tools sync to the server as data.

Core workflow verbs:

ToolDoes
lolly_list_toolsList / search the catalogue (by text, status, category, format, capability).
lolly_describe_toolOne tool's full input JSON Schema, built-in templates/presets, supported formats, canvas size and examples.
lolly_validateValidate inputs and return path-specific errors before a compile, URL build or render. Design also returns its artboard/layer tree and structural findings.
lolly_compile / lolly_inspect / lolly_measureCompile once, inspect the semantic document and measure it without rasterising.
lolly_build_urlBuild a shareable, editable link + raw render URL - without rendering.
lolly_renderRender a tool to a file (returns the bytes plus the editable link).
lolly_transformRun an on-device file utility (strip-data, compress-pdf) on a file you supply.
lolly_redactRedact regions of an image, SVG or PDF on-device - covered content is destroyed and the file rebuilt, so nothing is recoverable underneath.
lolly_verifyVerify a file's Content Credentials (C2PA) - the verdict, signer identity, edit history and embedded metadata. Checked in-process, never stored.

For Design, prefer templateId plus an optional presetId and a small set of input overrides. lolly_describe_tool lists those starting points; the same arguments work with validate, compile, inspect, measure, URL building and render. Inspect the template once to discover its stable layer IDs, then send layerPatches: [{ "id": "s1title", "set": { "text": "Your title" } }] to replace content without resending layer geometry. This lets an agent start from, for example, a slide deck or square poster without inventing raw coordinates.

Use layerOperations to change the layer set itself. It supports strict stable-ID add, duplicate, remove, reparent and reorder operations. Reorder anchors must be siblings. Reparent preserves the layer's geometry and accepts a destination artboardId (null means the pasteboard), plus an optional destination sibling anchor. Every duplicate takes an explicit newId; duplicating a non-empty artboard also requires a complete childIds map. Removing a non-empty artboard requires cascade: true. Operations run before layerPatches, so a newly created or moved layer can be patched in the same call:

{
  "toolId": "design",
  "templateId": "slide-deck",
  "layerOperations": [
    {
      "op": "add",
      "layer": { "id": "s1-kicker", "kind": "text", "frame": "slide1", "text": "Draft" },
      "afterId": "s1title"
    }
  ],
  "layerPatches": [
    { "id": "s1-kicker", "set": { "text": "Agent-added context" } }
  ]
}

Any format, transparently

lolly_render returns whatever format the tool declares - the server picks how to produce it, and the agent never has to know which engine ran:

Formats are per-tool - you can only request one a tool declares (lolly_describe_tool lists them). Ask a QR tool for svg and you get vector; ask an animated-ad tool for mp4 and you get video - the call is identical either way.

Connect a client

The recommended endpoint is the full one - https://mcp.lolly.tools/mcp (a browser-free serverless endpoint at https://lolly.tools/api/mcp also exists, for vector/data output only). Connect either one of two ways - both authenticate against the same shared access token, which your Lolly operator holds (it is never printed in a link or a log). Full reference: the MCP Server page.

A custom connector (OAuth). The endpoint is also a stateless OAuth 2.1 authorization server, so it drops straight into any MCP client that supports custom connectors:

  1. In your client's connector settings, add a custom connector pointing at https://mcp.lolly.tools/mcp. (Hosted assistants usually expose this under a Connectors or Integrations panel; on team/enterprise plans an admin typically adds it once for everyone.)
  2. Leave the OAuth Client ID / Secret blank - the server registers your client automatically (dynamic client registration).
  3. The client auto-discovers the OAuth server and opens a consent page. Paste the access token and approve - done.

Nothing is stored server-side: the client registration, the authorization code and the tokens are all short-lived signed values verified with a shared secret on each call (PKCE-protected, so a leaked link can't be replayed).

A bearer token (CLI / any HTTP client). The endpoint also accepts the raw token directly, so scripted clients skip the OAuth dance. Most MCP clients take a config entry like:

{
  "mcpServers": {
    "lolly": {
      "type": "http",
      "url": "https://mcp.lolly.tools/mcp",
      "headers": { "Authorization": "Bearer <your-access-token>" }
    }
  }
}

(Or run it locally over stdio during development - no token needed.)

A hosted add-on - not offline or edge

The MCP server is the one part of Lolly that is a server-side add-on, not an on-device component. Producing the full format range - animations, print PDF, HTML-layout raster - means driving a headless browser against a built web shell, so the full endpoint runs as a hosted service and is not suitable for offline or edge deployments. That full endpoint is live at https://mcp.lolly.tools/mcp; the lightweight serverless endpoint at lolly.tools/api/mcp runs the browser-free tier only (vector, data and PNG for SVG-native tools). The on-device shells - web PWA, desktop, mobile and CLI - remain the offline / air-gapped path. See the MCP Server page for the full reference.

Why this beats prompting an image model

Tips