mirror of
				https://github.com/microsoft/playwright-mcp.git
				synced 2025-10-12 00:25:14 +03:00 
			
		
		
		
	chore: merge browser and channel settings (#100)
This commit is contained in:
		
							
								
								
									
										18
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								README.md
									
									
									
									
									
								
							| @@ -59,9 +59,25 @@ code-insiders --add-mcp '{"name":"playwright","command":"npx","args":["@playwrig | ||||
|  | ||||
| After installation, the Playwright MCP server will be available for use with your GitHub Copilot agent in VS Code. | ||||
|  | ||||
| ### CLI Options | ||||
|  | ||||
| The Playwright MCP server supports the following command-line options: | ||||
|  | ||||
| - `--browser <browser>`: Browser or chrome channel to use. Possible values: | ||||
|   - `chrome`, `firefox`, `webkit`, `msedge` | ||||
|   - Chrome channels: `chrome-beta`, `chrome-canary`, `chrome-dev` | ||||
|   - Edge channels: `msedge-beta`, `msedge-canary`, `msedge-dev` | ||||
|   - Default: `chrome` | ||||
| - `--cdp-endpoint <endpoint>`: CDP endpoint to connect to | ||||
| - `--executable-path <path>`: Path to the browser executable | ||||
| - `--headless`: Run browser in headless mode (headed by default) | ||||
| - `--port <port>`: Port to listen on for SSE transport | ||||
| - `--user-data-dir <path>`: Path to the user data directory | ||||
| - `--vision`: Run server that uses screenshots (Aria snapshots are used by default) | ||||
|  | ||||
| ### User data directory | ||||
|  | ||||
| Playwright MCP will launch Chrome browser with the new profile, located at | ||||
| Playwright MCP will launch the browser with the new profile, located at | ||||
|  | ||||
| ``` | ||||
| - `%USERPROFILE%\AppData\Local\ms-playwright\mcp-chrome-profile` on Windows | ||||
|   | ||||
| @@ -20,6 +20,7 @@ import path from 'path'; | ||||
| import * as playwright from 'playwright'; | ||||
|  | ||||
| export type ContextOptions = { | ||||
|   browserName?: 'chromium' | 'firefox' | 'webkit'; | ||||
|   userDataDir: string; | ||||
|   launchOptions?: playwright.LaunchOptions; | ||||
|   cdpEndpoint?: string; | ||||
| @@ -73,7 +74,7 @@ export class Context { | ||||
|   } | ||||
|  | ||||
|   async install(): Promise<string> { | ||||
|     const channel = this._options.launchOptions?.channel || 'chrome'; | ||||
|     const channel = this._options.launchOptions?.channel ?? this._options.browserName ?? 'chrome'; | ||||
|     const cli = path.join(require.resolve('playwright/package.json'), '..', 'cli.js'); | ||||
|     const child = fork(cli, ['install', channel], { | ||||
|       stdio: 'pipe', | ||||
| @@ -125,9 +126,11 @@ export class Context { | ||||
|   private async _createPage(): Promise<{ browser?: playwright.Browser, page: playwright.Page }> { | ||||
|     if (this._options.remoteEndpoint) { | ||||
|       const url = new URL(this._options.remoteEndpoint); | ||||
|       if (this._options.browserName) | ||||
|         url.searchParams.set('browser', this._options.browserName); | ||||
|       if (this._options.launchOptions) | ||||
|         url.searchParams.set('launch-options', JSON.stringify(this._options.launchOptions)); | ||||
|       const browser = await playwright.chromium.connect(String(url)); | ||||
|       const browser = await playwright[this._options.browserName ?? 'chromium'].connect(String(url)); | ||||
|       const page = await browser.newPage(); | ||||
|       return { browser, page }; | ||||
|     } | ||||
| @@ -148,7 +151,8 @@ export class Context { | ||||
|  | ||||
|   private async _launchPersistentContext(): Promise<playwright.BrowserContext> { | ||||
|     try { | ||||
|       return await playwright.chromium.launchPersistentContext(this._options.userDataDir, this._options.launchOptions); | ||||
|       const browserType = this._options.browserName ? playwright[this._options.browserName] : playwright.chromium; | ||||
|       return await browserType.launchPersistentContext(this._options.userDataDir, this._options.launchOptions); | ||||
|     } catch (error: any) { | ||||
|       if (error.message.includes('Executable doesn\'t exist')) | ||||
|         throw new Error(`Browser specified in your config is not installed. Either install it (likely) or change the config.`); | ||||
|   | ||||
| @@ -65,6 +65,7 @@ const resources: Resource[] = [ | ||||
| ]; | ||||
|  | ||||
| type Options = { | ||||
|   browserName?: 'chromium' | 'firefox' | 'webkit'; | ||||
|   userDataDir?: string; | ||||
|   launchOptions?: LaunchOptions; | ||||
|   cdpEndpoint?: string; | ||||
| @@ -80,6 +81,7 @@ export function createServer(options?: Options): Server { | ||||
|     version: packageJSON.version, | ||||
|     tools, | ||||
|     resources, | ||||
|     browserName: options?.browserName, | ||||
|     userDataDir: options?.userDataDir ?? '', | ||||
|     launchOptions: options?.launchOptions, | ||||
|     cdpEndpoint: options?.cdpEndpoint, | ||||
|   | ||||
| @@ -35,21 +35,52 @@ const packageJSON = require('../package.json'); | ||||
| program | ||||
|     .version('Version ' + packageJSON.version) | ||||
|     .name(packageJSON.name) | ||||
|     .option('--browser <browser>', 'Browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.') | ||||
|     .option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.') | ||||
|     .option('--executable-path <path>', 'Path to the browser executable.') | ||||
|     .option('--headless', 'Run browser in headless mode, headed by default') | ||||
|     .option('--port <port>', 'Port to listen on for SSE transport.') | ||||
|     .option('--user-data-dir <path>', 'Path to the user data directory') | ||||
|     .option('--vision', 'Run server that uses screenshots (Aria snapshots are used by default)') | ||||
|     .option('--port <port>', 'Port to listen on for SSE transport.') | ||||
|     .option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.') | ||||
|     .option('--channel <channel>', 'Channel to use for browser, possible values: chrome, msedge, chromium. Default: chrome') | ||||
|     .option('--executable-path <path>', 'Path to the browser executable.') | ||||
|     .action(async options => { | ||||
|       let browserName: 'chromium' | 'firefox' | 'webkit'; | ||||
|       let channel: string | undefined; | ||||
|       switch (options.browser) { | ||||
|         case 'chrome': | ||||
|         case 'chrome-beta': | ||||
|         case 'chrome-canary': | ||||
|         case 'chrome-dev': | ||||
|         case 'msedge': | ||||
|         case 'msedge-beta': | ||||
|         case 'msedge-canary': | ||||
|         case 'msedge-dev': | ||||
|           browserName = 'chromium'; | ||||
|           channel = options.browser; | ||||
|           break; | ||||
|         case 'chromium': | ||||
|           browserName = 'chromium'; | ||||
|           break; | ||||
|         case 'firefox': | ||||
|           browserName = 'firefox'; | ||||
|           break; | ||||
|         case 'webkit': | ||||
|           browserName = 'webkit'; | ||||
|           break; | ||||
|         default: | ||||
|           browserName = 'chromium'; | ||||
|           channel = 'chrome'; | ||||
|       } | ||||
|  | ||||
|       const launchOptions: LaunchOptions = { | ||||
|         headless: !!options.headless, | ||||
|         channel: options.channel ?? 'chrome', | ||||
|         channel, | ||||
|         executablePath: options.executablePath, | ||||
|       }; | ||||
|       const userDataDir = options.userDataDir ?? await createUserDataDir(); | ||||
|  | ||||
|       const userDataDir = options.userDataDir ?? await createUserDataDir(browserName); | ||||
|  | ||||
|       const serverList = new ServerList(() => createServer({ | ||||
|         browserName, | ||||
|         userDataDir, | ||||
|         launchOptions, | ||||
|         vision: !!options.vision, | ||||
| @@ -75,7 +106,7 @@ function setupExitWatchdog(serverList: ServerList) { | ||||
|  | ||||
| program.parse(process.argv); | ||||
|  | ||||
| async function createUserDataDir() { | ||||
| async function createUserDataDir(browserName: 'chromium' | 'firefox' | 'webkit') { | ||||
|   let cacheDirectory: string; | ||||
|   if (process.platform === 'linux') | ||||
|     cacheDirectory = process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache'); | ||||
| @@ -85,7 +116,7 @@ async function createUserDataDir() { | ||||
|     cacheDirectory = process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'); | ||||
|   else | ||||
|     throw new Error('Unsupported platform: ' + process.platform); | ||||
|   const result = path.join(cacheDirectory, 'ms-playwright', 'mcp-chrome-profile'); | ||||
|   const result = path.join(cacheDirectory, 'ms-playwright', `mcp-${browserName}-profile`); | ||||
|   await fs.promises.mkdir(result, { recursive: true }); | ||||
|   return result; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Pavel Feldman
					Pavel Feldman