Skip to main content

Snapshots

Playwright MCP uses accessibility snapshots instead of screenshots. Every tool that interacts with the page returns a structured tree of accessible elements with refs for interaction.

Snapshot format

- heading "todos" [level=1] [ref=e3]
- textbox "What needs to be done?" [ref=e5]
- list [ref=e8]:
- listitem [ref=e9]:
- checkbox "Toggle Todo" [ref=e10]
- text: Buy groceries
- listitem [ref=e13]:
- checkbox "Toggle Todo" [ref=e14]
- text: Water flowers
- contentinfo [ref=e18]:
- text: 2 items left
- link "All" [ref=e20]
- link "Active" [ref=e21]
- link "Completed" [ref=e22]

Each element gets a unique ref (e.g., ref=e5). Tools that act on an element take that ref as their target:

browser_type { target: "e5", text: "headphones" }
browser_click { target: "e10" }
browser_click { target: "e20" }

Targeting elements

Tools that act on an element take a target, which accepts either form:

  • A refe12, or f1e12 for an element inside the first iframe. This is what the snapshot prints, and what you should normally pass.
  • A selector — any Playwright selector or locator string, for example getByRole('button', { name: 'Submit' }), #submit, or text=Sign in. Useful when you already know the element and want to skip a snapshot round-trip.

If a ref is stale, the tool fails with Ref <ref> not found in the current page snapshot. Try capturing new snapshot.

PropertyDetail
Formate followed by a number, optionally prefixed by a frame id (e1, e15, f2e7)
ScopeUnique within a single snapshot
LifetimeValid until the page changes
AssignmentAssigned to every node the accessibility tree exposes, not just interactive ones

On-demand snapshots

Most tools return a fresh snapshot automatically after each action, so the LLM always has up-to-date page state. Use browser_snapshot to capture it explicitly.

ParameterTypeRequiredDescription
targetstringnoSnapshot only this element's subtree
depthnumbernoLimit the depth of the snapshot tree
boxesbooleannoInclude each element's bounding box as [box=x,y,width,height], viewport-relative in CSS pixels
filenamestringnoSave the snapshot to a file instead of returning it in the response
→ browser_snapshot { depth: 2 }
→ browser_snapshot { target: "e8" } // just the todo list subtree
→ browser_snapshot { boxes: true } // add bounding boxes

Snapshot mode can also be set globally with --snapshot-mode=none to stop tools from attaching snapshots to responses, and --snapshot-boxes to always include bounding boxes.

Searching a snapshot

browser_find searches the current page's snapshot and returns only the matching nodes plus a few lines of surrounding context, each shown under its path from the root of the tree. On a large page this is far cheaper than capturing the whole snapshot when you only need to locate one element and its ref.

ParameterTypeRequiredDescription
textstringnoPlain text to search for (case-insensitive substring match)
regexstringnoRegular expression. Case-sensitive by default; wrap in slashes to add flags, e.g. /error/i

Provide exactly one of text or regex.

→ browser_find { text: "Deep Target Link" }

Found 1 match for "Deep Target Link":

- main [ref=e2]:
- region "Sidebar" [ref=e3]:
- navigation "Primary" [ref=e4]:
- list [ref=e5]:
...
- listitem [ref=e16]:
- link "Deep Target Link" [ref=e17]

→ browser_click { target: "e17" }

Gaps in the surrounding context are marked with ....

Snapshots with screenshots

For pages where visual context matters (canvas apps, charts, image-heavy layouts), combine snapshots with screenshots:

Take a snapshot and a screenshot of the current page.

The LLM gets both the structured accessibility tree for interaction and the visual screenshot for understanding layout. See Vision Mode for coordinate-based interaction using screenshots.

Why snapshots over screenshots

SnapshotsScreenshots
Token costLow — text onlyHigh — image tokens
PrecisionExact — refs point to specific elementsApproximate — requires coordinate guessing
SpeedInstant — text parsingSlower — vision model inference
ReliabilityDeterministic — same structure = same interactionVariable — layout changes break coordinates
Vision modelNot requiredRequired

Best practices

  1. Use refs, not selectors — refs from snapshots are more reliable than CSS selectors because they point to the exact element the LLM just saw
  2. Re-snapshot after navigation — refs are invalidated when the page changes
  3. Use browser_find on large pages — it returns only the matching subtree instead of the entire snapshot
  4. Combine with screenshots — when visual context is needed alongside structured data
  5. Check for dialogs — if a tool reports a dialog is open, handle it before proceeding with other actions