Skip to main content
Glama
muhammadraheel-vd

Playwright MCP Server

Playwright MCP Server — POC with 100+ Test Cases

VentureDive QA Engineering Prepared by: Raheel Imran Date: May 2026


Overview

This Proof of Concept (POC) demonstrates the Playwright MCP Server (@playwright/mcp) used as the browser automation engine for a complete test suite. It includes:

  • A fully functional demo web application — TaskMaster Pro

  • 166 Playwright test cases across 8 feature areas using reusable MCP-style commands

  • A cmd fixture that maps directly to @playwright/mcp tool names

  • A live MCP server demo that connects via @modelcontextprotocol/sdk and drives the browser using real MCP protocol — no external API calls

  • MCP server configuration for Claude Desktop and Claude Code

  • An interactive HTML test report


Related MCP server: mcp-browser-use

Architecture

┌──────────────────────────────────────────────────────────────┐
│                   Playwright MCP POC                         │
│                                                              │
│  ┌───────────────────┐   MCP Protocol    ┌────────────────┐  │
│  │  MCP Client       │◄─────────────────►│ @playwright/mcp│  │
│  │  (run-demo.ts)    │   stdio transport │  Server        │  │
│  └───────────────────┘                   └───────┬────────┘  │
│                                                  │           │
│                                         Playwright Browser   │
│                                                  │           │
│                                         ┌────────▼─────────┐ │
│                                         │ TaskMaster Pro   │ │
│                                         │ localhost:3000   │ │
│                                         └──────────────────┘ │
│                                                              │
│  Playwright Test Runner (166 tests)                          │
│  └── tests/fixtures/browser-commands.ts  ← reusable cmd      │
│      ├── auth.spec.ts          (25 tests)                    │
│      ├── navigation.spec.ts    (20 tests)                    │
│      ├── dashboard.spec.ts     (12 tests)                    │
│      ├── tasks.spec.ts         (45 tests)                    │
│      ├── categories.spec.ts    (14 tests)                    │
│      ├── profile.spec.ts       (17 tests)                    │
│      ├── settings.spec.ts      (17 tests)                    │
│      └── ui-components.spec.ts (16 tests)                    │
└──────────────────────────────────────────────────────────────┘

Quick Start

1. Install dependencies

npm install
npx playwright install chromium

2. Start the demo app

npm run dev
# → http://localhost:3000

3. Run all tests and generate HTML report

npm test
npm run test:report    # opens playwright-report/index.html

4. Run the MCP server demo (browser driven via MCP protocol)

npm run demo
# Starts @playwright/mcp server, connects as MCP client, runs 10 scenarios

5. Interactive test runner

npm run test:ui

npm Scripts

Script

Description

npm run dev

Start the TaskMaster Pro demo app on port 3000

npm test

Run all 100+ tests (Chromium + Firefox)

npm run test:ui

Open Playwright interactive UI mode

npm run test:report

Open generated HTML report

npm run test:headed

Run tests in headed browser

npm run test:debug

Run tests with Playwright debugger

npm run demo

Run the MCP server demo (real MCP protocol)

npm run mcp:start

Start @playwright/mcp standalone server


Reusable Browser Commands

All tests import from tests/fixtures/browser-commands.ts instead of @playwright/test directly. Command names match @playwright/mcp tool names exactly, making the test code portable to any MCP client.

import { test, expect } from './fixtures/browser-commands';

test('example', async ({ cmd }) => {
  await cmd.browser_navigate('/login.html');
  await cmd.browser_type('email-input', 'testuser@test.com');
  await cmd.browser_type('password-input', 'Test@123');
  await cmd.browser_click('login-btn');
  await cmd.browser_expect_url(/dashboard/);
  await cmd.browser_take_screenshot('login-success.png');
});

Full command reference

Command

MCP Tool

Description

cmd.browser_navigate(url)

browser_navigate

Navigate to URL

cmd.browser_navigate_back()

browser_navigate_back

Go back in history

cmd.browser_click(testId)

browser_click

Click element by data-testid

cmd.browser_type(testId, text)

browser_type

Fill input field

cmd.browser_clear_and_type(testId, text)

browser_type

Clear then fill

cmd.browser_select_option(testId, value)

browser_select_option

Select dropdown option

cmd.browser_check(testId)

