Skip to main content
Glama

Resize an image or a video

resize_creative

Resize an image or a video for a platform, an aspect ratio or, for an image, an exact pixel size the Rawa way, not by a crop, a stretch or a letterbox of your own. An image is re-framed generatively: the scene extends into the new shape and the subject, the text and the brand stay intact, delivered at exactly its pixels. A plain clip (an upload, a generated clip or an edit) is cut to each shape, its footage cropped shot by shot on what matters in each; a portrait clip going to a landscape shape has its footage extended by AI into the new width instead, at the same price. A Motion ad is re-laid out on each shape by Rawa's designer, keeping its layers and animation, and takes only 1:1, 4:5, 9:16 or 16:9. Use this whenever the user wants an image or a video resized, adapted or fitted to Snapchat, Google Ads, Stories, a feed, a banner, any ratio or any size; do not resize the pixels yourself. Name platforms, shapes, sizes or a mix; every canvas comes back as its own finished creative in the brand's library, and a shape the video already has is skipped. For an image, a placement makes each canvas that platform takes at its exact size (snapchat_ad is 1080x1920); an aspect ratio makes that shape at 2048 px on the long edge; a size makes exactly those pixels. Canvases are merged only when their pixels are the same, so naming 9:16 and snapchat_ad makes two canvases, 1152x2048 and 1080x1920: when the user names a platform, pass the placement alone. A video takes shapes and placements, not sizes or a format. The source is a creative of the brand (creativeId) or an image on the web (imageUrl: a direct, public URL to a JPEG, PNG or WebP file). An image the user pasted or attached in the chat has no such URL and you cannot read it yourself: call request_image_upload right away (do not ask them to re-attach it), and once the image has landed use its creativeId here. An image you hold as a file on your own filesystem (a coding agent in a project) goes through upload_image_file instead. A linked image is added to the brand's library first and its creativeId is returned as sourceCreativeId; an image the library already holds is not added again, and sourceCreativeId is that creative, with alreadyInLibrary: true. Reuse sourceCreativeId for any further work on the same image instead of passing imageUrl again. A video is resized only from the library, by its creativeId. Cost: An image costs 30 credits per canvas up to 4.2 MP (every placement canvas, and every aspect ratio at its default size), 50 credits per canvas above that. A clip costs per shape by its length: 564 credits for 6 s, 1410 credits for 15 s, 2820 credits for 30 s, less below 1080p. A Motion ad costs a Motion redo per shape, 40 credits a second: 240 at 6 s, 600 at 15 s, 1200 at 30 s. At most 6 canvases per call; the dry run quotes the exact price. Call with dryRun: true first and tell the user the cost. Once they agree, pass the quoted credits as expectedCredits; a call that would cost a different amount is refused. Give each new generation a new requestId, and repeat it unchanged only on a retry: a retry within 2 minutes returns the first result and is not charged again. Without a requestId, the same arguments within 2 minutes count as a retry. Needs generation allowed over MCP (see get_workspace); a dry run still quotes when it is not, and says why the call would be refused in wouldRefuse. Returns a jobId (for a Motion ad, jobs: one jobId per shape), creditsCharged and creditsRemaining; ready in 1 to 5 minutes, a clip longer. If a job panel shows, it tracks the work: do not poll, end your turn with one line saying it is under way, and later use show_creatives with the creativeIds you are told. Otherwise call wait_for_jobs with the jobIds until allFinal is true.

Input Schema

