Skip to main content
Glama
james8128

playwright-mcp-server

by james8128
README.md
# playwright-mcp-server

A small, self-contained Playwright helper you can drop into other Node projects.

Use it as:

1. **A class** — `PlaywrightSessionManager` opens isolated browser sessions, then gives you the real Playwright `page` when you need click, fill, screenshot, or anything else.
2. **An MCP server** — the same manager exposed as tools over stdio, so an agent can drive a browser.

Node 20+ and Chromium (via Playwright) are the only runtime requirements.

## Install in another project

From GitHub:

```bash
npm install github:james8128/playwright-mcp-server
npx playwright install chromium
```

From a local clone:

```bash
npm install ../playwright-mcp-server
npx playwright install chromium
```

This package depends on `playwright`. After install, Chromium still needs a one-time browser download (`npx playwright install chromium`).

## 30-second library use

```js
import { PlaywrightSessionManager } from "playwright-mcp-server";

const pw = new PlaywrightSessionManager();

const { sessionId, title } = await pw.openPage({
  url: "https://example.com",
  headless: true,
});

console.log(title);

await pw.use(sessionId, async ({ page }) => {
  await page.screenshot({ path: "example.png" });
});

await pw.close(sessionId);
```

`use()` is the escape hatch. Anything Playwright can do, you can do inside that callback while the session stays locked and alive.

Full method list: [docs/api.md](docs/api.md).

## MCP server

```bash
npm start
# same as: node server.js
```

Point an MCP client at `node /path/to/playwright-mcp-server/server.js`.

Tools: `openPage`, `getTitle`, `waitForElement`, `listSessions`, `closeBrowser`, `closeAll`.

Details: [docs/mcp.md](docs/mcp.md).

## Why this exists

Raw Playwright works, but a long-running helper still has to:

- isolate each job in its own browser context
- close browsers on failed navigation and on process exit
- cap how many sessions can exist
- time out idle sessions
- reject non-http(s) URLs
- serialize work so close cannot race with a click

That is what `PlaywrightSessionManager` does. Other projects should not have to reimplement it.

## Layout

| Path | What it is |
|---|---|
| `src/session-manager.js` | The class other projects import |
| `src/index.js` | Public library exports |
| `src/mcp-server.js` | MCP adapter (`playwright-mcp-server/mcp`) |
| `server.js` | Stdio MCP process |
| `docs/api.md` | Class API |
| `docs/mcp.md` | MCP tools and client config |
| `examples/` | Copy-paste starters |

## Scripts

```bash
npm test                 # unit + Chromium integration tests
npm start                # run the MCP server on stdio
npm run install-browser  # download Chromium for Playwright
```

## Defaults

| Setting | Default | Override |
|---|---|---|
| Max sessions | 8 | constructor `maxSessions` or `PLAYWRIGHT_MCP_MAX_SESSIONS` |
| Idle close | 5 minutes | constructor `idleTimeoutMs` or `PLAYWRIGHT_MCP_IDLE_MS` (`0` disables) |
| Navigation timeout | 60s | `openPage({ timeout })` |
| Retries | 1 extra attempt | `openPage({ retries: 0 })` for a single try |
| Headless | `true` | `openPage({ headless: false })` |

## License

ISC. See [LICENSE](LICENSE).