{"serverId":"mcp-registry/com.galleyrender/galley-render","tools":[{"name":"create_template","fixed":{"name":"create_template","description":"Create a new template at version 1 from an HTML document with Liquid expressions, plus a JSON Schema for its data. Use this when nothing in list_templates fits. The name must be free on this account — publishing a change to an existing template is `update_template`, not this. Free, but each plan keeps a limited number of templates of your own (the starter library never counts): at the limit this returns `plan_required` with how many the account has, and `update_template` still works.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["name","source"],"properties":{"name":{"type":"string","pattern":"^[a-z0-9][a-z0-9._-]{0,62}$","examples":["invoice","delivery-note"],"description":"Template name: lowercase letters, digits, dot, dash or underscore, 1-63 characters. Unique per account. Versions are separate — do not put `@1` here."},"engine":{"enum":["chromium","satori"],"type":"string","description":"Rendering engine. `chromium` (default) is full HTML and CSS and is required for PDF. `satori` is a fast PNG path for simple flexbox card layouts — no page breaks, no floats, no external CSS — and costs us less, so prefer it for OG images and social cards."},"schema":{"type":"object","examples":[{"type":"object","required":["title"],"properties":{"title":{"type":"string","description":"Headline, one line"}}}],"description":"JSON Schema (2020-12) for the `data` payload this template accepts. Strongly recommended: it is what turns a bad payload into a field-level error with a path, an expected type and a working example instead of a blank page. Use `required` and give each property a `description`.","propertyNames":{"type":"string"},"additionalProperties":{}},"source":{"type":"string","examples":["<html><body><h1>{{ title }}</h1></body></html>"],"minLength":1,"description":"One self-contained HTML document with inline CSS and Liquid expressions (`{{ customer.name }}`, `{% for line in line_items %}`). No file includes: everything the render needs must be in this string, or at a public https URL. Two extra filters ship by default: `money` and `date_medium`. For a PDF, use `@page { size: Letter; margin: 18mm }` to control pagination."},"example":{"description":"A payload that renders correctly. It is echoed back in validation errors, so include one.","type":"string"},"message":{"type":"string","description":"Change note for this version, like a commit message."},"options":{"type":"object","properties":{"css":{"type":"string","description":"Extra CSS appended after the template's own styles."},"scale":{"type":"number","maximum":3,"minimum":0.1,"description":"Device pixel ratio for png/jpg, 0.1-3. Use 2 for retina."},"width":{"type":"integer","maximum":9007199254740991,"description":"Viewport width in px for png/jpg. Default 1200.","exclusiveMinimum":0},"height":{"type":"integer","maximum":9007199254740991,"description":"Viewport height in px for png/jpg. Default 630.","exclusiveMinimum":0},"margin":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"object","properties":{"top":{"type":["string","number"]},"left":{"type":["string","number"]},"right":{"type":["string","number"]},"bottom":{"type":["string","number"]}}}],"description":"PDF margins, CSS lengths in `in`, `px`, `cm` or `mm`: `18mm`, or per side. A bare number is px."},"quality":{"type":"integer","maximum":100,"minimum":1,"description":"jpg only, 1-100. Default 90."},"full_page":{"type":"boolean","description":"png/jpg: capture the whole document instead of the viewport."},"landscape":{"type":"boolean","description":"PDF only. Default false."},"page_size":{"type":"string","description":"PDF page size: `Letter`, `A4`, `Legal`, or `210mm x 297mm`."},"background":{"type":"string","description":"CSS colour painted under the document, e.g. `#ffffff`."},"on_blocked_asset":{"enum":["fail","skip"],"type":"string","description":"What to do when an image or font the template asks for is refused by the egress policy or fails to fetch. `fail` (the default) fails the render with `asset_blocked` naming the URL; `skip` drops the asset and renders without it. Use `skip` only for decorative assets."},"print_background":{"type":"boolean","description":"PDF: print background colours and images. Default true."}},"description":"Render options, merged over the template's own defaults. Options are part of the cache key, so two calls that differ only here are two different renders."},"description":{"type":"string","description":"One line on what this template is for. Shown in list_templates."},"expected_pages":{"type":"integer","maximum":2000,"minimum":1,"description":"How many PDF pages a typical payload renders. Default 1. This is the estimate the free tier and the spend cap are checked against before the render starts, so a template that runs to several pages must say so or a render that cannot fit the allowance will be started and then go over. It is not a limit: the render is billed on the pages it actually produced."}}},"annotations":{"readOnlyHint":false,"openWorldHint":true,"idempotentHint":false,"destructiveHint":false},"title":"Create a template"},"changes":[{"kind":"schema","detail":"Added \"type\":\"string\" to untyped parameters: example. Change to number/boolean/array where that's what you accept.","verify":true}],"tokensBefore":1393,"tokensAfter":1397},{"name":"render","fixed":{"name":"render","description":"Render a template plus a JSON payload into a PDF, PNG or JPG and return a signed URL. This is the one tool most calls need.\n\nSmall jobs finish inside the call and come back `status: \"succeeded\"` with a `url` you can hand straight to a user. Anything with a `webhook_url`, `async: true` or a large payload comes back `status: \"queued\"` with an id for get_render.\n\nRenders are deterministic and cached: the same template version, data and options return the stored object with `cached: true`, free and ","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["template","data"],"properties":{"data":{"description":"The JSON payload for the template, matching its schema. Call get_template for the schema, or validate_data to dry-run a payload for free. If get_template shows a `lang` property in the schema, add `lang` (a BCP 47 tag such as `fi` or `pt-BR`) for the reader's language, and `labels` (key to text) to reword single strings. Do not send them to a template whose schema lacks them: they are unknown fields there (a warning on an open schema, a 422 on a closed one).","type":"string"},"async":{"type":"boolean","description":"Force the queued path even for a small job. Default false: small jobs finish inside the call and come back with a URL already."},"format":{"enum":["pdf","png","jpg","jpeg"],"type":"string","description":"Output format. Defaults to `pdf` for chromium templates and `png` for satori ones. `webp` is not supported in v1."},"options":{"type":"object","properties":{"css":{"type":"string","description":"Extra CSS appended after the template's own styles."},"scale":{"type":"number","maximum":3,"minimum":0.1,"description":"Device pixel ratio for png/jpg, 0.1-3. Use 2 for retina."},"width":{"type":"integer","maximum":9007199254740991,"description":"Viewport width in px for png/jpg. Default 1200.","exclusiveMinimum":0},"height":{"type":"integer","maximum":9007199254740991,"description":"Viewport height in px for png/jpg. Default 630.","exclusiveMinimum":0},"margin":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"object","properties":{"top":{"type":["string","number"]},"left":{"type":["string","number"]},"right":{"type":["string","number"]},"bottom":{"type":["string","number"]}}}],"description":"PDF margins, CSS lengths in `in`, `px`, `cm` or `mm`: `18mm`, or per side. A bare number is px."},"quality":{"type":"integer","maximum":100,"minimum":1,"description":"jpg only, 1-100. Default 90."},"full_page":{"type":"boolean","description":"png/jpg: capture the whole document instead of the viewport."},"landscape":{"type":"boolean","description":"PDF only. Default false."},"page_size":{"type":"string","description":"PDF page size: `Letter`, `A4`, `Legal`, or `210mm x 297mm`."},"background":{"type":"string","description":"CSS colour painted under the document, e.g. `#ffffff`."},"on_blocked_asset":{"enum":["fail","skip"],"type":"string","description":"What to do when an image or font the template asks for is refused by the egress policy or fails to fetch. `fail` (the default) fails the render with `asset_blocked` naming the URL; `skip` drops the asset and renders without it. Use `skip` only for decorative assets."},"print_background":{"type":"boolean","description":"PDF: print background colours and images. Default true."}},"description":"Render options, merged over the template's own defaults. Options are part of the cache key, so two calls that differ only here are two different renders."},"template":{"type":"string","examples":["invoice","invoice@3"],"minLength":1,"description":"Template to use: `invoice` for the latest version, or `invoice@3` to pin version 3. Pin the version in anything you ship — a new version changes the output and the cache key. Call list_templates to see what this account has."},"webhook_url":{"type":"string","examples":["https://example.com/hooks/galley"],"description":"Absolute https URL to POST the finished render to. Supplying one forces the queued path: the call returns immediately with status `queued`."}}},"annotations":{"readOnlyHint":false,"openWorldHint":true,"idempotentHint":true,"destructiveHint":false},"title":"Render a document"},"changes":[{"kind":"schema","detail":"Added \"type\":\"string\" to untyped parameters: data. Change to number/boolean/array where that's what you accept.","verify":true}],"tokensBefore":1132,"tokensAfter":1137},{"name":"update_template","fixed":{"name":"update_template","description":"Publish a new immutable version of an existing template. Versions are never edited in place: `invoice@2` keeps rendering exactly as it did, and anything pinned to it is unaffected. Renders cached against the old version stay valid, and the new version starts with a cold cache. `engine`, `schema`, `options` and `example` are inherited from the previous version unless you send them, so a source-only change needs only `template` and `source`. Free.","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["template","source"],"properties":{"engine":{"enum":["chromium","satori"],"type":"string","description":"Engine for the new version. Inherited from the previous version when omitted."},"schema":{"type":"object","examples":[{"type":"object","required":["title"],"properties":{"title":{"type":"string","description":"Headline, one line"}}}],"description":"JSON Schema for the `data` payload. Inherited from the previous version when omitted — send `{}` only if you really want a version that validates nothing.","propertyNames":{"type":"string"},"additionalProperties":{}},"source":{"type":"string","examples":["<html><body><h1>{{ title }}</h1></body></html>"],"minLength":1,"description":"One self-contained HTML document with inline CSS and Liquid expressions (`{{ customer.name }}`, `{% for line in line_items %}`). No file includes: everything the render needs must be in this string, or at a public https URL. Two extra filters ship by default: `money` and `date_medium`. For a PDF, use `@page { size: Letter; margin: 18mm }` to control pagination."},"example":{"description":"A payload that renders correctly under the new version. Inherited when omitted.","type":"string"},"message":{"type":"string","description":"Change note for this version, like a commit message."},"options":{"type":"object","properties":{"css":{"type":"string","description":"Extra CSS appended after the template's own styles."},"scale":{"type":"number","maximum":3,"minimum":0.1,"description":"Device pixel ratio for png/jpg, 0.1-3. Use 2 for retina."},"width":{"type":"integer","maximum":9007199254740991,"description":"Viewport width in px for png/jpg. Default 1200.","exclusiveMinimum":0},"height":{"type":"integer","maximum":9007199254740991,"description":"Viewport height in px for png/jpg. Default 630.","exclusiveMinimum":0},"margin":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"object","properties":{"top":{"type":["string","number"]},"left":{"type":["string","number"]},"right":{"type":["string","number"]},"bottom":{"type":["string","number"]}}}],"description":"PDF margins, CSS lengths in `in`, `px`, `cm` or `mm`: `18mm`, or per side. A bare number is px."},"quality":{"type":"integer","maximum":100,"minimum":1,"description":"jpg only, 1-100. Default 90."},"full_page":{"type":"boolean","description":"png/jpg: capture the whole document instead of the viewport."},"landscape":{"type":"boolean","description":"PDF only. Default false."},"page_size":{"type":"string","description":"PDF page size: `Letter`, `A4`, `Legal`, or `210mm x 297mm`."},"background":{"type":"string","description":"CSS colour painted under the document, e.g. `#ffffff`."},"on_blocked_asset":{"enum":["fail","skip"],"type":"string","description":"What to do when an image or font the template asks for is refused by the egress policy or fails to fetch. `fail` (the default) fails the render with `asset_blocked` naming the URL; `skip` drops the asset and renders without it. Use `skip` only for decorative assets."},"print_background":{"type":"boolean","description":"PDF: print background colours and images. Default true."}},"description":"Default render options. Inherited from the previous version when omitted."},"template":{"type":"string","pattern":"^[a-z0-9][a-z0-9._-]{0,62}$","examples":["invoice","delivery-note"],"description":"Name of an existing template. A new immutable version is published; earlier versions keep rendering, so anything pinned to `name@2` is unaffected."},"description":{"type":"string","description":"Replaces the template description."},"expected_pages":{"type":"integer","maximum":2000,"minimum":1,"description":"How many PDF pages a typical payload renders. Inherited from the previous version when omitted. This is the estimate the free tier and the spend cap are checked against before the render starts, so a template that runs to several pages must say so or a render that cannot fit the allowance will be started and then go over. It is not a limit: the render is billed on the pages it actually produced."}}},"annotations":{"readOnlyHint":false,"openWorldHint":true,"idempotentHint":false,"destructiveHint":false},"title":"Publish a new template version"},"changes":[{"kind":"schema","detail":"Added \"type\":\"string\" to untyped parameters: example. Change to number/boolean/array where that's what you accept.","verify":true}],"tokensBefore":1278,"tokensAfter":1282},{"name":"validate_data","fixed":{"name":"validate_data","description":"Dry-run a `data` payload against a template's JSON Schema and get back exactly the errors a render would raise — field path, expected type, what was received and a value that would be accepted. Costs nothing and renders nothing. Use it before a batch, or whenever you are assembling a payload from somewhere you do not control. `warnings` lists fields the template would not use, each with a `did_you_mean` where there is a near match, and, where the template's schema declares `lang`, what `data.lan","inputSchema":{"type":"object","$schema":"http://json-schema.org/draft-07/schema#","required":["template","data"],"properties":{"data":{"description":"The payload you intend to render. Checked against the template's JSON Schema; fields it does not use come back in `warnings`, not as errors. `lang` and `labels` at the root are honoured only if the template's schema declares them (check get_template); otherwise they are ordinary unknown fields.","type":"string"},"template":{"type":"string","examples":["invoice","invoice@3"],"minLength":1,"description":"Template to use: `invoice` for the latest version, or `invoice@3` to pin version 3. Pin the version in anything you ship — a new version changes the output and the cache key. Call list_templates to see what this account has."}}},"annotations":{"readOnlyHint":true,"openWorldHint":true},"title":"Validate a payload against a template"},"changes":[{"kind":"schema","detail":"Added \"type\":\"string\" to untyped parameters: data. Change to number/boolean/array where that's what you accept.","verify":true}],"tokensBefore":365,"tokensAfter":369}],"toolsChanged":4,"tokensSaved":0,"todo":[],"note":"Deterministic fixes. Changes marked verify need a human look before shipping (renames, inferred annotations, inferred types, removed text). Parameter descriptions in `todo` need to be written by someone who knows the API."}