Skip to main content

Configuration

Options can be supplied three ways, in increasing order of precedence: a config file, environment variables, and command-line arguments.

Headed and headless mode

By default, Playwright MCP runs the browser in headed mode so you can see what's happening. To run headless:

{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
}
}
}

Browser selection

["@playwright/mcp@latest", "--browser=firefox"]
ValueBrowser
chromeGoogle Chrome (default)
firefoxMozilla Firefox
webkitWebKit (Safari engine)
msedgeMicrosoft Edge

Device emulation

["@playwright/mcp@latest", "--device=iPhone 15"]

--mobile emulates a generic mobile device — Pixel 10 on Chromium, iPhone 17 on WebKit.

Viewport size

["@playwright/mcp@latest", "--viewport-size=1280x720"]

Proxy

["@playwright/mcp@latest", "--proxy-server=http://myproxy:3128", "--proxy-bypass=localhost,*.internal.com"]

Standalone HTTP server

When running a headed browser on a system without a display or from IDE worker processes, start the MCP server separately with HTTP transport:

npx @playwright/mcp@latest --port 8931

Then point your MCP client to the HTTP endpoint:

{
"mcpServers": {
"playwright": {
"url": "http://localhost:8931/mcp"
}
}
}

Use --host 0.0.0.0 to bind to all interfaces (useful in containers). Use --shared-browser-context to share a single browser context between multiple connected clients.

Secrets

Values the LLM should never see in tool responses can be kept in a dotenv file:

npx @playwright/mcp@latest --secrets ./.secrets

Matching plain text in tool responses is redacted, and typing a placeholder substitutes the real value in the page. This is a convenience, not a security boundary.

Configuration file

For advanced settings, use a JSON config file:

npx @playwright/mcp@latest --config path/to/config.json

Schema

{
browser?: {
browserName?: 'chromium' | 'firefox' | 'webkit';
isolated?: boolean;
userDataDir?: string;
launchOptions?: playwright.LaunchOptions;
contextOptions?: playwright.BrowserContextOptions;
cdpEndpoint?: string;
cdpHeaders?: Record<string, string>;
cdpTimeout?: number;
remoteEndpoint?: string | playwright.ConnectOptions & { endpoint: string };
initPage?: string[];
initScript?: string[];
};
extension?: boolean;
server?: {
port?: number;
host?: string;
allowedHosts?: string[];
};
capabilities?: ('network' | 'storage' | 'testing' | 'vision' | 'pdf' | 'devtools' | 'config')[];
saveSession?: boolean;
sharedBrowserContext?: boolean;
secrets?: Record<string, string>;
outputDir?: string;
outputMaxSize?: number;
console?: { level?: 'error' | 'warning' | 'info' | 'debug' };
network?: {
allowedOrigins?: string[];
blockedOrigins?: string[];
};
testIdAttribute?: string;
timeouts?: {
action?: number; // default: 5000ms
navigation?: number; // default: 60000ms
expect?: number; // default: 5000ms
settle?: number; // default: 500ms
};
imageResponses?: 'allow' | 'omit';
snapshot?: {
mode?: 'full' | 'none';
boxes?: boolean;
};
allowUnrestrictedFileAccess?: boolean;
codegen?: 'typescript' | 'python' | 'java' | 'csharp' | 'none';
}

The authoritative schema lives in config.d.ts.

Init scripts

Run code on every page before the page's own scripts:

{
"browser": {
"initScript": ["./setup.js"]
}
}
// setup.js
window.isPlaywrightMCP = true;

Init page

Run Playwright code on the page object at startup:

{
"browser": {
"initPage": ["./setup-page.ts"]
}
}
// setup-page.ts
export default async ({ page }) => {
await page.context().grantPermissions(['geolocation']);
await page.context().setGeolocation({ latitude: 37.7749, longitude: -122.4194 });
};

All command-line options

Browser

OptionDescriptionEnv Variable
--browser <browser>Browser or Chrome channel: chrome, firefox, webkit, msedgePLAYWRIGHT_MCP_BROWSER
--headlessRun headless (headed by default)PLAYWRIGHT_MCP_HEADLESS
--executable-path <path>Path to the browser executablePLAYWRIGHT_MCP_EXECUTABLE_PATH
--device <device>Device to emulate, e.g. "iPhone 15"PLAYWRIGHT_MCP_DEVICE
--mobileEmulate a generic mobile devicePLAYWRIGHT_MCP_MOBILE
--viewport-size <size>Viewport in pixels, e.g. "1280x720"PLAYWRIGHT_MCP_VIEWPORT_SIZE
--user-agent <ua>Custom user agent stringPLAYWRIGHT_MCP_USER_AGENT
--ignore-https-errorsIgnore HTTPS errorsPLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS
--proxy-server <url>Proxy server, e.g. http://myproxy:3128PLAYWRIGHT_MCP_PROXY_SERVER
--proxy-bypass <hosts>Comma-separated domains to bypass the proxyPLAYWRIGHT_MCP_PROXY_BYPASS
--grant-permissions <perms>Permissions to grant, e.g. geolocationPLAYWRIGHT_MCP_GRANT_PERMISSIONS
--block-service-workersBlock service workersPLAYWRIGHT_MCP_BLOCK_SERVICE_WORKERS
--sandbox / --no-sandboxEnable or disable the browser sandboxPLAYWRIGHT_MCP_SANDBOX
--init-page <path...>TypeScript files evaluated on the Playwright page objectPLAYWRIGHT_MCP_INIT_PAGE
--init-script <path...>JavaScript files added as page init scriptsPLAYWRIGHT_MCP_INIT_SCRIPT