NameRequiredDescriptionDefault
sizesNoExact pixel sizes to deliver, when the user names pixels (1080x1920). Each side 100 to 3840 px, at most 3:1 and 8.3 MP.
dryRunNotrue: return the exact cost (credits, breakdown, balanceAfter) without charging or starting anything, and wouldRefuse when the organization's spending controls would refuse the real call.
formatNoThe file type of every canvas: png (the default) or jpeg, a much smaller file with no transparency. Use jpeg when the user asks for it or the platform caps the file size.
brandIdNoA brand id from get_workspace or list_brands, or the brand's name. Omit it when the organization has a single brand.
imageUrlNoA direct, publicly reachable https URL of the image to work on, when it is not in the library yet.
requestIdNoYour own unique id for this request. Use a new one for every new request, even with the same arguments. Repeat it unchanged only to retry this exact call within 2 minutes; the retry returns the first result.
creativeIdNoA creative id from list_creatives, search_library, get_job or get_upload.
placementsNoPlatforms to produce every canvas of, each at its exact size; "Google Ads" is google_display, "Snapchat" is snapchat_ad (or snapchat for a Story). instagram_feed: Instagram / Facebook feed at 1080x1080, 1080x1350; instagram_story: Instagram / Facebook Stories at 1080x1920; instagram_story_ad: Instagram / Facebook Stories ad at 1080x1920; instagram_reels: Instagram Reels at 1080x1920; instagram_reels_ad: Instagram Reels ad at 1080x1920; tiktok_organic: TikTok (organic) at 1080x1920; tiktok_ad: TikTok in-feed ad at 1080x1920; snapchat: Snapchat Story at 1080x1920; snapchat_ad: Snapchat Snap Ad at 1080x1920; linkedin_feed: LinkedIn feed / sponsored (static) at 1200x1200, 1200x1500, 1200x628; linkedin_video: LinkedIn feed (video) at 1080x1920; linkedin_video_ad: LinkedIn sponsored (video) at 1080x1920; google_display: Google Display (responsive) at 1200x1200, 1200x628; youtube_instream: YouTube in-stream at 1920x1080; youtube_shorts: YouTube Shorts at 1080x1920; youtube_shorts_ad: YouTube Shorts ad at 1080x1920.
aspectRatiosNoShapes to produce at 2048 px on the long edge, by name or ratio ("9:16"). Only when the user names a shape and no platform or size.
expectedCreditsNoThe credits the dryRun quoted and the user agreed to. The call is refused if it would cost a different amount.

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedOutput schema / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "balanceAfter": {
      -        "type": "number"
      -      },
      -      "breakdown": {
      -        "type": "string"
      -      },
      -      "credits": {
      -        "type": "number"
      -      },
      -      "deduplicated": {
      -        "const": true,
      -        "description": "The same call was made in the last 2 minutes: this is its result, not charged again.",
      -        "type": "boolean"
      -      },
      -      "dryRun": {
      -        "const": true,
      -        "type": "boolean"
      -      },
      -      "wouldRefuse": {
      -        "description": "Set when the organization's MCP spending controls would refuse the real call: the refusal it would get.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "dryRun",
      -      "credits",
      -      "breakdown",
      -      "balanceAfter"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "alreadyInLibrary": {
      -        "const": true,
      -        "description": "The brand's library already held this image, so no new creative was added: the id names that one.",
      -        "type": "boolean"
      -      },
      -      "creditsCharged": {
      -        "type": "number"
      -      },
      -      "creditsRemaining": {
      -        "type": "number"
      -      },
      -      "deduplicated": {
      -        "const": true,
      -        "description": "The same call was made in the last 2 minutes: this is its result, not charged again.",
      -        "type": "boolean"
      -      },
      -      "jobId": {
      -        "type": "string"
      -      },
      -      "sourceCreativeId": {
      -        "type": "string"
      -      },
      -      "targets": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "watchToken": {
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "jobId",
      -      "watchToken",
      -      "creditsCharged",
      -      "creditsRemaining",
      -      "sourceCreativeId",
      -      "targets"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "balanceAfter": {
      +        "type": "number"
      +      },
      +      "breakdown": {
      +        "type": "string"
      +      },
      +      "credits": {
      +        "type": "number"
      +      },
      +      "deduplicated": {
      +        "const": true,
      +        "description": "The same call was made in the last 2 minutes: this is its result, not charged again.",
      +        "type": "boolean"
      +      },
      +      "dryRun": {
      +        "const": true,
      +        "type": "boolean"
      +      },
      +      "wouldRefuse": {
      +        "description": "Set when the organization's MCP spending controls would refuse the real call: the refusal it would get.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "dryRun",
      +      "credits",
      +      "breakdown",
      +      "balanceAfter"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "alreadyInLibrary": {
      +        "const": true,
      +        "description": "The brand's library already held this image, so no new creative was added: the id names that one.",
      +        "type": "boolean"
      +      },
      +      "creditsCharged": {
      +        "type": "number"
      +      },
      +      "creditsRemaining": {
      +        "type": "number"
      +      },
      +      "deduplicated": {
      +        "const": true,
      +        "description": "The same call was made in the last 2 minutes: this is its result, not charged again.",
      +        "type": "boolean"
      +      },
      +      "jobId": {
      +        "type": "string"
      +      },
      +      "sourceCreativeId": {
      +        "type": "string"
      +      },
      +      "targets": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "watchToken": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "jobId",
      +      "watchToken",
      +      "creditsCharged",
      +      "creditsRemaining",
      +      "sourceCreativeId",
      +      "targets"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "description": "A Motion ad: one job per shape.",
      +    "properties": {
      +      "creditsCharged": {
      +        "type": "number"
      +      },
      +      "creditsRemaining": {
      +        "type": "number"
      +      },
      +      "deduplicated": {
      +        "const": true,
      +        "description": "The same call was made in the last 2 minutes: this is its result, not charged again.",
      +        "type": "boolean"
      +      },
      +      "jobs": {
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "jobId": {
      +              "type": "string"
      +            },
      +            "target": {
      +              "description": "The shape this job re-lays the Motion ad out on.",
      +              "type": "string"
      +            },
      +            "watchToken": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "jobId",
      +            "target",
      +            "watchToken"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "sourceCreativeId": {
      +        "type": "string"
      +      },
      +      "targets": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "jobs",
      +      "sourceCreativeId",
      +      "targets",
      +      "creditsCharged",
      +      "creditsRemaining"
      +    ],
      +    "type": "object"
      +  }
      +]
  2. Changed6 schema fields changed
    • changedInput schema / properties / aspectRatios / description
      Previous value: -"Shapes to produce outright, by name or ratio (\"9:16\")."New value: +"Shapes to produce at 2048 px on the long edge, by name or ratio (\"9:16\"). Only when the user names a shape and no platform or size."
    • changedInput schema / properties / brandId / description
      Previous value: -"A brand id from get_workspace or list_brands. Omit it when the organization has a single brand."New value: +"A brand id from get_workspace or list_brands, or the brand's name. Omit it when the organization has a single brand."
    • addedInput schema / properties / format
      Added value: +{
      +  "description": "The file type of every canvas: png (the default) or jpeg, a much smaller file with no transparency. Use jpeg when the user asks for it or the platform caps the file size.",
      +  "enum": [
      +    "png",
      +    "jpeg"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / placements / description
      Previous value: -"Platforms to produce every shape for; \"Google Ads\" is google_display, \"Snapchat\" is snapchat_ad (or snapchat for a Story). instagram_feed: Instagram / Facebook feed (1:1 or 4:5); instagram_story: Instagram / Facebook Stories (9:16); instagram_story_ad: Instagram / Facebook Stories ad (9:16); instagram_reels: Instagram Reels (9:16); instagram_reels_ad: Instagram Reels ad (9:16); tiktok_organic: TikTok (organic) (9:16); tiktok_ad: TikTok in-feed ad (9:16); snapchat: Snapchat Story (9:16); snapchat_ad: Snapchat Snap Ad (9:16); linkedin_feed: LinkedIn feed / sponsored (static) (1:1, 4:5 or 1.91:1); linkedin_video: LinkedIn feed (video) (9:16); linkedin_video_ad: LinkedIn sponsored (video) (9:16); google_display: Google Display (responsive) (1:1 or 1.91:1); youtube_instream: YouTube in-stream (16:9); youtube_shorts: YouTube Shorts (9:16); youtube_shorts_ad: YouTube Shorts ad (9:16)."New value: +"Platforms to produce every canvas of, each at its exact size; \"Google Ads\" is google_display, \"Snapchat\" is snapchat_ad (or snapchat for a Story). instagram_feed: Instagram / Facebook feed at 1080x1080, 1080x1350; instagram_story: Instagram / Facebook Stories at 1080x1920; instagram_story_ad: Instagram / Facebook Stories ad at 1080x1920; instagram_reels: Instagram Reels at 1080x1920; instagram_reels_ad: Instagram Reels ad at 1080x1920; tiktok_organic: TikTok (organic) at 1080x1920; tiktok_ad: TikTok in-feed ad at 1080x1920; snapchat: Snapchat Story at 1080x1920; snapchat_ad: Snapchat Snap Ad at 1080x1920; linkedin_feed: LinkedIn feed / sponsored (static) at 1200x1200, 1200x1500, 1200x628; linkedin_video: LinkedIn feed (video) at 1080x1920; linkedin_video_ad: LinkedIn sponsored (video) at 1080x1920; google_display: Google Display (responsive) at 1200x1200, 1200x628; youtube_instream: YouTube in-stream at 1920x1080; youtube_shorts: YouTube Shorts at 1080x1920; youtube_shorts_ad: YouTube Shorts ad at 1080x1920."
    • addedInput schema / properties / sizes
      Added value: +{
      +  "description": "Exact pixel sizes to deliver, when the user names pixels (1080x1920). Each side 100 to 3840 px, at most 3:1 and 8.3 MP.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "height": {
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "width": {
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "width",
      +      "height"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • changedOutput schema / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "balanceAfter": {
      -        "type": "number"
      -      },
      -      "breakdown": {
      -        "type": "string"
      -      },
      -      "credits": {
      -        "type": "number"
      -      },
      -      "deduplicated": {
      -        "const": true,
      -        "description": "The same call was made in the last 2 minutes: this is its result, not charged again.",
      -        "type": "boolean"
      -      },
      -      "dryRun": {
      -        "const": true,
      -        "type": "boolean"
      -      },
      -      "wouldRefuse": {
      -        "description": "Set when the organization's MCP spending controls would refuse the real call: the refusal it would get.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "dryRun",
      -      "credits",
      -      "breakdown",
      -      "balanceAfter"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "creditsCharged": {
      -        "type": "number"
      -      },
      -      "creditsRemaining": {
      -        "type": "number"
      -      },
      -      "deduplicated": {
      -        "const": true,
      -        "description": "The same call was made in the last 2 minutes: this is its result, not charged again.",
      -        "type": "boolean"
      -      },
      -      "jobId": {
      -        "type": "string"
      -      },
      -      "sourceCreativeId": {
      -        "type": "string"
      -      },
      -      "targets": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "watchToken": {
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "jobId",
      -      "watchToken",
      -      "creditsCharged",
      -      "creditsRemaining",
      -      "sourceCreativeId",
      -      "targets"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "balanceAfter": {
      +        "type": "number"
      +      },
      +      "breakdown": {
      +        "type": "string"
      +      },
      +      "credits": {
      +        "type": "number"
      +      },
      +      "deduplicated": {
      +        "const": true,
      +        "description": "The same call was made in the last 2 minutes: this is its result, not charged again.",
      +        "type": "boolean"
      +      },
      +      "dryRun": {
      +        "const": true,
      +        "type": "boolean"
      +      },
      +      "wouldRefuse": {
      +        "description": "Set when the organization's MCP spending controls would refuse the real call: the refusal it would get.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "dryRun",
      +      "credits",
      +      "breakdown",
      +      "balanceAfter"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "alreadyInLibrary": {
      +        "const": true,
      +        "description": "The brand's library already held this image, so no new creative was added: the id names that one.",
      +        "type": "boolean"
      +      },
      +      "creditsCharged": {
      +        "type": "number"
      +      },
      +      "creditsRemaining": {
      +        "type": "number"
      +      },
      +      "deduplicated": {
      +        "const": true,
      +        "description": "The same call was made in the last 2 minutes: this is its result, not charged again.",
      +        "type": "boolean"
      +      },
      +      "jobId": {
      +        "type": "string"
      +      },
      +      "sourceCreativeId": {
      +        "type": "string"
      +      },
      +      "targets": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "watchToken": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "jobId",
      +      "watchToken",
      +      "creditsCharged",
      +      "creditsRemaining",
      +      "sourceCreativeId",
      +      "targets"
      +    ],
      +    "type": "object"
      +  }
      +]
  3. First observed

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare the safety profile, and the description adds substantial operational context: exact credit costs, dryRun quoting, expectedCredits refusal behavior, requestId retry semantics, jobId returns, 1–5 minute readiness, and generation-permission checks via get_workspace. There is no contradiction with readOnlyHint=false, openWorldHint=true, idempotentHint=false, or destructiveHint=false.

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

Conciseness3/5

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

The purpose is front-loaded, and most sentences carry useful information, but the description is extremely long and dense as a single block. It would be easier to scan with clearer separation between purpose, source rules, cost, and job handling.

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 complex, multi-modal generation tool with cost and retry semantics, the description covers everything an agent needs to call it correctly, including source selection, sizing rules, dry-run pricing, expectedCredits, and post-call job handling. The presence of an output schema does not leave any material gap.

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 schema already documents each parameter and its enum values. The description adds valuable cross-parameter semantics beyond the schema: platform alone vs. aspect-ratio plus placement, video restrictions on sizes/format, and sourceCreativeId reuse for linked images. Some of this duplicates the schema, preventing a 5.

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 description names a specific verb and resource (resize an image or video) and explicitly distinguishes Rawa's generative re-framing from cropping, stretching, or letterboxing. It also differentiates image, clip, and Motion ad behavior so an agent can tell this apart from siblings like edit_creative or generate_image.

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 gives explicit when-to-use guidance ('Use this whenever the user wants an image or a video resized, adapted or fitted...') and a clear exclusion ('do not resize the pixels yourself'). It also routes edge cases to specific siblings: pasted images to request_image_upload, local files to upload_image_file, and videos only from the library via creativeId.

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