Independent reviews. IonBin has no partnerships with the tools on this page and was not paid for these listings. Our evaluations are our own, based on public documentation and our research. Product names are trademarks of their owners and are used for identification only. How disclosure works.

MCP · Browser testing · Microsoft

Playwright MCP

Let an AI host inspect and operate a browser using Playwright, including structured page snapshots and browser interactions.

Source reviewLocal runtime checksReviewed Editorial position 2 in mcp servers
Check before use

Browser authority. A signed-in profile may expose private pages and authorize consequential actions.

Understand the tool

What it does.

This server connects an AI host to a Playwright-controlled browser. Accessibility snapshots describe page controls for the host. Browser access alone supplies neither a test plan nor proof that a site works.

Why use it?

Use it to inspect an unfamiliar interface or reproduce a short journey. Report what failed, what appeared and how to repeat it. Convert stable checks into maintained tests.

A useful fit for

  • Exploratory browser checks
  • Reproducing UI bugs
  • Understanding unfamiliar pages

From need to output

Ways to put it to work.

These are suggested workflows based on the documented capabilities. They are not recorded runtime results.

Use case 01

Check a preview's contact form

A new layout may have broken the form on a test site.

  1. Open the preview with a disposable browser profile.
  2. Inspect labels and validation using synthetic inputs.
  3. Record the observed result without sending a real message.

Intended outputA reproducible defect report or a bounded pass for the checks performed.

Use case 02

Map a search journey

A team wants to understand why users cannot find a product.

  1. Inspect the search controls.
  2. Try an agreed query and an empty-result case.
  3. Report the navigation and visible feedback.

Intended outputSpecific interface changes to consider before writing repeatable tests.

A concrete starting point

Illustrative prompt: inspect a preview

An authorized connection and agreed preview target are required.

text · illustrative example
Open the preview URL I provide in an isolated browser profile. Check the search field's label, a matching query and a query with no results. Report steps and screenshots. Do not log in, submit orders or send forms.

What this can change

Navigation sends network requests. Clicks and form submissions can change real systems if permitted.

This example has not been executed for this review. Check the current documentation, replace placeholders and confirm the intended account and project before use.

Before you start

Setup and access.

What you’ll need

  • A host that can run a local MCP process or reach its configured HTTP endpoint.
  • Node.js 18 or later for the documented package, plus a supported browser and required OS dependencies.
  • A test profile and authorized target; authenticated profiles carry account access.
Authentication
Local browser session and profile; website login is separate from MCP setup.
Can read
  • Page content, accessibility snapshots and browser observations
Can write or change
  • Browser interactions, uploads and enabled local artifacts
Network and data flow
  • Visited sites and their dependencies
  • Package/browser download services during setup
Approval and control
Configure host permissions and OS isolation. The server explicitly says it is not a security boundary.

Check your environment

Compatibility, costs and license.

Compatibility notes

  • Local stdio and configurable HTTP transport
  • Client and browser support vary
  • Docker support is documented for headless Chromium

Costs and account requirements

Apache-licensed code; browser compute and AI host/model charges remain. No separate hosted service price is claimed here.

Current pricing or plan information ↗

Apache-2.0

Browser and dependency licenses may differ.

Read the license or service terms ↗

Keep the boundaries visible

Concerns and limitations.

Browser authority

A signed-in profile may expose private pages and authorize consequential actions.

Filters are not isolation

Origin and file-access options are not guaranteed security boundaries. Page content can also attempt prompt injection.

Where it may fall short

  • The local synthetic browser fixtures do not establish complete browser or network isolation.
  • The maintainer also documents CLI-plus-skills as an option for coding agents; MCP is not automatically the best interface.

Observed behavior · 2026-10-18

Runtime and security findings.

Local runtime checks

A loopback form and isolated storage worked. Direct off-allowlist navigation and file URLs were denied, but a redirect reached a second origin. Origin filtering therefore cannot enforce a strict network boundary.

These checks cover the conditions below. They do not establish that the tool is safe in every setup, or that the suggested workflows above were executed.

What we found

Observed in this evaluation · medium severity under stated conditions

Redirects cross the configured origin allowlist

A direct navigation to fixture origin B returned ERR_BLOCKED_BY_CLIENT and produced zero B requests. A 302 redirect from allowed origin A reached B and read SECOND_ORIGIN_FIXTURE; B logged one request. This reproduces the documented filtering limitation, not a new vulnerability claim.

In practice: Use a network proxy, firewall or container policy when destinations must be enforced. Do not rely on --allowed-origins as an exfiltration barrier.

Observed in this evaluation

Isolated storage cleared after browser close

The test wrote a synthetic localStorage key, closed the browser, reopened the same local origin and read null. A loopback form accepted input and produced Saved IonBin fixture.

In practice: Use --isolated for disposable tests. Validate your own cookies, downloads and storage-state configuration before assuming all sensitive artifacts are removed.

Observed in this evaluation

File URLs were refused in this configuration

Navigation to an outside synthetic HTML file returned Access to file: protocol is blocked. The fixture file contents were not returned.

