@roxybrowser/playwright-mcp 0.0.5 → 0.0.6-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +832 -742
  2. package/dist/cli.mjs +250 -0
  3. package/dist/cli.mjs.LICENSE.txt +42 -0
  4. package/dist/index.mjs +250 -0
  5. package/dist/index.mjs.LICENSE.txt +42 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/index.d.ts +86 -23
  8. package/package.json +27 -41
  9. package/cli.js +0 -18
  10. package/config.d.ts +0 -119
  11. package/index.js +0 -19
  12. package/lib/browserContextFactory.js +0 -264
  13. package/lib/browserServerBackend.js +0 -77
  14. package/lib/config.js +0 -246
  15. package/lib/context.js +0 -242
  16. package/lib/extension/cdpRelay.js +0 -355
  17. package/lib/extension/extensionContextFactory.js +0 -54
  18. package/lib/index.js +0 -40
  19. package/lib/loop/loop.js +0 -69
  20. package/lib/loop/loopClaude.js +0 -152
  21. package/lib/loop/loopOpenAI.js +0 -141
  22. package/lib/loop/main.js +0 -60
  23. package/lib/loopTools/context.js +0 -67
  24. package/lib/loopTools/main.js +0 -54
  25. package/lib/loopTools/perform.js +0 -32
  26. package/lib/loopTools/snapshot.js +0 -29
  27. package/lib/loopTools/tool.js +0 -18
  28. package/lib/mcp/http.js +0 -120
  29. package/lib/mcp/inProcessTransport.js +0 -72
  30. package/lib/mcp/proxyBackend.js +0 -104
  31. package/lib/mcp/server.js +0 -123
  32. package/lib/mcp/tool.js +0 -29
  33. package/lib/program.js +0 -145
  34. package/lib/response.js +0 -165
  35. package/lib/sessionLog.js +0 -121
  36. package/lib/tab.js +0 -249
  37. package/lib/tools/common.js +0 -55
  38. package/lib/tools/console.js +0 -33
  39. package/lib/tools/dialogs.js +0 -47
  40. package/lib/tools/evaluate.js +0 -53
  41. package/lib/tools/files.js +0 -44
  42. package/lib/tools/install.js +0 -53
  43. package/lib/tools/keyboard.js +0 -78
  44. package/lib/tools/mouse.js +0 -99
  45. package/lib/tools/navigate.js +0 -70
  46. package/lib/tools/network.js +0 -41
  47. package/lib/tools/pdf.js +0 -40
  48. package/lib/tools/roxy.js +0 -50
  49. package/lib/tools/screenshot.js +0 -79
  50. package/lib/tools/snapshot.js +0 -139
  51. package/lib/tools/tabs.js +0 -87
  52. package/lib/tools/tool.js +0 -33
  53. package/lib/tools/utils.js +0 -74
  54. package/lib/tools/wait.js +0 -55
  55. package/lib/tools.js +0 -52
  56. package/lib/utils/codegen.js +0 -49
  57. package/lib/utils/fileUtils.js +0 -36
  58. package/lib/utils/guid.js +0 -22
  59. package/lib/utils/log.js +0 -21
  60. package/lib/utils/manualPromise.js +0 -111
  61. package/lib/utils/package.js +0 -20
  62. package/lib/vscode/host.js +0 -128
  63. package/lib/vscode/main.js +0 -62