Profile and session

OptionDescriptionEnv Variable
--isolatedKeep the browser profile in memory, do not save it to diskPLAYWRIGHT_MCP_ISOLATED
--user-data-dir <path>Custom profile directoryPLAYWRIGHT_MCP_USER_DATA_DIR
--storage-state <path>Initial storage state for isolated sessionsPLAYWRIGHT_MCP_STORAGE_STATE
--extensionConnect through the Playwright browser extensionPLAYWRIGHT_MCP_EXTENSION
--profile-dir-name <name>Browser profile directory to attach to with --extension, e.g. "Profile 1"PLAYWRIGHT_MCP_PROFILE_DIR_NAME
--cdp-endpoint <endpoint>CDP endpoint or channel name to connect toPLAYWRIGHT_MCP_CDP_ENDPOINT
--cdp-header <headers...>Headers for the CDP connect requestPLAYWRIGHT_MCP_CDP_HEADERS
--cdp-timeout <ms>CDP connect timeout, defaults to 30000PLAYWRIGHT_MCP_CDP_TIMEOUT
--endpoint <endpoint>Bound browser endpoint to connect to
--save-sessionSave the MCP session into the output directory

Server

OptionDescriptionEnv Variable
--port <port>Port to listen on for HTTP transportPLAYWRIGHT_MCP_PORT
--host <host>Host to bind to, defaults to localhostPLAYWRIGHT_MCP_HOST
--allowed-hosts <hosts...>Hosts the server may serve from; * disables the checkPLAYWRIGHT_MCP_ALLOWED_HOSTS
--shared-browser-contextReuse one browser context across HTTP clients
--config <path>Config file pathPLAYWRIGHT_MCP_CONFIG

Tools and output

OptionDescriptionEnv Variable
--caps <caps>Comma-separated capabilities to enablePLAYWRIGHT_MCP_CAPS
--console-level <level>Console level: error, warning, info, debugPLAYWRIGHT_MCP_CONSOLE_LEVEL
--codegen <lang>Code generation language: typescript, python, java, csharp, nonePLAYWRIGHT_MCP_CODEGEN
--test-id-attribute <attr>Attribute used for test ids, defaults to data-testidPLAYWRIGHT_MCP_TEST_ID_ATTRIBUTE
--snapshot-mode <mode>full (default) or none
--snapshot-boxesInclude [box=x,y,width,height] in snapshots
--image-responses <mode>allow (default) or omitPLAYWRIGHT_MCP_IMAGE_RESPONSES
--output-dir <path>Directory for automatically named output filesPLAYWRIGHT_MCP_OUTPUT_DIR
--output-max-size <bytes>Threshold for evicting old output filesPLAYWRIGHT_MCP_OUTPUT_MAX_SIZE
--secrets <path>Secrets file in dotenv formatPLAYWRIGHT_MCP_SECRETS_FILE

Timeouts

OptionDescriptionEnv Variable
--timeout-action <ms>Action timeout, defaults to 5000PLAYWRIGHT_MCP_TIMEOUT_ACTION
--timeout-navigation <ms>Navigation timeout, defaults to 60000PLAYWRIGHT_MCP_TIMEOUT_NAVIGATION
--timeout-settle <ms>How long to wait after each action for triggered work to settle, defaults to 500PLAYWRIGHT_MCP_TIMEOUT_SETTLE

Access control

OptionDescriptionEnv Variable
--allowed-origins <origins>Semicolon-separated origins the browser may requestPLAYWRIGHT_MCP_ALLOWED_ORIGINS
--blocked-origins <origins>Semicolon-separated origins to block; evaluated firstPLAYWRIGHT_MCP_BLOCKED_ORIGINS
--allow-unrestricted-file-accessAllow files outside the workspace roots and file:// navigationPLAYWRIGHT_MCP_ALLOW_UNRESTRICTED_FILE_ACCESS
note

Origin lists and the file-access guardrail are convenience defenses to catch unintended access, not a security boundary — they do not affect redirects and can be worked around deliberately. Rely on client-level permissions for real isolation.