Navigation

MCP

MCP tools

Read templates and generate images and PDFs from an MCP client.

The Bannerify MCP server exposes six tools. The assistant picks them automatically from your request, so you rarely call them by name.

Every tool works only on the workspace that approved the connection.

Tools

Tool What it does Arguments
list_templates Lists the templates in the workspace, with the layers you can override includeLayers (boolean, optional)
get_template Reads one template and its layers templateId (string)
get_project Reads the linked project, its plan, and its creation date none
create_image Renders a template and returns the image templateId (string), modifications (object, optional), format (png, jpeg, webp)
create_pdf Renders a template as a PDF and returns a download link templateId (string), modifications (object, optional)
create_image_from_shapes Composes an image from shapes, with no template shapes (array), canvas (object, optional), format (png, jpeg, webp)

A template id looks like tpl_xxxxx.

Find a template

Ask for the templates and their layers:

List my Bannerify templates, with the layers of each one.

The answer names every template and, for each layer, the name to use in modifications, for example:

[
  {
    "id": "tpl_lifecycle",
    "name": "Lifecycle email",
    "layers": [
      { "name": "headline", "type": "text", "suggestInput": "text" },
      { "name": "photo", "type": "image", "suggestInput": "src" },
      { "name": "qr", "type": "qrcode", "suggestInput": null }
    ]
  }
]

Layer names come from the template editor, so keep them descriptive: headline, price, qr, photo.

Pass layer values

modifications is an object keyed by layer name. A string sets the text of a layer. An object sets that layer’s own fields.

Layer type Example value
Text { "headline": "Summer sale" }
Image { "photo": { "src": "https://example.com/photo.png" } }
QR code { "qr": { "qrcode": "https://example.com/restart" } }
Table { "table": { "rows": [["Plan", "Price"], ["Pro", "$29"]] } }
Any layer { "tag": { "visible": false } }

A full example for create_image:

{
  "templateId": "tpl_lifecycle",
  "format": "png",
  "modifications": {
    "headline": "Welcome back, An",
    "price": "$29",
    "photo": { "src": "https://example.com/hero.png" },
    "qr": { "qrcode": "https://example.com/restart" }
  }
}

Layers you leave out keep the values from the template.

Read the result

create_image returns the image itself, so the assistant can show it or save it to a file. create_pdf stores the file and returns a link:

Generated a PDF from template tpl_lifecycle. Download: https://images.bannerify.co/files/mcp/9f1c....pdf

The link points to the Bannerify CDN and stays available like any other stored asset.

Compose an image without a template

Use create_image_from_shapes when no template fits. Give the tool a canvas and a list of shapes. It draws the shapes in order and returns the image, so the assistant can design a one-off banner, label, or invoice.

Every shape has type, x, y, width, and height, in pixels from the top left of the canvas. The first shape is at the back and the last is on top.

Type Required Optional
text text fontSize (24), align (left, center, right), lineClamp, color, fontFamily, fontWeight
frame — backgroundColor, borderColor, borderWidth, borderRadius
image src objectFit (cover), borderRadius
qrcode qrcode backgroundColor
barcode barcode —
icon icon color
star — star (1 to 5), color
table columns, rows footer, variant, stripe, compact, align, fontFamily

A few rules:

  • icon takes an Iconoir name, for example check-circle or arrow-right.
  • src and canvas.backgroundImage take an HTTPS URL or a data URL. canvas.backgroundImage also takes a CSS gradient, for example linear-gradient(to right, #4f46e5, #9333ea).
  • style takes CSS property names for the rest: padding, boxShadow, borderStyle, lineHeight, and similar. Set the size with width and height, not with style.
  • Table columns are the headers and rows hold one value per column in the same order.
  • Limits: 1 to 100 shapes, 16 to 4096 pixels on each side of the canvas, 4000 characters of text, 200 table rows, 12 table columns.

The canvas is white unless canvas.background is set. canvas.backgroundImage wins over canvas.background.

A full example: an invoice.

{
  "canvas": { "width": 800, "height": 560, "background": "#f8fafc" },
  "shapes": [
    { "type": "frame", "x": 0, "y": 0, "width": 800, "height": 120, "backgroundColor": "#0f172a" },
    { "type": "text", "x": 48, "y": 44, "width": 400, "height": 40, "text": "INVOICE", "fontSize": 30, "color": "#ffffff" },
    { "type": "text", "x": 500, "y": 52, "width": 252, "height": 24, "text": "INV-1042", "fontSize": 18, "align": "right", "color": "#94a3b8" },
    {
      "type": "table",
      "x": 48,
      "y": 176,
      "width": 704,
      "height": 180,
      "columns": ["Item", "Qty", "Total"],
      "rows": [["Logo pack", 1, "$29.00"], ["Banner credits", 500, "$19.00"]],
      "footer": ["", "Due", "$48.00"],
      "variant": "striped",
      "compact": true
    },
    { "type": "text", "x": 48, "y": 392, "width": 300, "height": 28, "text": "Thank you for your business.", "fontSize": 16, "color": "#475569" },
    { "type": "qrcode", "x": 632, "y": 384, "width": 120, "height": 120, "qrcode": "https://bannerify.co/invoices/1042" }
  ]
}

A generation from shapes counts against the same monthly and daily quota as a generation from a template. See Quota and limits.

Handle errors

A failed tool call returns a message with the error code, using the same codes as the REST API:

Code Meaning What to do
NOT_FOUND The template does not exist in this workspace Run list_templates and use a returned id
UNAUTHORIZED The connection is no longer valid Remove the server from your MCP client and add it again
USAGE_EXCEEDED The workspace reached its monthly or daily generation limit Wait for the next period, or check Quota and limits
TOO_MANY_REQUESTS Too many requests arrived in a short time Retry after a short wait
BAD_REQUEST A layer value does not match its layer, or a shape spec is not valid Check the layer with get_template, or the shape fields above
FETCH_IMAGE_ERROR A remote image could not be downloaded Use a public URL that returns an image

See Errors for the full list.

Learn more