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-07-16 16:40:00 -07:00
import { program , Option } 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-07-24 12:57:01 -07:00
import * as mcpTransport from './mcp/transport.js' ;
2025-07-17 10:19:18 -07:00
import { commaSeparatedList , resolveCLIConfig , semicolonSeparatedList } from './config.js' ;
2025-05-28 16:55:47 -07:00
import { packageJSON } from './package.js' ;
2025-07-18 17:12:44 -07:00
import { runWithExtension } from './extension/main.js' ;
2025-07-24 12:57:01 -07:00
import { BrowserServerBackend } from './browserServerBackend.js' ;
import { Context } from './context.js' ;
import { contextFactory } from './browserContextFactory.js' ;
2025-07-24 16:22:03 -07:00
import { runLoopTools } from './loopTools/main.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 )
2025-08-15 06:42:16 -06:00
. option ( '--artifact-dir <path>' , 'path to the directory for centralized artifact storage with session-specific subdirectories.' )
2025-05-13 14:40:03 -07:00
. 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-07-17 10:19:18 -07:00
. option ( '--caps <caps>' , 'comma-separated list of additional capabilities to enable, possible values: vision, pdf.' , commaSeparatedList )
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.' )
2025-08-24 14:12:00 -06:00
. option ( '--console-output-file <path>' , 'file path to write browser console output to for debugging and monitoring.' )
2025-05-13 14:40:03 -07:00
. 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-07-16 18:32:07 -07:00
. option ( '--image-responses <mode>' , 'whether to send image responses to the client. Can be "allow" or "omit", Defaults to "allow".' )
feat: add snapshot size limits and optional snapshots to fix token overflow
Implements comprehensive solution for browser_click and other interactive tools
returning massive responses (37K+ tokens) due to full page snapshots.
Features implemented:
1. **Snapshot size limits** (--max-snapshot-tokens, default 10k)
- Automatically truncates large snapshots with helpful messages
- Preserves essential info (URL, title, errors) when truncating
- Shows exact token counts and configuration suggestions
2. **Optional snapshots** (--no-snapshots)
- Disables automatic snapshots after interactive operations
- browser_snapshot tool always works for explicit snapshots
- Maintains backward compatibility (snapshots enabled by default)
3. **Differential snapshots** (--differential-snapshots)
- Shows only changes since last snapshot instead of full page
- Tracks URL, title, DOM structure, and console activity
- Significantly reduces token usage for incremental operations
4. **Enhanced tool descriptions**
- All interactive tools now document snapshot behavior
- Clear guidance on when snapshots are included/excluded
- Helpful suggestions for users experiencing token limits
Configuration options:
- CLI: --no-snapshots, --max-snapshot-tokens N, --differential-snapshots
- ENV: PLAYWRIGHT_MCP_INCLUDE_SNAPSHOTS, PLAYWRIGHT_MCP_MAX_SNAPSHOT_TOKENS, etc.
- Config file: includeSnapshots, maxSnapshotTokens, differentialSnapshots
Fixes token overflow errors while providing users full control over
snapshot behavior and response sizes.
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 07:54:36 -06:00
. option ( '--no-snapshots' , 'disable automatic page snapshots after interactive operations like clicks. Use browser_snapshot tool for explicit snapshots.' )
. option ( '--max-snapshot-tokens <tokens>' , 'maximum number of tokens allowed in page snapshots before truncation. Use 0 to disable truncation. Default is 10000.' , parseInt )
. option ( '--differential-snapshots' , 'enable differential snapshots that only show changes since the last snapshot instead of full page snapshots.' )
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-07-22 20:06:03 -07:00
. option ( '--save-session' , 'Whether to save the Playwright MCP session into the output directory.' )
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-07-18 17:12:44 -07:00
. addOption ( new Option ( '--extension' , 'Connect to a running browser instance (Edge/Chrome only). Requires the "Playwright MCP Bridge" browser extension to be installed.' ) . hideHelp ( ) )
2025-07-24 16:22:03 -07:00
. addOption ( new Option ( '--loop-tools' , 'Run loop tools' ) . hideHelp ( ) )
2025-07-16 16:40:00 -07:00
. addOption ( new Option ( '--vision' , 'Legacy option, use --caps=vision instead' ) . hideHelp ( ) )
2025-03-21 10:58:58 -07:00
. action ( async options = > {
2025-07-24 12:57:01 -07:00
2025-07-16 16:40:00 -07:00
if ( options . vision ) {
// eslint-disable-next-line no-console
console . error ( 'The --vision option is deprecated, use --caps=vision instead' ) ;
options . caps = 'vision' ;
}
feat: add snapshot size limits and optional snapshots to fix token overflow
Implements comprehensive solution for browser_click and other interactive tools
returning massive responses (37K+ tokens) due to full page snapshots.
Features implemented:
1. **Snapshot size limits** (--max-snapshot-tokens, default 10k)
- Automatically truncates large snapshots with helpful messages
- Preserves essential info (URL, title, errors) when truncating
- Shows exact token counts and configuration suggestions
2. **Optional snapshots** (--no-snapshots)
- Disables automatic snapshots after interactive operations
- browser_snapshot tool always works for explicit snapshots
- Maintains backward compatibility (snapshots enabled by default)
3. **Differential snapshots** (--differential-snapshots)
- Shows only changes since last snapshot instead of full page
- Tracks URL, title, DOM structure, and console activity
- Significantly reduces token usage for incremental operations
4. **Enhanced tool descriptions**
- All interactive tools now document snapshot behavior
- Clear guidance on when snapshots are included/excluded
- Helpful suggestions for users experiencing token limits
Configuration options:
- CLI: --no-snapshots, --max-snapshot-tokens N, --differential-snapshots
- ENV: PLAYWRIGHT_MCP_INCLUDE_SNAPSHOTS, PLAYWRIGHT_MCP_MAX_SNAPSHOT_TOKENS, etc.
- Config file: includeSnapshots, maxSnapshotTokens, differentialSnapshots
Fixes token overflow errors while providing users full control over
snapshot behavior and response sizes.
Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 07:54:36 -06:00
// Handle negated boolean options
if ( options . noSnapshots !== undefined )
options . includeSnapshots = ! options . noSnapshots ;
2025-05-14 16:01:08 -07:00
const config = await resolveCLIConfig ( options ) ;
2025-08-11 03:39:24 -06:00
const abortController = setupExitWatchdog ( config . server ) ;
2025-06-13 16:13:40 -07:00
2025-07-24 10:09:01 -07:00
if ( options . extension ) {
2025-07-24 16:02:02 -07:00
await runWithExtension ( config , abortController ) ;
2025-07-24 10:09:01 -07:00
return ;
}
2025-07-24 16:22:03 -07:00
if ( options . loopTools ) {
await runLoopTools ( config ) ;
return ;
}
2025-07-24 10:09:01 -07:00
2025-07-24 12:57:01 -07:00
const browserContextFactory = contextFactory ( config . browser ) ;
const serverBackendFactory = ( ) = > new BrowserServerBackend ( config , browserContextFactory ) ;
await mcpTransport . start ( serverBackendFactory , config . 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-08-11 03:39:24 -06:00
function setupExitWatchdog ( serverConfig : { host? : string ; port? : number } ) {
2025-07-24 16:02:02 -07:00
const abortController = new AbortController ( ) ;
2025-07-24 12:57:01 -07:00
let isExiting = false ;
const handleExit = async ( ) = > {
if ( isExiting )
return ;
isExiting = true ;
setTimeout ( ( ) = > process . exit ( 0 ) , 15000 ) ;
2025-07-24 16:02:02 -07:00
abortController . abort ( 'Process exiting' ) ;
2025-07-24 12:57:01 -07:00
await Context . disposeAll ( ) ;
process . exit ( 0 ) ;
} ;
2025-08-15 06:42:16 -06:00
if ( serverConfig . port !== undefined )
2025-08-11 03:39:24 -06:00
process . stdin . on ( 'close' , handleExit ) ;
2025-08-15 06:42:16 -06:00
2025-07-24 12:57:01 -07:00
process . on ( 'SIGINT' , handleExit ) ;
process . on ( 'SIGTERM' , handleExit ) ;
2025-07-24 16:02:02 -07:00
return abortController ;
2025-07-24 12:57:01 -07:00
}
2025-05-28 16:55:47 -07:00
void program . parseAsync ( process . argv ) ;