playwright-e2e-mcp 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -31
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ and every other MCP client — pick whichever route fits:
|
|
|
42
42
|
| --- | --- |
|
|
43
43
|
| **npm (canonical, fastest)** | `npx -y playwright-e2e-mcp` |
|
|
44
44
|
| **MCP Registry** (registry-aware clients discover it automatically) | `io.github.trajectiq-ai/E2E` — [listing](https://registry.modelcontextprotocol.io/) |
|
|
45
|
-
| **Any client, no npm account needed** | `npx -y github:trajectiq-ai/E2E#v0.1.
|
|
45
|
+
| **Any client, no npm account needed** | `npx -y github:trajectiq-ai/E2E#v0.1.4` (pin a release tag) |
|
|
46
46
|
| **Claude Desktop, zero Node setup** | double-click the [`.mcpb` extension](https://github.com/trajectiq-ai/E2E/releases) |
|
|
47
47
|
| **Remote-only clients (ChatGPT connectors)** | `https://playwright-e2e-mcp.vercel.app/api/mcp` |
|
|
48
48
|
|
|
@@ -242,8 +242,8 @@ builds `dist/` automatically on install). Pin a release tag: an unpinned
|
|
|
242
242
|
`github:trajectiq-ai/E2E` runs whatever is on the default branch at that moment.
|
|
243
243
|
|
|
244
244
|
```bash
|
|
245
|
-
npx -y github:trajectiq-ai/E2E#v0.1.
|
|
246
|
-
npm install -D github:trajectiq-ai/E2E#v0.1.
|
|
245
|
+
npx -y github:trajectiq-ai/E2E#v0.1.4
|
|
246
|
+
npm install -D github:trajectiq-ai/E2E#v0.1.4 @playwright/test # or as a project dependency
|
|
247
247
|
npx playwright install chromium
|
|
248
248
|
```
|
|
249
249
|
|
|
@@ -251,7 +251,7 @@ Or grab the packaged tarball from the repo's **GitHub Releases** page and instal
|
|
|
251
251
|
it locally:
|
|
252
252
|
|
|
253
253
|
```bash
|
|
254
|
-
npm install -D https://github.com/trajectiq-ai/E2E/releases/download/v0.1.
|
|
254
|
+
npm install -D https://github.com/trajectiq-ai/E2E/releases/download/v0.1.4/playwright-e2e-mcp-0.1.4.tgz
|
|
255
255
|
```
|
|
256
256
|
|
|
257
257
|
Listed in the **official [MCP Registry](https://registry.modelcontextprotocol.io/)** as
|
|
@@ -267,7 +267,7 @@ Listed in the **official [MCP Registry](https://registry.modelcontextprotocol.io
|
|
|
267
267
|
"mcpServers": {
|
|
268
268
|
"playwright-e2e": {
|
|
269
269
|
"command": "npx",
|
|
270
|
-
"args": ["-y", "github:trajectiq-ai/E2E#v0.1.
|
|
270
|
+
"args": ["-y", "github:trajectiq-ai/E2E#v0.1.4"],
|
|
271
271
|
"env": { "PW_MCP_PROJECT_ROOT": "/absolute/path/to/your/project" }
|
|
272
272
|
}
|
|
273
273
|
}
|
|
@@ -281,8 +281,8 @@ when the client launches it somewhere else (e.g. your home directory).
|
|
|
281
281
|
**Codex / VS Code / Copilot CLIs:**
|
|
282
282
|
|
|
283
283
|
```bash
|
|
284
|
-
codex mcp add playwright-e2e -- npx -y github:trajectiq-ai/E2E#v0.1.
|
|
285
|
-
code --add-mcp '{"name":"playwright-e2e","command":"npx","args":["-y","github:trajectiq-ai/E2E#v0.1.
|
|
284
|
+
codex mcp add playwright-e2e -- npx -y github:trajectiq-ai/E2E#v0.1.4
|
|
285
|
+
code --add-mcp '{"name":"playwright-e2e","command":"npx","args":["-y","github:trajectiq-ai/E2E#v0.1.4"]}'
|
|
286
286
|
```
|
|
287
287
|
|
|
288
288
|
Codex's defaults fight this server: the first launch clones the repo and runs
|
|
@@ -293,7 +293,7 @@ Codex's defaults fight this server: the first launch clones the repo and runs
|
|
|
293
293
|
```toml
|
|
294
294
|
[mcp_servers.playwright-e2e]
|
|
295
295
|
command = "npx"
|
|
296
|
-
args = ["-y", "github:trajectiq-ai/E2E#v0.1.
|
|
296
|
+
args = ["-y", "github:trajectiq-ai/E2E#v0.1.4"]
|
|
297
297
|
startup_timeout_sec = 60
|
|
298
298
|
tool_timeout_sec = 600
|
|
299
299
|
```
|
|
@@ -308,7 +308,7 @@ into `PW_MCP_PROJECT_ROOT`, so the tools point at a real project from the first
|
|
|
308
308
|
**Claude Code:**
|
|
309
309
|
|
|
310
310
|
```bash
|
|
311
|
-
claude mcp add playwright-e2e -- npx -y github:trajectiq-ai/E2E#v0.1.
|
|
311
|
+
claude mcp add playwright-e2e -- npx -y github:trajectiq-ai/E2E#v0.1.4
|
|
312
312
|
```
|
|
313
313
|
|
|
314
314
|
**Gemini CLI / Qwen Code:** paste the `mcpServers` block above into
|
|
@@ -349,7 +349,7 @@ Streamable HTTP bridge for exactly that case:
|
|
|
349
349
|
| --- | --- |
|
|
350
350
|
| **Endpoint** | `https://playwright-e2e-mcp.vercel.app/api/mcp` |
|
|
351
351
|
| **Transport** | MCP Streamable HTTP (`POST` JSON in, JSON or SSE out) |
|
|
352
|
-
| **Auth** |
|
|
352
|
+
| **Auth** | bearer token (`PW_MCP_HTTP_TOKEN`). The deployment at this URL requires it; a bridge started without the variable serves only the read-only tools |
|
|
353
353
|
| **Source** | [`api/mcp.ts`](api/mcp.ts) → [`src/http.ts`](src/http.ts) |
|
|
354
354
|
|
|
355
355
|
The bridge runs the *same* `createServer()` as the stdio transport; the SDK
|
|
@@ -357,28 +357,43 @@ serves every request with a fresh server instance, which is what a serverless
|
|
|
357
357
|
function wants. `test/http-bridge.test.mjs` drives the real Node adapter over
|
|
358
358
|
`node:http` so a broken bridge fails in CI, not in ChatGPT.
|
|
359
359
|
|
|
360
|
-
**
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
`
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
`
|
|
360
|
+
**This deployment is token-protected.** `https://playwright-e2e-mcp.vercel.app`
|
|
361
|
+
has `PW_MCP_HTTP_TOKEN` set, so a request without `Authorization: Bearer <token>`
|
|
362
|
+
— including a ChatGPT connector created with authentication *None* — gets
|
|
363
|
+
`401 {"error":"unauthorized"}`. Ask the operator for the token, or run your own
|
|
364
|
+
bridge (below).
|
|
365
|
+
|
|
366
|
+
**Open vs. token-protected.** With `PW_MCP_HTTP_TOKEN` set (at least 16
|
|
367
|
+
characters; use a random value) all eight tools are served to clients that send
|
|
368
|
+
`Authorization: Bearer <token>`, and every other request gets `401`. Without that
|
|
369
|
+
variable anyone who reaches the URL can call the bridge, so it degrades to
|
|
370
|
+
`list-tests` and `get-failure` in restricted mode: `list-tests` scans sources
|
|
371
|
+
instead of running `playwright test --list` (which would execute the project's
|
|
372
|
+
config), callers cannot pick another `projectRoot`, and nothing spawns a process,
|
|
373
|
+
drives a browser or writes a file. Child processes started over HTTP get only an
|
|
374
|
+
allowlisted environment. `PW_MCP_ALLOWED_HOSTS` (comma separated, `*` for any)
|
|
375
|
+
limits the accepted `Host` header; without a token and without that variable,
|
|
376
|
+
only `localhost` names and the deployment's own Vercel hostnames are accepted
|
|
371
377
|
(DNS-rebinding protection).
|
|
372
378
|
|
|
373
379
|
**Add it to ChatGPT:** Settings → Connectors → turn on **Advanced → Developer
|
|
374
|
-
mode** → *Create custom connector* → paste the endpoint above
|
|
375
|
-
**None** (read-only tools)
|
|
380
|
+
mode** → *Create custom connector* → paste the endpoint above. Authentication
|
|
381
|
+
**None** only works against a bridge with no token (read-only tools), so for this
|
|
382
|
+
deployment choose the connector's **API key** authentication and send
|
|
383
|
+
`Authorization: Bearer <token>` — or point the connector at your own deployment
|
|
384
|
+
with `PW_MCP_HTTP_TOKEN` unset.
|
|
385
|
+
|
|
386
|
+
To self-host the open, read-only variant, deploy this repo with
|
|
387
|
+
`PW_MCP_HTTP_TOKEN` unset; nothing else changes.
|
|
376
388
|
|
|
377
389
|
Codex can also take the remote transport instead of spawning `npx`, if you'd
|
|
378
|
-
rather not ship Playwright to every machine
|
|
390
|
+
rather not ship Playwright to every machine. Point it at the token through an
|
|
391
|
+
environment variable so the secret stays out of the config file:
|
|
379
392
|
|
|
380
393
|
```bash
|
|
381
|
-
|
|
394
|
+
export PW_MCP_HTTP_TOKEN=… # ask the operator for the value
|
|
395
|
+
codex mcp add playwright-e2e-remote --url https://playwright-e2e-mcp.vercel.app/api/mcp \
|
|
396
|
+
--bearer-token-env-var PW_MCP_HTTP_TOKEN
|
|
382
397
|
```
|
|
383
398
|
|
|
384
399
|
**What to expect:** `list-tests` works and reports the specs bundled with the
|
|
@@ -389,10 +404,12 @@ hint. Use the stdio install for real runs; the hosted endpoint is for discovery
|
|
|
389
404
|
and for clients that cannot run local processes.
|
|
390
405
|
|
|
391
406
|
```bash
|
|
392
|
-
# verify the handshake without any client
|
|
407
|
+
# verify the handshake without any client (the live deployment needs the token;
|
|
408
|
+
# drop the authorization header and it answers 401 instead)
|
|
393
409
|
curl -X POST https://playwright-e2e-mcp.vercel.app/api/mcp \
|
|
394
410
|
-H 'content-type: application/json' \
|
|
395
411
|
-H 'accept: application/json, text/event-stream' \
|
|
412
|
+
-H "authorization: Bearer $PW_MCP_HTTP_TOKEN" \
|
|
396
413
|
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
|
|
397
414
|
```
|
|
398
415
|
|
|
@@ -411,10 +428,17 @@ every push, so there is no token to manage and no CLI step — watch the
|
|
|
411
428
|
| `PW_MCP_PASSTHROUGH_ENV` | — | HTTP bridge only: comma-separated extra variables passed to test runs (e.g. `BASE_URL`) |
|
|
412
429
|
| `PW_MCP_MAX_CHILDREN` | `4` | HTTP bridge only: how many test runs and browser probes may run at once |
|
|
413
430
|
| `PW_MCP_BLOCK_PRIVATE_URLS` | off (on for the HTTP bridge) | `1` makes the URL tools refuse loopback, private-network and cloud-metadata addresses, including redirects and subresources |
|
|
414
|
-
| `LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error` \| `silent` |
|
|
415
|
-
| `LOG_FORMAT` | `text` | `text
|
|
431
|
+
| `LOG_LEVEL` / `MCP_LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error` \| `silent`; `LOG_LEVEL` wins when both are set |
|
|
432
|
+
| `LOG_FORMAT` / `MCP_LOG_FORMAT` | `text` | `text`, or `json` (also `ndjson`) for one structured JSON object per line — ready for a log ingester |
|
|
433
|
+
|
|
434
|
+
Logs always go to **stderr** — stdout is reserved for the MCP protocol. Unrecognized values
|
|
435
|
+
fall back to the default, so a typo in `LOG_LEVEL` logs at `info` and one in `LOG_FORMAT`
|
|
436
|
+
logs as text rather than silencing the server. With `LOG_FORMAT=json` each line is a single
|
|
437
|
+
object (`time`, `level`, `message` plus context):
|
|
416
438
|
|
|
417
|
-
|
|
439
|
+
```json
|
|
440
|
+
{"time":"2026-10-07T08:00:00.000Z","level":"info","message":"server ready","name":"playwright-e2e-mcp"}
|
|
441
|
+
```
|
|
418
442
|
|
|
419
443
|
## Typical workflow
|
|
420
444
|
|
|
@@ -509,6 +533,8 @@ npm install
|
|
|
509
533
|
npm run build # tsc → dist/ (zero errors)
|
|
510
534
|
npm test # build + test/run-tests.mjs (unit tests, any Node ≥20)
|
|
511
535
|
npm run e2e # build + e2e/run.mjs: live MCP ↔ Playwright integration suite
|
|
536
|
+
npm run mcpb # build + bundle dist/ into playwright-e2e-mcp-<version>.mcpb (+ .sha256)
|
|
537
|
+
npm run mcpb:smoke # ...then install that bundle in a temp dir, launch it and assert the handshake
|
|
512
538
|
```
|
|
513
539
|
|
|
514
540
|
Tests cover the report parser (sample Playwright JSON, trace attachments), path utils
|
|
@@ -521,8 +547,8 @@ helpers, the **trace reader** (synthetic trace.zip: error, failed action, DOM sn
|
|
|
521
547
|
(failure signatures, CONSISTENTLY FAILING / FLAKY / NOT REPRODUCING / NO TESTS RAN),
|
|
522
548
|
the **HTTP bridge** (token, restricted mode, Host allowlist), the **security
|
|
523
549
|
regressions** (sandbox escapes, argument smuggling, symlink writes, code injection,
|
|
524
|
-
SSRF ranges, env scrubbing, decode limits), the `.mcpb` manifest
|
|
525
|
-
files.
|
|
550
|
+
SSRF ranges, env scrubbing, decode limits), the `.mcpb` manifest, the `.mcpb` zip
|
|
551
|
+
extractor, and the MCP config files.
|
|
526
552
|
|
|
527
553
|
### Integration suite (`npm run e2e`)
|
|
528
554
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playwright-e2e-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "MCP server that runs, debugs, and inspects Playwright end-to-end tests from any MCP client",
|
|
5
|
+
"author": "trajectiq-ai <trajectiq@gmail.com>",
|
|
5
6
|
"mcpName": "io.github.trajectiq-ai/E2E",
|
|
6
7
|
"type": "module",
|
|
7
8
|
"license": "MIT",
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
"test": "npm run build && node test/run-tests.mjs",
|
|
50
51
|
"e2e": "npm run build && node e2e/run.mjs",
|
|
51
52
|
"mcpb": "npm run build && node scripts/build-mcpb.mjs",
|
|
53
|
+
"mcpb:smoke": "npm run mcpb && node scripts/mcpb-launch-sim.mjs",
|
|
52
54
|
"prepublishOnly": "npm test"
|
|
53
55
|
},
|
|
54
56
|
"engines": {
|
|
@@ -56,7 +58,7 @@
|
|
|
56
58
|
},
|
|
57
59
|
"dependencies": {
|
|
58
60
|
"zod": "^4.2.0",
|
|
59
|
-
"@modelcontextprotocol/server": "^2.3.
|
|
61
|
+
"@modelcontextprotocol/server": "^2.3.1"
|
|
60
62
|
},
|
|
61
63
|
"devDependencies": {
|
|
62
64
|
"@playwright/test": "1.63.0",
|