npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@testnexus_ai/playwright-mcp-extended

v0.1.0

Published

Playwright MCP Extended - Enhanced Browser Automation MCP Server with visual element highlighting

Readme

Playwright MCP Extended

An extended Model Context Protocol (MCP) server that provides browser automation capabilities using Playwright. This server enables LLMs to interact with web pages through structured accessibility snapshots, bypassing the need for screenshots or visually-tuned models.

Based on Microsoft's Playwright MCP with extended features and customizations by TestNexus AI.

Key Features

  • Fast and lightweight. Uses Playwright's accessibility tree, not pixel-based input.
  • LLM-friendly. No vision models needed, operates purely on structured data.
  • Deterministic tool application. Avoids ambiguity common with screenshot-based approaches.
  • Visual element highlighting. Shows users what the LLM is about to interact with before each action.

Visual Highlighting (Extended Feature)

Playwright MCP Extended includes visual element highlighting that shows users what the LLM is about to do before each action is performed. When enabled (default), elements are highlighted with a red border and an action indicator appears showing the action type and target.

Highlighted Tools:

  • browser_click - Shows "Click" indicator before clicking
  • browser_type - Shows "Type" indicator before typing
  • browser_fill_form - Shows "Fill form" indicator before filling each field
  • browser_select_option - Shows "Select" indicator before selecting

Disabling Highlighting:

To disable highlighting for faster automation (e.g., in CI environments):

{
  "mcpServers": {
    "playwright-extended": {
      "command": "npx",
      "args": [
        "@testnexus_ai/playwright-mcp-extended@latest",
        "--no-highlight"
      ]
    }
  }
}

Or set the environment variable: PLAYWRIGHT_MCP_NO_HIGHLIGHT=1

Requirements

  • Node.js 18 or newer
  • VS Code, Cursor, Windsurf, Claude Desktop, or any other MCP client

Getting started

Install Playwright MCP Extended with your client.

Standard config:

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

Use the Claude Code CLI to add Playwright MCP Extended:

claude mcp add playwright-extended npx @testnexus_ai/playwright-mcp-extended@latest

Follow the MCP install guide, use the standard config above.

Go to Cursor Settings -> MCP -> Add new MCP Server. Name to your liking, use command type with the command npx @testnexus_ai/playwright-mcp-extended@latest. You can also verify config or add command like arguments via clicking Edit.

Follow the MCP install guide, use the standard config above. You can also install using the VS Code CLI:

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

Configuration

Playwright MCP Extended supports the following arguments. They can be provided in the JSON configuration above, as a part of the "args" list:

| Option | Description | |--------|-------------| | --no-highlight | disable visual element highlighting before tool actions. By default, elements are highlighted with a red border before actions like click, type, and form fill.env PLAYWRIGHT_MCP_NO_HIGHLIGHT | | --allowed-hosts <hosts...> | comma-separated list of hosts this server is allowed to serve from. Defaults to the host the server is bound to. Pass '*' to disable the host check.env PLAYWRIGHT_MCP_ALLOWED_HOSTS | | --allowed-origins | semicolon-separated list of TRUSTED origins to allow the browser to request. Default is to allow all. Important: does not serve as a security boundary and does not affect redirects.env PLAYWRIGHT_MCP_ALLOWED_ORIGINS | | --allow-unrestricted-file-access | allow access to files outside of the workspace roots. Also allows unrestricted access to file:// URLs. By default access to file system is restricted to workspace root directories (or cwd if no roots are configured) only, and navigation to file:// URLs is blocked.env PLAYWRIGHT_MCP_ALLOW_UNRESTRICTED_FILE_ACCESS | | --blocked-origins | semicolon-separated list of origins to block the browser from requesting. Blocklist is evaluated before allowlist. If used without the allowlist, requests not matching the blocklist are still allowed. Important: does not serve as a security boundary and does not affect redirects.env PLAYWRIGHT_MCP_BLOCKED_ORIGINS | | --block-service-workers | block service workersenv PLAYWRIGHT_MCP_BLOCK_SERVICE_WORKERS | | --browser | browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.env PLAYWRIGHT_MCP_BROWSER | | --caps | comma-separated list of additional capabilities to enable, possible values: vision, pdf, devtools.env PLAYWRIGHT_MCP_CAPS | | --cdp-endpoint | CDP endpoint to connect to.env PLAYWRIGHT_MCP_CDP_ENDPOINT | | --cdp-header <headers...> | CDP headers to send with the connect request, multiple can be specified.env PLAYWRIGHT_MCP_CDP_HEADER | | --codegen | specify the language to use for code generation, possible values: "typescript", "none". Default is "typescript".env PLAYWRIGHT_MCP_CODEGEN | | --config | path to the configuration file.env PLAYWRIGHT_MCP_CONFIG | | --console-level | level of console messages to return: "error", "warning", "info", "debug". Each level includes the messages of more severe levels.env PLAYWRIGHT_MCP_CONSOLE_LEVEL | | --device | device to emulate, for example: "iPhone 15"env PLAYWRIGHT_MCP_DEVICE | | --executable-path | path to the browser executable.env PLAYWRIGHT_MCP_EXECUTABLE_PATH | | --extension | Connect to a running browser instance (Edge/Chrome only). Requires the "Playwright MCP Extended Bridge" browser extension to be installed.env PLAYWRIGHT_MCP_EXTENSION | | --grant-permissions <permissions...> | List of permissions to grant to the browser context, for example "geolocation", "clipboard-read", "clipboard-write".env PLAYWRIGHT_MCP_GRANT_PERMISSIONS | | --headless | run browser in headless mode, headed by defaultenv PLAYWRIGHT_MCP_HEADLESS | | --host | host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.env PLAYWRIGHT_MCP_HOST | | --ignore-https-errors | ignore https errorsenv PLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS | | --init-page <path...> | path to TypeScript file to evaluate on Playwright page objectenv PLAYWRIGHT_MCP_INIT_PAGE | | --init-script <path...> | path to JavaScript file to add as an initialization script. The script will be evaluated in every page before any of the page's scripts. Can be specified multiple times.env PLAYWRIGHT_MCP_INIT_SCRIPT | | --isolated | keep the browser profile in memory, do not save it to disk.env PLAYWRIGHT_MCP_ISOLATED | | --image-responses | whether to send image responses to the client. Can be "allow" or "omit", Defaults to "allow".env PLAYWRIGHT_MCP_IMAGE_RESPONSES | | --no-sandbox | disable the sandbox for all process types that are normally sandboxed.env PLAYWRIGHT_MCP_NO_SANDBOX | | --output-dir | path to the directory for output files.env PLAYWRIGHT_MCP_OUTPUT_DIR | | --output-mode | whether to save snapshots, console messages, network logs to a file or to the standard output. Can be "file" or "stdout". Default is "stdout".env PLAYWRIGHT_MCP_OUTPUT_MODE | | --port | port to listen on for SSE transport.env PLAYWRIGHT_MCP_PORT | | --proxy-bypass | comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"env PLAYWRIGHT_MCP_PROXY_BYPASS | | --proxy-server | specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"env PLAYWRIGHT_MCP_PROXY_SERVER | | --sandbox | enable the sandbox for all process types that are normally not sandboxed.env PLAYWRIGHT_MCP_SANDBOX | | --save-session | Whether to save the session into the output directory.env PLAYWRIGHT_MCP_SAVE_SESSION | | --save-trace | Whether to save the Playwright Trace of the session into the output directory.env PLAYWRIGHT_MCP_SAVE_TRACE | | --save-video | Whether to save the video of the session into the output directory. For example "--save-video=800x600"env PLAYWRIGHT_MCP_SAVE_VIDEO | | --secrets | path to a file containing secrets in the dotenv formatenv PLAYWRIGHT_MCP_SECRETS | | --shared-browser-context | reuse the same browser context between all connected HTTP clients.env PLAYWRIGHT_MCP_SHARED_BROWSER_CONTEXT | | --snapshot-mode | when taking snapshots for responses, specifies the mode to use. Can be "incremental", "full", or "none". Default is incremental.env PLAYWRIGHT_MCP_SNAPSHOT_MODE | | --storage-state | path to the storage state file for isolated sessions.env PLAYWRIGHT_MCP_STORAGE_STATE | | --test-id-attribute | specify the attribute to use for test ids, defaults to "data-testid"env PLAYWRIGHT_MCP_TEST_ID_ATTRIBUTE | | --timeout-action | specify action timeout in milliseconds, defaults to 5000msenv PLAYWRIGHT_MCP_TIMEOUT_ACTION | | --timeout-navigation | specify navigation timeout in milliseconds, defaults to 60000msenv PLAYWRIGHT_MCP_TIMEOUT_NAVIGATION | | --user-agent | specify user agent stringenv PLAYWRIGHT_MCP_USER_AGENT | | --user-data-dir | path to the user data directory. If not specified, a temporary directory will be created.env PLAYWRIGHT_MCP_USER_DATA_DIR | | --viewport-size | specify browser viewport size in pixels, for example "1280x720"env PLAYWRIGHT_MCP_VIEWPORT_SIZE |