browser_click

Check a checkbox

cmd.browser_uncheck(testId)

browser_click

Uncheck a checkbox

cmd.browser_take_screenshot(filename?)

browser_take_screenshot

Capture screenshot

cmd.browser_get_url()

Get current URL

cmd.browser_get_text(testId)

Get element text

cmd.browser_get_value(testId)

Get input value

cmd.browser_is_visible(testId)

browser_snapshot

Returns boolean

cmd.browser_is_checked(testId)

browser_snapshot

Returns boolean

cmd.browser_count(testId)

browser_snapshot

Count elements

cmd.browser_wait_for(testId, state?)

browser_wait_for

Wait for element

cmd.browser_wait_for_url(pattern)

Wait for URL

cmd.browser_set_storage(key, value)

— (fixture-only)

Set localStorage via page.evaluate

cmd.browser_evaluate(fn)

— (fixture-only)

Run JS via page.evaluate

cmd.browser_expect_url(pattern)

Assert current URL

cmd.browser_expect_visible(testId)

Assert visible

cmd.browser_expect_hidden(testId)

Assert hidden

cmd.browser_expect_text(testId, text)

Assert text content

cmd.browser_expect_count(testId, n)

Assert element count

cmd.browser_expect_value(testId, val)

Assert input value

cmd.browser_expect_checked(testId)

Assert checkbox state

cmd.browser_expect_disabled(testId)

Assert disabled

cmd.browser_expect_attr(testId, attr, val)

Assert attribute


Demo App — TaskMaster Pro

A fully self-contained web app using localStorage for all data persistence.

Page

URL

Features

Login

/login.html

Form validation, password toggle, remember-me

Register

/register.html

Password strength, validation

Dashboard

/dashboard.html

Stats, recent tasks, quick-add

Tasks

/tasks.html

CRUD, filter, search, sort, bulk actions

Categories

/tasks.html#categories

Create, edit, delete categories

Profile

/profile.html

Edit name, avatar, change password

Settings

/settings.html

Theme, notifications, language, export

404

/404.html

Error page

Default test credentials:

Email

Password

Role

testuser@test.com

Test@123

Test User

admin@test.com

Admin@123

Admin User

Pre-seeded data: 5 tasks (3 active, 2 completed) and 4 categories.

MCP Tools provided by @playwright/mcp

See the full categorized reference in MCP Server Setup → Available MCP tools below. Key tools used in this demo app:

Tool

Description

browser_navigate

Navigate to a URL

browser_snapshot

Get accessibility tree — returns ARIA refs for click/type targets

browser_click

Click an element by ARIA ref

browser_type

Type text into a focused field

browser_fill_form

Fill multiple form fields in one call

browser_select_option

Select a dropdown value

browser_take_screenshot

Capture the current page as an image

browser_localstorage_set

Write a localStorage key (used for fast auth seeding)

browser_evaluate

Evaluate JavaScript on the page

browser_wait_for

Wait for an element or condition

browser_network_requests

Inspect captured network traffic

browser_route

Mock API responses for isolated testing

browser_tabs

List, open, close, or switch tabs

browser_close

Close the browser


MCP Server Setup

@playwright/mcp exposes browser automation as MCP tools so any MCP-compatible client (Claude Code, Claude Desktop, VS Code, Cursor, Windsurf) can drive a real browser with no screenshots or vision models — just accessibility snapshots.

Claude Code (project-level)

A .mcp.json file is included at the project root. Claude Code picks it up automatically when you open this directory:

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

Or install it manually via the CLI:

claude mcp add playwright npx @playwright/mcp@latest

Claude Desktop

Add the following to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

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

VS Code

One-liner via the VS Code CLI:

code --add-mcp '{"name":"playwright","command":"npx","args":["@playwright/mcp@latest"]}'

Or use the included .vscode/mcp.json — VS Code with the Copilot extension picks it up automatically:

