Documentation Index Fetch the complete documentation index at: https://mintlify.com/microsoft/playwright-mcp/llms.txt
Use this file to discover all available pages before exploring further.
Playwright MCP can be embedded directly into your Node.js applications, allowing you to create custom MCP servers or integrate browser automation into existing services.
Installation
First, install the required packages:
npm install @playwright/mcp @modelcontextprotocol/sdk
Basic Usage
Create a headless Playwright MCP server with SSE transport:
import http from 'http' ;
import { createConnection } from '@playwright/mcp' ;
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js' ;
http . createServer ( async ( req , res ) => {
// Handle SSE endpoint
if ( req . url === '/mcp' || req . url === '/messages' ) {
// Create a headless Playwright MCP server
const connection = await createConnection ({
browser: {
launchOptions: {
headless: true
}
}
});
// Set up SSE transport
const transport = new SSEServerTransport ( '/messages' , res );
await connection . connect ( transport );
} else {
res . writeHead ( 404 );
res . end ( 'Not found' );
}
}). listen ( 8931 );
console . log ( 'Playwright MCP server listening on http://localhost:8931/mcp' );
Configuration Options
The createConnection function accepts the same configuration object as the JSON configuration file.
Browser Configuration
const connection = await createConnection ({
browser: {
browserName: 'chromium' ,
headless: true ,
isolated: false ,
userDataDir: '/path/to/profile' ,
launchOptions: {
headless: true ,
args: [ '--no-sandbox' ]
},
contextOptions: {
viewport: { width: 1920 , height: 1080 },
userAgent: 'Custom User Agent'
}
}
});
Capabilities
const connection = await createConnection ({
capabilities: [ 'core' , 'pdf' , 'vision' ],
browser: {
launchOptions: {
headless: true
}
}
});
Network Filtering
const connection = await createConnection ({
network: {
allowedOrigins: [ 'https://example.com:8080' , 'http://localhost:*' ],
blockedOrigins: [ 'https://tracking.com' ]
},
browser: {
launchOptions: {
headless: true
}
}
});
Timeouts
const connection = await createConnection ({
timeouts: {
action: 10000 , // 10 seconds
navigation: 120000 // 2 minutes
},
browser: {
launchOptions: {
headless: true
}
}
});
SSE Transport
Server-Sent Events (SSE) transport is used for HTTP-based communication.
Complete SSE Example
import http from 'http' ;
import { createConnection } from '@playwright/mcp' ;
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js' ;
const PORT = 8931 ;
http . createServer ( async ( req , res ) => {
// Handle CORS preflight
if ( req . method === 'OPTIONS' ) {
res . writeHead ( 204 , {
'Access-Control-Allow-Origin' : '*' ,
'Access-Control-Allow-Methods' : 'GET, POST, OPTIONS' ,
'Access-Control-Allow-Headers' : 'Content-Type'
});
res . end ();
return ;
}
// Handle MCP endpoint
if ( req . url === '/mcp' ) {
try {
const connection = await createConnection ({
browser: {
browserName: 'chromium' ,
launchOptions: {
headless: true
}
},
saveTrace: true ,
saveSession: true ,
outputDir: './output'
});
const transport = new SSEServerTransport ( '/messages' , res );
await connection . connect ( transport );
} catch ( error ) {
console . error ( 'Failed to create connection:' , error );
res . writeHead ( 500 );
res . end ( 'Internal Server Error' );
}
} else {
res . writeHead ( 404 );
res . end ( 'Not found' );
}
}). listen ( PORT , () => {
console . log ( `Playwright MCP server listening on http://localhost: ${ PORT } /mcp` );
});
Express.js Integration
import express from 'express' ;
import { createConnection } from '@playwright/mcp' ;
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js' ;
const app = express ();
const PORT = 8931 ;
app . get ( '/mcp' , async ( req , res ) => {
try {
const connection = await createConnection ({
browser: {
launchOptions: {
headless: true
}
}
});
const transport = new SSEServerTransport ( '/messages' , res );
await connection . connect ( transport );
} catch ( error ) {
console . error ( 'Failed to create connection:' , error );
res . status ( 500 ). send ( 'Internal Server Error' );
}
});
app . listen ( PORT , () => {
console . log ( `Playwright MCP server listening on http://localhost: ${ PORT } /mcp` );
});
Advanced Configuration
Using Configuration File
import { readFileSync } from 'fs' ;
import { createConnection } from '@playwright/mcp' ;
const config = JSON . parse ( readFileSync ( './config.json' , 'utf-8' ));
const connection = await createConnection ( config );
With CDP Endpoint
const connection = await createConnection ({
browser: {
cdpEndpoint: 'ws://localhost:9222/devtools/browser' ,
cdpHeaders: {
'Authorization' : 'Bearer token123'
},
cdpTimeout: 30000
}
});
With Output Configuration
const connection = await createConnection ({
outputDir: './playwright-output' ,
outputMode: 'file' ,
saveSession: true ,
saveTrace: true ,
saveVideo: {
width: 1280 ,
height: 720
},
browser: {
launchOptions: {
headless: true
}
}
});
Client Connection
Connect your MCP client to the programmatic server:
{
"mcpServers" : {
"playwright" : {
"url" : "http://localhost:8931/mcp"
}
}
}
Error Handling
import { createConnection } from '@playwright/mcp' ;
try {
const connection = await createConnection ({
browser: {
launchOptions: {
headless: true
}
}
});
const transport = new SSEServerTransport ( '/messages' , res );
await connection . connect ( transport );
// Handle cleanup on connection close
connection . onclose = () => {
console . log ( 'Connection closed' );
};
} catch ( error ) {
console . error ( 'Failed to create Playwright MCP connection:' , error );
throw error ;
}
Use Cases
Custom MCP Gateway Build a gateway service that manages multiple Playwright browser instances for different users or tenants.
Integration Server Embed Playwright MCP into existing services to add browser automation capabilities.
Testing Infrastructure Create custom test runners that leverage MCP for browser automation.
Automation Platform Build automation platforms that expose browser control through MCP to various clients.