Skip to main content
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.