Skip to main content
Glama

Validate selector or locator

validate-selector
Read-onlyIdempotent

Validates CSS, Playwright selectors and locators on a live page: checks match counts (actions need exactly 1), shows sample matches and returns a sturdier verified locator.

Instructions

Check a CSS selector, Playwright selector or locator (getByRole/getByTestId…, .first(), .filter(), frameLocator() for iframes) on a live page: validity, match count (actions need exactly 1), sample matches and a sturdier verified locator for each. Counts once after load: use waitFor or actions for late elements. Accepts storageState/headers/actions.

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>",
      "selector": "<selector>"
    },
    "name": "validate-selector"
  }
}

Input Schema

NameRequiredDescriptionDefault
harNo
urlYesFull URL of the live page to test against (http/https)
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 to be visible first (for elements that render late)
selectorYesSelector or locator, e.g. getByRole('button', { name: 'Save' })
viewportNo
timeoutMsNoOverall limit in ms (default 45000)
blockWritesNoAbort POST/PUT/PATCH/DELETE requests no mock answers, so steps cannot change real data (default: PW_MCP_BLOCK_WRITES)
projectRootNoProject whose Playwright launches the browser (default: server root)
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
actionTimeoutMsNoHow long each action waits for its element (default 10000); keep timeoutMs above the total

Output Schema

NameRequiredDescriptionDefault
okYesfalse when the call failed (see error) or the tests it ran failed
urlNo
errorNo
validNovalidate-selector: the selector parsed and ran
locatorNoa verified unique locator for the first match
matchesNoelements matched; actions need exactly 1
httpStatusNothe page's HTTP status

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 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 / offline
      Added value: +{
      +  "description": "Go offline once the page has loaded, before steps run, to check offline and retry states",
      +  "type": "boolean"
      +}
  2. Changed21 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 / 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
    • removedInput schema / properties / selector / minLength
      Removed value: -1
  3. Changed10 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"
      +}
    • addedInput schema / properties / waitFor
      Added value: +{
      +  "description": "Wait for this selector to be visible first (for elements that render late)",
      +  "type": "string"
      +}
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "https://json-schema.org/draft/2020-12/schema",
      +  "additionalProperties": false,
      +  "properties": {
      +    "error": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "hint": {
      +          "type": "string"
      +        },
      +        "kind": {
      +          "type": "string"
      +        },
      +        "message": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "kind",
      +        "message"
      +      ],
      +      "type": "object"
      +    },
      +    "httpStatus": {
      +      "description": "the page's HTTP status",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "locator": {
      +      "description": "a verified unique locator for the first match",
      +      "type": "string"
      +    },
      +    "matches": {
      +      "description": "elements matched; actions need exactly 1",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "ok": {
      +      "description": "false when the call failed (see error) or the tests it ran failed",
      +      "type": "boolean"
      +    },
      +    "url": {
      +      "type": "string"
      +    },
      +    "valid": {
      +      "description": "validate-selector: the selector parsed and ran",
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "ok"
      +  ],
      +  "type": "object"
      +}
  4. First observedv0.3.2

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnly/openWorld/idempotent, so the bar is lower; the description still adds real behavioral context beyond them — the count is taken once after load (not retried), late elements need waitFor/actions, and actions run in-order with a fresh browser per call. It stops short of noting rate limits or how the verified locator is derived.

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?

Three dense sentences, front-loaded with what is checked and against what, followed by the return values and the timing caveat. The parenthetical locator list is a bit packed but every clause carries information.

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?

For a 19-parameter tool with an output schema, the description covers the core contract (what is validated, what comes back, the single-count timing rule) plus the storageState/headers/actions entry points. Remaining gaps (har/routes/offline/blockWrites interactions) are handled by the schema, but their interplay with validation isn't summarized.

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 coverage is 89%, so parameters are largely self-documenting and baseline 3 applies. The description only gestures at 'Accepts storageState/headers/actions' without adding format or behavior detail beyond what the schema already provides for those fields.

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?

States a specific verb ('Check') and precise resource (CSS selector / Playwright selector or locator) against a live page, and enumerates the outputs: validity, match count, sample matches, and a sturdier verified locator. The parenthetical examples (getByRole, .first(), frameLocator) make the accepted locator grammar concrete, so an agent can distinguish this from sibling tools like inspect-page or run-test.

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?

Gives actionable usage conditions: 'Counts once after load: use waitFor or actions for late elements', and the constraint that actions need exactly 1 match. It does not name a sibling alternative or say when NOT to use this tool (e.g., versus inspect-page), so it falls short of explicit routing.

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