Skip to main content
Glama

Create a draft batch

create_batch

Saves a new draft batch in the workspace with one pending job per row for each page (pages, or every page of templates), or one video per row for a flow: an image, or a video when a row's output format is mp4, gif, webm or mov. Nothing renders and no credits are spent until run_batch. The result's creditCost is the exact number of credits run_batch will spend on these jobs. Every call creates a separate batch, so repeating a call duplicates it. To change an existing batch use update_batch. Rows are checked as in validate_batch, and one invalid row rejects the whole request with nothing saved. An animated page renders each image at one moment of its motion: the row's stillTime, else the page's own still time, else the last frame; a video renders all of it and takes no stillTime. Needs templates:read and batches:create.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "name": "<name>",
      "rows": "<rows>"
    },
    "name": "create_batch"
  }
}

Input Schema

NameRequiredDescriptionDefault
flowNoInstead of pages: one flow (get_template_inputs flows), a video joining some of its template's pages, that every row renders as, with a video output format. A name fills that layer on every page of the video; `<pageId>@<layer>` one page, `<pageId>#2@<layer>` a page's second visit.
nameYesBatch name shown in Kalpana and used in output filenames, 1 to 200 characters
rowsYes1 to 1,000 rows, each its own modifications and output, rendered on every page named (or as the flow's video)
pagesNoPage ids (get_template_inputs pages, from any templates) every row renders on, in order: one id for one file per row, several for one file per row per page, such as a carousel's slides. A row's plain keys fill every page that has the layer; `<pageId>@<layer>` fills one page.
templatesNoInstead of pages: template ids whose every page each row renders on, in page order

Output Schema

NameRequiredDescriptionDefault
idYesbatchId for run_batch and the other batch tools
statusYesdraft until run_batch
jobCountYesJobs created: one per row per page
rowCountYesRows given
creditCostYesActual credit cost to run every job in this batch.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed22 schema fields changed
    • removedInput schema / properties / columns
      Removed value: -{
      -  "description": "For array rows: the layer key of each cell, in order, like a spreadsheet header",
      -  "items": {
      -    "minLength": 1,
      -    "type": "string"
      -  },
      -  "maxItems": 100,
      -  "minItems": 1,
      -  "type": "array"
      -}
    • removedInput schema / properties / defaults
      Removed value: -{
      -  "additionalProperties": {
      -    "anyOf": [
      -      {
      -        "description": "A text layer's text, with <s1>...</s1> tags for runs when it has several styles; or an image layer's asset id or file name",
      -        "type": "string"
      -      },
      -      {
      -        "additionalProperties": {},
      -        "description": "A text layer's text and visibility",
      -        "properties": {
      -          "text": {
      -            "description": "The layer's new text, tagged like a string value",
      -            "type": "string"
      -          },
      -          "visible": {
      -            "description": "false hides the layer; layout closes the gap",
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      {
      -        "additionalProperties": {},
      -        "description": "An image layer's image and framing",
      -        "properties": {
      -          "asset": {
      -            "description": "An asset id (search_assets, upload_images), the image's file name, or a designer image key. Omit to keep the template's image and only re-frame it.",
      -            "type": "string"
      -          },
      -          "fit": {
      -            "description": "cover fills the slot and crops (default), contain shows the whole image, stretch distorts to the slot. The designer's names work too: fill is cover, fit is contain",
      -            "enum": [
      -              "cover",
      -              "contain",
      -              "stretch",
      -              "fill",
      -              "fit"
      -            ],
      -            "type": "string"
      -          },
      -          "panX": {
      -            "description": "Moves the image by this fraction of the slot width; positive = right",
      -            "maximum": 1,
      -            "minimum": -1,
      -            "type": "number"
      -          },
      -          "panY": {
      -            "description": "Moves the image by this fraction of the slot height; positive = down",
      -            "maximum": 1,
      -            "minimum": -1,
      -            "type": "number"
      -          },
      -          "visible": {
      -            "description": "false hides the layer",
      -            "type": "boolean"
      -          },
      -          "zoom": {
      -            "description": "Zoom about the slot centre; 1 = none",
      -            "maximum": 4,
      -            "minimum": 0.2,
      -            "type": "number"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    ]
      -  },
      -  "description": "Values every row gets unless it gives its own, such as a logo or call to action shared by all rows",
      -  "propertyNames": {
      -    "type": "string"
      -  },
      -  "type": "object"
      -}
    • addedInput schema / properties / flow
      Added value: +{
      +  "description": "Instead of pages: one flow (get_template_inputs flows), a video joining some of its template's pages, that every row renders as, with a video output format. A name fills that layer on every page of the video; `<pageId>@<layer>` one page, `<pageId>#2@<layer>` a page's second visit.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • removedInput schema / properties / flowIds
      Removed value: -{
      -  "description": "Instead of pageIds: this template's flows (get_template_inputs flows), each a video joining some of its pages, that every row renders as, one video per row per flow, with a video outputFormat. A name fills every layer with it across a video's pages.",
      -  "items": {
      -    "format": "uuid",
      -    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
      -    "type": "string"
      -  },
      -  "maxItems": 20,
      -  "minItems": 1,
      -  "type": "array"
      -}
    • removedInput schema / properties / outputFormat
      Removed value: -{
      -  "default": "png",
      -  "description": "Output format. png, jpeg and webp render one image per row and pdf one vector page; mp4 and gif render each row's whole motion as a video, and webm (VP9) and mov (ProRes 4444) as a transparent video for overlaying on other footage. Video needs an animated template (get_template_inputs isAnimated) and costs more credits per row",
      -  "enum": [
      -    "png",
      -    "jpeg",
      -    "webp",
      -    "pdf",
      -    "mp4",
      -    "gif",
      -    "webm",
      -    "mov"
      -  ],
      -  "type": "string"
      -}
    • removedInput schema / properties / pageIds
      Removed value: -{
      -  "description": "This template's pages (get_template_inputs pages) every row renders on, in order: one id for one file per row, several for one file per row per page, such as a carousel's slides. The first page when omitted. A row may carry keys of any of these pages; each page takes the keys it has.",
      -  "items": {
      -    "format": "uuid",
      -    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
      -    "type": "string"
      -  },
      -  "maxItems": 20,
      -  "minItems": 1,
      -  "type": "array"
      -}
    • addedInput schema / properties / pages
      Added value: +{
      +  "description": "Page ids (get_template_inputs pages, from any templates) every row renders on, in order: one id for one file per row, several for one file per row per page, such as a carousel's slides. A row's plain keys fill every page that has the layer; `<pageId>@<layer>` fills one page.",
      +  "items": {
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "maxItems": 20,
      +  "minItems": 1,
      +  "type": "array"
      +}
    • changedInput schema / properties / rows / description
      Previous value: -"1 to 500 rows. Each keys a layer by its name (case aside) or id, the key get_template_inputs gives, to a plain value: text as a string, an image as an asset id or file name, or { asset, fit, zoom, panX, panY } and { text, visible } when framing or visibility changes. rowExample in get_template_inputs is a ready row. With columns, a row is instead an array of cells in column order, which keeps large batches small. null leaves a layer at the template's own value. Layers left out keep the template's value, or the one in defaults."New value: +"1 to 1,000 rows, each its own modifications and output, rendered on every page named (or as the flow's video)"
    • addedInput schema / properties / rows / items / additionalProperties
      Added value: +false
    • removedInput schema / properties / rows / items / anyOf
      Removed value: -[
      -  {
      -    "additionalProperties": {
      -      "anyOf": [
      -        {
      -          "anyOf": [
      -            {
      -              "description": "A text layer's text, with <s1>...</s1> tags for runs when it has several styles; or an image layer's asset id or file name",
      -              "type": "string"
      -            },
      -            {
      -              "additionalProperties": {},
      -              "description": "A text layer's text and visibility",
      -              "properties": {
      -                "text": {
      -                  "description": "The layer's new text, tagged like a string value",
      -                  "type": "string"
      -                },
      -                "visible": {
      -                  "description": "false hides the layer; layout closes the gap",
      -                  "type": "boolean"
      -                }
      -              },
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": {},
      -              "description": "An image layer's image and framing",
      -              "properties": {
      -                "asset": {
      -                  "description": "An asset id (search_assets, upload_images), the image's file name, or a designer image key. Omit to keep the template's image and only re-frame it.",
      -                  "type": "string"
      -                },
      -                "fit": {
      -                  "description": "cover fills the slot and crops (default), contain shows the whole image, stretch distorts to the slot. The designer's names work too: fill is cover, fit is contain",
      -                  "enum": [
      -                    "cover",
      -                    "contain",
      -                    "stretch",
      -                    "fill",
      -                    "fit"
      -                  ],
      -                  "type": "string"
      -                },
      -                "panX": {
      -                  "description": "Moves the image by this fraction of the slot width; positive = right",
      -                  "maximum": 1,
      -                  "minimum": -1,
      -                  "type": "number"
      -                },
      -                "panY": {
      -                  "description": "Moves the image by this fraction of the slot height; positive = down",
      -                  "maximum": 1,
      -                  "minimum": -1,
      -                  "type": "number"
      -                },
      -                "visible": {
      -                  "description": "false hides the layer",
      -                  "type": "boolean"
      -                },
      -                "zoom": {
      -                  "description": "Zoom about the slot centre; 1 = none",
      -                  "maximum": 4,
      -                  "minimum": 0.2,
      -                  "type": "number"
      -                }
      -              },
      -              "type": "object"
      -            }
      -          ]
      -        },
      -        {
      -          "type": "null"
      -        }
      -      ]
      -    },
      -    "propertyNames": {
      -      "type": "string"
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "items": {
      -      "anyOf": [
      -        {
      -          "anyOf": [
      -            {
      -              "description": "A text layer's text, with <s1>...</s1> tags for runs when it has several styles; or an image layer's asset id or file name",
      -              "type": "string"
      -            },
      -            {
      -              "additionalProperties": {},
      -              "description": "A text layer's text and visibility",
      -              "properties": {
      -                "text": {
      -                  "description": "The layer's new text, tagged like a string value",
      -                  "type": "string"
      -                },
      -                "visible": {
      -                  "description": "false hides the layer; layout closes the gap",
      -                  "type": "boolean"
      -                }
      -              },
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": {},
      -              "description": "An image layer's image and framing",
      -              "properties": {
      -                "asset": {
      -                  "description": "An asset id (search_assets, upload_images), the image's file name, or a designer image key. Omit to keep the template's image and only re-frame it.",
      -                  "type": "string"
      -                },
      -                "fit": {
      -                  "description": "cover fills the slot and crops (default), contain shows the whole image, stretch distorts to the slot. The designer's names work too: fill is cover, fit is contain",
      -                  "enum": [
      -                    "cover",
      -                    "contain",
      -                    "stretch",
      -                    "fill",
      -                    "fit"
      -                  ],
      -                  "type": "string"
      -                },
      -                "panX": {
      -                  "description": "Moves the image by this fraction of the slot width; positive = right",
      -                  "maximum": 1,
      -                  "minimum": -1,
      -                  "type": "number"
      -                },
      -                "panY": {
      -                  "description": "Moves the image by this fraction of the slot height; positive = down",
      -                  "maximum": 1,
      -                  "minimum": -1,
      -                  "type": "number"
      -                },
      -                "visible": {
      -                  "description": "false hides the layer",
      -                  "type": "boolean"
      -                },
      -                "zoom": {
      -                  "description": "Zoom about the slot centre; 1 = none",
      -                  "maximum": 4,
      -                  "minimum": 0.2,
      -                  "type": "number"
      -                }
      -              },
      -              "type": "object"
      -            }
      -          ]
      -        },
      -        {
      -          "type": "null"
      -        }
      -      ]
      -    },
      -    "type": "array"
      -  }
      -]
    • addedInput schema / properties / rows / items / properties
      Added value: +{
      +  "modifications": {
      +    "additionalProperties": {
      +      "anyOf": [
      +        {
      +          "anyOf": [
      +            {
      +              "description": "A text layer's text, with <s1>...</s1> tags for runs when it has several styles; or an image layer's asset id or file name",
      +              "type": "string"
      +            },
      +            {
      +              "additionalProperties": {},
      +              "description": "A text layer's text and visibility",
      +              "properties": {
      +                "text": {
      +                  "description": "The layer's new text, tagged like a string value",
      +                  "type": "string"
      +                },
      +                "visible": {
      +                  "description": "false hides the layer; layout closes the gap",
      +                  "type": "boolean"
      +                }
      +              },
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": {},
      +              "description": "An image layer's image and framing",
      +              "properties": {
      +                "asset": {
      +                  "description": "An asset id (search_assets, upload_images), the image's file name, or a designer image key. Omit to keep the template's image and only re-frame it.",
      +                  "type": "string"
      +                },
      +                "fit": {
      +                  "description": "cover fills the slot and crops (default), contain shows the whole image, stretch distorts to the slot. The designer's names work too: fill is cover, fit is contain",
      +                  "enum": [
      +                    "cover",
      +                    "contain",
      +                    "stretch",
      +                    "fill",
      +                    "fit"
      +                  ],
      +                  "type": "string"
      +                },
      +                "panX": {
      +                  "description": "Moves the image by this fraction of the slot width; positive = right",
      +                  "maximum": 1,
      +                  "minimum": -1,
      +                  "type": "number"
      +                },
      +                "panY": {
      +                  "description": "Moves the image by this fraction of the slot height; positive = down",
      +                  "maximum": 1,
      +                  "minimum": -1,
      +                  "type": "number"
      +                },
      +                "visible": {
      +                  "description": "false hides the layer",
      +                  "type": "boolean"
      +                },
      +                "zoom": {
      +                  "description": "Zoom about the slot centre; 1 = none",
      +                  "maximum": 4,
      +                  "minimum": 0.2,
      +                  "type": "number"
      +                }
      +              },
      +              "type": "object"
      +            }
      +          ]
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "default": {},
      +    "description": "Layer key to value: a layer's name (case aside) or id, the key get_template_inputs gives, to a plain value: text as a string, an image as an asset id or file name, or { asset, fit, zoom, panX, panY } and { text, visible } when framing or visibility changes. rowExample in get_template_inputs is ready to use. null leaves a layer at the page's own value; layers left out keep it too.",
      +    "propertyNames": {
      +      "type": "string"
      +    },
      +    "type": "object"
      +  },
      +  "output": {
      +    "additionalProperties": false,
      +    "description": "What to make; png when omitted",
      +    "properties": {
      +      "fileName": {
      +        "description": "The file's name, without extension",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "format": {
      +        "default": "png",
      +        "description": "png, jpeg and webp render an image and pdf one vector page; mp4 and gif render the whole motion as a video, and webm (VP9) and mov (ProRes 4444) as a transparent video for overlaying on other footage. Video needs an animated template (get_template_inputs isAnimated) and costs more credits",
      +        "enum": [
      +          "png",
      +          "jpeg",
      +          "webp",
      +          "pdf",
      +          "mp4",
      +          "gif",
      +          "webm",
      +          "mov"
      +        ],
      +        "type": "string"
      +      },
      +      "stillTime": {
      +        "description": "Animated pages, images only: the second of the motion the image shows. Omit it to use the page's own still time (get_template_inputs stillTime), else the last frame. If the page has no still time, ask the user, because an outro or a loop can make the last frame a bad image.",
      +        "maximum": 600,
      +        "minimum": 0,
      +        "type": "number"
      +      }
      +    },
      +    "type": "object"
      +  }
      +}
    • addedInput schema / properties / rows / items / type
      Added value: +"object"
    • changedInput schema / properties / rows / maxItems
      Previous value: -500New value: +1000
    • removedInput schema / properties / stillTime
      Removed value: -{
      -  "description": "Animated templates only: the second of the motion that each image shows. Omit it to use the page's own still time (get_template_inputs stillTime), else the last frame. If the page has no still time, ask the user, because an outro or a loop can make the last frame a bad image.",
      -  "maximum": 600,
      -  "minimum": 0,
      -  "type": "number"
      -}
    • removedInput schema / properties / templateId
      Removed value: -{
      -  "description": "The whole template, from search_templates. Not a page or flow id.",
      -  "format": "uuid",
      -  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
      -  "type": "string"
      -}
    • addedInput schema / properties / templates
      Added value: +{
      +  "description": "Instead of pages: template ids whose every page each row renders on, in page order",
      +  "items": {
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "maxItems": 20,
      +  "minItems": 1,
      +  "type": "array"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "templateId",
      -  "name",
      -  "rows"
      -]New value: +[
      +  "name",
      +  "rows"
      +]
    • changedOutput schema / properties / jobCount / description
      Previous value: -"Jobs created: one per row per page or flow"New value: +"Jobs created: one per row per page"
    • addedOutput schema / properties / status
      Added value: +{
      +  "description": "draft until run_batch",
      +  "type": "string"
      +}
    • removedOutput schema / properties / warnings
      Removed value: -{
      -  "description": "Not errors: pass these on to the user, such as a flow longer than a video renders",
      -  "items": {
      -    "type": "string"
      -  },
      -  "type": "array"
      -}
    • removedOutput schema / properties / workspaceId
      Removed value: -{
      -  "type": "string"
      -}
    • changedOutput schema / required
      Previous value: -[
      -  "id",
      -  "workspaceId",
      -  "rowCount",
      -  "creditCost"
      -]New value: +[
      +  "id",
      +  "status",
      +  "rowCount",
      +  "jobCount",
      +  "creditCost"
      +]
  2. Changed1 schema field changed
    • changedOutput schema / properties / jobCount / description
      Previous value: -"Jobs created: one per row per page"New value: +"Jobs created: one per row per page or flow"
  3. Changed6 schema fields changed
    • addedInput schema / additionalProperties
      Added value: +false
    • addedInput schema / properties / flowIds
      Added value: +{
      +  "description": "Instead of pageIds: this template's flows (get_template_inputs flows), each a video joining some of its pages, that every row renders as, one video per row per flow, with a video outputFormat. A name fills every layer with it across a video's pages.",
      +  "items": {
      +    "format": "uuid",
      +    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
      +    "type": "string"
      +  },
      +  "maxItems": 20,
      +  "minItems": 1,
      +  "type": "array"
      +}
    • removedInput schema / properties / pageId
      Removed value: -{
      -  "description": "One page of the template (the designer connection's page_id). A template's pages are separate designs, each with its own inputs; the first page when omitted.",
      -  "format": "uuid",
      -  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
      -  "type": "string"
      -}
    • changedInput schema / properties / pageIds / description
      Previous value: -"Instead of pageId: pages every row renders on, one image per row per page, such as a carousel's slides in order. A row may carry keys of any of these pages; each page takes the keys it has."New value: +"This template's pages (get_template_inputs pages) every row renders on, in order: one id for one file per row, several for one file per row per page, such as a carousel's slides. The first page when omitted. A row may carry keys of any of these pages; each page takes the keys it has."
    • changedInput schema / properties / templateId / description
      Previous value: -"Template ID returned by search_templates"New value: +"The whole template, from search_templates. Not a page or flow id."
    • addedOutput schema / properties / warnings
      Added value: +{
      +  "description": "Not errors: pass these on to the user, such as a flow longer than a video renders",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  4. Changed13 schema fields changed
    • removedInput schema / additionalProperties
      Removed value: -false
    • removedInput schema / properties / defaults / additionalProperties / $ref
      Removed value: -"#/properties/rows/items/anyOf/0/additionalProperties/anyOf/0"
    • addedInput schema / properties / defaults / additionalProperties / anyOf
      Added value: +[
      +  {
      +    "description": "A text layer's text, with <s1>...</s1> tags for runs when it has several styles; or an image layer's asset id or file name",
      +    "type": "string"
      +  },
      +  {
      +    "additionalProperties": {},
      +    "description": "A text layer's text and visibility",
      +    "properties": {
      +      "text": {
      +        "description": "The layer's new text, tagged like a string value",
      +        "type": "string"
      +      },
      +      "visible": {
      +        "description": "false hides the layer; layout closes the gap",
      +        "type": "boolean"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": {},
      +    "description": "An image layer's image and framing",
      +    "properties": {
      +      "asset": {
      +        "description": "An asset id (search_assets, upload_images), the image's file name, or a designer image key. Omit to keep the template's image and only re-frame it.",
      +        "type": "string"
      +      },
      +      "fit": {
      +        "description": "cover fills the slot and crops (default), contain shows the whole image, stretch distorts to the slot. The designer's names work too: fill is cover, fit is contain",
      +        "enum": [
      +          "cover",
      +          "contain",
      +          "stretch",
      +          "fill",
      +          "fit"
      +        ],
      +        "type": "string"
      +      },
      +      "panX": {
      +        "description": "Moves the image by this fraction of the slot width; positive = right",
      +        "maximum": 1,
      +        "minimum": -1,
      +        "type": "number"
      +      },
      +      "panY": {
      +        "description": "Moves the image by this fraction of the slot height; positive = down",
      +        "maximum": 1,
      +        "minimum": -1,
      +        "type": "number"
      +      },
      +      "visible": {
      +        "description": "false hides the layer",
      +        "type": "boolean"
      +      },
      +      "zoom": {
      +        "description": "Zoom about the slot centre; 1 = none",
      +        "maximum": 4,
      +        "minimum": 0.2,
      +        "type": "number"
      +      }
      +    },
      +    "type": "object"
      +  }
      +]
    • addedInput schema / properties / defaults / propertyNames
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / pageId / pattern
      Added value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
    • addedInput schema / properties / pageIds
      Added value: +{
      +  "description": "Instead of pageId: pages every row renders on, one image per row per page, such as a carousel's slides in order. A row may carry keys of any of these pages; each page takes the keys it has.",
      +  "items": {
      +    "format": "uuid",
      +    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
      +    "type": "string"
      +  },
      +  "maxItems": 20,
      +  "minItems": 1,
      +  "type": "array"
      +}
    • changedInput schema / properties / rows / items / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": {
      -      "anyOf": [
      -        {
      -          "anyOf": [
      -            {
      -              "description": "A text layer's text, with <s1>...</s1> tags for runs when it has several styles; or an image layer's asset id or file name",
      -              "type": "string"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "description": "A text layer's text and visibility",
      -              "properties": {
      -                "text": {
      -                  "description": "The layer's new text, tagged like a string value",
      -                  "type": "string"
      -                },
      -                "visible": {
      -                  "description": "false hides the layer; layout closes the gap",
      -                  "type": "boolean"
      -                }
      -              },
      -              "type": "object"
      -            },
      -            {
      -              "additionalProperties": true,
      -              "description": "An image layer's image and framing",
      -              "properties": {
      -                "asset": {
      -                  "description": "An asset id (search_assets, upload_images), the image's file name, or a designer image key. Omit to keep the template's image and only re-frame it.",
      -                  "type": "string"
      -                },
      -                "fit": {
      -                  "description": "cover fills the slot and crops (default), contain shows the whole image, stretch distorts to the slot. The designer's names work too: fill is cover, fit is contain",
      -                  "enum": [
      -                    "cover",
      -                    "contain",
      -                    "stretch",
      -                    "fill",
      -                    "fit"
      -                  ],
      -                  "type": "string"
      -                },
      -                "panX": {
      -                  "description": "Moves the image by this fraction of the slot width; positive = right",
      -                  "maximum": 1,
      -                  "minimum": -1,
      -                  "type": "number"
      -                },
      -                "panY": {
      -                  "description": "Moves the image by this fraction of the slot height; positive = down",
      -                  "maximum": 1,
      -                  "minimum": -1,
      -                  "type": "number"
      -                },
      -                "visible": {
      -                  "description": "false hides the layer",
      -                  "type": "boolean"
      -                },
      -                "zoom": {
      -                  "description": "Zoom about the slot centre; 1 = none",
      -                  "maximum": 4,
      -                  "minimum": 0.2,
      -                  "type": "number"
      -                }
      -              },
      -              "type": "object"
      -            }
      -          ]
      -        },
      -        {
      -          "type": "null"
      -        }
      -      ]
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "items": {
      -      "anyOf": [
      -        {
      -          "$ref": "#/properties/rows/items/anyOf/0/additionalProperties/anyOf/0"
      -        },
      -        {
      -          "type": "null"
      -        }
      -      ]
      -    },
      -    "type": "array"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": {
      +      "anyOf": [
      +        {
      +          "anyOf": [
      +            {
      +              "description": "A text layer's text, with <s1>...</s1> tags for runs when it has several styles; or an image layer's asset id or file name",
      +              "type": "string"
      +            },
      +            {
      +              "additionalProperties": {},
      +              "description": "A text layer's text and visibility",
      +              "properties": {
      +                "text": {
      +                  "description": "The layer's new text, tagged like a string value",
      +                  "type": "string"
      +                },
      +                "visible": {
      +                  "description": "false hides the layer; layout closes the gap",
      +                  "type": "boolean"
      +                }
      +              },
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": {},
      +              "description": "An image layer's image and framing",
      +              "properties": {
      +                "asset": {
      +                  "description": "An asset id (search_assets, upload_images), the image's file name, or a designer image key. Omit to keep the template's image and only re-frame it.",
      +                  "type": "string"
      +                },
      +                "fit": {
      +                  "description": "cover fills the slot and crops (default), contain shows the whole image, stretch distorts to the slot. The designer's names work too: fill is cover, fit is contain",
      +                  "enum": [
      +                    "cover",
      +                    "contain",
      +                    "stretch",
      +                    "fill",
      +                    "fit"
      +                  ],
      +                  "type": "string"
      +                },
      +                "panX": {
      +                  "description": "Moves the image by this fraction of the slot width; positive = right",
      +                  "maximum": 1,
      +                  "minimum": -1,
      +                  "type": "number"
      +                },
      +                "panY": {
      +                  "description": "Moves the image by this fraction of the slot height; positive = down",
      +                  "maximum": 1,
      +                  "minimum": -1,
      +                  "type": "number"
      +                },
      +                "visible": {
      +                  "description": "false hides the layer",
      +                  "type": "boolean"
      +                },
      +                "zoom": {
      +                  "description": "Zoom about the slot centre; 1 = none",
      +                  "maximum": 4,
      +                  "minimum": 0.2,
      +                  "type": "number"
      +                }
      +              },
      +              "type": "object"
      +            }
      +          ]
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "propertyNames": {
      +      "type": "string"
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "items": {
      +      "anyOf": [
      +        {
      +          "anyOf": [
      +            {
      +              "description": "A text layer's text, with <s1>...</s1> tags for runs when it has several styles; or an image layer's asset id or file name",
      +              "type": "string"
      +            },
      +            {
      +              "additionalProperties": {},
      +              "description": "A text layer's text and visibility",
      +              "properties": {
      +                "text": {
      +                  "description": "The layer's new text, tagged like a string value",
      +                  "type": "string"
      +                },
      +                "visible": {
      +                  "description": "false hides the layer; layout closes the gap",
      +                  "type": "boolean"
      +                }
      +              },
      +              "type": "object"
      +            },
      +            {
      +              "additionalProperties": {},
      +              "description": "An image layer's image and framing",
      +              "properties": {
      +                "asset": {
      +                  "description": "An asset id (search_assets, upload_images), the image's file name, or a designer image key. Omit to keep the template's image and only re-frame it.",
      +                  "type": "string"
      +                },
      +                "fit": {
      +                  "description": "cover fills the slot and crops (default), contain shows the whole image, stretch distorts to the slot. The designer's names work too: fill is cover, fit is contain",
      +                  "enum": [
      +                    "cover",
      +                    "contain",
      +                    "stretch",
      +                    "fill",
      +                    "fit"
      +                  ],
      +                  "type": "string"
      +                },
      +                "panX": {
      +                  "description": "Moves the image by this fraction of the slot width; positive = right",
      +                  "maximum": 1,
      +                  "minimum": -1,
      +                  "type": "number"
      +                },
      +                "panY": {
      +                  "description": "Moves the image by this fraction of the slot height; positive = down",
      +                  "maximum": 1,
      +                  "minimum": -1,
      +                  "type": "number"
      +                },
      +                "visible": {
      +                  "description": "false hides the layer",
      +                  "type": "boolean"
      +                },
      +                "zoom": {
      +                  "description": "Zoom about the slot centre; 1 = none",
      +                  "maximum": 4,
      +                  "minimum": 0.2,
      +                  "type": "number"
      +                }
      +              },
      +              "type": "object"
      +            }
      +          ]
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "type": "array"
      +  }
      +]
    • addedInput schema / properties / templateId / pattern
      Added value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
    • addedOutput schema / properties / creditCost / maximum
      Added value: +9007199254740991
    • addedOutput schema / properties / id / pattern
      Added value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"
    • addedOutput schema / properties / jobCount
      Added value: +{
      +  "description": "Jobs created: one per row per page",
      +  "exclusiveMinimum": 0,
      +  "maximum": 9007199254740991,
      +  "type": "integer"
      +}
    • changedOutput schema / properties / rowCount / description
      Previous value: -"Jobs created, one per row"New value: +"Rows given"
    • addedOutput schema / properties / rowCount / maximum
      Added value: +9007199254740991
  5. First observed

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Substantially beyond the annotations: no credits are spent or rendering done until run_batch, creditCost is the exact future spend, each call creates a separate batch so repeats duplicate, and one invalid row rejects the entire request with nothing saved (worth noting given destructiveHint=false). It also states required scopes templates:read and batches:create. Minor gap: it doesn't say what the response contains apart from creditCost, though the output schema likely covers that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The most important facts are front-loaded: what it creates, that nothing renders or costs credits, then the duplication caveat and the alternative tools. Dense but earned; the stillTime paragraph slightly repeats the row schema's own wording and could be trimmed for a tighter read.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter creation tool with nested rows, an output schema already present, and full annotations, the description covers the remaining burden: atomicity, cost semantics, non-idempotency, auth scopes, and the stillTime behavior for animated pages. An agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description earns more by framing the three-way choice between pages, templates and flow in prose and by spelling out the stillTime fallback chain (row stillTime, then page still time, then last frame). It still largely restates schema content, but the prose tie-breaks the mutually exclusive alternatives that the schema only implies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb and resource (saves a new draft batch) plus the exact fan-out rule: one pending job per row per page, or one video per row for a flow. It clearly separates draft creation from rendering, and names run_batch, update_batch and validate_batch so the agent can place it among siblings without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states when to use this (build a draft that costs nothing yet) versus run_batch (spends credits and renders) and update_batch (modify an existing batch). It also warns that repeating the call duplicates the batch rather than updating it, which is exactly the misuse an agent would otherwise commit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources