@playwright/mcp 0.0.14 → 0.0.16

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.
package/README.md CHANGED
@@ -15,9 +15,14 @@ A Model Context Protocol (MCP) server that provides browser automation capabilit
15
15
  - Automated testing driven by LLMs
16
16
  - General-purpose browser interaction for agents
17
17
 
18
- ### Example config
18
+ <!--
19
+ // Generate using:
20
+ node utils/generate_links.js
21
+ -->
19
22
 
20
- #### NPX
23
+ [<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)
24
+
25
+ ### Example config
21
26
 
22
27
  ```js
23
28
  {
@@ -32,35 +37,29 @@ A Model Context Protocol (MCP) server that provides browser automation capabilit
32
37
  }
33
38
  ```
34
39
 
35
- #### Installation in VS Code
40
+ ### Table of Contents
36
41
 
37
- Install the Playwright MCP server in VS Code using one of these buttons:
42
+ - [Installation in VS Code](#installation-in-vs-code)
43
+ - [Command line](#command-line)
44
+ - [User profile](#user-profile)
45
+ - [Configuration file](#configuration-file)
46
+ - [Running on Linux](#running-on-linux)
47
+ - [Docker](#docker)
48
+ - [Programmatic usage](#programmatic-usage)
49
+ - [Tool modes](#tool-modes)
38
50
 
39
- <!--
40
- // Generate using?:
41
- const config = JSON.stringify({ name: 'playwright', command: 'npx', args: ["-y", "@playwright/mcp@latest"] });
42
- const urlForWebsites = `vscode:mcp/install?${encodeURIComponent(config)}`;
43
- // Github markdown does not allow linking to `vscode:` directly, so you can use our redirect:
44
- const urlForGithub = `https://insiders.vscode.dev/redirect?url=${encodeURIComponent(urlForWebsites)}`;
45
- -->
46
-
47
- [<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-y%2522%252C%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-y%2522%252C%2522%2540playwright%252Fmcp%2540latest%2522%255D%257D)
51
+ ### Installation in VS Code
48
52
 
49
- Alternatively, you can install the Playwright MCP server using the VS Code CLI:
53
+ You can install the Playwright MCP server using the VS Code CLI:
50
54
 
51
55
  ```bash
52
56
  # For VS Code
53
57
  code --add-mcp '{"name":"playwright","command":"npx","args":["@playwright/mcp@latest"]}'
54
58
  ```
55
59
 
56
- ```bash
57
- # For VS Code Insiders
58
- code-insiders --add-mcp '{"name":"playwright","command":"npx","args":["@playwright/mcp@latest"]}'
59
- ```
60
-
61
60
  After installation, the Playwright MCP server will be available for use with your GitHub Copilot agent in VS Code.
62
61
 
63
- ### CLI Options
62
+ ### Command line
64
63
 
65
64
  The Playwright MCP server supports the following command-line options:
66
65
 
@@ -73,42 +72,102 @@ The Playwright MCP server supports the following command-line options:
73
72
  - `--cdp-endpoint <endpoint>`: CDP endpoint to connect to
74
73
  - `--executable-path <path>`: Path to the browser executable
75
74
  - `--headless`: Run browser in headless mode (headed by default)
76
- - `--port <port>`: Port to listen on for SSE transport
75
+ - `--device`: Emulate mobile device
77
76
  - `--user-data-dir <path>`: Path to the user data directory
77
+ - `--port <port>`: Port to listen on for SSE transport
78
+ - `--host <host>`: Host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.
78
79
  - `--vision`: Run server that uses screenshots (Aria snapshots are used by default)
80
+ - `--config <path>`: Path to the configuration file
79
81
 
80
- ### User data directory
82
+ ### User profile
81
83
 
82
84
  Playwright MCP will launch the browser with the new profile, located at
83
85
 
84
86
  ```
85
- - `%USERPROFILE%\AppData\Local\ms-playwright\mcp-chrome-profile` on Windows
86
- - `~/Library/Caches/ms-playwright/mcp-chrome-profile` on macOS
87
- - `~/.cache/ms-playwright/mcp-chrome-profile` on Linux
87
+ - `%USERPROFILE%\AppData\Local\ms-playwright\mcp-{channel}-profile` on Windows
88
+ - `~/Library/Caches/ms-playwright/mcp-{channel}-profile` on macOS
89
+ - `~/.cache/ms-playwright/mcp-{channel}-profile` on Linux
88
90
  ```
89
91
 
90
92
  All the logged in information will be stored in that profile, you can delete it between sessions if you'd like to clear the offline state.
91
93
 
94
+ ### Configuration file
92
95
 
93
- ### Running headless browser (Browser without GUI).
96
+ The Playwright MCP server can be configured using a JSON configuration file. Here's the complete configuration format:
94
97
 
95
- This mode is useful for background or batch operations.
96
-
97
- ```js
98
+ ```typescript
98
99
  {
99
- "mcpServers": {
100
- "playwright": {
101
- "command": "npx",
102
- "args": [
103
- "@playwright/mcp@latest",
104
- "--headless"
105
- ]
100
+ // Browser configuration
101
+ browser?: {
102
+ // Browser type to use (chromium, firefox, or webkit)
103
+ browserName?: 'chromium' | 'firefox' | 'webkit';
104
+
105
+ // Path to user data directory for browser profile persistence
106
+ userDataDir?: string;
107
+
108
+ // Browser launch options (see Playwright docs)
109
+ // @see https://playwright.dev/docs/api/class-browsertype#browser-type-launch
110
+ launchOptions?: {
111
+ channel?: string; // Browser channel (e.g. 'chrome')
112
+ headless?: boolean; // Run in headless mode
113
+ executablePath?: string; // Path to browser executable
114
+ // ... other Playwright launch options
115
+ };
116
+
117
+ // Browser context options
118
+ // @see https://playwright.dev/docs/api/class-browser#browser-new-context
119
+ contextOptions?: {
120
+ viewport?: { width: number, height: number };
121
+ // ... other Playwright context options
122
+ };
123
+
124
+ // CDP endpoint for connecting to existing browser
125
+ cdpEndpoint?: string;
126
+
127
+ // Remote Playwright server endpoint
128
+ remoteEndpoint?: string;
129
+ },
130
+
131
+ // Server configuration
132
+ server?: {
133
+ port?: number; // Port to listen on
134
+ host?: string; // Host to bind to (default: localhost)
135
+ },
136
+
137
+ // List of enabled capabilities
138
+ capabilities?: Array<
139
+ 'core' | // Core browser automation
140
+ 'tabs' | // Tab management
141
+ 'pdf' | // PDF generation
142
+ 'history' | // Browser history
143
+ 'wait' | // Wait utilities
144
+ 'files' | // File handling
145
+ 'install' // Browser installation
146
+ >;
147
+
148
+ // Enable vision mode (screenshots instead of accessibility snapshots)
149
+ vision?: boolean;
150
+
151
+ // Directory for output files
152
+ outputDir?: string;
153
+
154
+ // Tool-specific configurations
155
+ tools?: {
156
+ browser_take_screenshot?: {
157
+ // Disable base64-encoded image responses
158
+ omitBase64?: boolean;
106
159
  }
107
160
  }
108
161
  }
109
162
  ```
110
163
 
111
- ### Running headed browser on Linux w/o DISPLAY
164
+ You can specify the configuration file using the `--config` command line option:
165
+
166
+ ```bash
167
+ npx @playwright/mcp@latest --config path/to/config.json
168
+ ```
169
+
170
+ ### Running on Linux
112
171
 
113
172
  When running headed browser on system w/o display or from worker processes of the IDEs,
114
173
  run the MCP server from environment with the DISPLAY and pass the `--port` flag to enable SSE transport.
@@ -132,6 +191,7 @@ And then in MCP client config, set the `url` to the SSE endpoint:
132
191
  ### Docker
133
192
 
134
193
  **NOTE:** The Docker implementation only supports headless chromium at the moment.
194
+
135
195
  ```js
136
196
  {
137
197
  "mcpServers": {
@@ -143,7 +203,33 @@ And then in MCP client config, set the `url` to the SSE endpoint:
143
203
  }
144
204
  ```
145
205
 
146
- ### Tool Modes
206
+ You can build the Docker image yourself.
207
+
208
+ ```
209
+ docker build -t mcp/playwright .
210
+ ```
211
+
212
+ ### Programmatic usage
213
+
214
+ ```js
215
+ import http from 'http';
216
+
217
+ import { createServer } from '@playwright/mcp';
218
+ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
219
+
220
+ http.createServer(async (req, res) => {
221
+ // ...
222
+
223
+ // Creates a headless Playwright MCP server with SSE transport
224
+ const mcpServer = await createServer({ headless: true });
225
+ const transport = new SSEServerTransport('/messages', res);
226
+ await mcpServer.connect(transport);
227
+
228
+ // ...
229
+ });
230
+ ```
231
+
232
+ ### Tool modes
147
233
 
148
234
  The tools are available in two modes:
149
235
 
@@ -169,33 +255,6 @@ To use Vision Mode, add the `--vision` flag when starting the server:
169
255
  Vision Mode works best with the computer use models that are able to interact with elements using
170
256
  X Y coordinate space, based on the provided screenshot.
171
257
 
172
- ### Build with Docker
173
-
174
- You can build the Docker image yourself.
175
- ```
176
- docker build -t mcp/playwright .
177
- ```
178
-
179
- ### Programmatic usage with custom transports
180
-
181
- ```js
182
- import http from 'http';
183
-
184
- import { createServer } from '@playwright/mcp';
185
- import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
186
-
187
- http.createServer(async (req, res) => {
188
- // ...
189
-
190
- // Creates a headless Playwright MCP server with SSE transport
191
- const mcpServer = await createServer({ headless: true });
192
- const transport = new SSEServerTransport('/messages', res);
193
- await mcpServer.connect(transport);
194
-
195
- // ...
196
- });
197
-
198
- ```
199
258
 
200
259
  <!--- Generated by update-readme.js -->
201
260
 
package/config.d.ts ADDED
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import type * as playwright from 'playwright';
18
+
19
+ export type ToolCapability = 'core' | 'tabs' | 'pdf' | 'history' | 'wait' | 'files' | 'install';
20
+
21
+ export type Config = {
22
+ /**
23
+ * The browser to use.
24
+ */
25
+ browser?: {
26
+ /**
27
+ * The type of browser to use.
28
+ */
29
+ browserName?: 'chromium' | 'firefox' | 'webkit';
30
+
31
+ /**
32
+ * Path to a user data directory for browser profile persistence.
33
+ * Temporary directory is created by default.
34
+ */
35
+ userDataDir?: string;
36
+
37
+ /**
38
+ * Launch options passed to
39
+ * @see https://playwright.dev/docs/api/class-browsertype#browser-type-launch-persistent-context
40
+ *
41
+ * This is useful for settings options like `channel`, `headless`, `executablePath`, etc.
42
+ */
43
+ launchOptions?: playwright.BrowserLaunchOptions;
44
+
45
+ /**
46
+ * Context options for the browser context.
47
+ *
48
+ * This is useful for settings options like `viewport`.
49
+ */
50
+ contextOptions?: playwright.BrowserContextOptions;
51
+
52
+ /**
53
+ * Chrome DevTools Protocol endpoint to connect to an existing browser instance in case of Chromium family browsers.
54
+ */
55
+ cdpEndpoint?: string;
56
+
57
+ /**
58
+ * Remote endpoint to connect to an existing Playwright server.
59
+ */
60
+ remoteEndpoint?: string;
61
+ },
62
+
63
+ server?: {
64
+ /**
65
+ * The port to listen on for SSE or MCP transport.
66
+ */
67
+ port?: number;
68
+
69
+ /**
70
+ * The host to bind the server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.
71
+ */
72
+ host?: string;
73
+ },
74
+
75
+ /**
76
+ * List of enabled tool capabilities. Possible values:
77
+ * - 'core': Core browser automation features.
78
+ * - 'tabs': Tab management features.
79
+ * - 'pdf': PDF generation and manipulation.
80
+ * - 'history': Browser history access.
81
+ * - 'wait': Wait and timing utilities.
82
+ * - 'files': File upload/download support.
83
+ * - 'install': Browser installation utilities.
84
+ */
85
+ capabilities?: ToolCapability[];
86
+
87
+ /**
88
+ * Run server that uses screenshots (Aria snapshots are used by default).
89
+ */
90
+ vision?: boolean;
91
+
92
+ /**
93
+ * The directory to save output files.
94
+ */
95
+ outputDir?: string;
96
+
97
+ /**
98
+ * Configuration for specific tools.
99
+ */
100
+ tools?: {
101
+ /**
102
+ * Configuration for the browser_take_screenshot tool.
103
+ */
104
+ browser_take_screenshot?: {
105
+
106
+ /**
107
+ * Whether to disable base64-encoded image responses to the clients that
108
+ * don't support binary data or prefer to save on tokens.
109
+ */
110
+ omitBase64?: boolean;
111
+ }
112
+ }
113
+ };
package/index.d.ts CHANGED
@@ -17,44 +17,7 @@
17
17
 
18
18
  import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
19
19
 
20
- type ToolCapability = 'core' | 'tabs' | 'pdf' | 'history' | 'wait' | 'files' | 'install';
20
+ import type { Config } from './config';
21
21
 
22
- type Options = {
23
- /**
24
- * The browser to use (e.g., 'chrome', 'chromium', 'firefox', 'webkit', 'msedge').
25
- */
26
- browser?: string;
27
- /**
28
- * Path to a user data directory for browser profile persistence.
29
- */
30
- userDataDir?: string;
31
- /**
32
- * Whether to run the browser in headless mode (default: true).
33
- */
34
- headless?: boolean;
35
- /**
36
- * Path to a custom browser executable.
37
- */
38
- executablePath?: string;
39
- /**
40
- * Chrome DevTools Protocol endpoint to connect to an existing browser instance.
41
- */
42
- cdpEndpoint?: string;
43
- /**
44
- * Enable vision capabilities (e.g., visual automation or OCR).
45
- */
46
- vision?: boolean;
47
- /**
48
- * List of enabled tool capabilities. Possible values:
49
- * - 'core': Core browser automation features.
50
- * - 'tabs': Tab management features.
51
- * - 'pdf': PDF generation and manipulation.
52
- * - 'history': Browser history access.
53
- * - 'wait': Wait and timing utilities.
54
- * - 'files': File upload/download support.
55
- * - 'install': Browser installation utilities.
56
- */
57
- capabilities?: ToolCapability[];
58
- };
59
- export declare function createServer(options?: Options): Promise<Server>;
22
+ export declare function createServer(config?: Config): Promise<Server>;
60
23
  export {};
package/lib/config.js ADDED
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Microsoft Corporation.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ var __importDefault = (this && this.__importDefault) || function (mod) {
18
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.resolveConfig = resolveConfig;
22
+ exports.configFromCLIOptions = configFromCLIOptions;
23
+ exports.outputFile = outputFile;
24
+ const fs_1 = __importDefault(require("fs"));
25
+ const net_1 = __importDefault(require("net"));
26
+ const os_1 = __importDefault(require("os"));
27
+ const path_1 = __importDefault(require("path"));
28
+ const playwright_1 = require("playwright");
29
+ const utils_1 = require("./tools/utils");
30
+ const defaultConfig = {
31
+ browser: {
32
+ browserName: 'chromium',
33
+ userDataDir: os_1.default.tmpdir(),
34
+ launchOptions: {
35
+ channel: 'chrome',
36
+ headless: os_1.default.platform() === 'linux' && !process.env.DISPLAY,
37
+ },
38
+ contextOptions: {
39
+ viewport: null,
40
+ },
41
+ },
42
+ };
43
+ async function resolveConfig(cliOptions) {
44
+ const config = await loadConfig(cliOptions.config);
45
+ const cliOverrides = await configFromCLIOptions(cliOptions);
46
+ return mergeConfig(defaultConfig, mergeConfig(config, cliOverrides));
47
+ }
48
+ async function configFromCLIOptions(cliOptions) {
49
+ let browserName;
50
+ let channel;
51
+ switch (cliOptions.browser) {
52
+ case 'chrome':
53
+ case 'chrome-beta':
54
+ case 'chrome-canary':
55
+ case 'chrome-dev':
56
+ case 'chromium':
57
+ case 'msedge':
58
+ case 'msedge-beta':
59
+ case 'msedge-canary':
60
+ case 'msedge-dev':
61
+ browserName = 'chromium';
62
+ channel = cliOptions.browser;
63
+ break;
64
+ case 'firefox':
65
+ browserName = 'firefox';
66
+ break;
67
+ case 'webkit':
68
+ browserName = 'webkit';
69
+ break;
70
+ default:
71
+ browserName = 'chromium';
72
+ channel = 'chrome';
73
+ }
74
+ const launchOptions = {
75
+ channel,
76
+ executablePath: cliOptions.executablePath,
77
+ headless: cliOptions.headless,
78
+ };
79
+ if (browserName === 'chromium')
80
+ launchOptions.webSocketPort = await findFreePort();
81
+ const contextOptions = cliOptions.device ? playwright_1.devices[cliOptions.device] : undefined;
82
+ return {
83
+ browser: {
84
+ browserName,
85
+ userDataDir: cliOptions.userDataDir ?? await createUserDataDir({ browserName, channel }),
86
+ launchOptions,
87
+ contextOptions,
88
+ cdpEndpoint: cliOptions.cdpEndpoint,
89
+ },
90
+ server: {
91
+ port: cliOptions.port,
92
+ host: cliOptions.host,
93
+ },
94
+ capabilities: cliOptions.caps?.split(',').map((c) => c.trim()),
95
+ vision: !!cliOptions.vision,
96
+ };
97
+ }
98
+ async function findFreePort() {
99
+ return new Promise((resolve, reject) => {
100
+ const server = net_1.default.createServer();
101
+ server.listen(0, () => {
102
+ const { port } = server.address();
103
+ server.close(() => resolve(port));
104
+ });
105
+ server.on('error', reject);
106
+ });
107
+ }
108
+ async function loadConfig(configFile) {
109
+ if (!configFile)
110
+ return {};
111
+ try {
112
+ return JSON.parse(await fs_1.default.promises.readFile(configFile, 'utf8'));
113
+ }
114
+ catch (error) {
115
+ throw new Error(`Failed to load config file: ${configFile}, ${error}`);
116
+ }
117
+ }
118
+ async function createUserDataDir(options) {
119
+ let cacheDirectory;
120
+ if (process.platform === 'linux')
121
+ cacheDirectory = process.env.XDG_CACHE_HOME || path_1.default.join(os_1.default.homedir(), '.cache');
122
+ else if (process.platform === 'darwin')
123
+ cacheDirectory = path_1.default.join(os_1.default.homedir(), 'Library', 'Caches');
124
+ else if (process.platform === 'win32')
125
+ cacheDirectory = process.env.LOCALAPPDATA || path_1.default.join(os_1.default.homedir(), 'AppData', 'Local');
126
+ else
127
+ throw new Error('Unsupported platform: ' + process.platform);
128
+ const result = path_1.default.join(cacheDirectory, 'ms-playwright', `mcp-${options.channel ?? options.browserName}-profile`);
129
+ await fs_1.default.promises.mkdir(result, { recursive: true });
130
+ return result;
131
+ }
132
+ async function outputFile(config, name) {
133
+ const result = config.outputDir ?? os_1.default.tmpdir();
134
+ await fs_1.default.promises.mkdir(result, { recursive: true });
135
+ const fileName = (0, utils_1.sanitizeForFilePath)(name);
136
+ return path_1.default.join(result, fileName);
137
+ }
138
+ function mergeConfig(base, overrides) {
139
+ const browser = {
140
+ ...base.browser,
141
+ ...overrides.browser,
142
+ launchOptions: {
143
+ ...base.browser?.launchOptions,
144
+ ...overrides.browser?.launchOptions,
145
+ ...{ assistantMode: true },
146
+ },
147
+ contextOptions: {
148
+ ...base.browser?.contextOptions,
149
+ ...overrides.browser?.contextOptions,
150
+ },
151
+ };
152
+ return {
153
+ ...base,
154
+ ...overrides,
155
+ browser,
156
+ };
157
+ }