User profile

You can run Playwright MCP Extended with persistent profile like a regular browser (default), in isolated contexts for testing sessions, or connect to your existing browser using the browser extension.

Persistent profile

All the logged in information will be stored in the persistent profile, you can delete it between sessions if you'd like to clear the offline state. Persistent profile is located at the following locations and you can override it with the --user-data-dir argument.

# Windows
%USERPROFILE%\AppData\Local\ms-playwright\mcp-{channel}-profile

# macOS
- ~/Library/Caches/ms-playwright/mcp-{channel}-profile

# Linux
- ~/.cache/ms-playwright/mcp-{channel}-profile

Isolated

In the isolated mode, each session is started in the isolated profile. Every time you ask MCP to close the browser, the session is closed and all the storage state for this session is lost. You can provide initial storage state to the browser via the config's contextOptions or via the --storage-state argument.

{
  "mcpServers": {
    "playwright-extended": {
      "command": "npx",
      "args": [
        "@testnexus_ai/playwright-mcp-extended@latest",
        "--isolated",
        "--storage-state={path/to/storage.json}"
      ]
    }
  }
}

Browser Extension

The Playwright MCP Extended Chrome Extension allows you to connect to existing browser tabs and leverage your logged-in sessions and browser state. See packages/extension/README.md for installation and setup instructions.

Configuration file

Playwright MCP Extended can be configured using a JSON configuration file. You can specify the configuration file using the --config command line option:

