From 862c6d5ffc685e73352d337286fbe26f2081d35f Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Fri, 10 Oct 2025 16:33:28 +0200 Subject: [PATCH 1/2] feat: support passing args to Chrome --- README.md | 5 +++++ src/browser.ts | 6 +----- src/cli.ts | 19 +++++++++++-------- src/main.ts | 1 - tests/cli.test.ts | 28 ++++++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 4c5e7a501..6f90f46ca 100644 --- a/README.md +++ b/README.md @@ -291,6 +291,11 @@ The Chrome DevTools MCP server supports the following configuration option: If enabled, ignores errors relative to self-signed and expired certificates. Use with caution. - **Type:** boolean +- **`--chromeArg`** + Additional arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp. + - **Type:** array + - **Default:** `` + Pass them via the `args` property in the JSON configuration. For example: diff --git a/src/browser.ts b/src/browser.ts index b0a7aaa5a..76fd14f42 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -60,7 +60,6 @@ export async function ensureBrowserConnected(options: { interface McpLaunchOptions { acceptInsecureCerts?: boolean; executablePath?: string; - customDevTools?: string; channel?: Channel; userDataDir?: string; headless: boolean; @@ -75,7 +74,7 @@ interface McpLaunchOptions { } export async function launch(options: McpLaunchOptions): Promise { - const {channel, executablePath, customDevTools, headless, isolated} = options; + const {channel, executablePath, headless, isolated} = options; const profileDirName = channel && channel !== 'stable' ? `chrome-profile-${channel}` @@ -98,9 +97,6 @@ export async function launch(options: McpLaunchOptions): Promise { ...(options.args ?? []), '--hide-crash-restore-bubble', ]; - if (customDevTools) { - args.push(`--custom-devtools-frontend=file://${customDevTools}`); - } if (headless) { args.push('--screen-info={3840x2160}'); } diff --git a/src/cli.ts b/src/cli.ts index 17b1df633..f33d34c32 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -43,13 +43,6 @@ export const cliOptions = { 'If specified, creates a temporary user-data-dir that is automatically cleaned up after the browser is closed.', default: false, }, - customDevtools: { - type: 'string', - description: 'Path to custom DevTools.', - hidden: true, - conflicts: 'browserUrl', - alias: 'd', - }, channel: { type: 'string', description: @@ -89,10 +82,16 @@ export const cliOptions = { description: `If enabled, ignores errors relative to self-signed and expired certificates. Use with caution.`, }, experimentalDevtools: { - type: 'boolean' as const, + type: 'boolean', describe: 'Whether to enable automation over DevTools targets', hidden: true, }, + chromeArg: { + type: 'array', + describe: + 'Additional arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp.', + default: [], + }, } satisfies Record; export function parseArguments(version: string, argv = process.argv) { @@ -122,6 +121,10 @@ export function parseArguments(version: string, argv = process.argv) { '$0 --viewport 1280x720', 'Launch Chrome with the initial viewport size of 1280x720px', ], + [ + `$0 --chrome-args='--no-sandbox' --chrome-args='--disable-setuid-sandbox'`, + 'Launch Chrome without sandboxes. Use with caution.', + ], ]); return yargsInstance diff --git a/src/main.ts b/src/main.ts index fdf185506..383d0fab5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -82,7 +82,6 @@ async function getContext(): Promise { : await ensureBrowserLaunched({ headless: args.headless, executablePath: args.executablePath, - customDevTools: args.customDevtools, channel: args.channel as Channel, isolated: args.isolated, logFile, diff --git a/tests/cli.test.ts b/tests/cli.test.ts index 1580825c7..ebc0ff5ed 100644 --- a/tests/cli.test.ts +++ b/tests/cli.test.ts @@ -17,6 +17,8 @@ describe('cli args parsing', () => { isolated: false, $0: 'npx chrome-devtools-mcp@latest', channel: 'stable', + 'chrome-arg': [], + chromeArg: [], }); }); @@ -35,6 +37,8 @@ describe('cli args parsing', () => { 'browser-url': 'http://localhost:3000', browserUrl: 'http://localhost:3000', u: 'http://localhost:3000', + 'chrome-arg': [], + chromeArg: [], }); }); @@ -54,6 +58,8 @@ describe('cli args parsing', () => { browserUrl: undefined, u: undefined, channel: 'stable', + 'chrome-arg': [], + chromeArg: [], }); }); @@ -72,6 +78,8 @@ describe('cli args parsing', () => { 'executable-path': '/tmp/test 123/chrome', e: '/tmp/test 123/chrome', executablePath: '/tmp/test 123/chrome', + 'chrome-arg': [], + chromeArg: [], }); }); @@ -92,6 +100,26 @@ describe('cli args parsing', () => { width: 888, height: 777, }, + 'chrome-arg': [], + chromeArg: [], + }); + }); + + it('parses viewport', async () => { + const args = parseArguments('1.0.0', [ + 'node', + 'main.js', + `--chrome-arg='--no-sandbox'`, + `--chrome-arg='--disable-setuid-sandbox'`, + ]); + assert.deepStrictEqual(args, { + _: [], + headless: false, + isolated: false, + $0: 'npx chrome-devtools-mcp@latest', + channel: 'stable', + 'chrome-arg': ['--no-sandbox', '--disable-setuid-sandbox'], + chromeArg: ['--no-sandbox', '--disable-setuid-sandbox'], }); }); }); From e96f34d9cc0a1d5c26224bbaacb851140aaecca1 Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Fri, 10 Oct 2025 16:40:55 +0200 Subject: [PATCH 2/2] feat: support arbitrary args --- README.md | 1 - src/cli.ts | 3 +-- src/main.ts | 2 +- tests/cli.test.ts | 10 ---------- 4 files changed, 2 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 6f90f46ca..be44ccaa9 100644 --- a/README.md +++ b/README.md @@ -294,7 +294,6 @@ The Chrome DevTools MCP server supports the following configuration option: - **`--chromeArg`** Additional arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp. - **Type:** array - - **Default:** `` diff --git a/src/cli.ts b/src/cli.ts index f33d34c32..513fff338 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -90,7 +90,6 @@ export const cliOptions = { type: 'array', describe: 'Additional arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp.', - default: [], }, } satisfies Record; @@ -122,7 +121,7 @@ export function parseArguments(version: string, argv = process.argv) { 'Launch Chrome with the initial viewport size of 1280x720px', ], [ - `$0 --chrome-args='--no-sandbox' --chrome-args='--disable-setuid-sandbox'`, + `$0 --chrome-arg='--no-sandbox' --chrome-arg='--disable-setuid-sandbox'`, 'Launch Chrome without sandboxes. Use with caution.', ], ]); diff --git a/src/main.ts b/src/main.ts index 383d0fab5..ada8cb308 100644 --- a/src/main.ts +++ b/src/main.ts @@ -69,7 +69,7 @@ server.server.setRequestHandler(SetLevelRequestSchema, () => { let context: McpContext; async function getContext(): Promise { - const extraArgs: string[] = []; + const extraArgs: string[] = (args.chromeArg ?? []).map(String); if (args.proxyServer) { extraArgs.push(`--proxy-server=${args.proxyServer}`); } diff --git a/tests/cli.test.ts b/tests/cli.test.ts index ebc0ff5ed..ab46582f0 100644 --- a/tests/cli.test.ts +++ b/tests/cli.test.ts @@ -17,8 +17,6 @@ describe('cli args parsing', () => { isolated: false, $0: 'npx chrome-devtools-mcp@latest', channel: 'stable', - 'chrome-arg': [], - chromeArg: [], }); }); @@ -37,8 +35,6 @@ describe('cli args parsing', () => { 'browser-url': 'http://localhost:3000', browserUrl: 'http://localhost:3000', u: 'http://localhost:3000', - 'chrome-arg': [], - chromeArg: [], }); }); @@ -58,8 +54,6 @@ describe('cli args parsing', () => { browserUrl: undefined, u: undefined, channel: 'stable', - 'chrome-arg': [], - chromeArg: [], }); }); @@ -78,8 +72,6 @@ describe('cli args parsing', () => { 'executable-path': '/tmp/test 123/chrome', e: '/tmp/test 123/chrome', executablePath: '/tmp/test 123/chrome', - 'chrome-arg': [], - chromeArg: [], }); }); @@ -100,8 +92,6 @@ describe('cli args parsing', () => { width: 888, height: 777, }, - 'chrome-arg': [], - chromeArg: [], }); });