Skip to main content
Glama

Compare visual state

compare-visual-state
DestructiveIdempotent

Captures a page or element screenshot, compares it with a stored baseline, and reports changed pixels, affected regions, color shifts, and a red-highlighted diff image.

Instructions

Visual regression check: screenshot a live page (or element), compare it to a stored baseline, and report how many pixels changed, WHERE they changed (bounding regions), and the average color shift ("blue → red"). First call saves the baseline; later calls compare. Writes a red-highlighted diff image for review.

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": {
      "url": "<url>",
      "name": "<name>"
    },
    "name": "compare-visual-state"
  }
}

Input Schema

NameRequiredDescriptionDefault
harNo
urlYesFull URL of the page (or element target) to capture
maskNoHide dynamic parts (timestamps, ads, avatars) from both images: selectors or locators. Saved with the baseline and reused by later compares
nameYesBaseline id, e.g. "checkout-page" or "submit-button"
actionNo'baseline' overwrites the stored baseline; 'compare' (default) compares against it
deviceNoPlaywright device preset, e.g. 'iPhone 15', 'Pixel 7', 'iPad Pro 11' (viewport, user agent, touch)
routesNoNetwork mocks, first match wins: json/body/status fulfil, abort fails, delayMs alone slows the real request
actionsNoSteps run in order after load to reach a state (modal, step 3). One call = one fresh browser, so include the login steps; end with a 'wait' on what the state shows
browserNoEngine (default chromium)
channelNoBranded Chromium to launch instead of the bundled one (must be installed)
connectNoRemote browser: Playwright ws(s):// endpoint or 'cdp:<url>'; keys as {{env:E2E_…}}
headersNoExtra HTTP headers, e.g. Authorization
offlineNoGo offline once the page has loaded, before steps run, to check offline and retry states
waitForNoWait for this selector before capturing
fullPageNoCapture the full scrollable page (default false)
selectorNoCapture only this element (selector or locator)
viewportNo
timeoutMsNo
toleranceNoPercent of pixels that may differ before reporting a change (default 0.1)
waitUntilNo
blockWritesNoAbort POST/PUT/PATCH/DELETE requests no mock answers, so steps cannot change real data (default: PW_MCP_BLOCK_WRITES)
projectRootNoProject directory; defaults to the server working directory
storageStateNoLogged-in session: storageState JSON inside the project, e.g. playwright/.auth/user.json
blockResourcesNoSkip these requests for speed and privacy: image, media, font, stylesheet, trackers (known analytics/ad hosts); default PW_MCP_BLOCK_RESOURCES
pixelThresholdNoCombined per-pixel channel delta considered different (default 60)
actionTimeoutMsNoHow long each action waits for its element (default 10000); keep timeoutMs above the total

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changedv0.14.0
    • addedInput schema / properties / blockResources
      Added value: +{
      +  "description": "Skip these requests for speed and privacy: image, media, font, stylesheet, trackers (known analytics/ad hosts); default PW_MCP_BLOCK_RESOURCES",
      +  "items": {
      +    "enum": [
      +      "image",
      +      "media",
      +      "font",
      +      "stylesheet",
      +      "trackers"
      +    ],
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / mask
      Added value: +{
      +  "description": "Hide dynamic parts (timestamps, ads, avatars) from both images: selectors or locators. Saved with the baseline and reused by later compares",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / offline
      Added value: +{
      +  "description": "Go offline once the page has loaded, before steps run, to check offline and retry states",
      +  "type": "boolean"
      +}
  2. Changed22 schema fields changedv0.13.0
    • removedInput schema / $schema
      Removed value: -"https://json-schema.org/draft/2020-12/schema"
    • removedInput schema / additionalProperties
      Removed value: -{}
    • changedInput schema / properties / actions / items / properties / type / enum
      Previous value: -[
      -  "goto",
      -  "click",
      -  "dblclick",
      -  "hover",
      -  "fill",
      -  "press",
      -  "check",
      -  "uncheck",
      -  "select",
      -  "wait"
      -]New value: +[
      +  "goto",
      +  "click",
      +  "dblclick",
      +  "hover",
      +  "fill",
      +  "press",
      +  "check",
      +  "uncheck",
      +  "select",
      +  "wait",
      +  "switchTab"
      +]
    • changedInput schema / properties / actions / items / properties / value / description
      Previous value: -"fill text, press key, select option"New value: +"fill text, press key, select option; switchTab: 'last' (default), 'first', a 1-based number, or text in the tab's URL or title"
    • removedInput schema / properties / actions / maxItems
      Removed value: -20
    • addedInput schema / properties / blockWrites
      Added value: +{
      +  "description": "Abort POST/PUT/PATCH/DELETE requests no mock answers, so steps cannot change real data (default: PW_MCP_BLOCK_WRITES)",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / connect
      Added value: +{
      +  "description": "Remote browser: Playwright ws(s):// endpoint or 'cdp:<url>'; keys as {{env:E2E_…}}",
      +  "type": "string"
      +}
    • removedInput schema / properties / device / maxLength
      Removed value: -60
    • removedInput schema / properties / device / minLength
      Removed value: -2
    • removedInput schema / properties / har / properties / path / maxLength
      Removed value: -500
    • removedInput schema / properties / har / properties / path / minLength
      Removed value: -1
    • removedInput schema / properties / har / properties / url / maxLength
      Removed value: -500
    • removedInput schema / properties / headers / propertyNames
      Removed value: -{
      -  "type": "string"
      -}
    • removedInput schema / properties / name / maxLength
      Removed value: -64
    • removedInput schema / properties / name / minLength
      Removed value: -1
    • removedInput schema / properties / routes / items / properties / body / maxLength
      Removed value: -200000
    • removedInput schema / properties / routes / items / properties / contentType / maxLength
      Removed value: -100
    • removedInput schema / properties / routes / items / properties / headers / propertyNames
      Removed value: -{
      -  "type": "string"
      -}
    • removedInput schema / properties / routes / items / properties / method / maxLength
      Removed value: -10
    • removedInput schema / properties / routes / items / properties / url / maxLength
      Removed value: -500
    • removedInput schema / properties / routes / items / properties / url / minLength
      Removed value: -1
    • removedInput schema / properties / routes / maxItems
      Removed value: -20
  3. Changed8 schema fields changedv0.6.1
    • addedInput schema / additionalProperties
      Added value: +{}
    • addedInput schema / properties / actionTimeoutMs
      Added value: +{
      +  "description": "How long each action waits for its element (default 10000); keep timeoutMs above the total",
      +  "maximum": 120000,
      +  "minimum": 1000,
      +  "type": "integer"
      +}
    • changedInput schema / properties / actions / description
      Previous value: -"Steps run after load to reach a state (modal, step 3)"New value: +"Steps run in order after load to reach a state (modal, step 3). One call = one fresh browser, so include the login steps; end with a 'wait' on what the state shows"
    • addedInput schema / properties / browser
      Added value: +{
      +  "description": "Engine (default chromium)",
      +  "enum": [
      +    "chromium",
      +    "firefox",
      +    "webkit"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / channel
      Added value: +{
      +  "description": "Branded Chromium to launch instead of the bundled one (must be installed)",
      +  "enum": [
      +    "chrome",
      +    "chrome-beta",
      +    "msedge",
      +    "msedge-beta"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / device
      Added value: +{
      +  "description": "Playwright device preset, e.g. 'iPhone 15', 'Pixel 7', 'iPad Pro 11' (viewport, user agent, touch)",
      +  "maxLength": 60,
      +  "minLength": 2,
      +  "type": "string"
      +}
    • addedInput schema / properties / har
      Added value: +{
      +  "properties": {
      +    "mode": {
      +      "description": "'replay' (default) answers requests from the file; 'record' saves the traffic",
      +      "enum": [
      +        "replay",
      +        "record"
      +      ],
      +      "type": "string"
      +    },
      +    "notFound": {
      +      "description": "replay: requests missing from the file abort (default) or go to the network",
      +      "enum": [
      +        "abort",
      +        "fallback"
      +      ],
      +      "type": "string"
      +    },
      +    "path": {
      +      "description": ".har or .zip inside the project",
      +      "maxLength": 500,
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "url": {
      +      "description": "Glob limiting the requests, e.g. '**/api/**'",
      +      "maxLength": 500,
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "path"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / routes
      Added value: +{
      +  "description": "Network mocks, first match wins: json/body/status fulfil, abort fails, delayMs alone slows the real request",
      +  "items": {
      +    "properties": {
      +      "abort": {
      +        "type": "boolean"
      +      },
      +      "body": {
      +        "maxLength": 200000,
      +        "type": "string"
      +      },
      +      "contentType": {
      +        "maxLength": 100,
      +        "type": "string"
      +      },
      +      "delayMs": {
      +        "maximum": 10000,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "headers": {
      +        "additionalProperties": {
      +          "type": "string"
      +        },
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "json": {},
      +      "method": {
      +        "maxLength": 10,
      +        "type": "string"
      +      },
      +      "status": {
      +        "maximum": 599,
      +        "minimum": 100,
      +        "type": "integer"
      +      },
      +      "url": {
      +        "description": "Glob, e.g. '**/api/cart'",
      +        "maxLength": 500,
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "url"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 20,
      +  "type": "array"
      +}
  4. First observedv0.3.2

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and idempotentHint=true; the description adds the side effects that matter beyond that: a baseline file is stored and later overwritten, a red-highlighted diff image is written for review, and masks persist into future compares. It stops short of covering the network-mock/actions machinery, but that lives in the schema.

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

Conciseness5/5

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

Three tight sentences, front-loaded with the verb and resource, then behavior, then the write side effect. Every clause carries information an agent needs and there is no filler.

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

Completeness4/5

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

With 26 parameters, deep nesting and no output schema, the description usefully summarizes the return shape (change count, where, color shift, diff image), which is exactly what the missing output schema would have carried. It does not touch the har/routes/actions/connect surface, though the high schema coverage covers that adequately.

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

Parameters3/5

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

Schema description coverage is 85%, so the schema already explains url, selector, mask, tolerance and the rest; the baseline 3 applies. The description reinforces page-vs-element capture and the baseline/compare lifecycle but adds nothing about tolerance, pixelThreshold, or how mask interacts with the stored baseline beyond a single clause.

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?

It names a specific operation (visual regression check), the concrete steps (screenshot live page or element, compare to stored baseline) and the concrete outputs (pixel count, bounding regions, average color shift, red-highlighted diff image). No sibling tool in the list does this, and the definition makes that unmistakable.

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

Usage Guidelines4/5

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

"First call saves the baseline; later calls compare" gives an explicit workflow, so an agent knows the first invocation is not a check. It does not name a moment-of-use trigger or alternatives (e.g. inspect-page for non-visual checks), and it never mentions the explicit `action` switch, which slightly undersells how to force a baseline reset.

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