The CheckOps Engineer home

Essay

Playwright MCP and MCP Servers for Agentic Testing

Playwright MCP, Browser Use's $17M seed and MCP tool poisoning: how MCP servers turn AI assistants into testing agents, and how to use them safely.

15 April 2025 · 11 min · Irfan Ahmad

In November we described the Model Context Protocol as plumbing that was about to become test infrastructure. Four months later, it has. Between mid-March and mid-April 2025, Microsoft released an official Playwright MCP server, OpenAI adopted MCP, a browser-agent startup raised a sizeable seed round, and security researchers showed exactly how MCP can be turned against the agents that use it.

This essay covers that window. The deeper theme is agentic testing through MCP: what changes when any AI assistant can drive a real browser through a standard interface, which patterns are useful for QA, and what has to be locked down first.

Playwright MCP: a browser for any agent

Microsoft’s Playwright MCP server launched around 22 March. It exposes Playwright’s browser automation as MCP tools, so any MCP client can open pages, click, type, take snapshots and read results: Claude Desktop, Claude Code, Cursor, VS Code with Copilot, and custom agents. Simon Willison wrote it up on 25 March, and the testing community picked it up quickly. Software Testing Weekly featured it at the start of April.

Setup is a single client configuration entry:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}

The key design choice: accessibility snapshots, not screenshots

The most important thing about Playwright MCP is how the model sees the page. Rather than sending screenshots, as computer-use agents do, it defaults to accessibility snapshots: a structured text representation of the page’s accessibility tree, with a short reference ID for each interactive element. A snapshot looks roughly like this:

- navigation:
  - link "Home" [ref=e3]
  - link "Pricing" [ref=e4]
- main:
  - heading "Sign in" [level=1]
  - textbox "Email" [ref=e12]
  - textbox "Password" [ref=e13]
  - button "Sign in" [ref=e14]

The model then calls tools like browser_click or browser_type with those references. The approach has big advantages for testing:

  • Cheaper and faster. Text snapshots use far fewer tokens than images, and no vision model is required.
  • More deterministic. Clicking ref=e14 targets exactly one element. There’s no guessing pixel coordinates.
  • Accessibility-aligned. If an element has no accessible role or name, the agent struggles to find it, just as a screen-reader user would. Agent failures surface accessibility bugs.

There’s also a vision mode, enabled through a flag, for canvas-heavy or poorly labelled UIs where the accessibility tree isn’t enough. It mirrors the trade-off we discussed in February: pixels are general but costly, structure is efficient but depends on a well-built app.

This builds directly on Playwright’s aria snapshot assertions, which shipped in 1.49. The same representation that lets you assert on structure now lets an agent act on it.

What QA teams are actually doing with it

Playwright MCP isn’t a test runner. It’s a way to give an assistant hands. The useful patterns are emerging quickly.

1. Exploratory sessions driven from chat

A tester describes a scenario in natural language and watches the assistant execute it in a visible browser:

Open https://staging.example.test, sign in as qa-editor@example.test (password in 1Password item "staging-editor"),
create a draft article with a 300-character title, and tell me exactly what validation messages appear.
Then try the same with a title containing emoji and RTL text.

It’s a fast way to probe edge cases without writing code. The agent reports what it observed, and the tester decides what matters.

2. Generating Playwright tests from a live session

Once the assistant has completed a flow, ask it to write the equivalent Playwright test using role-based locators. Because it worked from the accessibility tree, the generated locators tend to be the recommended getByRole style rather than brittle CSS:

test('editor sees validation for overlong title', async ({ page }) => {
  await page.goto('/articles/new');
  await page.getByRole('textbox', { name: 'Title' }).fill('x'.repeat(300));
  await page.getByRole('button', { name: 'Save draft' }).click();
  await expect(page.getByText('Title must be 200 characters or fewer')).toBeVisible();
});

This is the “agents draft, scripts gate” pattern made practical. The agent explores once, and the generated script then runs deterministically in CI.

3. Debugging failing tests with a live browser

Combine Playwright MCP with a coding agent like Claude Code or Copilot agent mode. The agent reads a failing test, opens the page through MCP, inspects the live accessibility tree, and proposes a fix to the locator or flow. It works well for simple breakages such as renamed buttons. It’s riskier for logic changes, where the “fix” might hide a real regression. See the guardrails in our March essay.

4. Accessibility smoke checks

Ask the agent to complete key tasks using only the snapshot. Where it can’t find a control, you’ve likely found an unlabelled button or a missing role. It’s not a substitute for axe-core or manual screen-reader testing, but it’s a cheap, novel signal.

An ecosystem forming around MCP

