Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions packages/playwright/src/mcp/browser/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export const defaultConfig: FullConfig = {
contextOptions: {
viewport: null,
},
isolated: false,
},
console: {
level: 'info',
Expand All @@ -107,13 +108,23 @@ export const defaultConfig: FullConfig = {
},
};

const defaultDaemonConfig: FullConfig = mergeConfig(defaultConfig, {
browser: {
launchOptions: {
headless: true,
},
isolated: true,
}
});

type BrowserUserConfig = NonNullable<Config['browser']>;

export type FullConfig = Config & {
browser: Omit<BrowserUserConfig, 'browserName' | 'launchOptions' | 'contextOptions'> & {
browserName: 'chromium' | 'firefox' | 'webkit';
launchOptions: NonNullable<BrowserUserConfig['launchOptions']>;
contextOptions: NonNullable<BrowserUserConfig['contextOptions']>;
isolated: boolean;
},
console: {
level: 'error' | 'warning' | 'info' | 'debug';
Expand Down Expand Up @@ -145,10 +156,7 @@ export async function resolveCLIConfig(cliOptions: CLIOptions): Promise<FullConf
const configFile = cliOverrides.configFile ?? envOverrides.configFile ?? daemonOverrides.configFile;
const configInFile = await loadConfig(configFile);

let result = defaultConfig;
// Daemon session is always headless by default.
if (cliOptions.daemonSession)
result.browser.launchOptions.headless = true;
let result = cliOptions.daemonSession ? defaultDaemonConfig : defaultConfig;
result = mergeConfig(result, configInFile);
result = mergeConfig(result, daemonOverrides);
result = mergeConfig(result, envOverrides);
Expand Down Expand Up @@ -373,9 +381,10 @@ async function configForDaemonSession(cliOptions: CLIOptions): Promise<Config &
const config = configFromCLIOptions({
config: sessionConfig.cli.config,
browser: sessionConfig.cli.browser,
isolated: sessionConfig.cli.isolated,
isolated: sessionConfig.cli.persistent === true ? false : undefined,
headless: sessionConfig.cli.headed ? false : undefined,
extension: sessionConfig.cli.extension,
userDataDir: sessionConfig.cli.profile,
outputMode: 'file',
snapshotMode: 'full',
});
Expand Down
105 changes: 43 additions & 62 deletions packages/playwright/src/mcp/terminal/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,43 @@ import type { AnyCommandSchema } from './command';

const open = declareCommand({
name: 'open',
description: 'Open URL',
description: 'Open the browser',
category: 'core',
args: z.object({
url: z.string().optional().describe('The URL to navigate to'),
}),
options: z.object({
browser: z.string().optional().describe('Browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.'),
config: z.string().optional().describe('Path to the configuration file, defaults to .playwright/cli.config.json'),
extension: z.boolean().optional().describe('Connect to browser extension'),
headed: z.boolean().optional().describe('Run browser in headed mode'),
persistent: z.boolean().optional().describe('Use persistent browser profile'),
profile: z.string().optional().describe('Use persistent browser profile, store profile in specified directory.'),
}),
toolName: 'browser_navigate',
toolParams: ({ url }) => ({ url: url || 'about:blank' }),
});

const close = declareCommand({
name: 'close',
description: 'Close the page',
description: 'Close the browser',
category: 'core',
args: z.object({}),
toolName: '',
toolParams: () => ({}),
});

const goto = declareCommand({
name: 'goto',
description: 'Navigate to a URL',
category: 'core',
args: z.object({
url: z.string().describe('The URL to navigate to'),
}),
toolName: 'browser_navigate',
toolParams: ({ url }) => ({ url }),
});

const goBack = declareCommand({
name: 'go-back',
description: 'Go back to the previous page',
Expand Down Expand Up @@ -743,65 +762,26 @@ const sessionList = declareCommand({
toolParams: () => ({}),
});

const sessionRestart = declareCommand({
name: 'session-restart',
description: 'Restart session',
category: 'session',
args: z.object({
name: z.string().optional().describe('Name of the session to restart. If omitted, current session is restarted.'),
}),
toolName: '',
toolParams: () => ({}),
});

const sessionStop = declareCommand({
name: 'session-stop',
description: 'Stop session',
category: 'session',
args: z.object({
name: z.string().optional().describe('Name of the session to stop. If omitted, current session is stopped.'),
}),
toolName: '',
toolParams: () => ({}),
});

const sessionStopAll = declareCommand({
name: 'session-stop-all',
const sessionCloseAll = declareCommand({
name: 'session-close-all',
description: 'Stop all sessions',
category: 'session',
toolName: '',
toolParams: () => ({}),
});

const killAll = declareCommand({
name: 'kill-all',
name: 'session-kill-all',
description: 'Forcefully kill all daemon processes (for stale/zombie processes)',
category: 'session',
toolName: '',
toolParams: () => ({}),
});

const sessionDelete = declareCommand({
name: 'session-delete',
const deleteData = declareCommand({
name: 'delete-data',
description: 'Delete session data',
category: 'session',
args: z.object({
name: z.string().optional().describe('Name of the session to delete. If omitted, current session is deleted.'),
}),
toolName: '',
toolParams: ({ name }) => ({ name }),
});

const config = declareCommand({
name: 'config',
description: 'Restart session with new config, defaults to `playwright-cli.json`',
category: 'config',
options: z.object({
browser: z.string().optional().describe('Browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.'),
config: z.string().optional().describe('Path to the configuration file'),
headed: z.boolean().optional().describe('Run browser in headed mode'),
['in-memory']: z.boolean().optional().describe('Keep the browser profile in memory, do not save it to disk.'),
}),
category: 'core',
toolName: '',
toolParams: () => ({}),
});
Expand All @@ -816,29 +796,33 @@ const configPrint = declareCommand({
});

const install = declareCommand({
name: 'install-browser',
description: 'Install browser',
name: 'install',
description: 'Initialize workspace',
category: 'install',
args: z.object({}),
options: z.object({
browser: z.string().optional().describe('Browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge'),
skills: z.boolean().optional().describe('Install skills for Claude / GitHub Copilot'),
}),
toolName: 'browser_install',
toolName: '',
toolParams: () => ({}),
});

const installSkills = declareCommand({
name: 'install-skills',
description: 'Install Claude / GitGub Copilot skills to the local workspace',
const installBrowser = declareCommand({
name: 'install-browser',
description: 'Install browser',
category: 'install',
args: z.object({}),
toolName: '',
options: z.object({
browser: z.string().optional().describe('Browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge'),
}),
toolName: 'browser_install',
toolParams: () => ({}),
});

const commandsArray: AnyCommandSchema[] = [
// core category
open,
close,
goto,
type,
click,
doubleClick,
Expand All @@ -856,6 +840,7 @@ const commandsArray: AnyCommandSchema[] = [
dialogDismiss,
resize,
runCode,
deleteData,

// navigation category
goBack,
Expand Down Expand Up @@ -908,12 +893,11 @@ const commandsArray: AnyCommandSchema[] = [
unroute,

// config category
config,
configPrint,

// install category
install,
installSkills,
installBrowser,

// devtools category
networkRequests,
Expand All @@ -924,10 +908,7 @@ const commandsArray: AnyCommandSchema[] = [

// session category
sessionList,
sessionStop,
sessionRestart,
sessionStopAll,
sessionDelete,
sessionCloseAll,
killAll,
];

Expand Down
5 changes: 0 additions & 5 deletions packages/playwright/src/mcp/terminal/helpGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,7 @@ export function generateHelp() {
}

lines.push('\nGlobal options:');
lines.push(formatWithGap(' --browser <browser>', 'browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge'));
lines.push(formatWithGap(' --config <path>', 'create a session with custom config, defaults to `playwright-cli.json`'));
lines.push(formatWithGap(' --extension', 'connect to a running browser instance using Playwright MCP Bridge extension'));
lines.push(formatWithGap(' --headed', 'create a headed session'));
lines.push(formatWithGap(' --help [command]', 'print help'));
lines.push(formatWithGap(' --in-memory', 'keep the browser profile in memory, do not save it to disk'));
lines.push(formatWithGap(' --session', 'run command in the scope of a specific session'));
lines.push(formatWithGap(' --version', 'print version'));

Expand Down
Loading
Loading