{
  "servers": {
    "playwright": {
      "type": "stdio",
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}

Cursor / Windsurf

Add the same block under mcpServers in their respective settings files.

Configuration options

Append flags to the args array to customise the server:

Flag

Effect

--headless

Run browser without a visible window (default: headed)

--browser <browser>

Browser to use: chrome, firefox, webkit, msedge (default: Chromium)

--isolated

Keep browser profile in memory; do not persist to disk

--port <n>

Expose the server over HTTP/SSE instead of stdio

--host <host>

Host to bind to (default: localhost; use 0.0.0.0 for all interfaces)

--vision

Use screenshots instead of accessibility snapshots (requires vision model)

--caps <caps>

Comma-separated capability subset: tabs,pdf,history,wait,files,install

--device <device>

Emulate a device, e.g. "iPhone 15"

--viewport-size <size>

Set viewport, e.g. "1280, 720"

--user-agent <ua>

Override the browser user-agent string

--storage-state <path>

Load saved auth state (cookies/localStorage) from a JSON file

--save-trace

Save a Playwright Trace of the session to --output-dir

--output-dir <path>

Directory for screenshots, PDFs, and traces

--proxy-server <proxy>

Route traffic through a proxy, e.g. http://myproxy:3128

--no-sandbox

Disable the browser sandbox (useful in some CI environments)

--extension

Connect to an existing browser tab instead of launching a new browser

--config <path>

Load advanced settings from a JSON config file

Example — headless Firefox in isolated mode:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest", "--headless", "--browser=firefox", "--isolated"]
    }
  }
}

Standalone server (HTTP transport)

For headless/CI environments where stdio is not suitable:

npx @playwright/mcp@latest --port 8931

Then point your MCP client at http://localhost:8931/mcp using the url form:

{
  "mcpServers": {
    "playwright": {
      "url": "http://localhost:8931/mcp"
    }
  }
}

Available MCP tools

Navigation

Tool

Description

browser_navigate

Navigate to a URL

browser_navigate_back / browser_navigate_forward

Browser history navigation

browser_reload

Reload the current page

Interaction

Tool

Description

browser_click

Click an element by ARIA ref

browser_check / browser_uncheck

Check or uncheck a checkbox

browser_type

Type text into a focused field

browser_press_sequentially

Type text one character at a time (for masked fields)

browser_fill_form

Fill multiple form fields by their labels in one call

browser_select_option

Select a dropdown value

browser_hover

Hover over an element

browser_drag / browser_drop

Drag-and-drop between elements

browser_press_key / browser_keydown / browser_keyup

Keyboard key events

browser_handle_dialog

Accept or dismiss browser dialogs

browser_file_upload

Upload a file to a file input

browser_mouse_click_xy / browser_mouse_move_xy / browser_mouse_drag_xy

Pixel-precise mouse control

browser_mouse_down / browser_mouse_up / browser_mouse_wheel

Low-level mouse events

Inspection & Assertions

Tool

Description

browser_snapshot

Get the page accessibility tree — primary way to read elements and obtain ARIA refs

browser_take_screenshot

Capture the current page as an image

browser_annotate

Capture a screenshot with annotated highlights

browser_highlight / browser_hide_highlight

Visually highlight an element on the page

browser_generate_locator

Generate a Playwright locator for a given element

browser_verify_element_visible

Assert an element is visible

browser_verify_text_visible

Assert specific text is visible on the page

browser_verify_list_visible

Assert a list of items is visible

browser_verify_value

Assert an element's value

browser_wait_for

Wait for an element or network condition

Storage

Tool

Description

browser_evaluate

Evaluate a JavaScript expression on the page

browser_localstorage_get / browser_localstorage_set / browser_localstorage_list

Read/write localStorage

browser_localstorage_clear / browser_localstorage_delete

Remove localStorage items

browser_sessionstorage_get / browser_sessionstorage_set / browser_sessionstorage_list

sessionStorage CRUD

browser_sessionstorage_clear / browser_sessionstorage_delete

Remove sessionStorage items

browser_cookie_get / browser_cookie_set / browser_cookie_list

Read/write cookies

browser_cookie_clear / browser_cookie_delete

Remove cookies

browser_storage_state

Export current cookies and storage to a file

browser_set_storage_state

Import previously saved storage state

Network

Tool

Description

browser_network_requests

List all captured network requests

browser_network_request

Get details for a single network request

browser_network_clear

Clear the captured request log

browser_network_state_set

Simulate online/offline/throttled network conditions

browser_route

Mock requests matching a URL pattern with a custom response

browser_route_list

List active route mocks

browser_unroute

Remove a route mock

Tabs

Tool

Description

browser_tabs

List, create (new), close, or switch to a tab by index

