Skip to main content
Glama
mcp-agent-playwright

mcp-agent-playwright

mcp-agent-playwright

Playwright browser automation for AI agents, as a local MCP server. Navigate, read accessibility snapshots, click, type, screenshot, and evaluate JavaScript in a real browser.

Build to be called by any MCP-aware agent harness (opencode, Claude, LM Studio agents, etc.) over stdio. Works in two modes:

  • Own browser (default) — lazily launches a fresh Playwright browser on first use and keeps it alive between tool calls.

  • CDP attach — set MCP_PLAYWRIGHT_CDP_ENDPOINT to connect over Chrome DevTools Protocol to an already-running browser (Brave, Chrome, …). The server adopts the existing tabs and detaches on close — it never shuts the user's browser down.

Tool surface

Domain

Tools

Navigation

browser_navigate, browser_go_back, browser_go_forward

Page state

browser_status, browser_snapshot, browser_console_messages

Interaction

browser_click, browser_type, browser_press_key, browser_hover, browser_select_option

Tabs

browser_tabs, browser_tab_new, browser_tab_switch, browser_tab_close

Waiting

browser_wait_for_text, browser_wait_for_timeout

Capture

browser_screenshot

Escape hatch

browser_evaluate

Lifecycle

browser_close

Related MCP server: agentic-browser-mcp

Requirements

  • Python 3.11+

  • uv

Install

git clone <repo-url> mcp_agent_playwright
cd mcp_agent_playwright
uv sync

Install a Playwright browser binary:

uv run playwright install chromium

Usage

Run as an MCP server (stdio — what harnesses expect)

uv run mcp-agent-playwright

Register in an MCP client

{
  "mcpServers": {
    "playwright": {
      "command": "uv",
      "args": ["--project", "/path/to/mcp_agent_playwright", "run", "mcp-agent-playwright"]
    }
  }
}

Attach to a running browser (CDP mode)

Launch your browser with the debugging flag (example: Brave):

