Playwright MCP Server

Playwright MCP Server

Enables browser automation through the MCP protocol, allowing AI agents to control a real browser using accessibility snapshots and natural language commands.

Category
访问服务器

README

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

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

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选