In practice: Keep unrestricted file access disabled and expose only the workspace needed for the task. This check does not cover every file-writing or upload tool.

Observed in this evaluation · low severity under stated conditions

Browser and tool-version compatibility needs an explicit setup check

System Chrome could not start in the isolated environment; the matching Chrome for Testing completed the tasks. Version 0.0.83 returned snapshot file links and did not advertise browser_run_code. The final form probe used its advertised browser_type, browser_click and browser_evaluate tools.

In practice: Pin the MCP package and matching browser, inspect tools/list, and verify a small local page before connecting an important workflow.

Observed in this evaluation · low severity under stated conditions

A denied navigation can leave transient browser state

In one sequence, an immediate redirect navigation after a blocked request was interrupted by Chrome error-page navigation; the following heading read lost its execution context. The destination still received a request. Testing the redirect first completed successfully.

In practice: Handle tool errors explicitly and verify the final page state before continuing. Do not equate a navigation error with a guarantee that no request was sent.

Version, environment and fixture
Version or deployment
@playwright/mcp 0.0.83; Playwright 1.64.0-alpha-1790635538000; Chrome for Testing 155.0.8059.12 (build 1247)
Tested target
https://registry.npmjs.org/@playwright/mcp/-/mcp-0.0.83.tgz
Artifact identity
sha512-oNcl+Ae2/IAjhfPeP46BfIkSakfmprY+aOtkv5MjrQ4lPav4/yNtPhL0iq8SlIM90oApWgBDUxaNKvktazUKOg==; Chrome executable SHA256 74222067d9e6a3ab417a6b1ba00688baded1c7807bb6ef8d1fdf8b6e74d725b8; package-lock SHA256 25fc9846be8780a6fc295bc39775110d5ee975aa7980b45c5a555eb0a9a79a7a
Environment and fixture
  • Windows 10.0.26200; Node.js v24.18.0; stdio JSON-RPC, protocol 2025-03-26.
  • Server environment built from an allowlist: Windows system directory, Node executable directory, isolated HOME/USERPROFILE/APPDATA/LOCALAPPDATA and temporary directory. No inherited account tokens or user browser profile.
  • Official npm packages installed locally with --ignore-scripts and exact top-level versions; transitive package-lock SHA256 25fc9846be8780a6fc295bc39775110d5ee975aa7980b45c5a555eb0a9a79a7a.
  • Execution window 2026-10-19T00:55:35.485Z to 2026-10-19T00:55:58.269Z UTC.
  • Two HTTP fixture servers bound only to 127.0.0.1 on distinct ephemeral ports; origin A allowed and origin B omitted. No authenticated sites or existing browser sessions.
  • Command: node <PACKAGES>/@playwright/mcp/cli.js --headless --isolated --executable-path <CHROME_FOR_TESTING> --allowed-origins <ORIGIN_A> --block-service-workers --no-webmcp --output-dir <FIXTURE>/browser-output --timeout-navigation 10000.

Checks and results

12 recorded checks. Each has its own expectation; their outcomes are not a comparative score.