Start-Process -FilePath "C:\Program Files\BraveSoftware\Brave-Browser\Application\brave.exe" `
  -ArgumentList '--remote-debugging-port=9222','--remote-allow-origins=*'

Replace the -FilePath with your browser's actual path (Brave, Chrome, Edge, or any Chromium-based browser).

Then set MCP_PLAYWRIGHT_CDP_ENDPOINT when starting the server (or in the MCP client config):

{
  "mcpServers": {
    "playwright": {
      "command": "uv",
      "args": ["--project", "/path/to/mcp_agent_playwright", "run", "mcp-agent-playwright"],
      "env": { "MCP_PLAYWRIGHT_CDP_ENDPOINT": "http://127.0.0.1:9222" }
    }
  }
}

browser_status reports which mode is active (mode: cdp vs mode: own-browser). If the CDP endpoint is configured but unreachable, the server falls back to launching its own browser and says so in the status note.

Workflow

Start with browser_navigate(url), then browser_snapshot to see the page as a numbered accessibility tree. Interact using a [ref] number or a locator string (role=button,name=Submit, css=#id, text=Hello). Always snapshot again after actions.

Configuration reference

Var

Default

Purpose

MCP_PLAYWRIGHT_HEADLESS

1

0 for a visible browser window (own-browser mode)

MCP_PLAYWRIGHT_BROWSER

chromium

firefox or webkit (own-browser mode only)

MCP_PLAYWRIGHT_VIEWPORT

1280,900

Browser viewport

MCP_PLAYWRIGHT_CDP_ENDPOINT

(blank)

CDP URL to attach to instead of launching a browser

MCP_PLAYWRIGHT_SCREENSHOT_DIR

./screenshots

Where browser_screenshot saves files

Development

uv run ruff check .     # lint
uv run pyright          # type check (src + tests, against .venv)
uv run pytest -q        # tests

uv sync installs the dev tooling (pytest, pytest-asyncio, pyright, ruff). The suite has two tiers: plain unit tests that need no browser, and tests marked browser that drive a real headless Chromium. The browser tier needs uv run playwright install chromium once; until then those tests skip rather than fail. CI installs Chromium, so nothing skips there.

License

MIT © 2026 Christof Milius

Available Tools

20 tools
browser_clickB

Click an element: snapshot ref number or locator string.

Inputs: target (required). Returns: result

browser_closeA

Shut down the browser and forget all state (tabs, refs, console log).

In CDP mode this detaches from the attached browser without closing it.

Inputs: no named parameters. Returns: result

browser_console_messagesA

Return recent browser console messages (errors, warnings, logs).

Inputs: level. Returns: result

browser_evaluateA

Run arbitrary JavaScript in the page and return the result.

Example: document.title or ({hrefs: [...document.querySelectorAll('a')].map(a => a.href)}). Use for scraping data the accessibility snapshot cannot express.

Inputs: js (required). Returns: result

browser_go_backA

Navigate the active tab back in history.

Inputs: no named parameters. Returns: result

browser_go_forwardB

Navigate the active tab forward in history.

Inputs: no named parameters. Returns: result

browser_hoverA

Move the mouse cursor over an element (for hover menus/tooltips).

Inputs: target (required). Returns: result

browser_navigateA

Open a URL in the browser. Creates a page if none exists; otherwise navigates the active tab.

Inputs: url (required). Returns: result

browser_press_keyA

Press a keyboard key on the page. For Enter after typing use browser_type(..., enter=True).

Inputs: key (required). Returns: result

browser_screenshotA

Take a screenshot of the current viewport and save it as a PNG file.

Returns the absolute file path and image size. Does NOT show the image to the model — use browser_snapshot for content.

Inputs: filename, full_page. Returns: result

browser_select_optionA

Select an option in a dropdown () by value or label.

Inputs: target (required), values (required). Returns: result

browser_snapshotA

Read the current page as a numbered accessibility tree.

Interactive elements are prefixed with [ref] numbers. Pass a ref to any browser_* tool that accepts a target. Re-run after every action.

Inputs: max_nodes. Returns: result

browser_statusA

Report browser state: current page URL, title, and open tab list.

Use this first if you are unsure whether a browser is running.

Inputs: no named parameters. Returns: result

browser_tab_closeA

Close a browser tab. Defaults to the active tab.

Inputs: index. Returns: result

browser_tab_newB

Open a new browser tab and switch to it.

Inputs: url. Returns: result

browser_tabsA

List open browser tabs with index, title and URL.

Inputs: no named parameters. Returns: result

browser_tab_switchA

Switch to an existing tab by its index from browser_tabs().

Inputs: index (required). Returns: result

browser_typeA

Type text into an input field, replacing its current content.

Inputs: text (required), target (required), enter. Returns: result

browser_wait_for_textA

Wait until a piece of text becomes visible on the page, or the timeout runs out.

Inputs: text (required), timeout. Returns: result

browser_wait_for_timeoutB

Wait a fixed amount of time (page sleeps/progress bars).

Inputs: ms. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 20 tools

    Disambiguation4/5

    Most tools map to distinct, well-separated browser actions like navigate, click, type, and tab management. The main overlap is between browser_status and browser_tabs, both reporting tab information, and between the two wait tools, but their descriptions are clear enough to guide correct selection.

    Naming Consistency4/5

    All tools share a consistent browser_ prefix and mostly use a clear verb-action pattern such as browser_navigate, browser_click, and browser_tab_switch. A few query-style names like browser_status, browser_snapshot, and browser_tabs deviate slightly from strict verb_noun naming, but the pattern remains highly predictable.

    Tool Count4/5

    Twenty tools is on the higher end but appropriate for browser automation, where atomic actions like clicking, typing, waiting, tab management, and screenshotting each need dedicated operations. The set could be slightly consolidated, but no tool feels redundant or out of place.

    Completeness4/5

    The toolset covers the core browser lifecycle well: navigation, interaction, waiting, tab management, JavaScript evaluation, console inspection, screenshots, and shutdown. Missing conveniences like explicit refresh or scroll are minor because browser_evaluate can cover them, so agents should not hit dead ends.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables MCP clients to automate a real Chrome browser via Playwright, supporting session sharing and tools for navigation, clicking, typing, and more.
      11
      105 npm
      2
      MIT
    • A
      license
      C
      quality
      D
      maintenance
      Exposes a remote browser as MCP tools via Playwright, enabling AI agents to navigate and interact with web pages through DOM snapshots, clicks, typing, and form operations.
      40
      10 npm
      14
      Apache 2.0
    • F
      license
      A
      quality
      C
      maintenance
      Enables coding agents to drive a real Playwright-backed browser session, navigating, observing, interacting, and capturing proof on web pages via MCP tools across stdio and Streamable HTTP transports.
      15
      2
      -