Launched in 2020, it has steadily grown into one of the most trusted tools in modern test automation projects, with adoption accelerating rapidly in the past few years.
Now, as we enter the era of AI-augmented development, Playwright has taken a major leap forward with the introduction of Playwright MCP in March 2025 and Playwright Agents in October 2025. Two additions that provide us with intelligent, agentic test automation.
In this blog post, we’ll explore the concepts behind Playwright MCP and Playwright Agents, what they are, how they work, how they interact with LLMs, and why they represent the next paradigm for writing and maintaining tests.
MCP stands for Model Context Protocol, an open standard created by Anthropic and adopted by many companies, including Microsoft for Playwright.
An MCP is the bridge that allows LLMs (Large Language Models like ChatGPT, Claude, Gemini,...) to safely and reliably interact with tools, APIs and applications in a standardized, secure way.
Before MCP, every AI tool needed its own custom integration with an application, API or test automation framework. This caused problems:
MCP solves this by defining a shared, open protocol.
For Playwright MCP, this means that it provides:
The LLM requests an “intention”, and Playwright MCP decides whether and how to execute them through Playwright.
The Playwright Agents are specialized, thin orchestrators built around an LLM for Playwright. The LLM is external.
You can think of the Playwright Agents as:
The intelligence (understanding instructions and making decisions) comes from the LLM model, not from Playwright itself.
By creating a LLM independent agent, test generation relies on the selected LLM to interpret your natural-language instruction and decide:
Since each LLM has different reasoning abilities, styles, and training data, the output varies between the chosen LLM and you can choose yourself the best suited one for your project.
If Playwright MCP is the bridge, as mentioned in previous chapter, Playwright Agents are the intelligent workers crossing it.
There are 3 Agents in Playwright:
These agents work together (and individually) to turn natural language instructions into valid and stable Playwright tests.
The planner agent can be seen as the project manager of the AI based test creation.
It will try to discover test cases by:
The output of these actions will be a human-readable test plan in markdown format (.md).
Example basic-operations.md:
| # Test Plan: Basic Operations ## Overview This plan covers essential user flows for the Example App homepage. ### Scenarios 1. **Navigate to Homepage** - Open `https://example.com` - Verify page title contains "Example Domain" 2. **Click "More information" Link** - Locate link with text "More information" - Click the link - Verify navigation to IANA page 3. **Check Heading** - Ensure first `<h1>` element is visible - Assert text equals "Example Domain" |
The generator agent acts as the developer of your automated test cases.
It will write the actual Playwright test code by:
The output of these actions will be files containing coded tests (.spec).
Example test.spec.ts:
| Import { test, expect } from '@Playwright/test'; test.describe('Basic Operations', () => { test('Navigate to Homepage and verify title', async ({ page }) => { await page.goto('https://example.com'); await expect(page).toHaveTitle(/Example Domain/); }); test('Click "More information" and verify navigation', async ({ page }) => { await page.goto('https://example.com'); await page.getByRole('link', { name: 'More information' }).click(); await expect(page).toHaveURL(/iana\.org/); }); test('Check heading text', async ({ page }) => { await page.goto('https://example.com'); const heading = page.locator('h1'); await expect(heading).toBeVisible(); await expect(heading).toHaveText('Example Domain'); }); }); |
The healer agent acts as the bug fixer of your automated test cases.
When a test fails, the healer will:
The LLM sends MCP commands directly to Playwright to execute an action in the browser.
Pros:
Cons:
High level code example:
| sync with ClientSession(*stdio) as session: # Initialize and discover server capabilities await session.initialize() tools = await session.list_tools() print("Available tools:", [t.name for t in tools.tools]) # 1) Navigate result_nav = await session.call_tool("browser_navigate", {"url": "https://example.com"}) print("Navigate result:", result_nav) # 2) Grab an accessibility snapshot (LLM-friendly DOM) result_snap = await session.call_tool("browser_snapshot", {}) # The content contains structured text/ARIA data that your LLM can reason over print("Snapshot length:", len(result_snap.content[0].text)) # 3) Click a link by visible text (example; adjust to your page) result_click = await session.call_tool("browser_click_text", {"text": "More information"}) print("Click by text result:", result_click) # 4) Cleanly close await session.call_tool("browser_close", {}) |
The LLM instructs a Playwright Agent to execute an action in the browser
Pros:
Cons:
High level code example:
| #1) Natural-language task; agent decides which tools to call & in what order instruction = """ Open https://example.com, click the link with text 'More information', then extract the first <h1> you see and return it as plain text. """ result = agent.run(instruction) |
With all this new exciting functionality, we would almost forget that there are some downsides on using the Playwright Agents:
So if speed and having automation matters more than absolute control and cost, definitely give Playwright Agents a go! They give us a new step in the exciting times to come for test automation!