npx @testnexus_ai/playwright-mcp-extended@latest --config path/to/config.json
{
  /**
   * The browser to use.
   */
  browser?: {
    /**
     * The type of browser to use.
     */
    browserName?: 'chromium' | 'firefox' | 'webkit';

    /**
     * Keep the browser profile in memory, do not save it to disk.
     */
    isolated?: boolean;

    /**
     * Path to a user data directory for browser profile persistence.
     * Temporary directory is created by default.
     */
    userDataDir?: string;

    /**
     * Launch options passed to
     * @see https://playwright.dev/docs/api/class-browsertype#browser-type-launch-persistent-context
     *
     * This is useful for settings options like `channel`, `headless`, `executablePath`, etc.
     */
    launchOptions?: playwright.LaunchOptions;

    /**
     * Context options for the browser context.
     *
     * This is useful for settings options like `viewport`.
     */
    contextOptions?: playwright.BrowserContextOptions;

    /**
     * Chrome DevTools Protocol endpoint to connect to an existing browser instance in case of Chromium family browsers.
     */
    cdpEndpoint?: string;

    /**
     * CDP headers to send with the connect request.
     */
    cdpHeaders?: Record<string, string>;

    /**
     * Timeout in milliseconds for connecting to CDP endpoint. Defaults to 30000 (30 seconds). Pass 0 to disable timeout.
     */
    cdpTimeout?: number;

    /**
     * Remote endpoint to connect to an existing Playwright server.
     */
    remoteEndpoint?: string;

    /**
     * Paths to TypeScript files to add as initialization scripts for Playwright page.
     */
    initPage?: string[];

    /**
     * Paths to JavaScript files to add as initialization scripts.
     * The scripts will be evaluated in every page before any of the page's scripts.
     */
    initScript?: string[];
  },

  server?: {
    /**
     * The port to listen on for SSE or MCP transport.
     */
    port?: number;

    /**
     * The host to bind the server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.
     */
    host?: string;

    /**
     * The hosts this server is allowed to serve from. Defaults to the host server is bound to.
     * This is not for CORS, but rather for the DNS rebinding protection.
     */
    allowedHosts?: string[];
  },

  /**
   * List of enabled tool capabilities. Possible values:
   *   - 'core': Core browser automation features.
   *   - 'pdf': PDF generation and manipulation.
   *   - 'vision': Coordinate-based interactions.
   */
  capabilities?: ToolCapability[];

  /**
   * Whether to save the session into the output directory.
   */
  saveSession?: boolean;

  /**
   * Whether to save the Playwright trace of the session into the output directory.
   */
  saveTrace?: boolean;

  /**
   * If specified, saves the Playwright video of the session into the output directory.
   */
  saveVideo?: {
    width: number;
    height: number;
  };

  /**
   * Reuse the same browser context between all connected HTTP clients.
   */
  sharedBrowserContext?: boolean;

  /**
   * Secrets are used to prevent LLM from getting sensitive data while
   * automating scenarios such as authentication.
   * Prefer the browser.contextOptions.storageState over secrets file as a more secure alternative.
   */
  secrets?: Record<string, string>;

  /**
   * The directory to save output files.
   */
  outputDir?: string;

  /**
   * Whether to save snapshots, console messages, network logs and other session logs to a file or to the standard output. Defaults to "stdout".
   */
  outputMode?: 'file' | 'stdout';

  console?: {
    /**
     * The level of console messages to return. Each level includes the messages of more severe levels. Defaults to "info".
     */
    level?: 'error' | 'warning' | 'info' | 'debug';
  },

  network?: {
    /**
     * List of origins to allow the browser to request. Default is to allow all. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
     */
    allowedOrigins?: string[];

    /**
     * List of origins to block the browser to request. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
     */
    blockedOrigins?: string[];
  };

  /**
   * Specify the attribute to use for test ids, defaults to "data-testid".
   */
  testIdAttribute?: string;

  timeouts?: {
    /*
     * Configures default action timeout: https://playwright.dev/docs/api/class-page#page-set-default-timeout. Defaults to 5000ms.
     */
    action?: number;

    /*
     * Configures default navigation timeout: https://playwright.dev/docs/api/class-page#page-set-default-navigation-timeout. Defaults to 60000ms.
     */
    navigation?: number;
  };

  /**
   * Whether to send image responses to the client. Can be "allow", "omit", or "auto". Defaults to "auto", which sends images if the client can display them.
   */
  imageResponses?: 'allow' | 'omit';

  snapshot?: {
    /**
     * When taking snapshots for responses, specifies the mode to use.
     */
    mode?: 'incremental' | 'full' | 'none';
  };

  /**
   * Whether to allow file uploads from anywhere on the file system.
   * By default (false), file uploads are restricted to paths within the MCP roots only.
   */
  allowUnrestrictedFileAccess?: boolean;

  /**
   * Specify the language to use for code generation.
   */
  codegen?: 'typescript' | 'none';
}

Standalone MCP server

When running headed browser on system w/o display or from worker processes of the IDEs, run the MCP server from environment with the DISPLAY and pass the --port flag to enable HTTP transport.

npx @testnexus_ai/playwright-mcp-extended@latest --port 8931

And then in MCP client config, set the url to the HTTP endpoint:

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

NOTE: The Docker implementation only supports headless chromium at the moment.

{
  "mcpServers": {
    "playwright-extended": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "--init", "--pull=always", "testnexusai/playwright-mcp-extended"]
    }
  }
}

Or If you prefer to run the container as a long-lived service instead of letting the MCP client spawn it, use:

docker run -d -i --rm --init --pull=always \
  --entrypoint node \
  --name playwright-mcp-extended \
  -p 8931:8931 \
  testnexusai/playwright-mcp-extended \
  cli.js --headless --browser chromium --no-sandbox --port 8931

