项目介绍
MCP 服务 · 2026-11-09 更新 · 本站尚未实测
Playwright MCP 由微软维护,是一个 Model Context Protocol(MCP)服务器,把 Playwright 的浏览器自动化能力开放给大语言模型。它通过结构化可访问性快照(accessibility snapshots)让模型与网页交互,官方说明这样可绕过对截图或视觉调优模型的依赖。README 还提示:如果使用编程智能体(coding agent),可考虑同组织的 CLI+SKILLS 方案,其对上下文更节省;MCP 更适合需要持续浏览器状态、深度页面结构与迭代推理的长任务。
核心能力
点击能力名称查看输入、输出和原文依据。
- 基于可访问性树:以 Playwright 的可访问性树而非像素输入工作。
- 无需视觉模型:官方称其只处理结构化数据。
- 确定性的工具调用:官方称可避免截屏方案常见的歧义。
- 浏览器与配置选项丰富:README 列出浏览器类型、headless、视口、代理、CDP 连接、扩展连接、初始化脚本、存储状态、输出目录、密钥脱敏等大量参数。
- 多客户端支持:提供 VS Code、Cursor、Windsurf、Claude Desktop、Goose、Grok、Junie 等标准配置说明。
以上能力均依据 README 描述,未做独立实测。
实际应用场景
适用场景
- 探索性网页自动化:让模型在持续浏览器上下文中反复观察与操作页面。
- 自愈式测试与长时自主流程:官方指出需要连续浏览器上下文的场景更受益于 MCP。
- 需要登录态复用:可通过持久化配置文件或浏览器扩展连接已有会话(需自行评估账号与数据风险)。
- 不适合追求极致 token 效率的高吞吐编码任务,README 建议那类场景优先考虑 CLI+SKILLS。
安装与接入
需要 Node.js 18+ 与 MCP 客户端。将 npx 设为服务端命令,参数为 @playwright/mcp@latest。各客户端配置文件与安装语法不同,请使用 README 对应客户端的配置示例。
例如 Claude Code 的原文命令:
claude mcp add playwright npx @playwright/mcp@latest
使用条件与限制
- 是否需要部署
- 需自行准备运行环境,具体要求见正文
- 是否需要注册
- 账号和认证要求见正文;未明确说明的项目仍待核验
- 是否需要 API Key
- 待核验
- 费用与额度
- 费用边界见正文,项目许可不代表模型或托管服务免费
- 所需权限
- 待核验
- 许可证与服务条款
- 待核验
权限费用与限制
- 权限与安全:默认限制文件系统访问在工作区根目录内,并阻止导航到
file://URL;--allow-unrestricted-file-access会放开这一限制。README 对--allowed-origins、--blocked-origins明确说明“不是安全边界且不影响重定向”。--secrets与--redact-url-params被描述为便利功能而非安全特性。使用者应自行评估页面数据、登录态和本地文件暴露风险。 - 浏览器沙箱:提供
--no-sandbox与--sandbox选项,是否使用需自行判断安全影响。 - 持久化配置冲突:同一工作区同一时间只能有一个浏览器实例使用持久化 profile;并发客户端需用
--isolated或不同--user-data-dir。 - 费用与额度:README 未说明本项目或 npm 包是否收费,也未说明模型调用费用,待向官方核验。
- 模型依赖:README 未指定必须使用哪家大模型,也未列举具体模型清单;它强调不依赖视觉模型。
国内使用情况
网友核验 用户经验分享
与站长实测独立,不代表官方认证或本站已实测。
最近核验:暂无有效核验。参与人数按当前项目有效身份去重;不同核验项分别统计,不合并成用户总结果。仅统计审核通过且未过期的记录。
分项统计、有效期与样本量
| 核验项目 | 有效人数 | 成功 / 部分 / 失败 / 无法判断 | 成功率 | 最近核验 / 有效期 |
|---|---|---|---|---|
| 官方网站访问 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 7 天 |
| GitHub 仓库访问 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 7 天 |
| 安装与运行 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 官方服务国内连接 / MCP 连接 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 国内网络情况 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 7 天 |
| 国内模型兼容性 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 自定义 API | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 海外服务依赖 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 海外账号要求 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 中文界面 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 客户端兼容性 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 账号及费用信息 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
成功率 = 成功 ÷(成功 + 部分成功 + 失败);无法判断不计入分母。至少 5 份可判断结果才显示成功率。账号、费用、海外依赖与语言等事实项,成功表示核查结论与资料吻合,具体观察另行统计;不表示免费或没有海外依赖。不同网络、客户端和版本的结果不能直接等同。
最近有效核验
暂无审核通过且未过期的网友核验。欢迎提交真实使用记录。
查看全部有效核验 →国内实测状态:国内可用性待核验。协议兼容和官方资料说明不等于国内网络可用。
- 官方网站访问
- 尚未实测 待核验
- GitHub 仓库访问
- 尚未实测 待核验
- 官方服务国内连接
- 尚未实测 待核验
- 国内网络情况
- 尚未实测 待核验
- 国内模型兼容性
- 尚未实测 待核验
- 自定义 API
- 尚未实测 待核验
- 海外服务依赖
- 尚未实测 待核验
- 海外账号要求
- 尚未实测 待核验
- 中文界面
- 尚未实测 待核验
- 国内最后核验时间
- 尚未实测
许可与国内使用
仓库代码在 Apache License 2.0 下发布(依据仓库 LICENSE 文件,版权声明为 Microsoft Corporation)。这一许可只覆盖本仓库代码,不当然覆盖 Playwright 浏览器二进制、第三方网站、npm 托管服务或任何模型服务;这些内容的许可与费用需分别核验。
“更偏好 CLI+SKILLS”系 README 观点,并非对本项目停更的声明。仓库状态、各客户端最新安装方式、国内网络下的 npx 与浏览器下载与使用体验待核验。未发现针对中国大陆网络环境的官方说明。
项目资料与来源
字段依据与待核验事项
access:来源确认 · First, install the Playwright MCP server with your client.
project_type:来源确认 · A Model Context Protocol (MCP) server
原始 README(折叠技术参考)
## Playwright MCP
A Model Context Protocol (MCP) server that provides browser automation capabilities using [Playwright](https://playwright.dev). This server enables LLMs to interact with web pages through structured accessibility snapshots, bypassing the need for screenshots or visually-tuned models.
### Playwright MCP vs Playwright CLI
This package provides MCP interface into Playwright. If you are using a **coding agent**, you might benefit from using the [CLI+SKILLS](https://github.com/microsoft/playwright-cli) instead.
- **CLI**: Modern **coding agents** increasingly favor CLI–based workflows exposed as SKILLs over MCP because CLI invocations are more token-efficient: they avoid loading large tool schemas and verbose accessibility trees into the model context, allowing agents to act through concise, purpose-built commands. This makes CLI + SKILLs better suited for high-throughput coding agents that must balance browser automation with large codebases, tests, and reasoning within limited context windows.<br>**Learn more about [Playwright CLI with SKILLS](https://github.com/microsoft/playwright-cli)**.
- **MCP**: MCP remains relevant for specialized agentic loops that benefit from persistent state, rich introspection, and iterative reasoning over page structure, such as exploratory automation, self-healing tests, or long-running autonomous workflows where maintaining continuous browser context outweighs token cost concerns.
### 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.
### Requirements
- Node.js 18 or newer
- VS Code, Cursor, Windsurf, Claude Desktop, Goose, Grok, Junie or any other MCP client
<!--
// Generate using:
node utils/generate-links.js
-->
### Getting started
First, install the Playwright MCP server with your client.
**Standard config** works in most of the tools:
```js
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
}
```
[<img src="https://img.shields.io/badge/VS_Code-VS_Code?style=flat-square&label=Install%20Server&color=0098FF" alt="Install in VS Code">](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522playwright%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522%2540playwright%252Fmcp%2540latest%2522%255D%257D) [<img alt="Install in VS Code Insiders" src="https://img.shields.io/badge/VS_Code_Insiders-VS_Code_Insiders?style=flat-square&label=Install%20Server&color=24bfa5">](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522playwright%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522%2540playwright%252Fmcp%2540latest%2522%255D%257D)
<details>
<summary>Amp</summary>
Add via the Amp VS Code extension settings screen or by updating your settings.json file:
```json
"amp.mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
```
**Amp CLI Setup:**
Add via the `amp mcp add` command below
```bash
amp mcp add playwright -- npx @playwright/mcp@latest
```
</details>
<details>
<summary>Antigravity</summary>
Add via the Antigravity settings or by updating your configuration file:
```json
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
}
```
</details>
<details>
<summary>Claude Code</summary>
Use the Claude Code CLI to add the Playwright MCP server:
```bash
claude mcp add playwright npx @playwright/mcp@latest
```
</details>
<details>
<summary>Claude Desktop</summary>
Follow the MCP install [guide](https://modelcontextprotocol.io/quickstart/user), use the standard config above.
</details>
<details>
<summary>Cline</summary>
Follow the instruction in the section [Configuring MCP Servers](https://docs.cline.bot/mcp/configuring-mcp-servers)
**Example: Local Setup**
Add the following to your [`cline_mcp_settings.json`](https://docs.cline.bot/mcp/configuring-mcp-servers#editing-mcp-settings-files) file:
```json
{
"mcpServers": {
"playwright": {
"type": "stdio",
"command": "npx",
"timeout": 30,
"args": [
"-y",
"@playwright/mcp@latest"
],
"disabled": false
}
}
}
```
</details>
<details>
<summary>Codex</summary>
Use the Codex CLI to add the Playwright MCP server:
```bash
codex mcp add playwright npx "@playwright/mcp@latest"
```
Alternatively, create or edit the configuration file `~/.codex/config.toml` and add:
```toml
[mcp_servers.playwright]
command = "npx"
args = ["@playwright/mcp@latest"]
```
For more information, see the [Codex MCP documentation](https://github.com/openai/codex/blob/main/codex-rs/config.md#mcp_servers).
</details>
<details>
<summary>Copilot</summary>
Use the Copilot CLI to interactively add the Playwright MCP server:
```bash
/mcp add
```
Alternatively, create or edit the configuration file `~/.copilot/mcp-config.json` and add:
```json
{
"mcpServers": {
"playwright": {
"type": "local",
"command": "npx",
"tools": [
"*"
],
"args": [
"@playwright/mcp@latest"
]
}
}
}
```
For more information, see the [Copilot CLI documentation](https://docs.github.com/en/copilot/concepts/agents/about-copilot-cli).
</details>
<details>
<summary>Cursor</summary>
#### Click the button to install:
[<img src="https://cursor.com/deeplink/mcp-install-dark.svg" alt="Install in Cursor">](https://cursor.com/en/install-mcp?name=Playwright&config=eyJjb21tYW5kIjoibnB4IEBwbGF5d3JpZ2h0L21jcEBsYXRlc3QifQ%3D%3D)
#### Or install manually:
Go to `Cursor Settings` -> `MCP` -> `Add new MCP Server`. Name to your liking, use `command` type with the command `npx @playwright/mcp@latest`. You can also verify config or add command like arguments via clicking `Edit`.
</details>
<details>
<summary>Factory</summary>
Use the Factory CLI to add the Playwright MCP server:
```bash
droid mcp add playwright "npx @playwright/mcp@latest"
```
Alternatively, type `/mcp` within Factory droid to open an interactive UI for managing MCP servers.
For more information, see the [Factory MCP documentation](https://docs.factory.ai/cli/configuration/mcp).
</details>
<details>
<summary>Gemini CLI</summary>
Follow the MCP install [guide](https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md#configure-the-mcp-server-in-settingsjson), use the standard config above.
</details>
<details>
<summary>Goose</summary>
#### Click the button to install:
[](https://block.github.io/goose/extension?cmd=npx&arg=%40playwright%2Fmcp%40latest&id=playwright&name=Playwright&description=Interact%20with%20web%20pages%20through%20structured%20accessibility%20snapshots%20using%20Playwright)
#### Or install manually:
Go to `Advanced settings` -> `Extensions` -> `Add custom extension`. Name to your liking, use type `STDIO`, and set the `command` to `npx @playwright/mcp`. Click "Add Extension".
</details>
<details>
<summary>Grok</summary>
Use the Grok CLI to add the Playwright MCP server:
```bash
grok mcp add playwright -- npx @playwright/mcp@latest
```
Alternatively, create or edit the configuration file `~/.grok/config.toml` and add:
```toml
[mcp_servers.playwright]
command = "npx"
args = ["@playwright/mcp@latest"]
```
For more information, see the [Grok MCP documentation](https://docs.x.ai/build/features/mcp-servers).
</details>
<details>
<summary>Junie</summary>
To add the Playwright MCP server in Junie CLI:
1. Type `/mcp`
2. Press `Ctrl+A` to add a new MCP server
3. Select **Playwright** from the list
Alternatively, add to `.junie/mcp/mcp.json`:
```json
{
"mcpServers": {
"Playwright": {
"command": "npx",
"args": [
"-y",
"@playwright/mcp@latest"
]
}
}
}
```
For more information, see the [Junie MCP configuration documentation](https://junie.jetbrains.com/docs/junie-cli-mcp-configuration.html).
</details>
<details>
<summary>Kiro</summary>
[](https://kiro.dev/launch/mcp/add?name=playwright&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22%40playwright%2Fmcp%40latest%22%5D%7D)
Follow the MCP Servers [documentation](https://kiro.dev/docs/mcp/). For example in `.kiro/settings/mcp.json`:
```json
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
}
```
</details>
<details>
<summary>LM Studio</summary>
#### Click the button to install:
[](https://lmstudio.ai/install-mcp?name=playwright&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyJAcGxheXdyaWdodC9tY3BAbGF0ZXN0Il19)
#### Or install manually:
Go to `Program` in the right sidebar -> `Install` -> `Edit mcp.json`. Use the standard config above.
</details>
<details>
<summary>opencode</summary>
Follow the MCP Servers [documentation](https://opencode.ai/docs/mcp-servers/). For example in `~/.config/opencode/opencode.json`:
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"playwright": {
"type": "local",
"command": [
"npx",
"@playwright/mcp@latest"
],
"enabled": true
}
}
}
```
</details>
<details>
<summary>Qodo Gen</summary>
Open [Qodo Gen](https://docs.qodo.ai/qodo-documentation/qodo-gen) chat panel in VSCode or IntelliJ → Connect more tools → + Add new MCP → Paste the standard config above.
Click <code>Save</code>.
</details>
<details>
<summary>VS Code</summary>
#### Click the button to install:
[<img src="https://img.shields.io/badge/VS_Code-VS_Code?style=flat-square&label=Install%20Server&color=0098FF" alt="Install in VS Code">](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522playwright%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522%2540playwright%252Fmcp%2540latest%2522%255D%257D) [<img alt="Install in VS Code Insiders" src="https://img.shields.io/badge/VS_Code_Insiders-VS_Code_Insiders?style=flat-square&label=Install%20Server&color=24bfa5">](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522playwright%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522%2540playwright%252Fmcp%2540latest%2522%255D%257D)
#### Or install manually:
Follow the MCP install [guide](https://code.visualstudio.com/docs/copilot/chat/mcp-servers#_add-an-mcp-server), use the standard config above. You can also install the Playwright MCP server using the VS Code CLI:
```bash
# For VS Code
code --add-mcp '{"name":"playwright","command":"npx","args":["@playwright/mcp@latest"]}'
```
After installation, the Playwright MCP server will be available for use with your GitHub Copilot agent in VS Code.
</details>
<details>
<summary>Warp</summary>
Go to `Settings` -> `AI` -> `Manage MCP Servers` -> `+ Add` to [add an MCP Server](https://docs.warp.dev/knowledge-and-collaboration/mcp#adding-an-mcp-server). Use the standard config above.
Alternatively, use the slash command `/add-mcp` in the Warp prompt and paste the standard config from above:
```js
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
}
```
</details>
<details>
<summary>Windsurf</summary>
Follow Windsurf MCP [documentation](https://docs.windsurf.com/windsurf/cascade/mcp). Use the standard config above.
</details>
### Configuration
Playwright MCP server supports following arguments. They can be provided in the JSON configuration above, as a part of the `"args"` list:
<!--- Options generated by update-readme.js -->
| Option | Description |
|--------|-------------|
| --allowed-hosts <hosts...> | comma-separated list of hosts this server is allowed to serve from. Defaults to localhost, loopback IPs and the host passed via --host; other hosts must be listed explicitly. Pass '*' to disable the host check.<br>*env* `PLAYWRIGHT_MCP_ALLOWED_HOSTS` |
| --allowed-origins <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.<br>*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.<br>*env* `PLAYWRIGHT_MCP_ALLOW_UNRESTRICTED_FILE_ACCESS` |
| --blocked-origins <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.<br>*env* `PLAYWRIGHT_MCP_BLOCKED_ORIGINS` |
| --block-service-workers | block service workers<br>*env* `PLAYWRIGHT_MCP_BLOCK_SERVICE_WORKERS` |
| --browser <browser> | browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.<br>*env* `PLAYWRIGHT_MCP_BROWSER` |
| --caps <caps> | comma-separated list of additional capabilities to enable, possible values: vision, pdf, devtools.<br>*env* `PLAYWRIGHT_MCP_CAPS` |
| --cdp-endpoint <endpoint> | CDP endpoint to connect to.<br>*env* `PLAYWRIGHT_MCP_CDP_ENDPOINT` |
| --cdp-header <headers...> | CDP headers to send with the connect request, multiple can be specified.<br>*env* `PLAYWRIGHT_MCP_CDP_HEADERS` |
| --cdp-timeout <timeout> | timeout in milliseconds for connecting to CDP endpoint, defaults to 30000ms<br>*env* `PLAYWRIGHT_MCP_CDP_TIMEOUT` |
| --codegen <lang> | specify the language to use for code generation, possible values: "typescript", "python", "java", "csharp", "none". Default is "typescript".<br>*env* `PLAYWRIGHT_MCP_CODEGEN` |
| --config <path> | path to the configuration file.<br>*env* `PLAYWRIGHT_MCP_CONFIG` |
| --console-level <level> | level of console messages to return: "error", "warning", "info", "debug". Each level includes the messages of more severe levels.<br>*env* `PLAYWRIGHT_MCP_CONSOLE_LEVEL` |
| --device <device> | device to emulate, for example: "iPhone 15"<br>*env* `PLAYWRIGHT_MCP_DEVICE` |
| --mobile | emulate a generic mobile device (Pixel 10 for Chromium, iPhone 17 for WebKit). Mobile pages are usually lighter, which saves tokens. Cannot be combined with --device.<br>*env* `PLAYWRIGHT_MCP_MOBILE` |
| --executable-path <path> | path to the browser executable.<br>*env* `PLAYWRIGHT_MCP_EXECUTABLE_PATH` |
| --extension | Connect to a running browser instance (Edge/Chrome only). Requires the "Playwright Extension" to be installed.<br>*env* `PLAYWRIGHT_MCP_EXTENSION` |
| --endpoint <endpoint> | Bound browser endpoint to connect to.<br>*env* `PLAYWRIGHT_MCP_ENDPOINT` |
| --file-paths <mode> | how file paths are rendered in tool results, "relative" to the workspace root or "absolute". Default is "relative".<br>*env* `PLAYWRIGHT_MCP_FILE_PATHS` |
| --grant-permissions <permissions...> | List of permissions to grant to the browser context, for example "geolocation", "clipboard-read", "clipboard-write".<br>*env* `PLAYWRIGHT_MCP_GRANT_PERMISSIONS` |
| --headless | run browser in headless mode, headed by default<br>*env* `PLAYWRIGHT_MCP_HEADLESS` |
| --host <host> | host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.<br>*env* `PLAYWRIGHT_MCP_HOST` |
| --idle-timeout <timeout> | close the browser after this many milliseconds without a completed tool call, the next tool call relaunches it. Defaults to one hour for headless browsers, never for headed ones, 0 disables.<br>*env* `PLAYWRIGHT_MCP_IDLE_TIMEOUT` |
| --ignore-https-errors | ignore https errors<br>*env* `PLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS` |
| --ignore-roots | do not ask the client for its workspace roots, use the current working directory as the workspace root instead. Use this with clients that advertise roots, but can not answer the roots request.<br>*env* `PLAYWRIGHT_MCP_IGNORE_ROOTS` |
| --init-page <path...> | path to TypeScript file to evaluate on Playwright page object<br>*env* `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.<br>*env* `PLAYWRIGHT_MCP_INIT_SCRIPT` |
| --isolated | keep the browser profile in memory, do not save it to disk.<br>*env* `PLAYWRIGHT_MCP_ISOLATED` |
| --image-responses <mode> | whether to send image responses to the client. Can be "allow", "omit" or "only". With "only", a response that carries an image consists of the image parts alone, without the text part. Defaults to "allow".<br>*env* `PLAYWRIGHT_MCP_IMAGE_RESPONSES` |
| --no-sandbox | disable the sandbox for all process types that are normally sandboxed.<br>*env* `PLAYWRIGHT_MCP_NO_SANDBOX` |
| --background | do not activate controlled tabs or focus the browser window when using --extension.<br>*env* `PLAYWRIGHT_MCP_BACKGROUND` |
| --no-tab-group | do not group controlled tabs when using --extension.<br>*env* `PLAYWRIGHT_MCP_NO_TAB_GROUP` |
| --no-webmcp | do not collect or expose the tools that a page registers through the WebMCP API.<br>*env* `PLAYWRIGHT_MCP_WEBMCP=false` |
| --output-dir <path> | path to the directory for automatically named output files, for example a screenshot taken without an explicit file name. Files with an explicit name are resolved against the workspace root instead and are not affected by this option.<br>*env* `PLAYWRIGHT_MCP_OUTPUT_DIR` |
| --output-max-size <bytes> | Threshold for evicting old output files, in bytes.<br>*env* `PLAYWRIGHT_MCP_OUTPUT_MAX_SIZE` |
| --port <port> | port to listen on for SSE transport.<br>*env* `PLAYWRIGHT_MCP_PORT` |
| --profile-dir-name <name> | name of the profile directory in the user data dir to connect to with --extension, for example "Profile 1". Defaults to the last used profile that has the extension installed.<br>*env* `PLAYWRIGHT_MCP_PROFILE_DIR_NAME` |
| --proxy-bypass <bypass> | comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"<br>*env* `PLAYWRIGHT_MCP_PROXY_BYPASS` |
| --proxy-server <proxy> | specify proxy server, for example "http://myproxy:3128", "http://user:password@myproxy:3128" or "socks5://myproxy:8080"<br>*env* `PLAYWRIGHT_MCP_PROXY_SERVER` |
| --redact-url-params <names> | comma-separated list of URL query and fragment parameter names, for example "access_token,code", whose values are replaced with <redacted> in the tool responses.<br>*env* `PLAYWRIGHT_MCP_REDACT_URL_PARAMS` |
| --sandbox | enable the sandbox for all process types that are normally not sandboxed.<br>*env* `PLAYWRIGHT_MCP_SANDBOX` |
| --save-session | Whether to save the Playwright MCP session into the output directory.<br>*env* `PLAYWRIGHT_MCP_SAVE_SESSION` |
| --secrets <path> | path to a file containing secrets in the dotenv format<br>*env* `PLAYWRIGHT_MCP_SECRETS_FILE` |
| --shared-browser-context | reuse the same browser context between all connected HTTP clients.<br>*env* `PLAYWRIGHT_MCP_SHARED_BROWSER_CONTEXT` |
| --snapshot-boxes | include each element's bounding box as [box=x,y,width,height] in snapshots. Coordinates are viewport-relative, in CSS pixels.<br>*env* `PLAYWRIGHT_MCP_SNAPSHOT_BOXES` |
| --snapshot-mode <mode> | when taking snapshots for responses, specifies the mode to use. Can be "full" or "none". Default is "full".<br>*env* `PLAYWRIGHT_MCP_SNAPSHOT_MODE` |
| --storage-state <path> | path to the storage state file for isolated sessions.<br>*env* `PLAYWRIGHT_MCP_STORAGE_STATE` |
| --test-id-attribute <attribute> | specify the attribute to use for test ids, defaults to "data-testid"<br>*env* `PLAYWRIGHT_MCP_TEST_ID_ATTRIBUTE` |
| --timeout-action <timeout> | specify action timeout in milliseconds, defaults to 5000ms<br>*env* `PLAYWRIGHT_MCP_TIMEOUT_ACTION` |
| --timeout-navigation <timeout> | specify navigation timeout in milliseconds, defaults to 60000ms<br>*env* `PLAYWRIGHT_MCP_TIMEOUT_NAVIGATION` |
| --timeout-settle <timeout> | how long to wait after each action for triggered work to settle, in milliseconds, defaults to 500ms<br>*env* `PLAYWRIGHT_MCP_TIMEOUT_SETTLE` |
| --user-agent <ua string> | specify user agent string<br>*env* `PLAYWRIGHT_MCP_USER_AGENT` |
| --user-data-dir <path> | path to the user data directory. If not specified, a temporary directory will be created.<br>*env* `PLAYWRIGHT_MCP_USER_DATA_DIR` |
| --viewport-size <size> | specify browser viewport size in pixels, for example "1280x720"<br>*env* `PLAYWRIGHT_MCP_VIEWPORT_SIZE` |
<!--- End of options generated section -->
### User profile
You can run Playwright MCP 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.
```bash
# Windows
%USERPROFILE%\AppData\Local\ms-playwright\mcp-{channel}-{workspace-hash}
# macOS
- ~/Library/Caches/ms-playwright/mcp-{channel}-{workspace-hash}
# Linux
- ~/.cache/ms-playwright/mcp-{channel}-{workspace-hash}
```
`{workspace-hash}` is derived from the MCP client's workspace root, so different projects get separate profiles automatically.
> [!IMPORTANT]
> A persistent profile can only be used by one browser instance at a time, so concurrent MCP clients sharing the same workspace will conflict. To run several clients in parallel, start each additional client with `--isolated` or point it at a distinct `--user-data-dir`.
**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. Learn more about the storage
state [here](https://playwright.dev/docs/auth).
```js
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--isolated",
"--storage-state={path/to/storage.json}"
]
}
}
}
```
**Browser Extension**
The Playwright MCP Chrome Extension allows you to connect to existing browser tabs and leverage your logged-in sessions and browser state. See [microsoft/playwright › packages/extension](https://github.com/microsoft/playwright/tree/main/packages/extension#readme) for installation and setup instructions.
### Initial state
There are multiple ways to provide the initial state to the browser context or a page.
For the storage state, you can either:
- Start with a user data directory using the `--user-data-dir` argument. This will persist all browser data between the sessions.
- Start with a storage state file using the `--storage-state` argument. This will load cookies and local storage from the file into an isolated browser context.
For the page state, you can use:
- `--init-page` to point to a TypeScript file that will be evaluated on the Playwright page object. This allows you to run arbitrary code to set up the page.
```ts
// init-page.ts
export default async ({ page }) => {
await page.context().grantPermissions(['geolocation']);
await page.context().setGeolocation({ latitude: 37.7749, longitude: -122.4194 });
await page.setViewportSize({ width: 1280, height: 720 });
};
```
- `--init-script` to point to a JavaScript file that will be added as an initialization script. The script will be evaluated in every page before any of the page's scripts.
This is useful for overriding browser APIs or setting up the environment.
```js
// init-script.js
window.isPlaywrightMCP = true;
```
### Configuration file
The Playwright MCP server can be configured using a JSON configuration file. You can specify the configuration file
using the `--config` command line option:
```bash
npx @playwright/mcp@latest --config path/to/config.json
```
<details>
<summary>Configuration file schema</summary>
<!--- Config generated by update-readme.js -->
```typescript
{
/**
* 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. May be a
* WebSocket URL string, or a [ConnectOptions] object that mirrors the
* `connectOptions` shape used by the test runner. When passed as an object,
* `exposeNetwork`, `headers`, `slowMo`, and `timeout` are forwarded to the
* underlying connect call.
*/
remoteEndpoint?: string | playwright.ConnectOptions & { endpoint: 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[];
},
/**
* Connect to a running browser instance (Edge/Chrome only). If specified, `browser`
* config is ignored.
* Requires the "Playwright Extension" to be installed.
*/
extension?: boolean;
/**
* Group controlled tabs when using the extension. Defaults to true.
*/
tabGroup?: boolean;
/**
* Do not activate controlled tabs or focus the browser window when using the extension.
* Defaults to false.
*/
background?: boolean;
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 localhost, loopback IPs and the host passed via --host; other hosts must be listed explicitly.
* 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.
* - 'devtools': Developer tools features.
*/
capabilities?: ToolCapability[];
/**
* Whether to save the Playwright session into the output directory.
*/
saveSession?: boolean;
/**
* Whether to collect and expose the tools that a page registers through the
* experimental WebMCP API. Enabled by default.
*/
webmcp?: boolean;
/**
* Reuse the same browser context between all connected HTTP clients.
*/
sharedBrowserContext?: boolean;
/**
* Secrets are used to replace matching plain text in the tool responses to prevent the LLM
* from accidentally getting sensitive data. It is a convenience and not a security feature,
* make sure to always examine information coming in and from the tool on the client.
*/
secrets?: Record<string, string>;
/**
* Names of URL query and fragment parameters, for example `access_token` or `code`, whose values
* are replaced with `<redacted>` in the tool responses. Use it for session and grant values that
* are minted at runtime and cannot be listed in `secrets`. Like `secrets`, it is a convenience
* and not a security feature.
*/
redactUrlParams?: string[];
/**
* The directory for automatically named output files, for example a screenshot taken without an
* explicit file name. Files with an explicit name are resolved against the workspace root instead
* and are not affected by this option.
*/
outputDir?: string;
/**
* Threshold for evicting old output files, in bytes.
*/
outputMaxSize?: number;
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.
*
* Supported formats:
* - Full origin: `https://example.com:8080` - matches only that origin
* - Wildcard port: `http://localhost:*` - matches any port on localhost with http protocol
*/
allowedOrigins?: string[];
/**
* List of origins to block the browser to request. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
*
* Supported formats:
* - Full origin: `https://example.com:8080` - matches only that origin
* - Wildcard port: `http://localhost:*` - matches any port on localhost with http protocol
*/
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;
/**
* Configures default expect timeout: https://playwright.dev/docs/test-timeouts#expect-timeout. Defaults to 5000ms.
*/
expect?: number;
/**
* How long to wait after each action for triggered work (navigations, requests) to settle before responding. Defaults to 500ms.
*/
settle?: number;
/**
* Close the browser after this many milliseconds without a tool call, and relaunch it on the next one.
* Defaults to one hour for headless browsers Playwright launched, and to no timeout for headed or attached ones. Pass 0 to disable.
* The CLI shuts the whole session down instead of relaunching.
*/
idle?: number;
};
/**
* Whether to send image responses to the client. Can be "allow", "omit", or "only". Defaults to "allow".
* With "only", a response that carries an image consists of the image parts alone, without the text part.
*/
imageResponses?: 'allow' | 'omit' | 'only';
/**
* How file paths are rendered in tool results. Can be "relative" to the workspace root or "absolute". Defaults to "relative".
*/
filePaths?: 'relative' | 'absolute';
snapshot?: {
/**
* When taking snapshots for responses, specifies the mode to use.
*/
mode?: 'full' | 'none';
/**
* Whether to include each element's bounding box as [box=x,y,width,height] in snapshots.
* Coordinates are viewport-relative, in CSS pixels (Element.getBoundingClientRect).
*/
boxes?: boolean;
};
/**
* allowUnrestrictedFileAccess acts as a guardrail to prevent the LLM from accidentally
* wandering outside its intended workspace. It is a convenience defense to catch unintended
* file access, not a secure boundary; a deliberate attempt to reach other directories can be
* easily worked around, so always rely on client-level permissions for true security.
*/
allowUnrestrictedFileAccess?: boolean;
/**
* Do not ask the client for its workspace roots, use the current working directory
* as the workspace root instead. Use this with clients that advertise roots, but
* can not answer the roots request.
*/
ignoreRoots?: boolean;
/**
* Specify the language to use for code generation.
*/
codegen?: 'typescript' | 'python' | 'java' | 'csharp' | 'none';
}
```
<!--- End of config generated section -->
</details>
### 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.
```bash
npx @playwright/mcp@latest --port 8931
```
And then in MCP client config, set the `url` to the HTTP endpoint:
```js
{
"mcpServers": {
"playwright": {
"url": "http://localhost:8931/mcp"
}
}
}
```
## Security
Playwright MCP is **not** a security boundary. See [MCP Security Best Practices](https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices) for guidance on securing your deployment.
<details>
<summary><b>Docker</b></summary>
**NOTE:** The Docker implementation only supports headless chromium at the moment.
```js
{
"mcpServers": {
"playwright": {
"command": "docker",
"args": ["run", "-i", "--rm", "--init", "--pull=always", "mcr.microsoft.com/playwright/mcp"]
}
}
}
```
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 \
-p 8931:8931 \
mcr.microsoft.com/playwright/mcp \
/app/cli.js --headless --browser chromium --no-sandbox --port 8931 --host 0.0.0.0
```
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 mcr.microsoft.com/playwright/mcp .
```
</details>
<details>
<summary><b>Programmatic usage</b></summary>
```js
import http from 'http';
import { createConnection } from '@playwright/mcp';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
http.createServer(async (req, res) => {
// ...
// Creates a headless Playwright MCP server with SSE transport
const connection = await createConnection({ browser: { launchOptions: { headless: true } } });
const transport = new SSEServerTransport('/messages', res);
await connection.connect(transport);
// ...
});
```
</details>
### Tools
<!--- Tools generated by update-readme.js -->
<details>
<summary><b>Core automation</b></summary>
<!-- NOTE: This has been generated via update-readme.js -->
- **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
- `target` (string): Exact target element reference from the page snapshot, or a unique element selector
- `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**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_close**
- Title: Close browser
- Description: Close the page
- Parameters: None
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_console_messages**
- Title: Get console messages
- Description: Returns all console messages
- Parameters:
- `level` (string): Level of the console messages to return. Each level includes the messages of more severe levels. Defaults to "info".
- `all` (boolean, optional): Return all console messages since the beginning of the session, not just since the last navigation. Defaults to false.
- `filename` (string, optional): File name to save the console messages to. Relative file names are resolved against the workspace root. If not provided, messages are returned as text.
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_drag**
- Title: Drag mouse
- Description: Perform drag and drop between two elements
- Parameters:
- `startElement` (string, optional): Human-readable source element description used to obtain the permission to interact with the element
- `startTarget` (string): Exact target element reference from the page snapshot, or a unique element selector
- `endElement` (string, optional): Human-readable target element description used to obtain the permission to interact with the element
- `endTarget` (string): Exact target element reference from the page snapshot, or a unique element selector
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_drop**
- Title: Drop files or data onto an element
- Description: Drop files or MIME-typed data onto an element, as if dragged from outside the page. At least one of "paths" or "data" must be provided.
- Parameters:
- `element` (string, optional): Human-readable element description used to obtain permission to interact with the element
- `target` (string): Exact target element reference from the page snapshot, or a unique element selector
- `paths` (array, optional): Absolute paths to files to drop onto the element.
- `data` (object, optional): Data to drop, as a map of MIME type to string value (e.g. {"text/plain": "hello", "text/uri-list": "https://example.com"}).
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_emulate_media**
- Title: Emulate media features
- Description: Emulate CSS media features for the page, for example switch between the light and dark color scheme. Omitted parameters are left unchanged; null clears an override.
- Parameters:
- `colorScheme` (optional): Emulates the prefers-color-scheme media feature
- `reducedMotion` (optional): Emulates the prefers-reduced-motion media feature
- `forcedColors` (optional): Emulates the forced-colors media feature
- `contrast` (optional): Emulates the prefers-contrast media feature
- `media` (optional): Changes the CSS media type of the page
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_evaluate**
- Title: Evaluate JavaScript
- Description: Evaluate JavaScript expression on page or element
- Parameters:
- `element` (string, optional): Human-readable element description used to obtain permission to interact with the element
- `target` (string, optional): Exact target element reference from the page snapshot, or a unique element selector
- `function` (string): () => { /* code */ } or (element) => { /* code */ } when element is provided
- `filename` (string, optional): File name to save the result to. Relative file names are resolved against the workspace root. If not provided, result is returned as text.
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_file_upload**
- Title: Upload files
- Description: Upload one or multiple files
- Parameters:
- `paths` (array, optional): The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled.
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_fill_form**
- Title: Fill form
- Description: Fill multiple form fields
- Parameters:
- `fields` (array): Fields to fill in
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_find**
- Title: Find in page snapshot
- Description: Search the accessibility snapshot of the current page for text or a regular expression. Returns matching snapshot nodes with a few lines of surrounding context (like search snippets), each shown under its path from the root of the tree, which is cheaper than capturing the whole snapshot when you only need to locate an element and its ref.
- Parameters:
- `text` (string, optional): Plain text to search for in the page snapshot (case-insensitive substring match). Provide either text or regex, not both.
- `regex` (string, optional): Regular expression to search for in the page snapshot. Matching is case-sensitive by default; wrap the pattern in slashes to add flags, e.g. "/error/i" for case-insensitive. Provide either text or regex, not both.
- `maxResults` (number, optional): Maximum number of matching items to return. Defaults to returning all matches.
- `filename` (string, optional): Save results to a file instead of returning them in the response. Relative file names are resolved against the workspace root.
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_handle_dialog**
- Title: Handle a dialog
- Description: Handle a dialog
- Parameters:
- `accept` (boolean): Whether to accept the dialog.
- `promptText` (string, optional): The text of the prompt in case of a prompt dialog.
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_hover**
- Title: Hover mouse
- Description: Hover over element on page
- Parameters:
- `element` (string, optional): Human-readable element description used to obtain permission to interact with the element
- `target` (string): Exact target element reference from the page snapshot, or a unique element selector
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_navigate**
- Title: Navigate to a URL
- Description: Navigate to a URL
- Parameters:
- `url` (string): The URL to navigate to
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_navigate_back**
- Title: Go back
- Description: Go back to the previous page in the history
- Parameters: None
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_network_request**
- Title: Show network request details
- Description: Returns full details (headers and body) of a single network request, or a single part if `part` is set. Use the number from browser_network_requests.
- Parameters:
- `index` (integer): 1-based index of the request, as printed by browser_network_requests.
- `part` (string, optional): Return only this part of the request. Omit to return full details.
- `filename` (string, optional): File name to save the result to. Relative file names are resolved against the workspace root. If not provided, output is returned as text.
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_network_requests**
- Title: List network requests
- Description: Returns a numbered list of network requests since loading the page. Use browser_network_request with the number to get full details.
- Parameters:
- `static` (boolean): Whether to include successful static resources like images, fonts, scripts, etc. Defaults to false.
- `filter` (string, optional): Only return requests whose URL matches this regexp (e.g. "/api/.*user").
- `all` (boolean, optional): Return all network requests since the beginning of the session, not just since the last navigation. Defaults to false.
- `filename` (string, optional): File name to save the network requests to. Relative file names are resolved against the workspace root. If not provided, requests are returned as text.
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_press_key**
- Title: Press a key
- Description: Press a key on the keyboard
- Parameters:
- `key` (string): Name of the key to press or a character to generate, such as `ArrowLeft` or `a`
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_resize**
- Title: Resize browser window
- Description: Resize the browser window
- Parameters:
- `width` (number): Width of the browser window
- `height` (number): Height of the browser window
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_run_code_unsafe**
- Title: Run Playwright code (unsafe)
- Description: Run a Playwright code snippet. Unsafe: executes arbitrary JavaScript in the Playwright server process and is RCE-equivalent.
- Parameters:
- `code` (string, optional): A JavaScript function containing Playwright code to execute. It will be invoked with a single argument, page, which you can use for any page interaction. For example: `async (page) => { await page.getByRole('button', { name: 'Submit' }).click(); return await page.title(); }`
- `filename` (string, optional): Load code from the specified file. Relative file names are resolved against the workspace root. If both code and filename are provided, code will be ignored.
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_select_option**
- Title: Select option
- Description: Select an option in a dropdown
- Parameters:
- `element` (string, optional): Human-readable element description used to obtain permission to interact with the element
- `target` (string): Exact target element reference from the page snapshot, or a unique element selector
- `values` (array): Array of values to select in the dropdown. This can be a single value or multiple values.
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_snapshot**
- Title: Page snapshot
- Description: Capture accessibility snapshot of the current page, this is better than screenshot
- Parameters:
- `target` (string, optional): Exact target element reference from the page snapshot, or a unique element selector
- `filename` (string, optional): Save snapshot to a file instead of returning it in the response. Relative file names are resolved against the workspace root.
- `depth` (number, optional): Limit the depth of the snapshot tree
- `boxes` (boolean, optional): Include each element's bounding box as [box=x,y,width,height] in the snapshot. Coordinates are viewport-relative, in CSS pixels (Element.getBoundingClientRect)
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_take_screenshot**
- Title: Take a screenshot
- Description: Take a screenshot of the current page. Use browser_snapshot for actions by default. With the vision capability enabled, use screenshot coordinates with the coordinate-based mouse tools for elements not exposed in the accessibility snapshot.
- Parameters:
- `element` (string, optional): Human-readable element description used to obtain permission to interact with the element
- `target` (string, optional): Exact target element reference from the page snapshot, or a unique element selector
- `type` (string, optional): Image format for the screenshot. If unset, inferred from the filename extension, otherwise png.
- `filename` (string, optional): File name to save the screenshot to. Relative file names are resolved against the workspace root. If not specified, the screenshot is saved into the output directory as `page-{timestamp}.{png|jpeg|webp}`.
- `fullPage` (boolean, optional): When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Cannot be used with element screenshots.
- `scale` (string): Image resolution scale. "css" produces a screenshot sized in CSS pixels (smaller, consistent across devices). "device" produces a high-resolution screenshot using device pixels (larger, accounts for the device pixel ratio). Default is css.
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_type**
- Title: Type text
- Description: Type text into editable element
- Parameters:
- `element` (string, optional): Human-readable element description used to obtain permission to interact with the element
- `target` (string): Exact target element reference from the page snapshot, or a unique element selector
- `text` (string): Text to type into the element
- `submit` (boolean, optional): Whether to submit entered text (press Enter after)
- `slowly` (boolean, optional): Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_wait_for**
- Title: Wait for
- Description: Wait for text to appear or disappear or a specified time to pass. When both text and textGone are provided, waits for the first one to happen
- Parameters:
- `time` (number, optional): The time to wait in seconds, at most 30. When combined with text or textGone, serves as a timeout for them instead of the default action timeout
- `text` (string, optional): The text to wait for
- `textGone` (string, optional): The text to wait for to disappear
- Read-only: **false**
</details>
<details>
<summary><b>Tab management</b></summary>
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_tabs**
- Title: Manage tabs
- Description: List, create, close, or select a browser tab.
- Parameters:
- `action` (string): Operation to perform
- `index` (number, optional): Tab index, used for close/select. If omitted for close, current tab is closed.
- `url` (string, optional): URL to navigate to in the new tab, used for new.
- `isolatedContext` (string, optional): Name of an isolated browser context to create the new tab in, used for new. Tabs in the same isolated context share cookies and storage, tabs in different contexts are fully isolated. If omitted or "default", the tab is created in the default context.
- Read-only: **false**
</details>
<details>
<summary><b>Browser installation</b></summary>
</details>
<details>
<summary><b>Configuration (opt-in via --caps=config)</b></summary>
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_get_config**
- Title: Get config
- Description: Get the final resolved config after merging CLI options, environment variables and config file.
- Parameters: None
- Read-only: **true**
</details>
<details>
<summary><b>Network (opt-in via --caps=network)</b></summary>
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_network_state_set**
- Title: Set network state
- Description: Sets the browser network state to online or offline. When offline, all network requests will fail.
- Parameters:
- `state` (string): Set to "offline" to simulate offline mode, "online" to restore network connectivity
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_route**
- Title: Mock network requests
- Description: Set up a route to mock network requests matching a URL pattern
- Parameters:
- `pattern` (string): URL pattern to match (e.g., "**/api/users", "**/*.{png,jpg}")
- `status` (number, optional): HTTP status code to return (default: 200)
- `body` (string, optional): Response body (text or JSON string)
- `contentType` (string, optional): Content-Type header (e.g., "application/json", "text/html")
- `headers` (array, optional): Headers to add in "Name: Value" format
- `removeHeaders` (string, optional): Comma-separated list of header names to remove from request
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_route_list**
- Title: List network routes
- Description: List all active network routes
- Parameters: None
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_unroute**
- Title: Remove network routes
- Description: Remove network routes matching a pattern (or all routes if no pattern specified)
- Parameters:
- `pattern` (string, optional): URL pattern to unroute (omit to remove all routes)
- Read-only: **false**
</details>
<details>
<summary><b>Storage (opt-in via --caps=storage)</b></summary>
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_cookie_clear**
- Title: Clear cookies
- Description: Clear all cookies
- Parameters: None
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_cookie_delete**
- Title: Delete cookie
- Description: Delete a specific cookie (optionally only on a given domain/path)
- Parameters:
- `name` (string): Cookie name to delete
- `domain` (string, optional): Only delete the cookie on this domain
- `path` (string, optional): Only delete the cookie on this path
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_cookie_get**
- Title: Get cookie
- Description: Get a specific cookie by name
- Parameters:
- `name` (string): Cookie name to get
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_cookie_list**
- Title: List cookies
- Description: List all cookies (optionally filtered by domain/path)
- Parameters:
- `domain` (string, optional): Filter cookies by domain
- `path` (string, optional): Filter cookies by path
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_cookie_set**
- Title: Set cookie
- Description: Set a cookie with optional flags (domain, path, expires, httpOnly, secure, sameSite)
- Parameters:
- `name` (string): Cookie name
- `value` (string): Cookie value
- `domain` (string, optional): Cookie domain
- `path` (string, optional): Cookie path
- `expires` (number, optional): Cookie expiration as Unix timestamp
- `httpOnly` (boolean, optional): Whether the cookie is HTTP only
- `secure` (boolean, optional): Whether the cookie is secure
- `sameSite` (string, optional): Cookie SameSite attribute
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_localstorage_clear**
- Title: Clear localStorage
- Description: Clear all localStorage
- Parameters: None
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_localstorage_delete**
- Title: Delete localStorage item
- Description: Delete a localStorage item
- Parameters:
- `key` (string): Key to delete
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_localstorage_get**
- Title: Get localStorage item
- Description: Get a localStorage item by key
- Parameters:
- `key` (string): Key to get
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_localstorage_list**
- Title: List localStorage
- Description: List all localStorage key-value pairs
- Parameters: None
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_localstorage_set**
- Title: Set localStorage item
- Description: Set a localStorage item
- Parameters:
- `key` (string): Key to set
- `value` (string): Value to set
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_sessionstorage_clear**
- Title: Clear sessionStorage
- Description: Clear all sessionStorage
- Parameters: None
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_sessionstorage_delete**
- Title: Delete sessionStorage item
- Description: Delete a sessionStorage item
- Parameters:
- `key` (string): Key to delete
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_sessionstorage_get**
- Title: Get sessionStorage item
- Description: Get a sessionStorage item by key
- Parameters:
- `key` (string): Key to get
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_sessionstorage_list**
- Title: List sessionStorage
- Description: List all sessionStorage key-value pairs
- Parameters: None
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_sessionstorage_set**
- Title: Set sessionStorage item
- Description: Set a sessionStorage item
- Parameters:
- `key` (string): Key to set
- `value` (string): Value to set
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_set_storage_state**
- Title: Restore storage state
- Description: Restore storage state (cookies, local storage) from a file. This clears existing cookies and local storage before restoring.
- Parameters:
- `filename` (string): Path to the storage state file to restore from. Relative file names are resolved against the workspace root.
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_storage_state**
- Title: Save storage state
- Description: Save storage state (cookies, local storage) to a file for later reuse
- Parameters:
- `filename` (string, optional): File name to save the storage state to. Relative file names are resolved against the workspace root. If not specified, the storage state is saved into the output directory as `storage-state-{timestamp}.json`.
- Read-only: **true**
</details>
<details>
<summary><b>DevTools (opt-in via --caps=devtools)</b></summary>
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_annotate**
- Title: Annotate the current page
- Description: Open the Playwright Dashboard in annotation mode for the current page and wait for the user to draw annotations. Returns the annotated screenshot, ARIA snapshot, and the list of annotations.
- Parameters: None
- Read-only: **true**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_hide_highlight**
- Title: Hide element highlight
- Description: Remove a highlight overlay previously added for the element.
- Parameters:
- `element` (string, optional): Human-readable element description used when adding the highlight; must match the value passed to browser_highlight.
- `target` (string, optional): Exact target element reference from the page snapshot, or a unique element selector
- Read-only: **t历史前置条件说明(补充参考)
Node.js 18 或更新版本;支持的 MCP 客户端(如 VS Code、Cursor、Windsurf、Claude Desktop、Goose、Grok、Junie 等);通过 npx 获取 npm 包 @playwright/mcp;模型/API Key 要求资料未明确,待核验;费用资料未说明,待核验;访问 npm 与下载浏览器等境外依赖的网络情况待核验。
项目来源与清单版权许可
https://github.com/microsoft/playwright-mcp
整理来源:https://github.com/slavakurilyak/awesome-ai-agents
清单版权与许可:
MIT License
Copyright (c) 2024 Slava Kurilyak
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.