package/README.md CHANGED
@@ -1,742 +1,832 @@
1
- ## Playwright MCP
2
-
3
- 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.
4
-
5
- ### Key Features
6
-
7
- - **Fast and lightweight**. Uses Playwright's accessibility tree, not pixel-based input.
8
- - **LLM-friendly**. No vision models needed, operates purely on structured data.
9
- - **Deterministic tool application**. Avoids ambiguity common with screenshot-based approaches.
10
-
11
- ### Requirements
12
- - Node.js 18 or newer
13
- - VS Code, Cursor, Windsurf, Claude Desktop, Goose or any other MCP client
14
-
15
- <!--
16
- // Generate using:
17
- node utils/generate-links.js
18
- -->
19
-
20
- ### Getting started
21
-
22
- First, install the Playwright MCP server with your client.
23
-
24
- **Standard config** works in most of the tools:
25
-
26
- ```js
27
- {
28
- "mcpServers": {
29
- "playwright": {
30
- "command": "npx",
31
- "args": [
32
- "@playwright/mcp@latest"
33
- ]
34
- }
35
- }
36
- }
37
- ```
38
-
39
- [<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)
40
-
41
-
42
- <details>
43
- <summary>Claude Code</summary>
44
-
45
- Use the Claude Code CLI to add the Playwright MCP server:
46
-
47
- ```bash
48
- claude mcp add playwright npx @playwright/mcp@latest
49
- ```
50
- </details>
51
-
52
- <details>
53
- <summary>Claude Desktop</summary>
54
-
55
- Follow the MCP install [guide](https://modelcontextprotocol.io/quickstart/user), use the standard config above.
56
-
57
- </details>
58
-
59
- <details>
60
- <summary>Codex</summary>
61
-
62
- Create or edit the configuration file `~/.codex/config.toml` and add:
63
-
64
- ```toml
65
- [mcp_servers.playwright]
66
- command = "npx"
67
- args = ["@playwright/mcp@latest"]
68
- ```
69
-
70
- For more information, see the [Codex MCP documentation](https://github.com/openai/codex/blob/main/codex-rs/config.md#mcp_servers).
71
-
72
- </details>
73
-
74
- <details>
75
- <summary>Cursor</summary>
76
-
77
- #### Click the button to install:
78
-
79
- [![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](cursor://anysphere.cursor-deeplink/mcp/install?name=Playwright&config=eyJjb21tYW5kIjoibnB4IEBwbGF5d3JpZ2h0L21jcEBsYXRlc3QifQ%3D%3D)
80
-
81
- #### Or install manually:
82
-
83
- Go to `Cursor Settings` -> `MCP` -> `Add new MCP Server`. Name to your liking, use `command` type with the command `npx @playwright/mcp`. You can also verify config or add command like arguments via clicking `Edit`.
84
-
85
- </details>
86
-
87
- <details>
88
- <summary>Gemini CLI</summary>
89
-
90
- 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.
91
-
92
- </details>
93
-
94
- <details>
95
- <summary>Goose</summary>
96
-
97
- #### Click the button to install:
98
-
99
- [![Install in Goose](https://block.github.io/goose/img/extension-install-dark.svg)](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)
100
-
101
- #### Or install manually:
102
-
103
- 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".
104
- </details>
105
-
106
- <details>
107
- <summary>LM Studio</summary>
108
-
109
- #### Click the button to install:
110
-
111
- [![Add MCP Server playwright to LM Studio](https://files.lmstudio.ai/deeplink/mcp-install-light.svg)](https://lmstudio.ai/install-mcp?name=playwright&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyJAcGxheXdyaWdodC9tY3BAbGF0ZXN0Il19)
112
-
113
- #### Or install manually:
114
-
115
- Go to `Program` in the right sidebar -> `Install` -> `Edit mcp.json`. Use the standard config above.
116
- </details>
117
-
118
- <details>
119
- <summary>opencode</summary>
120
-
121
- Follow the MCP Servers [documentation](https://opencode.ai/docs/mcp-servers/). For example in `~/.config/opencode/opencode.json`:
122
-
123
- ```json
124
- {
125
- "$schema": "https://opencode.ai/config.json",
126
- "mcp": {
127
- "playwright": {
128
- "type": "local",
129
- "command": [
130
- "npx",
131
- "@playwright/mcp@latest"
132
- ],
133
- "enabled": true
134
- }
135
- }
136
- }
137
-
138
- ```
139
- </details>
140
-
141
- <details>
142
- <summary>Qodo Gen</summary>
143
-
144
- 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.
145
-
146
- Click <code>Save</code>.
147
- </details>
148
-
149
- <details>
150
- <summary>VS Code</summary>
151
-
152
- #### Click the button to install:
153
-
154
- [<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)
155
-
156
- #### Or install manually:
157
-
158
- 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:
159
-
160
- ```bash
161
- # For VS Code
162
- code --add-mcp '{"name":"playwright","command":"npx","args":["@playwright/mcp@latest"]}'
163
- ```
164
-
165
- After installation, the Playwright MCP server will be available for use with your GitHub Copilot agent in VS Code.
166
- </details>
167
-
168
- <details>
169
- <summary>Windsurf</summary>
170
-
171
- Follow Windsurf MCP [documentation](https://docs.windsurf.com/windsurf/cascade/mcp). Use the standard config above.
172
-
173
- </details>
174
-
175
- ### Configuration
176
-
177
- Playwright MCP server supports following arguments. They can be provided in the JSON configuration above, as a part of the `"args"` list:
178
-
179
- <!--- Options generated by update-readme.js -->
180
-
181
- ```
182
- > npx @playwright/mcp@latest --help
183
- --allowed-origins <origins> semicolon-separated list of origins to allow the
184
- browser to request. Default is to allow all.
185
- --blocked-origins <origins> semicolon-separated list of origins to block the
186
- browser from requesting. Blocklist is evaluated
187
- before allowlist. If used without the allowlist,
188
- requests not matching the blocklist are still
189
- allowed.
190
- --block-service-workers block service workers
191
- --browser <browser> browser or chrome channel to use, possible
192
- values: chrome, firefox, webkit, msedge.
193
- --caps <caps> comma-separated list of additional capabilities
194
- to enable, possible values: vision, pdf.
195
- --cdp-endpoint <endpoint> CDP endpoint to connect to.
196
- --config <path> path to the configuration file.
197
- --device <device> device to emulate, for example: "iPhone 15"
198
- --executable-path <path> path to the browser executable.
199
- --extension Connect to a running browser instance
200
- (Edge/Chrome only). Requires the "Playwright MCP
201
- Bridge" browser extension to be installed.
202
- --headless run browser in headless mode, headed by default
203
- --host <host> host to bind server to. Default is localhost. Use
204
- 0.0.0.0 to bind to all interfaces.
205
- --ignore-https-errors ignore https errors
206
- --isolated keep the browser profile in memory, do not save
207
- it to disk.
208
- --image-responses <mode> whether to send image responses to the client.
209
- Can be "allow" or "omit", Defaults to "allow".
210
- --no-sandbox disable the sandbox for all process types that
211
- are normally sandboxed.
212
- --output-dir <path> path to the directory for output files.
213
- --port <port> port to listen on for SSE transport.
214
- --proxy-bypass <bypass> comma-separated domains to bypass proxy, for
215
- example ".com,chromium.org,.domain.com"
216
- --proxy-server <proxy> specify proxy server, for example
217
- "http://myproxy:3128" or "socks5://myproxy:8080"
218
- --save-session Whether to save the Playwright MCP session into
219
- the output directory.
220
- --save-trace Whether to save the Playwright Trace of the
221
- session into the output directory.
222
- --storage-state <path> path to the storage state file for isolated
223
- sessions.
224
- --user-agent <ua string> specify user agent string
225
- --user-data-dir <path> path to the user data directory. If not
226
- specified, a temporary directory will be created.
227
- --viewport-size <size> specify browser viewport size in pixels, for
228
- example "1280, 720"
229
- ```
230
-
231
- <!--- End of options generated section -->
232
-
233
- ### User profile
234
-
235
- 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.
236
-
237
- **Persistent profile**
238
-
239
- 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.
240
- Persistent profile is located at the following locations and you can override it with the `--user-data-dir` argument.
241
-
242
- ```bash
243
- # Windows
244
- %USERPROFILE%\AppData\Local\ms-playwright\mcp-{channel}-profile
245
-
246
- # macOS
247
- - ~/Library/Caches/ms-playwright/mcp-{channel}-profile
248
-
249
- # Linux
250
- - ~/.cache/ms-playwright/mcp-{channel}-profile
251
- ```
252
-
253
- **Isolated**
254
-
255
- In the isolated mode, each session is started in the isolated profile. Every time you ask MCP to close the browser,
256
- the session is closed and all the storage state for this session is lost. You can provide initial storage state
257
- to the browser via the config's `contextOptions` or via the `--storage-state` argument. Learn more about the storage
258
- state [here](https://playwright.dev/docs/auth).
259
-
260
- ```js
261
- {
262
- "mcpServers": {
263
- "playwright": {
264
- "command": "npx",
265
- "args": [
266
- "@playwright/mcp@latest",
267
- "--isolated",
268
- "--storage-state={path/to/storage.json}"
269
- ]
270
- }
271
- }
272
- }
273
- ```
274
-
275
- **Browser Extension**
276
-
277
- The Playwright MCP Chrome Extension allows you to connect to existing browser tabs and leverage your logged-in sessions and browser state. See [extension/README.md](extension/README.md) for installation and setup instructions.
278
-
279
- ### Configuration file
280
-
281
- The Playwright MCP server can be configured using a JSON configuration file. You can specify the configuration file
282
- using the `--config` command line option:
283
-
284
- ```bash
285
- npx @playwright/mcp@latest --config path/to/config.json
286
- ```
287
-
288
- <details>
289
- <summary>Configuration file schema</summary>
290
-
291
- ```typescript
292
- {
293
- // Browser configuration
294
- browser?: {
295
- // Browser type to use (chromium, firefox, or webkit)
296
- browserName?: 'chromium' | 'firefox' | 'webkit';
297
-
298
- // Keep the browser profile in memory, do not save it to disk.
299
- isolated?: boolean;
300
-
301
- // Path to user data directory for browser profile persistence
302
- userDataDir?: string;
303
-
304
- // Browser launch options (see Playwright docs)
305
- // @see https://playwright.dev/docs/api/class-browsertype#browser-type-launch
306
- launchOptions?: {
307
- channel?: string; // Browser channel (e.g. 'chrome')
308
- headless?: boolean; // Run in headless mode
309
- executablePath?: string; // Path to browser executable
310
- // ... other Playwright launch options
311
- };
312
-
313
- // Browser context options
314
- // @see https://playwright.dev/docs/api/class-browser#browser-new-context
315
- contextOptions?: {
316
- viewport?: { width: number, height: number };
317
- // ... other Playwright context options
318
- };
319
-
320
- // CDP endpoint for connecting to existing browser
321
- cdpEndpoint?: string;
322
-
323
- // Remote Playwright server endpoint
324
- remoteEndpoint?: string;
325
- },
326
-
327
- // Server configuration
328
- server?: {
329
- port?: number; // Port to listen on
330
- host?: string; // Host to bind to (default: localhost)
331
- },
332
-
333
- // List of additional capabilities
334
- capabilities?: Array<
335
- 'tabs' | // Tab management
336
- 'install' | // Browser installation
337
- 'pdf' | // PDF generation
338
- 'vision' | // Coordinate-based interactions
339
- >;
340
-
341
- // Directory for output files
342
- outputDir?: string;
343
-
344
- // Network configuration
345
- network?: {
346
- // List of origins to allow the browser to request. Default is to allow all. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
347
- allowedOrigins?: string[];
348
-
349
- // List of origins to block the browser to request. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
350
- blockedOrigins?: string[];
351
- };
352
-
353
- /**
354
- * Whether to send image responses to the client. Can be "allow" or "omit".
355
- * Defaults to "allow".
356
- */
357
- imageResponses?: 'allow' | 'omit';
358
- }
359
- ```
360
- </details>
361
-
362
- ### Standalone MCP server
363
-
364
- When running headed browser on system w/o display or from worker processes of the IDEs,
365
- run the MCP server from environment with the DISPLAY and pass the `--port` flag to enable HTTP transport.
366
-
367
- ```bash
368
- npx @playwright/mcp@latest --port 8931
369
- ```
370
-
371
- And then in MCP client config, set the `url` to the HTTP endpoint:
372
-
373
- ```js
374
- {
375
- "mcpServers": {
376
- "playwright": {
377
- "url": "http://localhost:8931/mcp"
378
- }
379
- }
380
- }
381
- ```
382
-
383
- <details>
384
- <summary><b>Docker</b></summary>
385
-
386
- **NOTE:** The Docker implementation only supports headless chromium at the moment.
387
-
388
- ```js
389
- {
390
- "mcpServers": {
391
- "playwright": {
392
- "command": "docker",
393
- "args": ["run", "-i", "--rm", "--init", "--pull=always", "mcr.microsoft.com/playwright/mcp"]
394
- }
395
- }
396
- }
397
- ```
398
-
399
- You can build the Docker image yourself.
400
-
401
- ```
402
- docker build -t mcr.microsoft.com/playwright/mcp .
403
- ```
404
- </details>
405
-
406
- <details>
407
- <summary><b>Programmatic usage</b></summary>
408
-
409
- ```js
410
- import http from 'http';
411
-
412
- import { createConnection } from '@playwright/mcp';
413
- import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
414
-
415
- http.createServer(async (req, res) => {
416
- // ...
417
-
418
- // Creates a headless Playwright MCP server with SSE transport
419
- const connection = await createConnection({ browser: { launchOptions: { headless: true } } });
420
- const transport = new SSEServerTransport('/messages', res);
421
- await connection.sever.connect(transport);
422
-
423
- // ...
424
- });
425
- ```
426
- </details>
427
-
428
- ### Tools
429
-
430
- <!--- Tools generated by update-readme.js -->
431
-
432
- <details>
433
- <summary><b>Core automation</b></summary>
434
-
435
- <!-- NOTE: This has been generated via update-readme.js -->
436
-
437
- - **browser_click**
438
- - Title: Click
439
- - Description: Perform click on a web page
440
- - Parameters:
441
- - `element` (string): Human-readable element description used to obtain permission to interact with the element
442
- - `ref` (string): Exact target element reference from the page snapshot
443
- - `doubleClick` (boolean, optional): Whether to perform a double click instead of a single click
444
- - `button` (string, optional): Button to click, defaults to left
445
- - Read-only: **false**
446
-
447
- <!-- NOTE: This has been generated via update-readme.js -->
448
-
449
- - **browser_close**
450
- - Title: Close browser
451
- - Description: Close the page
452
- - Parameters: None
453
- - Read-only: **true**
454
-
455
- <!-- NOTE: This has been generated via update-readme.js -->
456
-
457
- - **browser_connect_roxy**
458
- - Title: Connect to RoxyBrowser
459
- - Description: Connect to RoxyBrowser using CDP WebSocket endpoint
460
- - Parameters:
461
- - `cdpEndpoint` (string): The CDP WebSocket endpoint URL from RoxyBrowser (e.g., ws://127.0.0.1:59305/devtools/browser/4d876b0b-6adc-4e9f-b572-bb68ff02a199)
462
- - Read-only: **false**
463
-
464
- <!-- NOTE: This has been generated via update-readme.js -->
465
-
466
- - **browser_console_messages**
467
- - Title: Get console messages
468
- - Description: Returns all console messages
469
- - Parameters: None
470
- - Read-only: **true**
471
-
472
- <!-- NOTE: This has been generated via update-readme.js -->
473
-
474
- - **browser_drag**
475
- - Title: Drag mouse
476
- - Description: Perform drag and drop between two elements
477
- - Parameters:
478
- - `startElement` (string): Human-readable source element description used to obtain the permission to interact with the element
479
- - `startRef` (string): Exact source element reference from the page snapshot
480
- - `endElement` (string): Human-readable target element description used to obtain the permission to interact with the element
481
- - `endRef` (string): Exact target element reference from the page snapshot
482
- - Read-only: **false**
483
-
484
- <!-- NOTE: This has been generated via update-readme.js -->
485
-
486
- - **browser_evaluate**
487
- - Title: Evaluate JavaScript
488
- - Description: Evaluate JavaScript expression on page or element
489
- - Parameters:
490
- - `function` (string): () => { /* code */ } or (element) => { /* code */ } when element is provided
491
- - `element` (string, optional): Human-readable element description used to obtain permission to interact with the element
492
- - `ref` (string, optional): Exact target element reference from the page snapshot
493
- - Read-only: **false**
494
-
495
- <!-- NOTE: This has been generated via update-readme.js -->
496
-
497
- - **browser_file_upload**
498
- - Title: Upload files
499
- - Description: Upload one or multiple files
500
- - Parameters:
501
- - `paths` (array): The absolute paths to the files to upload. Can be a single file or multiple files.
502
- - Read-only: **false**
503
-
504
- <!-- NOTE: This has been generated via update-readme.js -->
505
-
506
- - **browser_handle_dialog**
507
- - Title: Handle a dialog
508
- - Description: Handle a dialog
509
- - Parameters:
510
- - `accept` (boolean): Whether to accept the dialog.
511
- - `promptText` (string, optional): The text of the prompt in case of a prompt dialog.
512
- - Read-only: **false**
513
-
514
- <!-- NOTE: This has been generated via update-readme.js -->
515
-
516
- - **browser_hover**
517
- - Title: Hover mouse
518
- - Description: Hover over element on page
519
- - Parameters:
520
- - `element` (string): Human-readable element description used to obtain permission to interact with the element
521
- - `ref` (string): Exact target element reference from the page snapshot
522
- - Read-only: **true**
523
-
524
- <!-- NOTE: This has been generated via update-readme.js -->
525
-
526
- - **browser_navigate**
527
- - Title: Navigate to a URL
528
- - Description: Navigate to a URL
529
- - Parameters:
530
- - `url` (string): The URL to navigate to
531
- - Read-only: **false**
532
-
533
- <!-- NOTE: This has been generated via update-readme.js -->
534
-
535
- - **browser_navigate_back**
536
- - Title: Go back
537
- - Description: Go back to the previous page
538
- - Parameters: None
539
- - Read-only: **true**
540
-
541
- <!-- NOTE: This has been generated via update-readme.js -->
542
-
543
- - **browser_navigate_forward**
544
- - Title: Go forward
545
- - Description: Go forward to the next page
546
- - Parameters: None
547
- - Read-only: **true**
548
-
549
- <!-- NOTE: This has been generated via update-readme.js -->
550
-
551
- - **browser_network_requests**
552
- - Title: List network requests
553
- - Description: Returns all network requests since loading the page
554
- - Parameters: None
555
- - Read-only: **true**
556
-
557
- <!-- NOTE: This has been generated via update-readme.js -->
558
-
559
- - **browser_press_key**
560
- - Title: Press a key
561
- - Description: Press a key on the keyboard
562
- - Parameters:
563
- - `key` (string): Name of the key to press or a character to generate, such as `ArrowLeft` or `a`
564
- - Read-only: **false**
565
-
566
- <!-- NOTE: This has been generated via update-readme.js -->
567
-
568
- - **browser_resize**
569
- - Title: Resize browser window
570
- - Description: Resize the browser window
571
- - Parameters:
572
- - `width` (number): Width of the browser window
573
- - `height` (number): Height of the browser window
574
- - Read-only: **true**
575
-
576
- <!-- NOTE: This has been generated via update-readme.js -->
577
-
578
- - **browser_select_option**
579
- - Title: Select option
580
- - Description: Select an option in a dropdown
581
- - Parameters:
582
- - `element` (string): Human-readable element description used to obtain permission to interact with the element
583
- - `ref` (string): Exact target element reference from the page snapshot
584
- - `values` (array): Array of values to select in the dropdown. This can be a single value or multiple values.
585
- - Read-only: **false**
586
-
587
- <!-- NOTE: This has been generated via update-readme.js -->
588
-
589
- - **browser_snapshot**
590
- - Title: Page snapshot
591
- - Description: Capture accessibility snapshot of the current page, this is better than screenshot
592
- - Parameters: None
593
- - Read-only: **true**
594
-
595
- <!-- NOTE: This has been generated via update-readme.js -->
596
-
597
- - **browser_take_screenshot**
598
- - Title: Take a screenshot
599
- - Description: Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.
600
- - Parameters:
601
- - `type` (string, optional): Image format for the screenshot. Default is png.
602
- - `filename` (string, optional): File name to save the screenshot to. Defaults to `page-{timestamp}.{png|jpeg}` if not specified.
603
- - `element` (string, optional): Human-readable element description used to obtain permission to screenshot the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too.
604
- - `ref` (string, optional): Exact target element reference from the page snapshot. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too.
605
- - `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.
606
- - Read-only: **true**
607
-
608
- <!-- NOTE: This has been generated via update-readme.js -->
609
-
610
- - **browser_type**
611
- - Title: Type text
612
- - Description: Type text into editable element
613
- - Parameters:
614
- - `element` (string): Human-readable element description used to obtain permission to interact with the element
615
- - `ref` (string): Exact target element reference from the page snapshot
616
- - `text` (string): Text to type into the element
617
- - `submit` (boolean, optional): Whether to submit entered text (press Enter after)
618
- - `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.
619
- - Read-only: **false**
620
-
621
- <!-- NOTE: This has been generated via update-readme.js -->
622
-
623
- - **browser_wait_for**
624
- - Title: Wait for
625
- - Description: Wait for text to appear or disappear or a specified time to pass
626
- - Parameters:
627
- - `time` (number, optional): The time to wait in seconds
628
- - `text` (string, optional): The text to wait for
629
- - `textGone` (string, optional): The text to wait for to disappear
630
- - Read-only: **true**
631
-
632
- </details>
633
-
634
- <details>
635
- <summary><b>Tab management</b></summary>
636
-
637
- <!-- NOTE: This has been generated via update-readme.js -->
638
-
639
- - **browser_tab_close**
640
- - Title: Close a tab
641
- - Description: Close a tab
642
- - Parameters:
643
- - `index` (number, optional): The index of the tab to close. Closes current tab if not provided.
644
- - Read-only: **false**
645
-
646
- <!-- NOTE: This has been generated via update-readme.js -->
647
-
648
- - **browser_tab_list**
649
- - Title: List tabs
650
- - Description: List browser tabs
651
- - Parameters: None
652
- - Read-only: **true**
653
-
654
- <!-- NOTE: This has been generated via update-readme.js -->
655
-
656
- - **browser_tab_new**
657
- - Title: Open a new tab
658
- - Description: Open a new tab
659
- - Parameters:
660
- - `url` (string, optional): The URL to navigate to in the new tab. If not provided, the new tab will be blank.
661
- - Read-only: **true**
662
-
663
- <!-- NOTE: This has been generated via update-readme.js -->
664
-
665
- - **browser_tab_select**
666
- - Title: Select a tab
667
- - Description: Select a tab by index
668
- - Parameters:
669
- - `index` (number): The index of the tab to select
670
- - Read-only: **true**
671
-
672
- </details>
673
-
674
- <details>
675
- <summary><b>Browser installation</b></summary>
676
-
677
- <!-- NOTE: This has been generated via update-readme.js -->
678
-
679
- - **browser_install**
680
- - Title: Install the browser specified in the config
681
- - Description: Install the browser specified in the config. Call this if you get an error about the browser not being installed.
682
- - Parameters: None
683
- - Read-only: **false**
684
-
685
- </details>
686
-
687
- <details>
688
- <summary><b>Coordinate-based (opt-in via --caps=vision)</b></summary>
689
-
690
- <!-- NOTE: This has been generated via update-readme.js -->
691
-
692
- - **browser_mouse_click_xy**
693
- - Title: Click
694
- - Description: Click left mouse button at a given position
695
- - Parameters:
696
- - `element` (string): Human-readable element description used to obtain permission to interact with the element
697
- - `x` (number): X coordinate
698
- - `y` (number): Y coordinate
699
- - Read-only: **false**
700
-
701
- <!-- NOTE: This has been generated via update-readme.js -->
702
-
703
- - **browser_mouse_drag_xy**
704
- - Title: Drag mouse
705
- - Description: Drag left mouse button to a given position
706
- - Parameters:
707
- - `element` (string): Human-readable element description used to obtain permission to interact with the element
708
- - `startX` (number): Start X coordinate
709
- - `startY` (number): Start Y coordinate
710
- - `endX` (number): End X coordinate
711
- - `endY` (number): End Y coordinate
712
- - Read-only: **false**
713
-
714
- <!-- NOTE: This has been generated via update-readme.js -->
715
-
716
- - **browser_mouse_move_xy**
717
- - Title: Move mouse
718
- - Description: Move mouse to a given position
719
- - Parameters:
720
- - `element` (string): Human-readable element description used to obtain permission to interact with the element
721
- - `x` (number): X coordinate
722
- - `y` (number): Y coordinate
723
- - Read-only: **true**
724
-
725
- </details>
726
-
727
- <details>
728
- <summary><b>PDF generation (opt-in via --caps=pdf)</b></summary>
729
-
730
- <!-- NOTE: This has been generated via update-readme.js -->
731
-
732
- - **browser_pdf_save**
733
- - Title: Save as PDF
734
- - Description: Save page as PDF
735
- - Parameters:
736
- - `filename` (string, optional): File name to save the pdf to. Defaults to `page-{timestamp}.pdf` if not specified.
737
- - Read-only: **true**
738
-
739
- </details>
740
-
741
-
742
- <!--- End of tools generated section -->
1
+ > This repository contains a customized Playwright MCP for RoxyBrowser, designed to enable RoxyBrowser users to control RoxyChrome-based browsers through AI. For more details, please refer to: [RoxyBrowser Now Supports MCP — AI Can Finally Do the Work for You](https://roxybrowser.com/blog/roxybrowser-mcp-integration)
2
+
3
+ ## Playwright MCP
4
+
5
+ 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.
6
+
7
+ ### Key Features
8
+
9
+ - **Fast and lightweight**. Uses Playwright's accessibility tree, not pixel-based input.
10
+ - **LLM-friendly**. No vision models needed, operates purely on structured data.
11
+ - **Deterministic tool application**. Avoids ambiguity common with screenshot-based approaches.
12
+
13
+ ### Requirements
14
+ - Node.js 18 or newer
15
+ - VS Code, Cursor, Windsurf, Claude Desktop, Goose or any other MCP client
16
+
17
+ <!--
18
+ // Generate using:
19
+ node utils/generate-links.js
20
+ -->
21
+
22
+ ### Getting started
23
+
24
+ First, install the Playwright MCP server with your client.
25
+
26
+ **推荐:使用本包(含 Roxy 连接等扩展)**
27
+
28
+ ```json
29
+ {
30
+ "mcpServers": {
31
+ "roxybrowser-playwright-mcp": {
32
+ "command": "npx",
33
+ "args": [
34
+ "@roxybrowser/playwright-mcp@latest"
35
+ ]
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ 如需 HTTP(Studio 协议)连接,可先启动服务再在配置里填 URL:
42
+
43
+ ```bash
44
+ npx @roxybrowser/playwright-mcp --port 9324
45
+ ```
46
+
47
+ ```json
48
+ {
49
+ "mcpServers": {
50
+ "roxybrowser-playwright-mcp": {
51
+ "url": "http://localhost:9324/mcp"
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ [<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)
58
+
59
+
60
+ <details>
61
+ <summary>Claude Code</summary>
62
+
63
+ Use the Claude Code CLI to add the Playwright MCP server:
64
+
65
+ ```bash
66
+ claude mcp add playwright npx @playwright/mcp@latest
67
+ ```
68
+ </details>
69
+
70
+ <details>
71
+ <summary>Claude Desktop</summary>
72
+
73
+ Follow the MCP install [guide](https://modelcontextprotocol.io/quickstart/user), use the standard config above.
74
+
75
+ </details>
76
+
77
+ <details>
78
+ <summary>Codex</summary>
79
+
80
+ Create or edit the configuration file `~/.codex/config.toml` and add:
81
+
82
+ ```toml
83
+ [mcp_servers.playwright]
84
+ command = "npx"
85
+ args = ["@playwright/mcp@latest"]
86
+ ```
87
+
88
+ For more information, see the [Codex MCP documentation](https://github.com/openai/codex/blob/main/codex-rs/config.md#mcp_servers).
89
+
90
+ </details>
91
+
92
+ <details>
93
+ <summary>Cursor</summary>
94
+
95
+ #### Click the button to install:
96
+
97
+ [![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](cursor://anysphere.cursor-deeplink/mcp/install?name=Playwright&config=eyJjb21tYW5kIjoibnB4IEBwbGF5d3JpZ2h0L21jcEBsYXRlc3QifQ%3D%3D)
98
+
99
+ #### Or install manually:
100
+
101
+ Go to `Cursor Settings` -> `MCP` -> `Add new MCP Server`. Name to your liking, use `command` type with the command `npx @playwright/mcp`. You can also verify config or add command like arguments via clicking `Edit`.
102
+
103
+ </details>
104
+
105
+ <details>
106
+ <summary>Gemini CLI</summary>
107
+
108
+ 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.
109
+
110
+ </details>
111
+
112
+ <details>
113
+ <summary>Goose</summary>
114
+
115
+ #### Click the button to install:
116
+
117
+ [![Install in Goose](https://block.github.io/goose/img/extension-install-dark.svg)](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)
118
+
119
+ #### Or install manually:
120
+
121
+ 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".
122
+ </details>
123
+
124
+ <details>
125
+ <summary>LM Studio</summary>
126
+
127
+ #### Click the button to install:
128
+
129
+ [![Add MCP Server playwright to LM Studio](https://files.lmstudio.ai/deeplink/mcp-install-light.svg)](https://lmstudio.ai/install-mcp?name=playwright&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyJAcGxheXdyaWdodC9tY3BAbGF0ZXN0Il19)
130
+
131
+ #### Or install manually:
132
+
133
+ Go to `Program` in the right sidebar -> `Install` -> `Edit mcp.json`. Use the standard config above.
134
+ </details>
135
+
136
+ <details>
137
+ <summary>opencode</summary>
138
+
139
+ Follow the MCP Servers [documentation](https://opencode.ai/docs/mcp-servers/). For example in `~/.config/opencode/opencode.json`:
140
+
141
+ ```json
142
+ {
143
+ "$schema": "https://opencode.ai/config.json",
144
+ "mcp": {
145
+ "playwright": {
146
+ "type": "local",
147
+ "command": [
148
+ "npx",
149
+ "@playwright/mcp@latest"
150
+ ],
151
+ "enabled": true
152
+ }
153
+ }
154
+ }
155
+
156
+ ```
157
+ </details>
158
+
159
+ <details>
160
+ <summary>Qodo Gen</summary>
161
+
162
+ 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.
163
+
164
+ Click <code>Save</code>.
165
+ </details>
166
+
167
+ <details>
168
+ <summary>VS Code</summary>
169
+
170
+ #### Click the button to install:
171
+
172
+ [<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)
173
+
174
+ #### Or install manually:
175
+
176
+ 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:
177
+
178
+ ```bash
179
+ # For VS Code
180
+ code --add-mcp '{"name":"playwright","command":"npx","args":["@playwright/mcp@latest"]}'
181
+ ```
182
+
183
+ After installation, the Playwright MCP server will be available for use with your GitHub Copilot agent in VS Code.
184
+ </details>
185
+
186
+ <details>
187
+ <summary>Windsurf</summary>
188
+
189
+ Follow Windsurf MCP [documentation](https://docs.windsurf.com/windsurf/cascade/mcp). Use the standard config above.
190
+
191
+ </details>
192
+
193
+ ### Configuration
194
+
195
+ Playwright MCP server supports following arguments. They can be provided in the JSON configuration above, as a part of the `"args"` list:
196
+
197
+ <!--- Options generated by update-readme.js -->
198
+
199
+ ```
200
+ > npx @playwright/mcp@latest --help
201
+ --allowed-origins <origins> semicolon-separated list of origins to allow the
202
+ browser to request. Default is to allow all.
203
+ --blocked-origins <origins> semicolon-separated list of origins to block the
204
+ browser from requesting. Blocklist is evaluated
205
+ before allowlist. If used without the allowlist,
206
+ requests not matching the blocklist are still
207
+ allowed.
208
+ --block-service-workers block service workers
209
+ --browser <browser> browser or chrome channel to use, possible
210
+ values: chrome, firefox, webkit, msedge.
211
+ --caps <caps> comma-separated list of additional capabilities
212
+ to enable, possible values: vision, pdf.
213
+ --cdp-endpoint <endpoint> CDP endpoint to connect to.
214
+ --config <path> path to the configuration file.
215
+ --device <device> device to emulate, for example: "iPhone 15"
216
+ --executable-path <path> path to the browser executable.
217
+ --extension Connect to a running browser instance
218
+ (Edge/Chrome only). Requires the "Playwright MCP
219
+ Bridge" browser extension to be installed.
220
+ --headless run browser in headless mode, headed by default
221
+ --host <host> host to bind server to. Default is localhost. Use
222
+ 0.0.0.0 to bind to all interfaces.
223
+ --ignore-https-errors ignore https errors
224
+ --isolated keep the browser profile in memory, do not save
225
+ it to disk.
226
+ --image-responses <mode> whether to send image responses to the client.
227
+ Can be "allow" or "omit", Defaults to "allow".
228
+ --no-sandbox disable the sandbox for all process types that
229
+ are normally sandboxed.
230
+ --output-dir <path> path to the directory for output files.
231
+ --port <port> port to listen on for SSE transport.
232
+ --proxy-bypass <bypass> comma-separated domains to bypass proxy, for
233
+ example ".com,chromium.org,.domain.com"
234
+ --proxy-server <proxy> specify proxy server, for example
235
+ "http://myproxy:3128" or "socks5://myproxy:8080"
236
+ --save-session Whether to save the Playwright MCP session into
237
+ the output directory.
238
+ --save-trace Whether to save the Playwright Trace of the
239
+ session into the output directory.
240
+ --storage-state <path> path to the storage state file for isolated
241
+ sessions.
242
+ --user-agent <ua string> specify user agent string
243
+ --user-data-dir <path> path to the user data directory. If not
244
+ specified, a temporary directory will be created.
245
+ --viewport-size <size> specify browser viewport size in pixels, for
246
+ example "1280, 720"
247
+ ```
248
+
249
+ <!--- End of options generated section -->
250
+
251
+ ### User profile
252
+
253
+ 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.
254
+
255
+ **Persistent profile**
256
+
257
+ 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.
258
+ Persistent profile is located at the following locations and you can override it with the `--user-data-dir` argument.
259
+
260
+ ```bash
261
+ # Windows
262
+ %USERPROFILE%\AppData\Local\ms-playwright\mcp-{channel}-profile
263
+
264
+ # macOS
265
+ - ~/Library/Caches/ms-playwright/mcp-{channel}-profile
266
+
267
+ # Linux
268
+ - ~/.cache/ms-playwright/mcp-{channel}-profile
269
+ ```
270
+
271
+ **Isolated**
272
+
273
+ In the isolated mode, each session is started in the isolated profile. Every time you ask MCP to close the browser,
274
+ the session is closed and all the storage state for this session is lost. You can provide initial storage state
275
+ to the browser via the config's `contextOptions` or via the `--storage-state` argument. Learn more about the storage
276
+ state [here](https://playwright.dev/docs/auth).
277
+
278
+ ```js
279
+ {
280
+ "mcpServers": {
281
+ "playwright": {
282
+ "command": "npx",
283
+ "args": [
284
+ "@playwright/mcp@latest",
285
+ "--isolated",
286
+ "--storage-state={path/to/storage.json}"
287
+ ]
288
+ }
289
+ }
290
+ }
291
+ ```
292
+
293
+ **Browser Extension**
294
+
295
+ The Playwright MCP Chrome Extension allows you to connect to existing browser tabs and leverage your logged-in sessions and browser state. See [extension/README.md](extension/README.md) for installation and setup instructions.
296
+
297
+ ### Configuration file
298
+
299
+ The Playwright MCP server can be configured using a JSON configuration file. You can specify the configuration file
300
+ using the `--config` command line option:
301
+
302
+ ```bash
303
+ npx @playwright/mcp@latest --config path/to/config.json
304
+ ```
305
+
306
+ <details>
307
+ <summary>Configuration file schema</summary>
308
+
309
+ ```typescript
310
+ {
311
+ // Browser configuration
312
+ browser?: {
313
+ // Browser type to use (chromium, firefox, or webkit)
314
+ browserName?: 'chromium' | 'firefox' | 'webkit';
315
+
316
+ // Keep the browser profile in memory, do not save it to disk.
317
+ isolated?: boolean;
318
+
319
+ // Path to user data directory for browser profile persistence
320
+ userDataDir?: string;
321
+
322
+ // Browser launch options (see Playwright docs)
323
+ // @see https://playwright.dev/docs/api/class-browsertype#browser-type-launch
324
+ launchOptions?: {
325
+ channel?: string; // Browser channel (e.g. 'chrome')
326
+ headless?: boolean; // Run in headless mode
327
+ executablePath?: string; // Path to browser executable
328
+ // ... other Playwright launch options
329
+ };
330
+
331
+ // Browser context options
332
+ // @see https://playwright.dev/docs/api/class-browser#browser-new-context
333
+ contextOptions?: {
334
+ viewport?: { width: number, height: number };
335
+ // ... other Playwright context options
336
+ };
337
+
338
+ // CDP endpoint for connecting to existing browser
339
+ cdpEndpoint?: string;
340
+
341
+ // Remote Playwright server endpoint
342
+ remoteEndpoint?: string;
343
+ },
344
+
345
+ // Server configuration
346
+ server?: {
347
+ port?: number; // Port to listen on
348
+ host?: string; // Host to bind to (default: localhost)
349
+ },
350
+
351
+ // List of additional capabilities
352
+ capabilities?: Array<
353
+ 'tabs' | // Tab management
354
+ 'install' | // Browser installation
355
+ 'pdf' | // PDF generation
356
+ 'vision' | // Coordinate-based interactions
357
+ >;
358
+
359
+ // Directory for output files
360
+ outputDir?: string;
361
+
362
+ // Network configuration
363
+ network?: {
364
+ // List of origins to allow the browser to request. Default is to allow all. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
365
+ allowedOrigins?: string[];
366
+
367
+ // List of origins to block the browser to request. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
368
+ blockedOrigins?: string[];
369
+ };
370
+
371
+ /**
372
+ * Whether to send image responses to the client. Can be "allow" or "omit".
373
+ * Defaults to "allow".
374
+ */
375
+ imageResponses?: 'allow' | 'omit';
376
+ }
377
+ ```
378
+ </details>
379
+
380
+ ### 第三方集成与程序化调用
381
+
382
+ 本包支持三种使用方式,便于接入 Cursor/IDE 或自建应用。
383
+
384
+ #### 1. CLI 快速启动(stdio)
385
+
386
+ MCP 客户端配置中指定 command,由客户端拉起进程、通过 stdio 通信:
387
+
388
+ ```json
389
+ {
390
+ "mcpServers": {
391
+ "roxybrowser-playwright-mcp": {
392
+ "command": "npx",
393
+ "args": ["@roxybrowser/playwright-mcp@latest"]
394
+ }
395
+ }
396
+ }
397
+ ```
398
+
399
+ #### 2. Studio 协议(HTTP/SSE)
400
+
401
+ 通过代码启动 HTTP 服务,第三方应用用 URL 连接(如 Studio、自研前端):
402
+
403
+ ```js
404
+ import { startServer } from '@roxybrowser/playwright-mcp';
405
+
406
+ const { url } = await startServer({ port: 9324, host: 'localhost' });
407
+ console.log('MCP URL:', url); // http://localhost:9324/mcp
408
+ // 进程持续运行,客户端连接 url 即可
409
+ ```
410
+
411
+ 也可直接用 CLI 起 HTTP 服务,再在客户端填 URL:
412
+
413
+ ```bash
414
+ npx @roxybrowser/playwright-mcp --port 9324
415
+ ```
416
+
417
+ ```json
418
+ { "mcpServers": { "roxybrowser-playwright-mcp": { "url": "http://localhost:9324/mcp" } } }
419
+ ```
420
+
421
+ #### 3. 程序化 createConnection(自管 transport
422
+
423
+ 在进程内创建 MCP Server,自行连接 stdio 或自定义 transport,便于嵌入到其他应用:
424
+
425
+ ```js
426
+ import { createConnection } from '@roxybrowser/playwright-mcp';
427
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
428
+
429
+ const server = await createConnection(); // 可选:传入 config 或 contextGetter
430
+ await server.connect(new StdioServerTransport());
431
+ ```
432
+
433
+ #### 4. 导出工具类(扩展或二次封装)
434
+
435
+ 如需继承 Backend、增加自定义工具或复用 Roxy 连接逻辑,可从主入口引用:
436
+
437
+ ```js
438
+ import {
439
+ createConnection,
440
+ startServer,
441
+ CustomBackend,
442
+ DynamicCdpContextFactory,
443
+ defineExtraTool,
444
+ extraToolToMcp,
445
+ } from '@roxybrowser/playwright-mcp';
446
+ ```
447
+
448
+ - **CustomBackend**:在 Playwright 官方工具基础上增加 `browser_connect_roxy` 等,可子类化继续加工具。
449
+ - **DynamicCdpContextFactory**:支持 `reconnectToCDP(endpoint)` 的 context 工厂,用于 Roxy/CDP 连接。
450
+ - **defineExtraTool** / **extraToolToMcp**:定义额外 MCP 工具并转为 listTools 格式的辅助函数。
451
+
452
+ ### Standalone MCP server
453
+
454
+ When running headed browser on system w/o display or from worker processes of the IDEs,
455
+ run the MCP server from environment with the DISPLAY and pass the `--port` flag to enable HTTP transport.
456
+
457
+ ```bash
458
+ npx @playwright/mcp@latest --port 8931
459
+ ```
460
+
461
+ And then in MCP client config, set the `url` to the HTTP endpoint:
462
+
463
+ ```js
464
+ {
465
+ "mcpServers": {
466
+ "playwright": {
467
+ "url": "http://localhost:8931/mcp"
468
+ }
469
+ }
470
+ }
471
+ ```
472
+
473
+ <details>
474
+ <summary><b>Docker</b></summary>
475
+
476
+ **NOTE:** The Docker implementation only supports headless chromium at the moment.
477
+
478
+ ```js
479
+ {
480
+ "mcpServers": {
481
+ "playwright": {
482
+ "command": "docker",
483
+ "args": ["run", "-i", "--rm", "--init", "--pull=always", "mcr.microsoft.com/playwright/mcp"]
484
+ }
485
+ }
486
+ }
487
+ ```
488
+
489
+ You can build the Docker image yourself.
490
+
491
+ ```
492
+ docker build -t mcr.microsoft.com/playwright/mcp .
493
+ ```
494
+ </details>
495
+
496
+ <details>
497
+ <summary><b>Programmatic usage</b></summary>
498
+
499
+ ```js
500
+ import http from 'http';
501
+
502
+ import { createConnection } from '@playwright/mcp';
503
+ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
504
+
505
+ http.createServer(async (req, res) => {
506
+ // ...
507
+
508
+ // Creates a headless Playwright MCP server with SSE transport
509
+ const connection = await createConnection({ browser: { launchOptions: { headless: true } } });
510
+ const transport = new SSEServerTransport('/messages', res);
511
+ await connection.sever.connect(transport);
512
+
513
+ // ...
514
+ });
515
+ ```
516
+ </details>
517
+
518
+ ### Tools
519
+
520
+ <!--- Tools generated by update-readme.js -->
521
+
522
+ <details>
523
+ <summary><b>Core automation</b></summary>
524
+
525
+ <!-- NOTE: This has been generated via update-readme.js -->
526
+
527
+ - **browser_click**
528
+ - Title: Click
529
+ - Description: Perform click on a web page
530
+ - Parameters:
531
+ - `element` (string): Human-readable element description used to obtain permission to interact with the element
532
+ - `ref` (string): Exact target element reference from the page snapshot
533
+ - `doubleClick` (boolean, optional): Whether to perform a double click instead of a single click
534
+ - `button` (string, optional): Button to click, defaults to left
535
+ - Read-only: **false**
536
+
537
+ <!-- NOTE: This has been generated via update-readme.js -->
538
+
539
+ - **browser_close**
540
+ - Title: Close browser
541
+ - Description: Close the page
542
+ - Parameters: None
543
+ - Read-only: **true**
544
+
545
+ <!-- NOTE: This has been generated via update-readme.js -->
546
+
547
+ - **browser_connect_roxy**
548
+ - Title: Connect to RoxyBrowser
549
+ - Description: Connect to RoxyBrowser using CDP WebSocket endpoint
550
+ - Parameters:
551
+ - `cdpEndpoint` (string): The CDP WebSocket endpoint URL from RoxyBrowser (e.g., ws://127.0.0.1:59305/devtools/browser/4d876b0b-6adc-4e9f-b572-bb68ff02a199)
552
+ - Read-only: **false**
553
+
554
+ <!-- NOTE: This has been generated via update-readme.js -->
555
+
556
+ - **browser_console_messages**
557
+ - Title: Get console messages
558
+ - Description: Returns all console messages
559
+ - Parameters: None
560
+ - Read-only: **true**
561
+
562
+ <!-- NOTE: This has been generated via update-readme.js -->
563
+
564
+ - **browser_drag**
565
+ - Title: Drag mouse
566
+ - Description: Perform drag and drop between two elements
567
+ - Parameters:
568
+ - `startElement` (string): Human-readable source element description used to obtain the permission to interact with the element
569
+ - `startRef` (string): Exact source element reference from the page snapshot
570
+ - `endElement` (string): Human-readable target element description used to obtain the permission to interact with the element
571
+ - `endRef` (string): Exact target element reference from the page snapshot
572
+ - Read-only: **false**
573
+
574
+ <!-- NOTE: This has been generated via update-readme.js -->
575
+
576
+ - **browser_evaluate**
577
+ - Title: Evaluate JavaScript
578
+ - Description: Evaluate JavaScript expression on page or element
579
+ - Parameters:
580
+ - `function` (string): () => { /* code */ } or (element) => { /* code */ } when element is provided
581
+ - `element` (string, optional): Human-readable element description used to obtain permission to interact with the element
582
+ - `ref` (string, optional): Exact target element reference from the page snapshot
583
+ - Read-only: **false**
584
+
585
+ <!-- NOTE: This has been generated via update-readme.js -->
586
+
587
+ - **browser_file_upload**
588
+ - Title: Upload files
589
+ - Description: Upload one or multiple files
590
+ - Parameters:
591
+ - `paths` (array): The absolute paths to the files to upload. Can be a single file or multiple files.
592
+ - Read-only: **false**
593
+
594
+ <!-- NOTE: This has been generated via update-readme.js -->
595
+
596
+ - **browser_handle_dialog**
597
+ - Title: Handle a dialog
598
+ - Description: Handle a dialog
599
+ - Parameters:
600
+ - `accept` (boolean): Whether to accept the dialog.
601
+ - `promptText` (string, optional): The text of the prompt in case of a prompt dialog.
602
+ - Read-only: **false**
603
+
604
+ <!-- NOTE: This has been generated via update-readme.js -->
605
+
606
+ - **browser_hover**
607
+ - Title: Hover mouse
608
+ - Description: Hover over element on page
609
+ - Parameters:
610
+ - `element` (string): Human-readable element description used to obtain permission to interact with the element
611
+ - `ref` (string): Exact target element reference from the page snapshot
612
+ - Read-only: **true**
613
+
614
+ <!-- NOTE: This has been generated via update-readme.js -->
615
+
616
+ - **browser_navigate**
617
+ - Title: Navigate to a URL
618
+ - Description: Navigate to a URL
619
+ - Parameters:
620
+ - `url` (string): The URL to navigate to
621
+ - Read-only: **false**
622
+
623
+ <!-- NOTE: This has been generated via update-readme.js -->
624
+
625
+ - **browser_navigate_back**
626
+ - Title: Go back
627
+ - Description: Go back to the previous page
628
+ - Parameters: None
629
+ - Read-only: **true**
630
+
631
+ <!-- NOTE: This has been generated via update-readme.js -->
632
+
633
+ - **browser_navigate_forward**
634
+ - Title: Go forward
635
+ - Description: Go forward to the next page
636
+ - Parameters: None
637
+ - Read-only: **true**
638
+
639
+ <!-- NOTE: This has been generated via update-readme.js -->
640
+
641
+ - **browser_network_requests**
642
+ - Title: List network requests
643
+ - Description: Returns all network requests since loading the page
644
+ - Parameters: None
645
+ - Read-only: **true**
646
+
647
+ <!-- NOTE: This has been generated via update-readme.js -->
648
+
649
+ - **browser_press_key**
650
+ - Title: Press a key
651
+ - Description: Press a key on the keyboard
652
+ - Parameters:
653
+ - `key` (string): Name of the key to press or a character to generate, such as `ArrowLeft` or `a`
654
+ - Read-only: **false**
655
+
656
+ <!-- NOTE: This has been generated via update-readme.js -->
657
+
658
+ - **browser_resize**
659
+ - Title: Resize browser window
660
+ - Description: Resize the browser window
661
+ - Parameters:
662
+ - `width` (number): Width of the browser window
663
+ - `height` (number): Height of the browser window
664
+ - Read-only: **true**
665
+
666
+ <!-- NOTE: This has been generated via update-readme.js -->
667
+
668
+ - **browser_select_option**
669
+ - Title: Select option
670
+ - Description: Select an option in a dropdown
671
+ - Parameters:
672
+ - `element` (string): Human-readable element description used to obtain permission to interact with the element
673
+ - `ref` (string): Exact target element reference from the page snapshot
674
+ - `values` (array): Array of values to select in the dropdown. This can be a single value or multiple values.
675
+ - Read-only: **false**
676
+
677
+ <!-- NOTE: This has been generated via update-readme.js -->
678
+
679
+ - **browser_snapshot**
680
+ - Title: Page snapshot
681
+ - Description: Capture accessibility snapshot of the current page, this is better than screenshot
682
+ - Parameters: None
683
+ - Read-only: **true**
684
+
685
+ <!-- NOTE: This has been generated via update-readme.js -->
686
+
687
+ - **browser_take_screenshot**
688
+ - Title: Take a screenshot
689
+ - Description: Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.
690
+ - Parameters:
691
+ - `type` (string, optional): Image format for the screenshot. Default is png.
692
+ - `filename` (string, optional): File name to save the screenshot to. Defaults to `page-{timestamp}.{png|jpeg}` if not specified.
693
+ - `element` (string, optional): Human-readable element description used to obtain permission to screenshot the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too.
694
+ - `ref` (string, optional): Exact target element reference from the page snapshot. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too.
695
+ - `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.
696
+ - Read-only: **true**
697
+
698
+ <!-- NOTE: This has been generated via update-readme.js -->
699
+
700
+ - **browser_type**
701
+ - Title: Type text
702
+ - Description: Type text into editable element
703
+ - Parameters:
704
+ - `element` (string): Human-readable element description used to obtain permission to interact with the element
705
+ - `ref` (string): Exact target element reference from the page snapshot
706
+ - `text` (string): Text to type into the element
707
+ - `submit` (boolean, optional): Whether to submit entered text (press Enter after)
708
+ - `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.
709
+ - Read-only: **false**
710
+
711
+ <!-- NOTE: This has been generated via update-readme.js -->
712
+
713
+ - **browser_wait_for**
714
+ - Title: Wait for
715
+ - Description: Wait for text to appear or disappear or a specified time to pass
716
+ - Parameters:
717
+ - `time` (number, optional): The time to wait in seconds
718
+ - `text` (string, optional): The text to wait for
719
+ - `textGone` (string, optional): The text to wait for to disappear
720
+ - Read-only: **true**
721
+
722
+ </details>
723
+
724
+ <details>
725
+ <summary><b>Tab management</b></summary>
726
+
727
+ <!-- NOTE: This has been generated via update-readme.js -->
728
+
729
+ - **browser_tab_close**
730
+ - Title: Close a tab
731
+ - Description: Close a tab
732
+ - Parameters:
733
+ - `index` (number, optional): The index of the tab to close. Closes current tab if not provided.
734
+ - Read-only: **false**
735
+
736
+ <!-- NOTE: This has been generated via update-readme.js -->
737
+
738
+ - **browser_tab_list**
739
+ - Title: List tabs
740
+ - Description: List browser tabs
741
+ - Parameters: None
742
+ - Read-only: **true**
743
+
744
+ <!-- NOTE: This has been generated via update-readme.js -->
745
+
746
+ - **browser_tab_new**
747
+ - Title: Open a new tab
748
+ - Description: Open a new tab
749
+ - Parameters:
750
+ - `url` (string, optional): The URL to navigate to in the new tab. If not provided, the new tab will be blank.
751
+ - Read-only: **true**
752
+
753
+ <!-- NOTE: This has been generated via update-readme.js -->
754
+
755
+ - **browser_tab_select**
756
+ - Title: Select a tab
757
+ - Description: Select a tab by index
758
+ - Parameters:
759
+ - `index` (number): The index of the tab to select
760
+ - Read-only: **true**
761
+
762
+ </details>
763
+
764
+ <details>
765
+ <summary><b>Browser installation</b></summary>
766
+
767
+ <!-- NOTE: This has been generated via update-readme.js -->
768
+
769
+ - **browser_install**
770
+ - Title: Install the browser specified in the config
771
+ - Description: Install the browser specified in the config. Call this if you get an error about the browser not being installed.
772
+ - Parameters: None
773
+ - Read-only: **false**
774
+
775
+ </details>
776
+
777
+ <details>
778
+ <summary><b>Coordinate-based (opt-in via --caps=vision)</b></summary>
779
+
780
+ <!-- NOTE: This has been generated via update-readme.js -->
781
+
782
+ - **browser_mouse_click_xy**
783
+ - Title: Click
784
+ - Description: Click left mouse button at a given position
785
+ - Parameters:
786
+ - `element` (string): Human-readable element description used to obtain permission to interact with the element
787
+ - `x` (number): X coordinate
788
+ - `y` (number): Y coordinate
789
+ - Read-only: **false**
790
+
791
+ <!-- NOTE: This has been generated via update-readme.js -->
792
+
793
+ - **browser_mouse_drag_xy**
794
+ - Title: Drag mouse
795
+ - Description: Drag left mouse button to a given position
796
+ - Parameters:
797
+ - `element` (string): Human-readable element description used to obtain permission to interact with the element
798
+ - `startX` (number): Start X coordinate
799
+ - `startY` (number): Start Y coordinate
800
+ - `endX` (number): End X coordinate
801
+ - `endY` (number): End Y coordinate
802
+ - Read-only: **false**
803
+
804
+ <!-- NOTE: This has been generated via update-readme.js -->
805
+
806
+ - **browser_mouse_move_xy**
807
+ - Title: Move mouse
808
+ - Description: Move mouse to a given position
809
+ - Parameters:
810
+ - `element` (string): Human-readable element description used to obtain permission to interact with the element
811
+ - `x` (number): X coordinate
812
+ - `y` (number): Y coordinate
813
+ - Read-only: **true**
814
+
815
+ </details>
816
+
817
+ <details>
818
+ <summary><b>PDF generation (opt-in via --caps=pdf)</b></summary>
819
+
820
+ <!-- NOTE: This has been generated via update-readme.js -->
821
+
822
+ - **browser_pdf_save**
823
+ - Title: Save as PDF
824
+ - Description: Save page as PDF
825
+ - Parameters:
826
+ - `filename` (string, optional): File name to save the pdf to. Defaults to `page-{timestamp}.pdf` if not specified.
827
+ - Read-only: **true**
828
+
829
+ </details>
830
+
831
+
832
+ <!--- End of tools generated section -->