The server will listen on host port 8931 and can be reached by any MCP client.

You can build the Docker image yourself.

docker build -t testnexusai/playwright-mcp-extended .
import http from 'http';

import { createConnection } from '@testnexus_ai/playwright-mcp-extended';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';

http.createServer(async (req, res) => {
  // ...

  // Creates a headless Playwright MCP Extended server with SSE transport
  const connection = await createConnection({ browser: { launchOptions: { headless: true } } });
  const transport = new SSEServerTransport('/messages', res);
  await connection.connect(transport);

  // ...
});

Tools

  • browser_click

    • Title: Click
    • Description: Perform click on a web page
    • Parameters:
      • element (string, optional): Human-readable element description used to obtain permission to interact with the element
      • ref (string): Exact target element reference from the page snapshot
      • doubleClick (boolean, optional): Whether to perform a double click instead of a single click
      • button (string, optional): Button to click, defaults to left
      • modifiers (array, optional): Modifier keys to press
    • Read-only: false
  • browser_close

    • Title: Close browser
    • Description: Close the page
    • Parameters: None
    • Read-only: false
  • browser_console_messages

    • Title: Get console messages
    • Description: Returns all console messages
    • Read-only: true
  • browser_drag

    • Title: Drag mouse
    • Description: Perform drag and drop between two elements
    • Read-only: false
  • browser_evaluate

    • Title: Evaluate JavaScript
    • Description: Evaluate JavaScript expression on page or element
    • Read-only: false
  • browser_file_upload

    • Title: Upload files
    • Description: Upload one or multiple files
    • Read-only: false
  • browser_fill_form

    • Title: Fill form
    • Description: Fill multiple form fields
    • Read-only: false
  • browser_handle_dialog

    • Title: Handle a dialog
    • Description: Handle a dialog
    • Read-only: false
  • browser_hover

    • Title: Hover mouse
    • Description: Hover over element on page
    • Read-only: false
  • browser_navigate

    • Title: Navigate to a URL
    • Description: Navigate to a URL
    • Read-only: false
  • browser_navigate_back

    • Title: Go back
    • Description: Go back to the previous page in the history
    • Read-only: false
  • browser_network_requests

    • Title: List network requests
    • Description: Returns all network requests since loading the page
    • Read-only: true
  • browser_press_key

    • Title: Press a key
    • Description: Press a key on the keyboard
    • Read-only: false
  • browser_resize

    • Title: Resize browser window
    • Description: Resize the browser window
    • Read-only: false
  • browser_run_code

    • Title: Run Playwright code
    • Description: Run Playwright code snippet
    • Read-only: false
  • browser_select_option

    • Title: Select option
    • Description: Select an option in a dropdown
    • Read-only: false
  • browser_snapshot

    • Title: Page snapshot
    • Description: Capture accessibility snapshot of the current page, this is better than screenshot
    • Read-only: true
  • browser_take_screenshot

    • Title: Take a screenshot
    • Description: Take a screenshot of the current page
    • Read-only: true
  • browser_type

    • Title: Type text
    • Description: Type text into editable element
    • Read-only: false
  • browser_wait_for

    • Title: Wait for
    • Description: Wait for text to appear or disappear or a specified time to pass
    • Read-only: false
  • browser_tabs
    • Title: Manage tabs
    • Description: List, create, close, or select a browser tab.
    • Read-only: false
  • browser_install
    • Title: Install the browser specified in the config
    • Description: Install the browser specified in the config. Call this if you get an error about the browser not being installed.
    • Read-only: false
  • browser_mouse_click_xy - Click at coordinates
  • browser_mouse_down - Press mouse down
  • browser_mouse_drag_xy - Drag to coordinates
  • browser_mouse_move_xy - Move mouse
  • browser_mouse_up - Release mouse
  • browser_mouse_wheel - Scroll
  • browser_pdf_save - Save page as PDF
  • browser_generate_locator - Generate locator for element
  • browser_verify_element_visible - Verify element is visible
  • browser_verify_list_visible - Verify list is visible
  • browser_verify_text_visible - Verify text is visible
  • browser_verify_value - Verify element value

License

Apache-2.0