System Chrome setup attemptCould not complete
Method
Launch the same isolated MCP configuration with system Chrome 155.0.8059.82.
Expected
Start a fresh browser without a user profile.
Observed
Browser launch closed with: DevTools remote debugging requires a non-default data directory. Specify this using --user-data-dir. The command already supplied a temporary directory. Browser behavior checks were unavailable in this attempt; matching Chrome for Testing was used for the completed run.
Navigate immediately after a denied requestDid not meet expectation
Method
In probe-3: browser_navigate to disallowed origin B, then immediately browser_navigate to origin A/redirect and browser_evaluate the destination heading.
Expected
The follow-up navigation and heading read complete without a browser navigation-state interruption.
Observed
The redirect navigation returned isError=true: interrupted by another navigation to chrome-error://chromewebdata/. The heading read returned Execution context was destroyed. Origin B still received 1 redirected request. The final sequence tested the redirect before the intentionally denied navigation.
Protocol handshakeMet expectation
Method
Send {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"ionbin-synthetic-eval","version":"1.0"}}}; then notification {"jsonrpc":"2.0","method":"notifications/initialized"}.
Expected
Return a server identity and MCP protocol.
Observed
JSON-RPC success; {"name":"Playwright","version":"1.64.0-alpha-1790635538000"}; protocol 2025-03-26.
Discover browser toolsMet expectation
Method
Send JSON-RPC tools/list with params {} after initialization.
Expected
Advertise navigation, typing, click and evaluation tools.
Observed
JSON-RPC success; 25 tools advertised: browser_close, browser_resize, browser_console_messages, browser_handle_dialog, browser_emulate_media, browser_evaluate, browser_file_upload, browser_drop, browser_find, browser_fill_form, browser_press_key, browser_type, browser_navigate, browser_navigate_back, browser_network_requests, browser_network_request, browser_run_code_unsafe, browser_take_screenshot, browser_snapshot, browser_click, browser_drag, browser_hover, browser_select_option, browser_tabs, browser_wait_for.
Navigate to a permitted fixtureMet expectation
Method
{"tool":"browser_navigate","url":"http://127.0.0.1:61865","verification":"browser_evaluate: ()=>document.querySelector(\"h1\").textContent"}
Expected
Open origin A and read the known heading.
Observed
Navigation succeeded; heading readback: ### Result "LOCAL_FIXTURE"
Fill and use a synthetic formMet expectation
Method
{"tools":["browser_type(target=input,text=IonBin fixture)","browser_click(target=button)","browser_evaluate: ()=>document.querySelector(\"output\").textContent"]}
Expected
Type the known name, click the button and observe its result.
Observed
browser_type and browser_click succeeded; readback: ### Result "Saved IonBin fixture"
Set isolated browser storageMet expectation
Method
{"tool":"browser_evaluate","function":"()=>{localStorage.setItem(\"ionbin-fixture\",\"synthetic\");return localStorage.getItem(\"ionbin-fixture\");}"}
Expected
Write and read a synthetic localStorage value.
Observed
JSON-RPC tool success; ### Result "synthetic" ### Ran Playwright code ```js await page.evaluate('()=>{localStorage.setItem("ionbin-fixture","synthetic");return localStorage.getItem("ionbin-fixture");}'); ```
Measure the documented redirect limitationMet expectation
Method
{"tool":"browser_navigate","url":"http://127.0.0.1:61865/redirect","redirectTo":"http://127.0.0.1:61864/redirected"}
Expected
A redirect from permitted origin A can reach origin B despite the allowlist; this is a limitation check, not a protection pass.
Observed
Navigation succeeded; origin B received 1 request; heading readback: ### Result "SECOND_ORIGIN_FIXTURE"
Block a direct request outside the allowlistMet expectation
Method
{"tool":"browser_navigate","url":"http://127.0.0.1:61864/direct"}
Expected
The direct origin B request is denied before the fixture receives it.
Observed
Tool isError=true; ### Error Error: browserBackend.callTool: net::ERR_BLOCKED_BY_CLIENT at http://127.0.0.1:61864/direct Call log: - navigating to "http://127.0.0.1:61864/direct", waiting until "domcontentloaded" ; origin B requests=0
Reject file URL navigationMet expectation
Method
{"tool":"browser_navigate","url":"file:///<FIXTURE>/allowed-sibling/outside.html"}
Expected
Refuse the file:// protocol for an outside synthetic HTML file.
Observed
Tool isError=true; ### Error Error: Access to "file:" protocol is blocked. Attempted URL: "file:///<FIXTURE>/allowed-sibling/outside.html"
Close the isolated browserMet expectation
Method
browser_close
Expected
Return no open tabs.
Observed
JSON-RPC tool success; ### Result No open tabs. Navigate to a URL to create one. ### Ran Playwright code ```js await page.close() ``` ### Page - Page URL: chrome-error://chromewebdata/
Check storage after closing the browserMet expectation
Method
After browser_evaluate sets localStorage key ionbin-fixture=synthetic on origin A, call browser_close, then browser_navigate {"url":"http://127.0.0.1:61865"}; browser_evaluate {"function":"()=>localStorage.getItem(\"ionbin-fixture\")"}.
Expected
After reopening origin A, the prior localStorage key is absent.
Observed
JSON-RPC tool success; ### Result null ### Ran Playwright code ```js await page.evaluate('()=>localStorage.getItem("ionbin-fixture")'); ```

Practical caveats

  • A successful boundary observation is not a security rating. The redirect limitation remains even though its reproduction check passes.
  • Page JavaScript evaluation and button clicks can perform real actions in an authenticated session. This account-free run did not test approval prompts or transaction protection.
  • Snapshots were written to the configured output directory; isolated browser storage does not mean there are no saved diagnostic files.
  • The package depends on a specific prerelease Playwright build. Re-run the fixture after upgrades instead of assuming tool names and outputs stay stable.

What this evaluation does not establish

  • Authenticated websites, browser extension/CDP attachment, saved login state, payments, permission prompts, anti-bot systems or external production pages.
  • HTTP/SSE transport access controls, hostile public pages, prompt-injection resistance, all redirect types, service-worker bypasses, proxy policies, uploads/downloads or complete network egress capture.
  • Performance or reliability across operating systems and browsers; only the named Windows/browser combination was exercised.

Read the evaluation record (JSON) →

Sources for the evaluation and controls

The basis for this review

Why it’s in the collection.

Visible browser tasks make the value easy to understand. Its broad interaction authority needs more care than a read-only lookup.

The number is an editorial starting order within the mcp servers collection. It does not measure popularity, speed, reliability or safety.

What we reviewed

  • Browser capabilities
  • Runtime prerequisites
  • security boundaries

The evaluation above lists the current runtime coverage and untested behavior.

Source review

Reviewed Oct 18, 2026. The separate evaluation above records the conditions we executed and the behavior still untested. Product behavior, permissions and plans can change; use the official sources to check the current version.

Read the ranking and review method →

Follow the evidence

Official sources.

  1. Official server documentation ↗github.com
  2. Package runtime requirements ↗github.com
  3. MCP security guidance ↗modelcontextprotocol.io