Playwright MCP isn’t alone. The weeks after its release brought a flood of testing-adjacent MCP servers, from TestGuild’s round-ups to vendor announcements. In mid-April they broadly fall into these categories:

MCP server type What it lets an agent do Testing use
Browser automation (Playwright MCP, Puppeteer-based servers) Navigate, click, type, snapshot Exploration, test drafting, debugging
Test runners / CI Run suites, fetch results and artefacts “Run the checkout tests and summarise failures”
Issue trackers (Jira, Linear, GitHub) Read and create tickets Turn findings into well-formed bug reports
Databases Query test data Verify outcomes, seed fixtures
Observability (logs, traces) Search logs and traces Connect a UI failure to a backend error
API clients Send HTTP requests Ad-hoc API probing, contract exploration

The real power is combination. An agent with browser, CI, tracker and log servers can reproduce a failure, find the backend error and file a ticket with evidence in one conversation. That’s also exactly why permission design matters so much.

Building your own testing MCP server

The servers you install are only half the story. Many QA teams will get more value from a small, custom MCP server that exposes their own test infrastructure to AI assistants, with exactly the permissions they choose. A server that lets an assistant query recent test results and flaky-test statistics, read-only, takes an afternoon:

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';

const server = new McpServer({ name: 'qa-insights', version: '0.2.0' });

server.tool(
  'flaky_tests',
  'List tests whose pass rate on main over the last N days is below the threshold. Read-only.',
  { days: z.number().int().min(1).max(30), threshold: z.number().min(0).max(1) },
  async ({ days, threshold }) => {
    const rows = await db.query(
      'select test_id, pass_rate, runs from test_stats where window_days = $1 and pass_rate < $2 order by pass_rate',
      [days, threshold],
    );
    return { content: [{ type: 'text', text: JSON.stringify(rows) }] };
  },
);

server.tool(
  'failure_artifacts',
  'Return trace and screenshot URLs for a failed run. Read-only.',
  { runId: z.string() },
  async ({ runId }) => ({ content: [{ type: 'text', text: JSON.stringify(await artifacts(runId)) }] }),
);

await server.connect(new StdioServerTransport());

With that connected, a developer can ask “which checkout tests flaked most this week, and what do their traces have in common?” and get an answer grounded in your real data. A few design rules keep custom servers safe and useful:

  • Make tools narrow and read-only by default. “Query flaky tests” is safe. “Run arbitrary SQL” isn’t.
  • Write descriptions for the model and the human. The description is what the model uses to decide when to call the tool. Keep it accurate and free of anything you wouldn’t want an attacker to edit.
  • Return structured data. JSON results let the model reason precisely and make it easier to verify what it was told.
  • Log every call. You’ll want to know which questions people ask and which tools the model reaches for.
  • Version and review the server like any other code. It’s part of your test infrastructure now.

Custom servers are also a good first step for teams nervous about third-party MCP servers. You control the code, the permissions and the update cadence.

OpenAI adopts MCP: the standard is settled

On 26 March OpenAI announced MCP support in its Agents SDK, with Sam Altman saying it would come to more OpenAI products. With both major model providers backing it, MCP stopped being an Anthropic project and became the de facto standard. For tool builders, including test tool vendors, that removes the “which protocol?” question. Expect most testing platforms to ship MCP servers this year.

On 9 April Google announced the Agent2Agent (A2A) protocol for communication between agents, positioned as complementary to MCP. It’s early, but multi-agent testing setups, where a planner agent delegates to executor agents, are a plausible next step.

Browser Use raises $17M

On 23 March Browser Use, an open-source library for making websites accessible to AI agents, announced a $17M seed round led by Felicis. Browser Use takes a different angle from Playwright MCP. It’s a Python framework for building agents that browse, built on Playwright, rather than a server exposing browser tools to an existing assistant. For QA teams the distinction is practical:

  • Playwright MCP is best when a human is in the loop with an AI assistant: exploration, drafting, debugging.
  • Browser Use and similar frameworks are best when you’re building an autonomous agent programmatically, for example a nightly exploratory job that tries a list of goals and reports findings.
from browser_use import Agent
from langchain_openai import ChatOpenAI

agent = Agent(
    task="Go to staging.example.test, add the cheapest item to the cart, and report the cart total and any errors shown.",
    llm=ChatOpenAI(model="gpt-4o"),
)
result = await agent.run()

Funding for this layer signals that investors expect agents to become a significant share of web traffic, which loops back to the “agents as users” testing concerns from February.

The security wake-up call: tool poisoning

In early April, Invariant Labs published research on tool poisoning attacks against MCP, followed by a proof of concept against a WhatsApp MCP server. Simon Willison summarised the problem as “MCP has prompt injection security problems”.

