2025-03-21 10:58:58 -07:00
/ * *
* Copyright ( c ) Microsoft Corporation .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
2025-06-13 22:15:17 +02:00
import { Option , program } from 'commander' ;
2025-05-14 20:15:09 -07:00
// @ts-ignore
import { startTraceViewerServer } from 'playwright-core/lib/server' ;
2025-04-28 15:04:59 -07:00
2025-06-13 16:13:40 -07:00
import { startHttpServer , startHttpTransport , startStdioTransport } from './transport.js' ;
2025-05-28 16:55:47 -07:00
import { resolveCLIConfig } from './config.js' ;
import { Server } from './server.js' ;
import { packageJSON } from './package.js' ;
2025-06-13 16:13:40 -07:00
import { startCDPRelayServer } from './cdpRelay.js' ;
2025-03-21 10:58:58 -07:00
program
. version ( 'Version ' + packageJSON . version )
. name ( packageJSON . name )
2025-05-13 14:40:03 -07:00
. 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' )
2025-05-13 15:30:02 -07:00
. option ( '--browser <browser>' , 'browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.' )
2025-06-04 09:14:50 -07:00
. option ( '--browser-agent <endpoint>' , 'Use browser agent (experimental).' )
2025-05-13 14:40:03 -07:00
. option ( '--caps <caps>' , 'comma-separated list of capabilities to enable, possible values: tabs, pdf, history, wait, files, install. Default is all.' )
2025-04-01 10:26:48 -07:00
. option ( '--cdp-endpoint <endpoint>' , 'CDP endpoint to connect to.' )
2025-05-13 14:40:03 -07:00
. option ( '--config <path>' , 'path to the configuration file.' )
. option ( '--device <device>' , 'device to emulate, for example: "iPhone 15"' )
. option ( '--executable-path <path>' , 'path to the browser executable.' )
. option ( '--headless' , 'run browser in headless mode, headed by default' )
. option ( '--host <host>' , 'host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.' )
. option ( '--ignore-https-errors' , 'ignore https errors' )
. option ( '--isolated' , 'keep the browser profile in memory, do not save it to disk.' )
2025-05-27 01:25:09 -07:00
. option ( '--image-responses <mode>' , 'whether to send image responses to the client. Can be "allow", "omit", or "auto". Defaults to "auto", which sends images if the client can display them.' )
2025-05-13 15:30:02 -07:00
. option ( '--no-sandbox' , 'disable the sandbox for all process types that are normally sandboxed.' )
2025-05-13 14:40:03 -07:00
. option ( '--output-dir <path>' , 'path to the directory for output files.' )
. 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"' )
2025-05-14 18:08:44 -07:00
. option ( '--save-trace' , 'Whether to save the Playwright Trace of the session into the output directory.' )
2025-05-13 14:40:03 -07:00
. 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"' )
2025-03-21 10:58:58 -07:00
. option ( '--vision' , 'Run server that uses screenshots (Aria snapshots are used by default)' )
2025-06-13 22:15:17 +02:00
. addOption ( new Option ( '--extension' , 'Allow connecting to a running browser instance (Edge/Chrome only). Requires the \'Playwright MCP\' browser extension to be installed.' ) . hideHelp ( ) )
2025-03-21 10:58:58 -07:00
. action ( async options = > {
2025-05-14 16:01:08 -07:00
const config = await resolveCLIConfig ( options ) ;
2025-06-13 16:13:40 -07:00
const httpServer = config . server . port !== undefined ? await startHttpServer ( config . server ) : undefined ;
if ( config . extension ) {
if ( ! httpServer )
throw new Error ( '--port parameter is required for extension mode' ) ;
// Point CDP endpoint to the relay server.
config . browser . cdpEndpoint = await startCDPRelayServer ( httpServer ) ;
}
const server = new Server ( config ) ;
2025-05-28 16:55:47 -07:00
server . setupExitWatchdog ( ) ;
2025-03-25 14:46:39 -07:00
2025-06-13 16:13:40 -07:00
if ( httpServer )
await startHttpTransport ( httpServer , server ) ;
2025-04-28 11:11:31 +02:00
else
2025-05-28 16:55:47 -07:00
await startStdioTransport ( server ) ;
2025-05-14 20:15:09 -07:00
if ( config . saveTrace ) {
const server = await startTraceViewerServer ( ) ;
const urlPrefix = server . urlPrefix ( 'human-readable' ) ;
const url = urlPrefix + '/trace/index.html?trace=' + config . browser . launchOptions . tracesDir + '/trace.json' ;
// eslint-disable-next-line no-console
console . error ( '\nTrace viewer listening on ' + url ) ;
}
2025-03-21 10:58:58 -07:00
} ) ;
2025-05-05 11:28:14 -07:00
function semicolonSeparatedList ( value : string ) : string [ ] {
return value . split ( ';' ) . map ( v = > v . trim ( ) ) ;
}
2025-05-28 16:55:47 -07:00
void program . parseAsync ( process . argv ) ;