mirror of
https://github.com/microsoft/playwright-mcp.git
synced 2025-07-26 08:32:26 +08:00
feat(args): allow configuring proxy, UA, viewport, https errors (#410)
This commit is contained in:
parent
ce72367208
commit
7be0c8872e
22
README.md
22
README.md
@ -110,6 +110,9 @@ Follow the MCP install [guide](https://modelcontextprotocol.io/quickstart/user),
|
|||||||
|
|
||||||
Playwright MCP server supports following arguments. They can be provided in the JSON configuration above, as a part of the `"args"` list:
|
Playwright MCP server supports following arguments. They can be provided in the JSON configuration above, as a part of the `"args"` list:
|
||||||
|
|
||||||
|
- `--allowed-origins <origins>`: Semicolon-separated list of origins to allow the browser to request. Default is to allow all. Origins matching both `--allowed-origins` and `--blocked-origins` will be blocked.
|
||||||
|
- `--blocked-origins <origins>`: Semicolon-separated list of origins to block the browser to request. Origins matching both `--allowed-origins` and `--blocked-origins` will be blocked.
|
||||||
|
- `--block-service-workers`: Block service workers
|
||||||
- `--browser <browser>`: Browser or chrome channel to use. Possible values:
|
- `--browser <browser>`: Browser or chrome channel to use. Possible values:
|
||||||
- `chrome`, `firefox`, `webkit`, `msedge`
|
- `chrome`, `firefox`, `webkit`, `msedge`
|
||||||
- Chrome channels: `chrome-beta`, `chrome-canary`, `chrome-dev`
|
- Chrome channels: `chrome-beta`, `chrome-canary`, `chrome-dev`
|
||||||
@ -117,18 +120,21 @@ Playwright MCP server supports following arguments. They can be provided in the
|
|||||||
- Default: `chrome`
|
- Default: `chrome`
|
||||||
- `--caps <caps>`: Comma-separated list of capabilities to enable, possible values: tabs, pdf, history, wait, files, install. Default is all.
|
- `--caps <caps>`: Comma-separated list of capabilities to enable, possible values: tabs, pdf, history, wait, files, install. Default is all.
|
||||||
- `--cdp-endpoint <endpoint>`: CDP endpoint to connect to
|
- `--cdp-endpoint <endpoint>`: CDP endpoint to connect to
|
||||||
- `--isolated`: Keep the browser profile in memory, do not save it to disk
|
- `--config <path>`: Path to the configuration file
|
||||||
|
- `--device`: Emulate mobile device
|
||||||
- `--executable-path <path>`: Path to the browser executable
|
- `--executable-path <path>`: Path to the browser executable
|
||||||
- `--headless`: Run browser in headless mode (headed by default)
|
- `--headless`: Run browser in headless mode (headed by default)
|
||||||
- `--device`: Emulate mobile device
|
|
||||||
- `--user-data-dir <path>`: Path to the user data directory
|
|
||||||
- `--port <port>`: Port to listen on for SSE transport
|
|
||||||
- `--host <host>`: Host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.
|
- `--host <host>`: Host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.
|
||||||
- `--allowed-origins <origins>`: Semicolon-separated list of origins to allow the browser to request. Default is to allow all. Origins matching both `--allowed-origins` and `--blocked-origins` will be blocked.
|
- `--ignore-https-errors`: Ignore https errors
|
||||||
- `--blocked-origins <origins>`: Semicolon-separated list of origins to block the browser to request. Origins matching both `--allowed-origins` and `--blocked-origins` will be blocked.
|
- `--isolated`: Keep the browser profile in memory, do not save it to disk
|
||||||
- `--vision`: Run server that uses screenshots (Aria snapshots are used by default)
|
|
||||||
- `--output-dir`: Directory for output files
|
- `--output-dir`: Directory for output files
|
||||||
- `--config <path>`: Path to the configuration file
|
- `--port <port>`: Port to listen on for SSE transport
|
||||||
|
- `--proxy-bypass <bypass>`: Comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"'
|
||||||
|
- `--proxy-server <proxy>`: Proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"'
|
||||||
|
- `--user-agent <ua string>`: Specify user agent string
|
||||||
|
- `--user-data-dir <path>`: Path to the user data directory. If not specified, a temporary directory will be created
|
||||||
|
- `--viewport-size <size>`: Specify browser viewport size in pixels, for example "1280, 720"
|
||||||
|
- `--vision`: Run server that uses screenshots (Aria snapshots are used by default)
|
||||||
|
|
||||||
### User profile
|
### User profile
|
||||||
|
|
||||||
|
@ -25,23 +25,29 @@ import type { BrowserContextOptions, LaunchOptions } from 'playwright';
|
|||||||
import { sanitizeForFilePath } from './tools/utils.js';
|
import { sanitizeForFilePath } from './tools/utils.js';
|
||||||
|
|
||||||
export type CLIOptions = {
|
export type CLIOptions = {
|
||||||
|
allowedOrigins?: string[];
|
||||||
|
blockedOrigins?: string[];
|
||||||
|
blockServiceWorkers?: boolean;
|
||||||
browser?: string;
|
browser?: string;
|
||||||
caps?: string;
|
caps?: string;
|
||||||
cdpEndpoint?: string;
|
cdpEndpoint?: string;
|
||||||
isolated?: boolean;
|
config?: string;
|
||||||
|
device?: string;
|
||||||
executablePath?: string;
|
executablePath?: string;
|
||||||
headless?: boolean;
|
headless?: boolean;
|
||||||
device?: string;
|
|
||||||
userDataDir?: string;
|
|
||||||
storageState?: string;
|
|
||||||
port?: number;
|
|
||||||
host?: string;
|
host?: string;
|
||||||
vision?: boolean;
|
ignoreHttpsErrors?: boolean;
|
||||||
config?: string;
|
isolated?: boolean;
|
||||||
allowedOrigins?: string[];
|
|
||||||
blockedOrigins?: string[];
|
|
||||||
outputDir?: string;
|
|
||||||
noImageResponses?: boolean;
|
noImageResponses?: boolean;
|
||||||
|
outputDir?: string;
|
||||||
|
port?: number;
|
||||||
|
proxyBypass?: string;
|
||||||
|
proxyServer?: string;
|
||||||
|
storageState?: string;
|
||||||
|
userAgent?: string;
|
||||||
|
userDataDir?: string;
|
||||||
|
viewportSize?: string;
|
||||||
|
vision?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultConfig: Config = {
|
const defaultConfig: Config = {
|
||||||
@ -94,6 +100,7 @@ export async function configFromCLIOptions(cliOptions: CLIOptions): Promise<Conf
|
|||||||
channel = 'chrome';
|
channel = 'chrome';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Launch options
|
||||||
const launchOptions: LaunchOptions = {
|
const launchOptions: LaunchOptions = {
|
||||||
channel,
|
channel,
|
||||||
executablePath: cliOptions.executablePath,
|
executablePath: cliOptions.executablePath,
|
||||||
@ -103,10 +110,39 @@ export async function configFromCLIOptions(cliOptions: CLIOptions): Promise<Conf
|
|||||||
if (browserName === 'chromium')
|
if (browserName === 'chromium')
|
||||||
(launchOptions as any).cdpPort = await findFreePort();
|
(launchOptions as any).cdpPort = await findFreePort();
|
||||||
|
|
||||||
|
if (cliOptions.proxyServer) {
|
||||||
|
launchOptions.proxy = {
|
||||||
|
server: cliOptions.proxyServer
|
||||||
|
};
|
||||||
|
if (cliOptions.proxyBypass)
|
||||||
|
launchOptions.proxy.bypass = cliOptions.proxyBypass;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context options
|
||||||
const contextOptions: BrowserContextOptions = cliOptions.device ? devices[cliOptions.device] : {};
|
const contextOptions: BrowserContextOptions = cliOptions.device ? devices[cliOptions.device] : {};
|
||||||
if (cliOptions.storageState)
|
if (cliOptions.storageState)
|
||||||
contextOptions.storageState = cliOptions.storageState;
|
contextOptions.storageState = cliOptions.storageState;
|
||||||
|
|
||||||
|
if (cliOptions.userAgent)
|
||||||
|
contextOptions.userAgent = cliOptions.userAgent;
|
||||||
|
|
||||||
|
if (cliOptions.viewportSize) {
|
||||||
|
try {
|
||||||
|
const [width, height] = cliOptions.viewportSize.split(',').map(n => +n);
|
||||||
|
if (isNaN(width) || isNaN(height))
|
||||||
|
throw new Error('bad values');
|
||||||
|
contextOptions.viewport = { width, height };
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('Invalid viewport size format: use "width,height", for example --viewport-size="800,600"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cliOptions.ignoreHttpsErrors)
|
||||||
|
contextOptions.ignoreHTTPSErrors = true;
|
||||||
|
|
||||||
|
if (cliOptions.blockServiceWorkers)
|
||||||
|
contextOptions.serviceWorkers = 'block';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
browser: {
|
browser: {
|
||||||
browserName,
|
browserName,
|
||||||
|
@ -25,24 +25,30 @@ import { packageJSON } from './context.js';
|
|||||||
program
|
program
|
||||||
.version('Version ' + packageJSON.version)
|
.version('Version ' + packageJSON.version)
|
||||||
.name(packageJSON.name)
|
.name(packageJSON.name)
|
||||||
.option('--browser <browser>', 'Browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.')
|
.option('--browser <browser>', 'browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.')
|
||||||
.option('--caps <caps>', 'Comma-separated list of capabilities to enable, possible values: tabs, pdf, history, wait, files, install. Default is all.')
|
.option('--allowed-origins <origins>', 'semicolon-separated list of origins to allow the browser to request. Default is to allow all.', semicolonSeparatedList)
|
||||||
|
.option('--blocked-origins <origins>', 'semicolon-separated list of origins to block the browser from requesting. Blocklist is evaluated before allowlist. If used without the allowlist, requests not matching the blocklist are still allowed.', semicolonSeparatedList)
|
||||||
|
.option('--block-service-workers', 'block service workers')
|
||||||
|
.option('--caps <caps>', 'comma-separated list of capabilities to enable, possible values: tabs, pdf, history, wait, files, install. Default is all.')
|
||||||
.option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.')
|
.option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.')
|
||||||
.option('--isolated', 'Keep the browser profile in memory, do not save it to disk.')
|
.option('--config <path>', 'path to the configuration file.')
|
||||||
.option('--storage-state <path>', 'Path to the storage state file for isolated sessions.')
|
.option('--device <device>', 'device to emulate, for example: "iPhone 15"')
|
||||||
.option('--executable-path <path>', 'Path to the browser executable.')
|
.option('--executable-path <path>', 'path to the browser executable.')
|
||||||
.option('--headless', 'Run browser in headless mode, headed by default')
|
.option('--headless', 'run browser in headless mode, headed by default')
|
||||||
.option('--device <device>', 'Device to emulate, for example: "iPhone 15"')
|
.option('--host <host>', 'host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.')
|
||||||
.option('--user-data-dir <path>', 'Path to the user data directory. If not specified, a temporary directory will be created.')
|
.option('--in-memory', 'use in-memory storage for user data directory.')
|
||||||
.option('--in-memory', 'Use in-memory storage for user data directory.')
|
.option('--ignore-https-errors', 'ignore https errors')
|
||||||
.option('--port <port>', 'Port to listen on for SSE transport.')
|
.option('--isolated', 'keep the browser profile in memory, do not save it to disk.')
|
||||||
.option('--host <host>', 'Host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.')
|
.option('--no-image-responses', 'do not send image responses to the client.')
|
||||||
.option('--allowed-origins <origins>', 'Semicolon-separated list of origins to allow the browser to request. Default is to allow all.', semicolonSeparatedList)
|
.option('--output-dir <path>', 'path to the directory for output files.')
|
||||||
.option('--blocked-origins <origins>', 'Semicolon-separated list of origins to block the browser from requesting. Blocklist is evaluated before allowlist. If used without the allowlist, requests not matching the blocklist are still allowed.', semicolonSeparatedList)
|
.option('--port <port>', 'port to listen on for SSE transport.')
|
||||||
|
.option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"')
|
||||||
|
.option('--proxy-server <proxy>', 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"')
|
||||||
|
.option('--storage-state <path>', 'path to the storage state file for isolated sessions.')
|
||||||
|
.option('--user-agent <ua string>', 'specify user agent string')
|
||||||
|
.option('--user-data-dir <path>', 'path to the user data directory. If not specified, a temporary directory will be created.')
|
||||||
|
.option('--viewport-size <size>', 'specify browser viewport size in pixels, for example "1280, 720"')
|
||||||
.option('--vision', 'Run server that uses screenshots (Aria snapshots are used by default)')
|
.option('--vision', 'Run server that uses screenshots (Aria snapshots are used by default)')
|
||||||
.option('--no-image-responses', 'Do not send image responses to the client.')
|
|
||||||
.option('--output-dir <path>', 'Path to the directory for output files.')
|
|
||||||
.option('--config <path>', 'Path to the configuration file.')
|
|
||||||
.action(async options => {
|
.action(async options => {
|
||||||
const config = await resolveConfig(options);
|
const config = await resolveConfig(options);
|
||||||
const connectionList: Connection[] = [];
|
const connectionList: Connection[] = [];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user