Skip to main content
Glama

Record HTML to video

record_html

Record a web page or HTML5 creative (banner, ad, animation, landing page) to a video: MP4 (default), WebM or GIF. Returns the finished recording with a video link.

Input: either url (a public http(s) page; localhost and private networks are out of reach) or html (a complete single-file HTML document you wrote, published at an unlisted public URL and recorded from there). Set width and height to the creative's size (e.g. 300×250, 728×90, 1080×1920, 1920×1080) and durationSec to how long it runs.

Waiting: the call waits up to waitSec (default 45 s) for the video. If it isn't done by then, you get the recording with status queued or running; it keeps going. Call get_recording with its id and waitSec to wait for it; don't call record_html again for it.

Retries are safe: identical calls within 10 minutes return the same recording. After changing the creative behind the same url, pass a new revision to record it again. A failed recording is never reused: call again once you've fixed the cause.

Trim markers: by default the video starts at the page's load event and lasts durationSec. To capture exactly the animation, the page can mark it. The recorder defines two global functions in every frame (iframes included):

  • trim_start(): call it once when the assets are loaded, just before the animation starts. The video starts there.

  • trim_end(): call it once from the animation's completion callback (e.g. GSAP onComplete, the last animationend). The video ends there and durationSec becomes the maximum. Guard both so the page still works in a normal browser: // assets loaded, just before the animation starts: if (typeof trim_start === 'function') trim_start(); // in the animation's completion callback: if (typeof trim_end === 'function') trim_end(); Never call the two right after each other: that marks an empty clip. With sync "markers" the recording fails instead of falling back to the load event when trim_start() isn't called within markerWaitSec (default 10 s). report.anchor says "trim_start" when the start marker was used.

Links: video.url is signed and valid for 1 hour (get_recording mints a fresh one). pageUrl is the recording's page in the web app, for a person to open later (they sign in).

Limits: the account's limits apply (length, size, fps, recordings at a time and per day); estimate_recording checks a request without recording. Errors say what to change: fix it and call again.

Input Schema

NameRequiredDescriptionDefault
crfNoQuality for mp4 and webm, from 10 (best, largest) to 35 (smallest). Not together with bitrateMbps; not for gif.
fitNoHow the frame fills outputSize: fill (stretch), contain (letterbox in background) or cover (crop to fill).
fpsNoFrame rate: one of 15, 23.976, 24, 25, 29.97, 30, 59.94, 60 (default 30). For gif, a whole number from 1 to 30.
urlNoPublic http(s) URL of the page or creative to record. The recorder runs on the internet: localhost and private networks are out of reach. Pass url or html, not both.
cropNoRecord only this region of the viewport: { x, y, width, height } in pixels, even values, inside the viewport.
htmlNoA complete HTML document to record instead of a url, e.g. a banner you just wrote. One file: inline the CSS and JavaScript, and load images, fonts and libraries from public https URLs or data: URIs. It is published at an unlisted public URL and recorded from there.
loopNogif only: whether the gif loops.
syncNoHow trim markers are used: auto (default: markers when the page calls trim_start(), else the load event), load (ignore markers) or markers (fail when trim_start() is not called within markerWaitSec).
audioNoRecord the page’s audio too. Not for gif.
widthYesViewport width in CSS pixels: even, 16–7680. Use the creative’s size, e.g. 300 for a 300×250 banner or 1920 for a full HD page.
formatNomp4 (default, H.264), webm or gif.
heightYesViewport height in CSS pixels: even, 16–7680.
startAtNoWhere the video starts: "load" (default: the load event, or the first trim_start() call) or that many milliseconds after it (0–120000).
waitSecNoHow long to wait for the finished video, in seconds (0–45, default 45). The recording keeps going after the call returns.
rendererNoauto (default), cpu or gpu. Leave it on auto.
revisionNoAny label that changes when the creative changes. Identical calls within 10 minutes return the same recording; after you change the creative behind the same url, pass a new revision to record it again.
backgroundNoLetterbox colour for fit: contain, as #rrggbb.
outputSizeNoScale the video to { width, height } (even values); see fit.
bitrateMbpsNoA target bitrate in Mbps (1–100) instead of crf, for platforms with a bitrate spec (e.g. DOOH). Not for gif.
bitrateModeNovbr (default) or cbr. Needs bitrateMbps.
durationSecYesLength of the video in seconds (1–300; your account limit applies). With trim_end() it is the maximum.
pixelFormatNoyuv420p (default; plays everywhere), yuv422p or yuv444p.
markerWaitSecNoHow long to wait for trim_start() after load, in seconds (0–60, default 10).
markerLatencyMsNoOverrides the measured delay between a marker call and the frame it marks (0–1000 ms). Rarely needed.

Output Schema

NameRequiredDescriptionDefault
idYes
errorYes
videoYes
reportYes
statusYes
pageUrlYes
requestYes
progressYes
rendererYes
createdAtYes
finishedAtYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed8 schema fields changed
    • addedInput schema / properties / crop / properties / height / multipleOf
      Added value: +2
    • addedInput schema / properties / crop / properties / width / multipleOf
      Added value: +2
    • addedInput schema / properties / crop / properties / x / multipleOf
      Added value: +2
    • addedInput schema / properties / crop / properties / y / multipleOf
      Added value: +2
    • addedInput schema / properties / height / multipleOf
      Added value: +2
    • addedInput schema / properties / outputSize / properties / height / multipleOf
      Added value: +2
    • addedInput schema / properties / outputSize / properties / width / multipleOf
      Added value: +2
    • addedInput schema / properties / width / multipleOf
      Added value: +2
  2. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already establish that this is a non-read-only, open-world, non-destructive operation, and the description adds substantial operational detail: waiting semantics, 10-minute retry deduplication, failed-recording behavior, trim marker protocol, signed-link expiry, and account-limit errors. No annotation contradiction is present.

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 definition is front-loaded with the core action and then organized into scannable sections for input, waiting, retries, trim markers, links, and limits. It is long, especially the marker code snippet, but most of that length is justified by the tool's 24-parameter complexity.

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?

Given the output schema, annotations, and rich parameter schema, the description supplies the missing operational context: recording lifecycle, polling, retry semantics, marker synchronization, URL expiry, and limit handling. An agent has enough information to invoke and recover from this tool 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 description coverage is 100%, so the schema already carries most parameter meaning. The description still adds meaningful workflow semantics for url/html exclusivity, width/height/duration, waitSec polling, sync, revision, and trim markers, though it does not explain all 24 parameters.

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 states a specific verb and resource: recording a web page or HTML5 creative to video. It names supported outputs (MP4, WebM, GIF) and clarifies the two input modes, so an agent can distinguish it from sibling tools without opening the 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 explicitly routes the agent between url and html inputs, says to poll with get_recording instead of calling record_html again, explains safe retry behavior, and points to estimate_recording for checking limits without recording. These are concrete when-to-use and when-not-to-repeat guidelines tied to sibling tools.

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