Forum Discussion

shobhit-vishwakarma's avatar
shobhit-vishwakarma
Copper Contributor
Jul 31, 2026

Looking for Guidance: Improving Playwright MCP Runbook Replay Reliability

Hi everyone,

We are building an AI-powered browser automation agent using Playwright MCP, and we have implemented a runbook/replay mechanism to reduce repeated reasoning and improve navigation performance.

Current Architecture

Our setup currently looks like this:

  • AI Agent (Client) – Hosted on Azure Container Apps
  • Playwright MCP Server – Hosted on Azure Container Apps
  • Chrome Extension – Running in the user's browser

The Chrome Extension maintains a webhook connection with the Playwright MCP relay/server.

The MCP server generates Chrome DevTools Protocol (CDP) commands, which are executed by the Chrome Extension in the user's browser.

Runbook Functionality

When the agent needs to navigate to a particular page, it normally performs multiple browser actions such as:

  • browser_navigate
  • browser_snapshot
  • browser_click
  • browser_type
  • Other Playwright MCP tools

During the first successful execution, we record the tool calls and their parameters used by the agent to reach the desired page. We store these actions as a runbook.

For subsequent requests requiring navigation to the same destination, instead of asking the AI agent to reason through the navigation steps again, we directly replay the stored runbook.

First execution

User Request ↓ Agent Reasoning ↓ MCP Tools ↓ Browser ↓ Desired Page

Example recorded sequence:

browser_navigate → browser_snapshot → browser_click → browser_snapshot → browser_type ...

Subsequent execution

User Request ↓ Runbook Replay ↓ MCP Tools ↓ Browser ↓ Desired Page

This significantly reduces latency, token usage, and unnecessary LLM reasoning.

Example Runbook Step

{ "tool": "browser_click", "args": { "target": "e140", "element": "Earn credentials link" }, "a11y": { "role": "link", "name": "Earn credentials", "index": 0, "text": "Earn credentials", "textIndex": 0, "path": "generic/list/listitem/article/generic/generic", "url": "https://learn.microsoft.com/en-us/" }, "pageUrl": "https://learn.microsoft.com/en-us/", "timestamp": "2026-07-30T10:24:04.374Z" }

For each recorded action, we persist information such as:

  • MCP tool name
  • Tool parameters
  • Snapshot reference
  • Accessibility role
  • Accessibility name
  • Element text
  • Element index
  • Text index
  • Accessibility-tree path
  • Page URL
  • Other relevant metadata

The Problem

The main challenge is runbook replay reliability.

A runbook contains references obtained from a previous browser_snapshot. During replay, the page may have:

  • Slightly different DOM structure
  • Timing differences
  • Dynamic content
  • Accessibility-tree changes

As a result, a previously recorded snapshot reference may no longer match the current page.

For example, a recorded action may effectively be:

browser_click(ref="some_snapshot_ref")

During replay, that reference may no longer exist or may resolve to a different element because the current snapshot has changed.

This causes intermittent failures in operations such as:

  • browser_click
  • browser_type
  • Other element interactions

Current Status

We have improved the replay mechanism and currently achieve approximately 90% replay success.

The remaining ~10% failures are difficult because they are often nondeterministic. The same runbook can succeed or fail depending on the current browser or page state.

Questions

We would appreciate advice from anyone with experience using Playwright MCP or building production browser automation systems.

  1. What is the recommended way to make Playwright MCP tool calls more resilient to changes in snapshot or accessibility-tree references?
  2. Is relying on snapshot ref values fundamentally unreliable for replay? Should we instead store a different representation of the target element?
  3. If so, what additional information would you recommend storing for each interaction?
  4. What is the best strategy for re-resolving an element when the original snapshot reference is no longer valid instead of failing the entire runbook?
  5. Are there Playwright MCP capabilities or recommended patterns that specifically address dynamic pages and changing accessibility trees?
  6. For a production-grade browser automation agent, what architecture or strategy would you recommend to achieve >99% replay reliability?

Our goal is not to eliminate dynamic behavior from websites, but to make the runbook intelligent enough to recover when previously recorded element references become invalid.

Any architectural recommendations, implementation patterns, or examples from production systems would be greatly appreciated.

Thank you!

1 Reply

  • hi shobhit-vishwakarma​ here is my 2 cents, 90% replay success is a good start. From my understanding, the main challenge here is that the ref generated from a snapshot is tied to that particular snapshot, so I wouldn't treat it as a permanent identifier for the element.

    I would consider storing the ref as the first option, but also keep multiple ways to identify the element, such as:

    • Role + accessible name
    • Visible text
    • Stable attributes or test IDs, where available
    • href or other unique properties
    • Parent/ancestor context
    • Page URL or a normalized URL

    During replay, you could try the original ref first. If it no longer exists, fall back to the strongest available locator and re-resolve the element from a fresh snapshot.

    I'd also add explicit waits and verification between important steps. For example, instead of simply replaying click → type, use something closer to:

    Navigate → Wait for expected state → Resolve element → Interact → Verify result

    If the element can't be resolved, rather than failing the entire runbook, you could take a new snapshot and use a lightweight recovery step to identify the intended element based on the stored metadata. If successful, you could even update the runbook with the new locator information.

    I think the key is to treat the runbook as self-healing rather than static replay. The ref is useful for fast execution, but the runbook should retain enough context to recover when the DOM or accessibility tree changes.

    It may also be worth categorizing your remaining 10% failures timing, dynamic content, authentication/session state, element resolution, or navigation state. You might find that most failures are coming from one or two specific areas.

    For a production target of 99%+, I'd probably go with a hybrid approach: deterministic replay for stable steps, with targeted re-resolution and recovery only when a step fails. That should preserve most of the latency and token savings you're getting while giving the automation a way to recover from dynamic pages.