The attack is simple and unsettling. An MCP tool’s description is text the model reads to decide how to use the tool. A malicious or compromised server can hide instructions in that description, invisible in most client UIs. When the model reads them, it follows them. In the WhatsApp example, a seemingly harmless tool later changed its description to instruct the agent to forward the user’s message history to an attacker through the legitimate WhatsApp server the user had also connected.

For QA and test infrastructure, the implications are direct:

  • Your test agent may have powerful tools connected. Browser sessions logged into staging, CI tokens, database access. A poisoned server could direct the agent to misuse them.
  • Tool descriptions can change after you’ve approved them. This is a “rug pull”: a server that looked fine at install time can change later.
  • Page content is input too. An agent browsing a page through Playwright MCP reads that page’s text. A malicious page, or user-generated content in your own app, could contain instructions. That’s indirect prompt injection, LLM01 in the OWASP LLM Top 10.

A minimum safety baseline for MCP in testing

Risk Control
Malicious or compromised server Install only from trusted sources; pin versions; review tool descriptions
Description changes after approval Pin server versions; re-review on upgrade; prefer clients that show full descriptions
Over-privileged tools Separate agent profiles per task; read-only DB users; scoped CI tokens
Cross-server data exfiltration Don’t combine messaging, email or external-write tools with sensitive data tools in one session
Indirect injection via page content Test against environments with controlled content; require confirmation for writes
Credential exposure Use test accounts; never personal or production credentials

Burp Suite’s new AI features, launched on 31 March as Burp AI, show the security tooling side moving into AI too. Expect AI-specific security testing of agent setups to become a real discipline. We cover that in our security testing tools 2025 roundup.

Other moves in the window

  • Google agreed to acquire Wiz for $32 billion on 18 March, the largest security acquisition in its history. It’s a sign of how central cloud and application security has become.
  • Insomnia 11 shipped on 18 March with project-level Git Sync and external vault integrations, relevant for API testing teams managing secrets.
  • Bruno v2 arrived around 21 March, continuing the shift toward git-native, offline-first API clients. We compare them in Best API testing tools 2025.

How to tell whether it’s working

Agentic tooling is easy to adopt and hard to evaluate, because sessions feel productive whether or not they are. Track a few simple numbers for the first quarter:

  • Findings per exploratory hour. Count defects and usability issues found in MCP-assisted sessions against unassisted exploratory sessions of similar length.
  • Draft-to-commit ratio. Of the Playwright tests the agent drafts, how many survive review and get committed, and how many of those are still stable a month later?
  • Time to diagnose. For failing CI tests, compare triage time with and without agent-assisted debugging.
  • Incidents and near-misses. Any case of an agent taking an unintended action, even in staging, gets written up like a production incident.

If the first three improve and the fourth stays at zero, expand. If they don’t move, you’ve learned something valuable cheaply. The tooling is free, but your team’s attention isn’t.

Pros and cons of MCP-driven agentic testing

Pros

  • Standard interface: one integration works with many AI clients.
  • Accessibility-snapshot approach is cheap, fast and surfaces a11y issues.
  • Turns exploration into reviewed, deterministic scripts.
  • Combines browser, data, CI and tracker tools in one workflow.

Cons

  • New attack surface: tool poisoning, rug pulls, indirect injection.
  • Easy to over-grant permissions in the excitement of a demo.
  • Non-deterministic sessions aren’t release evidence.
  • Quality depends on the app’s accessibility tree, which is weakest exactly where automation is hardest.

What this means for your team

Try Playwright MCP this sprint, safely. Install it in a coding assistant, point it at staging with a test account, and use it for one exploratory session and one test-drafting exercise. Note where it struggles. Those spots are often accessibility issues.

Keep agents out of the release gate. Use MCP sessions to explore and draft. Commit the resulting Playwright tests and let them gate merges.

Write an MCP policy before adoption spreads. Define allowed servers, version pinning, credential rules and which tool combinations are forbidden in one session. It’s far easier before ten engineers have installed twenty servers each.

Add MCP to your threat model. If your product exposes an MCP server, or uses agents internally, test for tool poisoning and indirect injection like any other input-validation risk.

Invest in your accessibility tree. The single best way to make your app testable by agents is to make it accessible to people. Roles, names and labels pay off three times: for users, for scripted tests and for AI agents.

MCP has done for agentic testing what WebDriver did for browser automation two decades ago. It’s given everyone a common interface. As with WebDriver, the hard parts are still test design, oracles and discipline, now joined by a security model we have to build deliberately.

Further reading on CheckOps