Playwright MCP
官方用于浏览器自动化、页面检查、截图以及来自Claude、Cursor和其他AI代理的网页交互的官方Playwright MCP服务器。
你可以用 Playwright MCP 做什么?
- 无障碍树浏览 — 让您的AI导航页面并读取结构化的无障碍快照,无需视觉模型。
- 持久化浏览器会话 — 通过
--user-data-dir或--storage-state在对话间保持登录状态,适用于需要认证的工作流程。 - 多浏览器自动化 — 使用
--browser标志驱动Chromium、Firefox、WebKit或Edge,进行跨引擎测试。 - 设备模拟 — 通过
--device模拟“iPhone 15”等移动设备,或使用通用--mobile模式进行响应式测试。 - 代码生成 — 使用
--codegen选项生成TypeScript、Python、Java或C#的Playwright测试脚本。 - 隔离测试上下文 — 使用
--isolated标志运行会话,在每次浏览器关闭后丢弃所有状态。
文档
Playwright MCP
一个使用 Playwright 提供浏览器自动化能力的模型上下文协议(MCP)服务器。该服务器使 LLM 能够通过结构化的可访问性快照与网页交互,无需截图或针对视觉调优的模型。
Playwright MCP 与 Playwright CLI 的对比
本包提供 Playwright 的 MCP 接口。如果您使用的是编码代理,您可能更适合使用 CLI+SKILLS。
-
CLI:现代编码代理越来越倾向于使用以 SKILL 形式暴露的基于 CLI 的工作流,而非 MCP,因为 CLI 调用的令牌效率更高:它们避免将大型工具模式和冗长的可访问性树加载到模型上下文中,使代理能够通过简洁、专用的命令进行操作。这使得 CLI + SKILLS 更适合高吞吐量的编码代理,这些代理必须在有限的上下文窗口内平衡浏览器自动化与大型代码库、测试和推理。
了解更多关于 Playwright CLI with SKILLS。 -
MCP:MCP 仍然适用于特定的代理循环,这些循环受益于持久状态、丰富的内省和对页面结构的迭代推理,例如探索性自动化、自愈测试或长时间运行的自主工作流,在这些场景中,维持持续的浏览器上下文比令牌成本更重要。
主要特性
- 快速且轻量。使用 Playwright 的可访问性树,而非基于像素的输入。
- 对 LLM 友好。无需视觉模型,仅基于结构化数据运行。
- 确定性工具应用。避免了基于截图方法常见的歧义。
环境要求
- Node.js 18 或更高版本
- VS Code、Cursor、Windsurf、Claude Desktop、Goose、Grok、Junie 或任何其他 MCP 客户端
快速开始
首先,使用您的客户端安装 Playwright MCP 服务器。
标准配置适用于大多数工具:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
}
Amp
通过 Amp VS Code 扩展设置界面或更新您的 settings.json 文件来添加:
"amp.mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
Amp CLI 设置:
通过下面的 amp mcp add 命令添加
amp mcp add playwright -- npx @playwright/mcp@latest
Antigravity
通过 Antigravity 设置或更新您的配置文件来添加:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
}
Claude Code
使用 Claude Code CLI 添加 Playwright MCP 服务器:
claude mcp add playwright npx @playwright/mcp@latest
Claude Desktop
按照 MCP 安装指南,使用上面的标准配置。
Cline
按照配置 MCP 服务器部分的说明操作。
示例:本地设置
将以下内容添加到您的 cline_mcp_settings.json 文件中:
{
"mcpServers": {
"playwright": {
"type": "stdio",
"command": "npx",
"timeout": 30,
"args": [
"-y",
"@playwright/mcp@latest"
],
"disabled": false
}
}
}
Codex
使用 Codex CLI 添加 Playwright MCP 服务器:
codex mcp add playwright npx "@playwright/mcp@latest"
或者,创建或编辑配置文件 ~/.codex/config.toml 并添加:
[mcp_servers.playwright]
command = "npx"
args = ["@playwright/mcp@latest"]
有关更多信息,请参阅 Codex MCP 文档。
Copilot
使用 Copilot CLI 以交互方式添加 Playwright MCP 服务器:
/mcp add
或者,创建或编辑配置文件 ~/.copilot/mcp-config.json 并添加:
{
"mcpServers": {
"playwright": {
"type": "local",
"command": "npx",
"tools": [
"*"
],
"args": [
"@playwright/mcp@latest"
]
}
}
}
有关更多信息,请参阅 Copilot CLI 文档。
Cursor
点击按钮安装:
或手动安装:
前往 Cursor Settings -> MCP -> Add new MCP Server。按您的喜好命名,使用 command 类型,命令为 npx @playwright/mcp@latest。您还可以通过点击 Edit 来验证配置或添加命令参数。
Factory
使用 Factory CLI 添加 Playwright MCP 服务器:
droid mcp add playwright "npx @playwright/mcp@latest"
或者,在 Factory droid 中输入 /mcp 以打开管理 MCP 服务器的交互式界面。
有关更多信息,请参阅 Factory MCP 文档。
Gemini CLI
按照 MCP 安装指南,使用上面的标准配置。
Goose
点击按钮安装:
或手动安装:
前往 Advanced settings -> Extensions -> Add custom extension。按您的喜好命名,使用 STDIO 类型,并将 command 设置为 npx @playwright/mcp。点击“添加扩展”。
Grok
使用 Grok CLI 添加 Playwright MCP 服务器:
grok mcp add playwright -- npx @playwright/mcp@latest
或者,创建或编辑配置文件 ~/.grok/config.toml 并添加:
[mcp_servers.playwright]
command = "npx"
args = ["@playwright/mcp@latest"]
有关更多信息,请参阅 Grok MCP 文档。
Junie
要在 Junie CLI 中添加 Playwright MCP 服务器:
- 输入
/mcp - 按
Ctrl+A添加新的 MCP 服务器 - 从列表中选择 Playwright
或者,添加到 .junie/mcp/mcp.json:
{
"mcpServers": {
"Playwright": {
"command": "npx",
"args": [
"-y",
"@playwright/mcp@latest"
]
}
}
}
有关更多信息,请参阅 Junie MCP 配置文档。
Kiro
按照 MCP 服务器文档操作。例如在 .kiro/settings/mcp.json 中:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
}
opencode
按照 MCP 服务器文档操作。例如在 ~/.config/opencode/opencode.json 中:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"playwright": {
"type": "local",
"command": [
"npx",
"@playwright/mcp@latest"
],
"enabled": true
}
}
}
VS Code
点击按钮安装:
或手动安装:
按照 MCP 安装指南,使用上面的标准配置。您还可以使用 VS Code CLI 安装 Playwright MCP 服务器:
# For VS Code
code --add-mcp '{"name":"playwright","command":"npx","args":["@playwright/mcp@latest"]}'
安装后,Playwright MCP 服务器将可用于您在 VS Code 中的 GitHub Copilot 代理。
Warp
前往 Settings -> AI -> Manage MCP Servers -> + Add 以添加 MCP 服务器。使用上面的标准配置。
或者,在 Warp 提示符中使用斜杠命令 /add-mcp 并粘贴上面的标准配置:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
}
Windsurf
按照 Windsurf MCP 文档操作。使用上面的标准配置。
配置
Playwright MCP 服务器支持以下参数。它们可以在上面的 JSON 配置中提供,作为 "args" 列表的一部分:
| 选项 | 描述 |
|---|---|
| --allowed-hosts <hosts...> | 允许此服务器提供服务的逗号分隔主机列表。默认为服务器绑定的主机。传入 '*' 可禁用主机检查。 env PLAYWRIGHT_MCP_ALLOWED_HOSTS |
| --allowed-origins | 允许浏览器请求的受信任来源的分号分隔列表。默认允许所有来源。重要提示:不 作为安全边界,且不 影响重定向。 env PLAYWRIGHT_MCP_ALLOWED_ORIGINS |
| --allow-unrestricted-file-access | 允许访问工作区根目录之外的文件。同时允许无限制访问 file:// URL。默认情况下,文件系统访问仅限于工作区根目录(如果未配置根目录,则为当前工作目录),并且阻止导航到 file:// URL。 env PLAYWRIGHT_MCP_ALLOW_UNRESTRICTED_FILE_ACCESS |
| --blocked-origins | 阻止浏览器请求的来源的分号分隔列表。黑名单在白名单之前评估。如果未与白名单一起使用,不匹配黑名单的请求仍然被允许。重要提示:不 作为安全边界,且不 影响重定向。 env PLAYWRIGHT_MCP_BLOCKED_ORIGINS |
| --block-service-workers | 阻止服务工作者 env PLAYWRIGHT_MCP_BLOCK_SERVICE_WORKERS |
| --browser | 要使用的浏览器或 chrome 渠道,可能的值:chrome、firefox、webkit、msedge。 env PLAYWRIGHT_MCP_BROWSER |
| --caps | 要启用的附加功能的逗号分隔列表,可能的值:vision、pdf、devtools。 env PLAYWRIGHT_MCP_CAPS |
| --cdp-endpoint | 要连接的 CDP 端点。 env PLAYWRIGHT_MCP_CDP_ENDPOINT |
| --cdp-header <headers...> | 随连接请求发送的 CDP 标头,可指定多个。 env PLAYWRIGHT_MCP_CDP_HEADERS |
| --cdp-timeout | 连接 CDP 端点的超时时间(毫秒),默认为 30000 毫秒 env PLAYWRIGHT_MCP_CDP_TIMEOUT |
| --codegen | 指定用于代码生成的语言,可能的值:"typescript"、"python"、"java"、"csharp"、"none"。默认为 "typescript"。 env PLAYWRIGHT_MCP_CODEGEN |
| --config | 配置文件的路径。 env PLAYWRIGHT_MCP_CONFIG |
| --console-level | 要返回的控制台消息级别:"error"、"warning"、"info"、"debug"。每个级别包含更严重级别的消息。 env PLAYWRIGHT_MCP_CONSOLE_LEVEL |
| --device | 要模拟的设备,例如:"iPhone 15" env PLAYWRIGHT_MCP_DEVICE |
| --mobile | 模拟通用移动设备(Chromium 为 Pixel 10,WebKit 为 iPhone 17)。移动页面通常更轻量,可节省令牌。不能与 --device 组合使用。 env PLAYWRIGHT_MCP_MOBILE |
| --executable-path | 浏览器可执行文件的路径。 env PLAYWRIGHT_MCP_EXECUTABLE_PATH |
| --extension | 连接到正在运行的浏览器实例(仅限 Edge/Chrome)。需要安装 "Playwright Extension"。 env PLAYWRIGHT_MCP_EXTENSION |
| --endpoint | 要连接的绑定浏览器端点。 env PLAYWRIGHT_MCP_ENDPOINT |
| --grant-permissions <permissions...> | 授予浏览器上下文的权限列表,例如 "geolocation"、"clipboard-read"、"clipboard-write"。 env PLAYWRIGHT_MCP_GRANT_PERMISSIONS |
| --headless | 以无头模式运行浏览器,默认有头 env PLAYWRIGHT_MCP_HEADLESS |
| --host | 服务器绑定的主机。默认为 localhost。使用 0.0.0.0 绑定所有接口。 env PLAYWRIGHT_MCP_HOST |
| --ignore-https-errors | 忽略 https 错误 env PLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS |
| --init-page <path...> | 要在 Playwright 页面对象上评估的 TypeScript 文件路径 env PLAYWRIGHT_MCP_INIT_PAGE |
| --init-script <path...> | 要作为初始化脚本添加的 JavaScript 文件路径。该脚本将在每个页面的任何页面脚本之前被评估。可多次指定。 env PLAYWRIGHT_MCP_INIT_SCRIPT |
| --isolated | 将浏览器配置文件保留在内存中,不保存到磁盘。 env PLAYWRIGHT_MCP_ISOLATED |
| --image-responses | 是否将图像响应发送给客户端。可以是 "allow" 或 "omit",默认为 "allow"。 env PLAYWRIGHT_MCP_IMAGE_RESPONSES |
| --no-sandbox | 为所有通常被沙箱化的进程类型禁用沙箱。 env PLAYWRIGHT_MCP_NO_SANDBOX |
| --output-dir | 输出文件的目录路径。 env PLAYWRIGHT_MCP_OUTPUT_DIR |
| --output-max-size | 驱逐旧输出文件的阈值,以字节为单位。 env PLAYWRIGHT_MCP_OUTPUT_MAX_SIZE |
| --port | 用于 SSE 传输的监听端口。 env PLAYWRIGHT_MCP_PORT |
| --proxy-bypass | 绕过代理的逗号分隔域,例如 ".com,chromium.org,.domain.com" env PLAYWRIGHT_MCP_PROXY_BYPASS |
| --proxy-server | 指定代理服务器,例如 "http://myproxy:3128" 或 "socks5://myproxy:8080" env PLAYWRIGHT_MCP_PROXY_SERVER |
| --sandbox | 为所有通常不被沙箱化的进程类型启用沙箱。 env PLAYWRIGHT_MCP_SANDBOX |
| --save-session | 是否将 Playwright MCP 会话保存到输出目录。 env PLAYWRIGHT_MCP_SAVE_SESSION |
| --secrets | 包含 dotenv 格式密钥的文件的路径 env PLAYWRIGHT_MCP_SECRETS_FILE |
| --shared-browser-context | 在所有连接的 HTTP 客户端之间重用相同的浏览器上下文。 env PLAYWRIGHT_MCP_SHARED_BROWSER_CONTEXT |
| --snapshot-boxes | 在快照中包含每个元素的边界框,格式为 [box=x,y,width,height]。坐标相对于视口,以 CSS 像素为单位。 env PLAYWRIGHT_MCP_SNAPSHOT_BOXES |
| --snapshot-mode | 为响应拍摄快照时,指定使用的模式。可以是 "full" 或 "none"。默认为 "full"。 env PLAYWRIGHT_MCP_SNAPSHOT_MODE |
| --storage-state | 隔离会话的存储状态文件路径。 env PLAYWRIGHT_MCP_STORAGE_STATE |
| --test-id-attribute | 指定用于测试 ID 的属性,默认为 "data-testid" env PLAYWRIGHT_MCP_TEST_ID_ATTRIBUTE |
| --timeout-action | 指定操作超时时间(毫秒),默认为 5000 毫秒 env PLAYWRIGHT_MCP_TIMEOUT_ACTION |
| --timeout-navigation | 指定导航超时时间(毫秒),默认为 60000 毫秒 env PLAYWRIGHT_MCP_TIMEOUT_NAVIGATION |
| --timeout-settle | 每次操作后等待触发的工作稳定下来的时间(毫秒),默认为 500 毫秒 env PLAYWRIGHT_MCP_TIMEOUT_SETTLE |
| --user-agent | 指定用户代理字符串 env PLAYWRIGHT_MCP_USER_AGENT |
| --user-data-dir | 用户数据目录的路径。如果未指定,将创建临时目录。 env PLAYWRIGHT_MCP_USER_DATA_DIR |
| --viewport-size | 指定浏览器视口大小(像素),例如 "1280x720" env PLAYWRIGHT_MCP_VIEWPORT_SIZE |
用户配置文件
您可以像普通浏览器一样使用持久配置文件运行 Playwright MCP(默认),在隔离上下文中进行测试会话,或使用浏览器扩展连接到现有浏览器。
持久配置文件
所有登录信息将存储在持久配置文件中,如果您想清除离线状态,可以在会话之间删除它。
持久配置文件位于以下位置,您可以使用 --user-data-dir 参数覆盖它。
# 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} 从 MCP 客户端的工作区根目录派生,因此不同项目会自动获得单独的配置文件。
[!IMPORTANT] 持久配置文件一次只能由一个浏览器实例使用,因此共享同一工作区的并发 MCP 客户端将发生冲突。要并行运行多个客户端,请使用
--isolated启动每个附加客户端,或将其指向不同的--user-data-dir。
隔离模式
在隔离模式下,每个会话都在隔离配置文件中启动。每次您要求 MCP 关闭浏览器时,
会话将关闭,该会话的所有存储状态将丢失。您可以通过配置的 contextOptions 或通过 --storage-state 参数向浏览器提供初始存储状态。了解有关存储
状态的更多信息 此处。
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--isolated",
"--storage-state={path/to/storage.json}"
]
}
}
}
浏览器扩展
Playwright MCP Chrome 扩展允许您连接到现有浏览器标签页,并利用您已登录的会话和浏览器状态。有关安装和设置说明,请参阅 microsoft/playwright › packages/extension。
初始状态
有多种方式可以向浏览器上下文或页面提供初始状态。
对于存储状态,您可以:
- 使用
--user-data-dir参数从用户数据目录开始。这将在会话之间持久化所有浏览器数据。 - 使用
--storage-state参数从存储状态文件开始。这将从文件加载 cookie 和本地存储到隔离的浏览器上下文中。
对于页面状态,您可以使用:
--init-page指向一个 TypeScript 文件,该文件将在 Playwright 页面对象上评估。这允许您运行任意代码来设置页面。
// 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指向一个 JavaScript 文件,该文件将作为初始化脚本添加。该脚本将在每个页面的任何页面脚本之前被评估。 这对于覆盖浏览器 API 或设置环境非常有用。
// init-script.js
window.isPlaywrightMCP = true;
配置文件
Playwright MCP 服务器可以使用 JSON 配置文件进行配置。您可以使用 --config 命令行选项指定配置文件:
npx @playwright/mcp@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. 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;
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.
* - 'devtools': Developer tools features.
*/
capabilities?: ToolCapability[];
/**
* Whether to save the Playwright session into the output directory.
*/
saveSession?: 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>;
/**
* The directory to save output files.
*/
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;
};
/**
* 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?: '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;
/**
* Specify the language to use for code generation.
*/
codegen?: 'typescript' | 'python' | 'java' | 'csharp' | 'none';
}
独立 MCP 服务器
在没有显示器的系统上或从 IDE 的工作进程运行有头浏览器时,
请从具有 DISPLAY 的环境中运行 MCP 服务器,并传递 --port 标志以启用 HTTP 传输。
npx @playwright/mcp@latest --port 8931
然后在 MCP 客户端配置中,将 url 设置为 HTTP 端点:
{
"mcpServers": {
"playwright": {
"url": "http://localhost:8931/mcp"
}
}
}
安全性
Playwright MCP 不是 安全边界。有关保护部署的指导,请参阅 MCP 安全最佳实践。
Docker
注意: Docker 实现目前仅支持无头 Chromium。
{
"mcpServers": {
"playwright": {
"command": "docker",
"args": ["run", "-i", "--rm", "--init", "--pull=always", "mcr.microsoft.com/playwright/mcp"]
}
}
}
或者,如果您希望将容器作为长期运行的服务运行,而不是让 MCP 客户端生成它,请使用:
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
服务器将监听主机端口 8931,任何 MCP 客户端都可以访问。
您可以自行构建 Docker 镜像。
docker build -t mcr.microsoft.com/playwright/mcp .
编程使用
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);
// ...
});
工具
核心自动化
- browser_click
- 标题:点击
- 描述:在网页上执行点击操作
- 参数:
element(字符串,可选):用于获取与元素交互权限的人类可读元素描述target(字符串):页面快照中的精确目标元素引用,或唯一的元素选择器doubleClick(布尔值,可选):是否执行双击而不是单击button(字符串,可选):要点击的按钮,默认为左键modifiers(数组,可选):要按下的修饰键
- 只读:false
- browser_close
- 标题:关闭浏览器
- 描述:关闭页面
- 参数:无
- 只读:false
- browser_console_messages
- 标题:获取控制台消息
- 描述:返回所有控制台消息
- 参数:
level(字符串):要返回的控制台消息级别。每个级别包含更严重级别的消息。默认为“info”。all(布尔值,可选):返回自会话开始以来的所有控制台消息,而不仅仅是自上次导航以来的消息。默认为 false。filename(字符串,可选):将控制台消息保存到的文件名。如果未提供,消息将以文本形式返回。
- 只读:true
- browser_drag
- 标题:拖动鼠标
- 描述:在两个元素之间执行拖放操作
- 参数:
startElement(字符串,可选):用于获取与元素交互权限的人类可读源元素描述startTarget(字符串):页面快照中的精确目标元素引用,或唯一的元素选择器endElement(字符串,可选):用于获取与元素交互权限的人类可读目标元素描述endTarget(字符串):页面快照中的精确目标元素引用,或唯一的元素选择器
- 只读:false
- browser_drop
- 标题:将文件或数据拖放到元素上
- 描述:将文件或 MIME 类型数据拖放到元素上,就像从页面外部拖入一样。必须提供“paths”或“data”中的至少一个。
- 参数:
element(字符串,可选):用于获取与元素交互权限的人类可读元素描述target(字符串):页面快照中的精确目标元素引用,或唯一的元素选择器paths(数组,可选):要拖放到元素上的文件的绝对路径。data(对象,可选):要拖放的数据,作为 MIME 类型到字符串值的映射(例如 {"text/plain": "hello", "text/uri-list": "https://example.com"})。
- 只读:false
- browser_evaluate
- 标题:评估 JavaScript
- 描述:在页面或元素上评估 JavaScript 表达式
- 参数:
element(字符串,可选):用于获取与元素交互权限的人类可读元素描述target(字符串,可选):页面快照中的精确目标元素引用,或唯一的元素选择器function(字符串):() => { /* code / } 或 (element) => { / code */ }(当提供元素时)filename(字符串,可选):将结果保存到的文件名。如果未提供,结果将以文本形式返回。
- 只读:false
- browser_file_upload
- 标题:上传文件
- 描述:上传一个或多个文件
- 参数:
paths(数组,可选):要上传的文件的绝对路径。可以是单个文件或多个文件。如果省略,文件选择器将被取消。
- 只读:false
- browser_fill_form
- 标题:填写表单
- 描述:填写多个表单字段
- 参数:
fields(数组):要填写的字段
- 只读:false
- browser_find
- 标题:在页面快照中查找
- 描述:在当前页面的无障碍快照中搜索文本或正则表达式。返回匹配的快照节点,并附带几行上下文(如搜索片段),每个节点显示在从树根开始的路径下,这比在只需要定位元素及其引用时捕获整个快照更节省资源。
- 参数:
text(字符串,可选):在页面快照中搜索的纯文本(不区分大小写的子字符串匹配)。提供文本或正则表达式,不要同时提供。regex(字符串,可选):在页面快照中搜索的正则表达式。默认区分大小写;将模式包裹在斜杠中以添加标志,例如 "/error/i" 表示不区分大小写。提供文本或正则表达式,不要同时提供。
- 只读:true
- browser_handle_dialog
- 标题:处理对话框
- 描述:处理对话框
- 参数:
accept(布尔值):是否接受对话框。promptText(字符串,可选):如果是提示对话框,则为提示的文本。
- 只读:false
- browser_hover
- 标题:悬停鼠标
- 描述:将鼠标悬停在页面元素上
- 参数:
element(字符串,可选):用于获取与元素交互权限的人类可读元素描述target(字符串):页面快照中的精确目标元素引用,或唯一的元素选择器
- 只读:false
- browser_navigate
- 标题:导航到 URL
- 描述:导航到 URL
- 参数:
url(字符串):要导航到的 URL
- 只读:false
- browser_navigate_back
- 标题:返回
- 描述:返回历史记录中的上一个页面
- 参数:无
- 只读:false
- browser_network_request
- 标题:显示网络请求详情
- 描述:返回单个网络请求的完整详情(标头和正文),如果设置了
part,则返回单个部分。使用 browser_network_requests 中的编号。 - 参数:
index(整数):请求的从 1 开始的索引,如 browser_network_requests 所打印的。part(字符串,可选):仅返回请求的此部分。省略以返回完整详情。filename(字符串,可选):将结果保存到的文件名。如果未提供,输出将以文本形式返回。
- 只读:true
- browser_network_requests
- 标题:列出网络请求
- 描述:返回自页面加载以来的编号网络请求列表。使用 browser_network_request 和编号获取完整详情。
- 参数:
static(布尔值):是否包含成功的静态资源,如图像、字体、脚本等。默认为 false。filter(字符串,可选):仅返回 URL 匹配此正则表达式的请求(例如 "/api/.*user")。filename(字符串,可选):将网络请求保存到的文件名。如果未提供,请求将以文本形式返回。
- 只读:true
- browser_press_key
- 标题:按键
- 描述:在键盘上按键
- 参数:
key(字符串):要按下的键的名称或要生成的字符,例如ArrowLeft或a
- 只读:false
- browser_resize
- 标题:调整浏览器窗口大小
- 描述:调整浏览器窗口大小
- 参数:
width(数字):浏览器窗口的宽度height(数字):浏览器窗口的高度
- 只读:false
- browser_run_code_unsafe
- 标题:运行 Playwright 代码(不安全)
- 描述:运行 Playwright 代码片段。不安全:在 Playwright 服务器进程中执行任意 JavaScript,等同于 RCE。
- 参数:
code(字符串,可选):包含要执行的 Playwright 代码的 JavaScript 函数。它将使用单个参数 page 调用,您可以使用它进行任何页面交互。例如:async (page) => { await page.getByRole('button', { name: 'Submit' }).click(); return await page.title(); }filename(字符串,可选):从指定文件加载代码。如果同时提供代码和文件名,代码将被忽略。
- 只读:false
- browser_select_option
- 标题:选择选项
- 描述:在下拉列表中选择一个选项
- 参数:
element(字符串,可选):用于获取与元素交互权限的人类可读元素描述target(字符串):页面快照中的精确目标元素引用,或唯一的元素选择器values(数组):要在下拉列表中选择的值数组。可以是单个值或多个值。
- 只读:false
- browser_snapshot
- 标题:页面快照
- 描述:捕获当前页面的无障碍快照,这比截图更好
- 参数:
target(字符串,可选):页面快照中的精确目标元素引用,或唯一的元素选择器filename(字符串,可选):将快照保存到 markdown 文件,而不是在响应中返回。depth(数字,可选):限制快照树的深度boxes(布尔值,可选):在快照中包含每个元素的边界框,格式为 [box=x,y,width,height]。坐标相对于视口,以 CSS 像素为单位(Element.getBoundingClientRect)
- 只读:true
- browser_take_screenshot
- 标题:截图
- 描述:截取当前页面的截图。您不能基于截图执行操作,请使用 browser_snapshot 进行操作。
- 参数:
element(字符串,可选):用于获取与元素交互权限的人类可读元素描述target(字符串,可选):页面快照中的精确目标元素引用,或唯一的元素选择器type(字符串,可选):截图的图像格式。如果未设置,则从文件扩展名推断,否则为 png。filename(字符串,可选):保存截图的文件名。如果未指定,默认为page-{timestamp}.{png|jpeg|webp}。建议使用相对文件名以保持在输出目录内。fullPage(布尔值,可选):为 true 时,截取整个可滚动页面的截图,而不是当前可见的视口。不能与元素截图一起使用。scale(字符串):图像分辨率比例。“css”生成以 CSS 像素为单位的截图(较小,跨设备一致)。“device”使用设备像素生成高分辨率截图(较大,考虑设备像素比)。默认为 css。
- 只读:true
- browser_type
- 标题:输入文本
- 描述:在可编辑元素中输入文本
- 参数:
element(字符串,可选):用于获取与元素交互权限的人类可读元素描述target(字符串):页面快照中的精确目标元素引用,或唯一的元素选择器text(字符串):要输入到元素中的文本submit(布尔值,可选):是否提交输入的文本(之后按 Enter)slowly(布尔值,可选):是否一次输入一个字符。用于触发页面中的按键处理程序。默认情况下,整个文本一次性填入。
- 只读:false
- browser_wait_for
- 标题:等待
- 描述:等待文本出现或消失,或等待指定时间过去
- 参数:
time(数字,可选):等待的时间(秒)text(字符串,可选):要等待出现的文本textGone(字符串,可选):要等待消失的文本
- 只读:false
标签页管理
- browser_tabs
- 标题:管理标签页
- 描述:列出、创建、关闭或选择浏览器标签页。
- 参数:
action(字符串):要执行的操作index(数字,可选):标签页索引,用于关闭/选择。如果关闭时省略,则关闭当前标签页。url(字符串,可选):新标签页中要导航到的 URL,用于新建。
- 只读:false
浏览器安装
配置(通过 --caps=config 选择加入)
- browser_get_config
- 标题:获取配置
- 描述:获取合并 CLI 选项、环境变量和配置文件后的最终解析配置。
- 参数:无
- 只读:true
网络(通过 --caps=network 选择加入)
- browser_network_state_set
- 标题:设置网络状态
- 描述:将浏览器网络状态设置为在线或离线。离线时,所有网络请求都将失败。
- 参数:
state(字符串):设置为 "offline" 以模拟离线模式,"online" 以恢复网络连接
- 只读:false
- browser_route
- 标题:模拟网络请求
- 描述:设置路由以模拟匹配 URL 模式的网络请求
- 参数:
pattern(字符串):要匹配的 URL 模式(例如,"/api/users"、"/*.{png,jpg}")status(数字,可选):要返回的 HTTP 状态码(默认:200)body(字符串,可选):响应体(文本或 JSON 字符串)contentType(字符串,可选):Content-Type 标头(例如,"application/json"、"text/html")headers(数组,可选):以 "名称: 值" 格式添加的标头removeHeaders(字符串,可选):要从请求中移除的标头名称的逗号分隔列表
- 只读:false
- browser_route_list
- 标题:列出网络路由
- 描述:列出所有活动的网络路由
- 参数:无
- 只读:true
- browser_unroute
- 标题:移除网络路由
- 描述:移除匹配模式的路由(如果未指定模式,则移除所有路由)
- 参数:
pattern(字符串,可选):要取消路由的 URL 模式(省略以移除所有路由)
- 只读:false
存储(通过 --caps=storage 选择加入)
- browser_cookie_clear
- 标题:清除 Cookie
- 描述:清除所有 Cookie
- 参数:无
- 只读:false
- browser_cookie_delete
- 标题:删除 Cookie
- 描述:删除特定的 Cookie
- 参数:
name(字符串):要删除的 Cookie 名称
- 只读:false
- browser_cookie_get
- 标题:获取 Cookie
- 描述:按名称获取特定的 Cookie
- 参数:
name(字符串):要获取的 Cookie 名称
- 只读:true
- browser_cookie_list
- 标题:列出 Cookie
- 描述:列出所有 Cookie(可选地按域/路径过滤)
- 参数:
domain(字符串,可选):按域过滤 Cookiepath(字符串,可选):按路径过滤 Cookie
- 只读:true
- browser_cookie_set
- 标题:设置 Cookie
- 描述:设置带有可选标志的 Cookie(域、路径、过期时间、httpOnly、secure、sameSite)
- 参数:
name(字符串):Cookie 名称value(字符串):Cookie 值domain(字符串,可选):Cookie 域path(字符串,可选):Cookie 路径expires(数字,可选):Cookie 过期时间(Unix 时间戳)httpOnly(布尔值,可选):Cookie 是否仅限 HTTPsecure(布尔值,可选):Cookie 是否安全sameSite(字符串,可选):Cookie 的 SameSite 属性
- 只读:false
- browser_localstorage_clear
- 标题:清除 localStorage
- 描述:清除所有 localStorage
- 参数:无
- 只读:false
- browser_localstorage_delete
- 标题:删除 localStorage 项
- 描述:删除一个 localStorage 项
- 参数:
key(字符串):要删除的键
- 只读:false
- browser_localstorage_get
- 标题:获取 localStorage 项
- 描述:按键获取 localStorage 项
- 参数:
key(字符串):要获取的键
- 只读:true
- browser_localstorage_list
- 标题:列出 localStorage
- 描述:列出所有 localStorage 键值对
- 参数:无
- 只读:true
- browser_localstorage_set
- 标题:设置 localStorage 项
- 描述:设置一个 localStorage 项
- 参数:
key(字符串):要设置的键value(字符串):要设置的值
- 只读:false
- browser_sessionstorage_clear
- 标题:清除 sessionStorage
- 描述:清除所有 sessionStorage
- 参数:无
- 只读:false
- browser_sessionstorage_delete
- 标题:删除 sessionStorage 项
- 描述:删除一个 sessionStorage 项
- 参数:
key(字符串):要删除的键
- 只读:false
- browser_sessionstorage_get
- 标题:获取 sessionStorage 项
- 描述:按键获取 sessionStorage 项
- 参数:
key(字符串):要获取的键
- 只读:true
- browser_sessionstorage_list
- 标题:列出 sessionStorage
- 描述:列出所有 sessionStorage 键值对
- 参数:无
- 只读:true
- browser_sessionstorage_set
- 标题:设置 sessionStorage 项
- 描述:设置一个 sessionStorage 项
- 参数:
key(字符串):要设置的键value(字符串):要设置的值
- 只读:false
- browser_set_storage_state
- 标题:恢复存储状态
- 描述:从文件恢复存储状态(Cookie、本地存储)。这会在恢复前清除现有的 Cookie 和本地存储。
- 参数:
filename(字符串):要从中恢复的存储状态文件的路径
- 只读:false
- browser_storage_state
- 标题:保存存储状态
- 描述:将存储状态(Cookie、本地存储)保存到文件以供以后重用
- 参数:
filename(字符串,可选):保存存储状态的文件名。如果未指定,默认为storage-state-{timestamp}.json。
- 只读:true
DevTools(通过 --caps=devtools 选择加入)
- browser_annotate
- 标题:注释当前页面
- 描述:以注释模式为当前页面打开 Playwright Dashboard,并等待用户绘制注释。返回带注释的截图、ARIA 快照和注释列表。
- 参数:无
- 只读:true
- browser_hide_highlight
- 标题:隐藏元素高亮
- 描述:移除先前为元素添加的高亮覆盖层。
- 参数:
element(字符串,可选):添加高亮时使用的人类可读元素描述;必须与传递给 browser_highlight 的值匹配。target(字符串,可选):页面快照中的精确目标元素引用,或唯一的元素选择器
- 只读:true
- browser_highlight
- 标题:高亮元素
- 描述:在页面上元素周围显示持久的高亮覆盖层。
- 参数:
element(字符串,可选):用于获取与元素交互权限的人类可读元素描述target(字符串):页面快照中的精确目标元素引用,或唯一的元素选择器style(字符串,可选):应用于高亮覆盖层的额外内联 CSS,例如 "outline: 2px dashed red"。
- 只读:true
- browser_resume
- 标题:恢复暂停的脚本执行
- 描述:在脚本执行暂停后恢复执行。当 step 设置为 true 时,执行将在下一个操作前再次暂停。
- 参数:
step(布尔值,可选):为 true 时,执行将在下一个操作前再次暂停,允许逐步调试。location(字符串,可选):在特定的 : 处暂停执行,例如 "example.spec.ts:42"。
- 只读:false
- browser_start_recording
- 标题:开始录制用户操作
- 描述:开始将用户在浏览器中执行的操作录制为 Playwright 代码。当用户希望手动演示流程时使用。当用户表示完成时,调用 browser_stop_recording 以获取录制的操作。
- 参数:无
- 只读:true
- browser_start_tracing
- 标题:开始跟踪
- 描述:开始录制跟踪
- 参数:无
- 只读:true
- browser_start_video
- 标题:开始视频
- 描述:开始视频录制
- 参数:
filename(字符串,可选):保存视频的文件名。size(对象,可选):视频大小
- 只读:true
- browser_stop_recording
- 标题:停止录制用户操作
- 描述:停止使用 browser_start_recording 开始的录制,并将录制的操作作为 Playwright 代码返回。
- 参数:无
- 只读:true
- browser_stop_tracing
- 标题:停止跟踪
- 描述:停止跟踪录制
- 参数:无
- 只读:true
- browser_stop_video
- 标题:停止视频
- 描述:停止视频录制
- 参数:无
- 只读:true
- browser_video_chapter
- 标题:视频章节
- 描述:向视频录制添加章节标记。显示带有模糊背景的全屏章节卡片。
- 参数:
title(字符串):章节标题description(字符串,可选):章节描述duration(数字,可选):显示章节卡片的持续时间(毫秒)
- 只读:true
- browser_video_hide_actions
- 标题:隐藏操作覆盖层
- 描述:停止注释页面上执行的操作。
- 参数:无
- 只读:true
- browser_video_show_actions
- 标题:显示操作叠加层
- 描述:在页面上执行后续操作时,用标注框标注操作名称并高亮目标元素。在录制视频或屏幕录制时非常有用。
- 参数:
duration(数字,可选):每个操作标注在屏幕上停留的时间,以毫秒为单位。默认值为 500。position(字符串,可选):操作标题相对于页面的放置位置。默认值为右上角。cursor(字符串,可选):指针操作的鼠标装饰。"pointer"(默认)会从上一个操作点动画显示鼠标指针到下一个操作点;"none" 禁用鼠标装饰。
- 只读:true
基于坐标(通过 --caps=vision 选择加入)
- browser_mouse_click_xy
- 标题:点击
- 描述:在指定位置点击鼠标按钮
- 参数:
x(数字):X 坐标y(数字):Y 坐标button(字符串,可选):要点击的按钮,默认为左键clickCount(数字,可选):点击次数,默认为 1delay(数字,可选):鼠标按下和释放之间的等待时间,以毫秒为单位,默认为 0
- 只读:false
- browser_mouse_down
- 标题:按下鼠标
- 描述:按下鼠标
- 参数:
button(字符串,可选):要按下的按钮,默认为左键
- 只读:false
- browser_mouse_drag_xy
- 标题:拖动鼠标
- 描述:将左键拖动到指定位置
- 参数:
startX(数字):起始 X 坐标startY(数字):起始 Y 坐标endX(数字):结束 X 坐标endY(数字):结束 Y 坐标
- 只读:false
- browser_mouse_move_xy
- 标题:移动鼠标
- 描述:将鼠标移动到指定位置
- 参数:
x(数字):X 坐标y(数字):Y 坐标
- 只读:false
- browser_mouse_up
- 标题:释放鼠标
- 描述:释放鼠标
- 参数:
button(字符串,可选):要释放的按钮,默认为左键
- 只读:false
- browser_mouse_wheel
- 标题:滚动鼠标滚轮
- 描述:滚动鼠标滚轮
- 参数:
deltaX(数字):X 增量deltaY(数字):Y 增量
- 只读:false
PDF 生成(通过 --caps=pdf 选择加入)
- browser_pdf_save
- 标题:另存为 PDF
- 描述:将页面另存为 PDF
- 参数:
filename(字符串,可选):保存 PDF 的文件名。如果未指定,默认为page-{timestamp}.pdf。建议使用相对文件名以保持在输出目录内。
- 只读:true
测试断言(通过 --caps=testing 选择加入)
- browser_generate_locator
- 标题:为元素创建定位器
- 描述:为给定元素生成定位器,用于测试
- 参数:
element(字符串,可选):用于获取与元素交互权限的人类可读元素描述target(字符串):页面快照中的精确目标元素引用,或唯一的元素选择器
- 只读:true
- browser_verify_element_visible
- 标题:验证元素可见
- 描述:验证元素在页面上可见
- 参数:
role(字符串):元素的 ROLE。可以在快照中这样找到:- {ROLE} "Accessible Name":accessibleName(字符串):元素的 ACCESSIBLE_NAME。可以在快照中这样找到:- role "{ACCESSIBLE_NAME}"
- 只读:false
- browser_verify_list_visible
- 标题:验证列表可见
- 描述:验证列表在页面上可见
- 参数:
element(字符串):人类可读的列表描述target(字符串):指向列表的精确目标元素引用items(数组):要验证的项目
- 只读:false
- browser_verify_text_visible
- 标题:验证文本可见
- 描述:验证文本在页面上可见。如果可能,优先使用 browser_verify_element_visible。
- 参数:
text(字符串):要验证的 TEXT。可以在快照中这样找到:- role "Accessible Name": {TEXT}或这样:- text: {TEXT}
- 只读:false
- browser_verify_value
- 标题:验证值
- 描述:验证元素值
- 参数:
type(字符串):元素类型element(字符串):人类可读的元素描述target(字符串):页面快照中的精确目标元素引用value(字符串):要验证的值。对于复选框,使用 "true" 或 "false"。
- 只读:false