Console

Tool

Description

browser_console_messages

Get browser console output

browser_console_clear

Clear the console message log

Recording & Tracing

Tool

Description

browser_start_tracing / browser_stop_tracing

Record a Playwright Trace

browser_start_video / browser_stop_video / browser_video_chapter

Record session video

browser_pdf_save

Save the current page as a PDF

Misc

Tool

Description

browser_resize

Resize the browser window

browser_get_config

Get the current server configuration

browser_run_code_unsafe

Execute an arbitrary Playwright script (RCE-equivalent; trusted clients only)

browser_close

Close the browser

How accessibility snapshots work: Instead of returning a screenshot, browser_snapshot returns a structured text tree of all visible elements with their roles, labels, and unique [ref=…] identifiers. LLMs reference these ids when calling browser_click or browser_type — no vision model required.

Verify the server is working

# Start the demo app first
npm run dev

# Then run the MCP demo (connects via stdio and runs 10 browser scenarios)
npm run demo

MCP Demo (demo/)

demo/run-demo.ts connects to @playwright/mcp via real MCP stdio protocol using @modelcontextprotocol/sdk. It runs 10 browser scenarios with no external API dependencies.

npm run demo
╔══════════════════════════════════════════════════════════╗
║  Playwright MCP Server — Direct MCP Protocol Demo       ║
╚══════════════════════════════════════════════════════════╝

Target: http://localhost:3000
Transport: stdio (@playwright/mcp subprocess)

Connecting to @playwright/mcp server…
Connected.

Available MCP tools (14):
  • browser_navigate
  • browser_snapshot
  • browser_click
  …

S01  ✓ PASS  Login page loads via MCP browser_navigate
S02  ✓ PASS  Fill login form using browser_type
S03  ✓ PASS  Capture login page screenshot
…

Test Coverage

Area

Tests

TC Range

Authentication

25

TC001–TC025

Navigation

20

TC026–TC045

Dashboard

12

TC046–TC057

Task Management

45

TC058–TC102

Categories

14

TC103–TC116

Profile

17

TC117–TC133

Settings

17

TC134–TC150

UI Components

16

TC151–TC166

Total

166


Project Structure

.
├── demo-app/
│   ├── server.js                  Express static file server (port 3000)
│   └── public/
│       ├── index.html             Entry point (redirect)
│       ├── login.html
│       ├── register.html
│       ├── dashboard.html
│       ├── tasks.html             Tasks + Categories
│       ├── profile.html
│       ├── settings.html
│       ├── 404.html
│       ├── css/styles.css
│       └── js/utils.js            Shared helpers + seed data
├── tests/
│   ├── fixtures/
│   │   └── browser-commands.ts    Reusable MCP-style command fixture
│   ├── helpers/
│   │   └── auth.helper.ts         Fast localStorage-based auth setup
│   ├── auth.spec.ts               TC001–TC025
│   ├── navigation.spec.ts         TC026–TC045
│   ├── dashboard.spec.ts          TC046–TC057
│   ├── tasks.spec.ts              TC058–TC102
│   ├── categories.spec.ts         TC103–TC116
│   ├── profile.spec.ts            TC117–TC133
│   ├── settings.spec.ts           TC134–TC150
│   └── ui-components.spec.ts      TC151–TC166
├── demo/
│   ├── scenarios.ts               10 MCP test scenario definitions
│   └── run-demo.ts                MCP client demo (real MCP protocol)
├── playwright-report/             Generated HTML report (after npm test)
├── playwright.config.ts
├── package.json
└── tsconfig.json

Key Design Decisions

Decision

Rationale

data-testid attributes on all elements

Tests don't break when CSS or text changes

Reusable browser-commands.ts fixture

Command names match @playwright/mcp tools — tests are portable

loginViaStorage() helper

Sets session via localStorage.setItem directly — 10× faster than UI login

Sequential workers (workers: 1)

Prevents localStorage conflicts between parallel tests

retries: 1 locally, retries: 2 on CI

Handles transient timing issues without masking real failures

No external API dependencies

MCP demo uses @playwright/mcp directly via stdio protocol


F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/muhammadraheel-vd/Playwright_mcp_server_poc_with_plus_100_tc'

If you have feedback or need assistance with the MCP directory API, please join our Discord server