Pavel Feldman commited on
Commit
8d86ce4
·
unverified ·
1 Parent(s): 8774166

chore: use mcp sdk via playwright (#973)

Browse files
package-lock.json CHANGED
@@ -9,16 +9,13 @@
9
  "version": "0.0.36",
10
  "license": "Apache-2.0",
11
  "dependencies": {
12
- "@modelcontextprotocol/sdk": "^1.16.0",
13
  "commander": "^13.1.0",
14
  "debug": "^4.4.1",
15
  "dotenv": "^17.2.0",
16
  "mime": "^4.0.7",
17
  "playwright": "1.56.0-alpha-1756505518000",
18
  "playwright-core": "1.56.0-alpha-1756505518000",
19
- "ws": "^8.18.1",
20
- "zod": "^3.24.1",
21
- "zod-to-json-schema": "^3.24.4"
22
  },
23
  "bin": {
24
  "mcp-server-playwright": "cli.js"
@@ -27,6 +24,7 @@
27
  "@anthropic-ai/sdk": "^0.57.0",
28
  "@eslint/eslintrc": "^3.2.0",
29
  "@eslint/js": "^9.19.0",
 
30
  "@playwright/test": "1.56.0-alpha-1756505518000",
31
  "@stylistic/eslint-plugin": "^3.0.1",
32
  "@types/debug": "^4.1.12",
@@ -40,7 +38,9 @@
40
  "eslint-plugin-import": "^2.31.0",
41
  "eslint-plugin-notice": "^1.0.0",
42
  "openai": "^5.10.2",
43
- "typescript": "^5.8.2"
 
 
44
  },
45
  "engines": {
46
  "node": ">=18"
@@ -642,9 +642,10 @@
642
  }
643
  },
644
  "node_modules/@modelcontextprotocol/sdk": {
645
- "version": "1.16.0",
646
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.16.0.tgz",
647
- "integrity": "sha512-8ofX7gkZcLj9H9rSd50mCgm3SSF8C7XoclxJuLoV0Cz3rEQ1tv9MZRYYvJtm9n1BiEQQMzSmE/w2AEkNacLYfg==",
 
648
  "license": "MIT",
649
  "dependencies": {
650
  "ajv": "^6.12.6",
@@ -1052,6 +1053,7 @@
1052
  "version": "2.0.0",
1053
  "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
1054
  "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
 
1055
  "license": "MIT",
1056
  "dependencies": {
1057
  "mime-types": "^3.0.0",
@@ -1088,6 +1090,7 @@
1088
  "version": "6.12.6",
1089
  "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
1090
  "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
 
1091
  "license": "MIT",
1092
  "dependencies": {
1093
  "fast-deep-equal": "^3.1.1",
@@ -1280,6 +1283,7 @@
1280
  "version": "2.2.0",
1281
  "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
1282
  "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
 
1283
  "license": "MIT",
1284
  "dependencies": {
1285
  "bytes": "^3.1.2",
@@ -1324,6 +1328,7 @@
1324
  "version": "3.1.2",
1325
  "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
1326
  "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
 
1327
  "license": "MIT",
1328
  "engines": {
1329
  "node": ">= 0.8"
@@ -1352,6 +1357,7 @@
1352
  "version": "1.0.2",
1353
  "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
1354
  "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
 
1355
  "license": "MIT",
1356
  "dependencies": {
1357
  "es-errors": "^1.3.0",
@@ -1365,6 +1371,7 @@
1365
  "version": "1.0.4",
1366
  "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
1367
  "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
 
1368
  "license": "MIT",
1369
  "dependencies": {
1370
  "call-bind-apply-helpers": "^1.0.2",
@@ -1444,6 +1451,7 @@
1444
  "version": "1.0.0",
1445
  "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
1446
  "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
 
1447
  "license": "MIT",
1448
  "dependencies": {
1449
  "safe-buffer": "5.2.1"
@@ -1456,15 +1464,17 @@
1456
  "version": "1.0.5",
1457
  "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
1458
  "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
 
1459
  "license": "MIT",
1460
  "engines": {
1461
  "node": ">= 0.6"
1462
  }
1463
  },
1464
  "node_modules/cookie": {
1465
- "version": "0.7.1",
1466
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
1467
- "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
 
1468
  "license": "MIT",
1469
  "engines": {
1470
  "node": ">= 0.6"
@@ -1474,6 +1484,7 @@
1474
  "version": "1.2.2",
1475
  "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
1476
  "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
 
1477
  "license": "MIT",
1478
  "engines": {
1479
  "node": ">=6.6.0"
@@ -1483,6 +1494,7 @@
1483
  "version": "2.8.5",
1484
  "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
1485
  "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
 
1486
  "license": "MIT",
1487
  "dependencies": {
1488
  "object-assign": "^4",
@@ -1496,6 +1508,7 @@
1496
  "version": "7.0.6",
1497
  "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
1498
  "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
 
1499
  "license": "MIT",
1500
  "dependencies": {
1501
  "path-key": "^3.1.0",
@@ -1624,6 +1637,7 @@
1624
  "version": "2.0.0",
1625
  "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
1626
  "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
 
1627
  "license": "MIT",
1628
  "engines": {
1629
  "node": ">= 0.8"
@@ -1658,6 +1672,7 @@
1658
  "version": "1.0.1",
1659
  "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
1660
  "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
 
1661
  "license": "MIT",
1662
  "dependencies": {
1663
  "call-bind-apply-helpers": "^1.0.1",
@@ -1672,12 +1687,14 @@
1672
  "version": "1.1.1",
1673
  "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
1674
  "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
 
1675
  "license": "MIT"
1676
  },
1677
  "node_modules/encodeurl": {
1678
  "version": "2.0.0",
1679
  "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
1680
  "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
 
1681
  "license": "MIT",
1682
  "engines": {
1683
  "node": ">= 0.8"
@@ -1753,6 +1770,7 @@
1753
  "version": "1.0.1",
1754
  "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
1755
  "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
 
1756
  "license": "MIT",
1757
  "engines": {
1758
  "node": ">= 0.4"
@@ -1762,6 +1780,7 @@
1762
  "version": "1.3.0",
1763
  "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
1764
  "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
 
1765
  "license": "MIT",
1766
  "engines": {
1767
  "node": ">= 0.4"
@@ -1771,6 +1790,7 @@
1771
  "version": "1.1.1",
1772
  "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
1773
  "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
 
1774
  "license": "MIT",
1775
  "dependencies": {
1776
  "es-errors": "^1.3.0"
@@ -1869,6 +1889,7 @@
1869
  "version": "1.0.3",
1870
  "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
1871
  "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
 
1872
  "license": "MIT"
1873
  },
1874
  "node_modules/escape-string-regexp": {
@@ -2188,27 +2209,30 @@
2188
  "version": "1.8.1",
2189
  "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
2190
  "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
 
2191
  "license": "MIT",
2192
  "engines": {
2193
  "node": ">= 0.6"
2194
  }
2195
  },
2196
  "node_modules/eventsource": {
2197
- "version": "3.0.5",
2198
- "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.5.tgz",
2199
- "integrity": "sha512-LT/5J605bx5SNyE+ITBDiM3FxffBiq9un7Vx0EwMDM3vg8sWKx/tO2zC+LMqZ+smAM0F2hblaDZUVZF0te2pSw==",
 
2200
  "license": "MIT",
2201
  "dependencies": {
2202
- "eventsource-parser": "^3.0.0"
2203
  },
2204
  "engines": {
2205
  "node": ">=18.0.0"
2206
  }
2207
  },
2208
  "node_modules/eventsource-parser": {
2209
- "version": "3.0.0",
2210
- "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.0.tgz",
2211
- "integrity": "sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==",
 
2212
  "license": "MIT",
2213
  "engines": {
2214
  "node": ">=18.0.0"
@@ -2218,6 +2242,7 @@
2218
  "version": "5.1.0",
2219
  "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
2220
  "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
 
2221
  "license": "MIT",
2222
  "dependencies": {
2223
  "accepts": "^2.0.0",
@@ -2257,9 +2282,10 @@
2257
  }
2258
  },
2259
  "node_modules/express-rate-limit": {
2260
- "version": "7.5.0",
2261
- "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz",
2262
- "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==",
 
2263
  "license": "MIT",
2264
  "engines": {
2265
  "node": ">= 16"
@@ -2268,13 +2294,14 @@
2268
  "url": "https://github.com/sponsors/express-rate-limit"
2269
  },
2270
  "peerDependencies": {
2271
- "express": "^4.11 || 5 || ^5.0.0-beta.1"
2272
  }
2273
  },
2274
  "node_modules/fast-deep-equal": {
2275
  "version": "3.1.3",
2276
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
2277
  "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
 
2278
  "license": "MIT"
2279
  },
2280
  "node_modules/fast-glob": {
@@ -2311,6 +2338,7 @@
2311
  "version": "2.1.0",
2312
  "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
2313
  "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
 
2314
  "license": "MIT"
2315
  },
2316
  "node_modules/fast-levenshtein": {
@@ -2360,6 +2388,7 @@
2360
  "version": "2.1.0",
2361
  "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
2362
  "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
 
2363
  "license": "MIT",
2364
  "dependencies": {
2365
  "debug": "^4.4.0",
@@ -2438,6 +2467,7 @@
2438
  "version": "0.2.0",
2439
  "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
2440
  "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
 
2441
  "license": "MIT",
2442
  "engines": {
2443
  "node": ">= 0.6"
@@ -2447,6 +2477,7 @@
2447
  "version": "2.0.0",
2448
  "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
2449
  "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
 
2450
  "license": "MIT",
2451
  "engines": {
2452
  "node": ">= 0.8"
@@ -2470,6 +2501,7 @@
2470
  "version": "1.1.2",
2471
  "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
2472
  "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
 
2473
  "license": "MIT",
2474
  "funding": {
2475
  "url": "https://github.com/sponsors/ljharb"
@@ -2510,6 +2542,7 @@
2510
  "version": "1.3.0",
2511
  "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
2512
  "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
 
2513
  "license": "MIT",
2514
  "dependencies": {
2515
  "call-bind-apply-helpers": "^1.0.2",
@@ -2534,6 +2567,7 @@
2534
  "version": "1.0.1",
2535
  "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
2536
  "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
 
2537
  "license": "MIT",
2538
  "dependencies": {
2539
  "dunder-proto": "^1.0.1",
@@ -2608,6 +2642,7 @@
2608
  "version": "1.2.0",
2609
  "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
2610
  "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
 
2611
  "license": "MIT",
2612
  "engines": {
2613
  "node": ">= 0.4"
@@ -2679,6 +2714,7 @@
2679
  "version": "1.1.0",
2680
  "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
2681
  "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
 
2682
  "license": "MIT",
2683
  "engines": {
2684
  "node": ">= 0.4"
@@ -2707,6 +2743,7 @@
2707
  "version": "2.0.2",
2708
  "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
2709
  "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
 
2710
  "license": "MIT",
2711
  "dependencies": {
2712
  "function-bind": "^1.1.2"
@@ -2719,6 +2756,7 @@
2719
  "version": "2.0.0",
2720
  "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
2721
  "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
 
2722
  "license": "MIT",
2723
  "dependencies": {
2724
  "depd": "2.0.0",
@@ -2731,10 +2769,21 @@
2731
  "node": ">= 0.8"
2732
  }
2733
  },
 
 
 
 
 
 
 
 
 
 
2734
  "node_modules/iconv-lite": {
2735
  "version": "0.6.3",
2736
  "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
2737
  "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
 
2738
  "license": "MIT",
2739
  "dependencies": {
2740
  "safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -2784,6 +2833,7 @@
2784
  "version": "2.0.4",
2785
  "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
2786
  "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
 
2787
  "license": "ISC"
2788
  },
2789
  "node_modules/internal-slot": {
@@ -2805,6 +2855,7 @@
2805
  "version": "1.9.1",
2806
  "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
2807
  "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
 
2808
  "license": "MIT",
2809
  "engines": {
2810
  "node": ">= 0.10"
@@ -3047,6 +3098,7 @@
3047
  "version": "4.0.0",
3048
  "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
3049
  "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
 
3050
  "license": "MIT"
3051
  },
3052
  "node_modules/is-regex": {
@@ -3205,6 +3257,7 @@
3205
  "version": "2.0.0",
3206
  "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
3207
  "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
 
3208
  "license": "ISC"
3209
  },
3210
  "node_modules/js-yaml": {
@@ -3231,6 +3284,7 @@
3231
  "version": "0.4.1",
3232
  "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
3233
  "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
 
3234
  "license": "MIT"
3235
  },
3236
  "node_modules/json-stable-stringify-without-jsonify": {
@@ -3311,6 +3365,7 @@
3311
  "version": "1.1.0",
3312
  "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
3313
  "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
 
3314
  "license": "MIT",
3315
  "engines": {
3316
  "node": ">= 0.4"
@@ -3320,6 +3375,7 @@
3320
  "version": "1.1.0",
3321
  "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
3322
  "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
 
3323
  "license": "MIT",
3324
  "engines": {
3325
  "node": ">= 0.8"
@@ -3329,6 +3385,7 @@
3329
  "version": "2.0.0",
3330
  "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
3331
  "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
 
3332
  "license": "MIT",
3333
  "engines": {
3334
  "node": ">=18"
@@ -3387,6 +3444,7 @@
3387
  "version": "1.54.0",
3388
  "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
3389
  "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
 
3390
  "license": "MIT",
3391
  "engines": {
3392
  "node": ">= 0.6"
@@ -3396,6 +3454,7 @@
3396
  "version": "3.0.1",
3397
  "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
3398
  "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
 
3399
  "license": "MIT",
3400
  "dependencies": {
3401
  "mime-db": "^1.54.0"
@@ -3444,6 +3503,7 @@
3444
  "version": "1.0.0",
3445
  "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
3446
  "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
 
3447
  "license": "MIT",
3448
  "engines": {
3449
  "node": ">= 0.6"
@@ -3453,6 +3513,7 @@
3453
  "version": "4.1.1",
3454
  "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
3455
  "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
 
3456
  "license": "MIT",
3457
  "engines": {
3458
  "node": ">=0.10.0"
@@ -3462,6 +3523,7 @@
3462
  "version": "1.13.4",
3463
  "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
3464
  "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
 
3465
  "license": "MIT",
3466
  "engines": {
3467
  "node": ">= 0.4"
@@ -3558,6 +3620,7 @@
3558
  "version": "2.4.1",
3559
  "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
3560
  "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
 
3561
  "license": "MIT",
3562
  "dependencies": {
3563
  "ee-first": "1.1.1"
@@ -3570,6 +3633,7 @@
3570
  "version": "1.4.0",
3571
  "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
3572
  "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
 
3573
  "license": "ISC",
3574
  "dependencies": {
3575
  "wrappy": "1"
@@ -3682,6 +3746,7 @@
3682
  "version": "1.3.3",
3683
  "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
3684
  "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
 
3685
  "license": "MIT",
3686
  "engines": {
3687
  "node": ">= 0.8"
@@ -3701,6 +3766,7 @@
3701
  "version": "3.1.1",
3702
  "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
3703
  "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
 
3704
  "license": "MIT",
3705
  "engines": {
3706
  "node": ">=8"
@@ -3717,6 +3783,7 @@
3717
  "version": "8.2.0",
3718
  "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
3719
  "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
 
3720
  "license": "MIT",
3721
  "engines": {
3722
  "node": ">=16"
@@ -3739,6 +3806,7 @@
3739
  "version": "5.0.0",
3740
  "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz",
3741
  "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==",
 
3742
  "license": "MIT",
3743
  "engines": {
3744
  "node": ">=16.20.0"
@@ -3798,6 +3866,7 @@
3798
  "version": "2.0.7",
3799
  "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
3800
  "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
 
3801
  "license": "MIT",
3802
  "dependencies": {
3803
  "forwarded": "0.2.0",
@@ -3811,6 +3880,7 @@
3811
  "version": "2.3.1",
3812
  "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
3813
  "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
 
3814
  "license": "MIT",
3815
  "engines": {
3816
  "node": ">=6"
@@ -3820,6 +3890,7 @@
3820
  "version": "6.14.0",
3821
  "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
3822
  "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
 
3823
  "license": "BSD-3-Clause",
3824
  "dependencies": {
3825
  "side-channel": "^1.1.0"
@@ -3856,6 +3927,7 @@
3856
  "version": "1.2.1",
3857
  "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
3858
  "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
 
3859
  "license": "MIT",
3860
  "engines": {
3861
  "node": ">= 0.6"
@@ -3865,6 +3937,7 @@
3865
  "version": "3.0.0",
3866
  "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
3867
  "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
 
3868
  "license": "MIT",
3869
  "dependencies": {
3870
  "bytes": "3.1.2",
@@ -3966,6 +4039,7 @@
3966
  "version": "2.2.0",
3967
  "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
3968
  "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
 
3969
  "license": "MIT",
3970
  "dependencies": {
3971
  "debug": "^4.4.0",
@@ -4026,6 +4100,7 @@
4026
  "version": "5.2.1",
4027
  "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
4028
  "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
 
4029
  "funding": [
4030
  {
4031
  "type": "github",
@@ -4081,6 +4156,7 @@
4081
  "version": "2.1.2",
4082
  "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
4083
  "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
 
4084
  "license": "MIT"
4085
  },
4086
  "node_modules/semver": {
@@ -4100,6 +4176,7 @@
4100
  "version": "1.2.0",
4101
  "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
4102
  "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
 
4103
  "license": "MIT",
4104
  "dependencies": {
4105
  "debug": "^4.3.5",
@@ -4122,6 +4199,7 @@
4122
  "version": "2.2.0",
4123
  "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
4124
  "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
 
4125
  "license": "MIT",
4126
  "dependencies": {
4127
  "encodeurl": "^2.0.0",
@@ -4186,12 +4264,14 @@
4186
  "version": "1.2.0",
4187
  "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
4188
  "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
 
4189
  "license": "ISC"
4190
  },
4191
  "node_modules/shebang-command": {
4192
  "version": "2.0.0",
4193
  "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
4194
  "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
 
4195
  "license": "MIT",
4196
  "dependencies": {
4197
  "shebang-regex": "^3.0.0"
@@ -4204,6 +4284,7 @@
4204
  "version": "3.0.0",
4205
  "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
4206
  "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
 
4207
  "license": "MIT",
4208
  "engines": {
4209
  "node": ">=8"
@@ -4213,6 +4294,7 @@
4213
  "version": "1.1.0",
4214
  "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
4215
  "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
 
4216
  "license": "MIT",
4217
  "dependencies": {
4218
  "es-errors": "^1.3.0",
@@ -4232,6 +4314,7 @@
4232
  "version": "1.0.0",
4233
  "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
4234
  "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
 
4235
  "license": "MIT",
4236
  "dependencies": {
4237
  "es-errors": "^1.3.0",
@@ -4248,6 +4331,7 @@
4248
  "version": "1.0.1",
4249
  "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
4250
  "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
 
4251
  "license": "MIT",
4252
  "dependencies": {
4253
  "call-bound": "^1.0.2",
@@ -4266,6 +4350,7 @@
4266
  "version": "1.0.2",
4267
  "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
4268
  "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
 
4269
  "license": "MIT",
4270
  "dependencies": {
4271
  "call-bound": "^1.0.2",
@@ -4282,9 +4367,10 @@
4282
  }
4283
  },
4284
  "node_modules/statuses": {
4285
- "version": "2.0.1",
4286
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
4287
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
 
4288
  "license": "MIT",
4289
  "engines": {
4290
  "node": ">= 0.8"
@@ -4415,6 +4501,7 @@
4415
  "version": "1.0.1",
4416
  "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
4417
  "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
 
4418
  "license": "MIT",
4419
  "engines": {
4420
  "node": ">=0.6"
@@ -4463,6 +4550,7 @@
4463
  "version": "2.0.1",
4464
  "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
4465
  "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
 
4466
  "license": "MIT",
4467
  "dependencies": {
4468
  "content-type": "^1.0.5",
@@ -4595,6 +4683,7 @@
4595
  "version": "1.0.0",
4596
  "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
4597
  "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
 
4598
  "license": "MIT",
4599
  "engines": {
4600
  "node": ">= 0.8"
@@ -4604,6 +4693,7 @@
4604
  "version": "4.4.1",
4605
  "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
4606
  "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
 
4607
  "license": "BSD-2-Clause",
4608
  "dependencies": {
4609
  "punycode": "^2.1.0"
@@ -4613,6 +4703,7 @@
4613
  "version": "1.1.2",
4614
  "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
4615
  "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
 
4616
  "license": "MIT",
4617
  "engines": {
4618
  "node": ">= 0.8"
@@ -4622,6 +4713,7 @@
4622
  "version": "2.0.2",
4623
  "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
4624
  "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
 
4625
  "license": "ISC",
4626
  "dependencies": {
4627
  "isexe": "^2.0.0"
@@ -4736,6 +4828,7 @@
4736
  "version": "1.0.2",
4737
  "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
4738
  "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
 
4739
  "license": "ISC"
4740
  },
4741
  "node_modules/ws": {
@@ -4776,6 +4869,7 @@
4776
  "version": "3.24.2",
4777
  "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
4778
  "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==",
 
4779
  "license": "MIT",
4780
  "funding": {
4781
  "url": "https://github.com/sponsors/colinhacks"
@@ -4785,6 +4879,7 @@
4785
  "version": "3.24.4",
4786
  "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.4.tgz",
4787
  "integrity": "sha512-0uNlcvgabyrni9Ag8Vghj21drk7+7tp7VTwwR7KxxXXc/3pbXz2PHlDgj3cICahgF1kHm4dExBFj7BXrZJXzig==",
 
4788
  "license": "ISC",
4789
  "peerDependencies": {
4790
  "zod": "^3.24.1"
 
9
  "version": "0.0.36",
10
  "license": "Apache-2.0",
11
  "dependencies": {
 
12
  "commander": "^13.1.0",
13
  "debug": "^4.4.1",
14
  "dotenv": "^17.2.0",
15
  "mime": "^4.0.7",
16
  "playwright": "1.56.0-alpha-1756505518000",
17
  "playwright-core": "1.56.0-alpha-1756505518000",
18
+ "ws": "^8.18.1"
 
 
19
  },
20
  "bin": {
21
  "mcp-server-playwright": "cli.js"
 
24
  "@anthropic-ai/sdk": "^0.57.0",
25
  "@eslint/eslintrc": "^3.2.0",
26
  "@eslint/js": "^9.19.0",
27
+ "@modelcontextprotocol/sdk": "^1.16.0",
28
  "@playwright/test": "1.56.0-alpha-1756505518000",
29
  "@stylistic/eslint-plugin": "^3.0.1",
30
  "@types/debug": "^4.1.12",
 
38
  "eslint-plugin-import": "^2.31.0",
39
  "eslint-plugin-notice": "^1.0.0",
40
  "openai": "^5.10.2",
41
+ "typescript": "^5.8.2",
42
+ "zod": "^3.24.1",
43
+ "zod-to-json-schema": "^3.24.4"
44
  },
45
  "engines": {
46
  "node": ">=18"
 
642
  }
643
  },
644
  "node_modules/@modelcontextprotocol/sdk": {
645
+ "version": "1.17.4",
646
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.17.4.tgz",
647
+ "integrity": "sha512-zq24hfuAmmlNZvik0FLI58uE5sriN0WWsQzIlYnzSuKDAHFqJtBFrl/LfB1NLgJT5Y7dEBzaX4yAKqOPrcetaw==",
648
+ "dev": true,
649
  "license": "MIT",
650
  "dependencies": {
651
  "ajv": "^6.12.6",
 
1053
  "version": "2.0.0",
1054
  "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
1055
  "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
1056
+ "dev": true,
1057
  "license": "MIT",
1058
  "dependencies": {
1059
  "mime-types": "^3.0.0",
 
1090
  "version": "6.12.6",
1091
  "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
1092
  "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
1093
+ "dev": true,
1094
  "license": "MIT",
1095
  "dependencies": {
1096
  "fast-deep-equal": "^3.1.1",
 
1283
  "version": "2.2.0",
1284
  "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
1285
  "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
1286
+ "dev": true,
1287
  "license": "MIT",
1288
  "dependencies": {
1289
  "bytes": "^3.1.2",
 
1328
  "version": "3.1.2",
1329
  "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
1330
  "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
1331
+ "dev": true,
1332
  "license": "MIT",
1333
  "engines": {
1334
  "node": ">= 0.8"
 
1357
  "version": "1.0.2",
1358
  "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
1359
  "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
1360
+ "dev": true,
1361
  "license": "MIT",
1362
  "dependencies": {
1363
  "es-errors": "^1.3.0",
 
1371
  "version": "1.0.4",
1372
  "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
1373
  "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
1374
+ "dev": true,
1375
  "license": "MIT",
1376
  "dependencies": {
1377
  "call-bind-apply-helpers": "^1.0.2",
 
1451
  "version": "1.0.0",
1452
  "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
1453
  "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
1454
+ "dev": true,
1455
  "license": "MIT",
1456
  "dependencies": {
1457
  "safe-buffer": "5.2.1"
 
1464
  "version": "1.0.5",
1465
  "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
1466
  "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
1467
+ "dev": true,
1468
  "license": "MIT",
1469
  "engines": {
1470
  "node": ">= 0.6"
1471
  }
1472
  },
1473
  "node_modules/cookie": {
1474
+ "version": "0.7.2",
1475
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
1476
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
1477
+ "dev": true,
1478
  "license": "MIT",
1479
  "engines": {
1480
  "node": ">= 0.6"
 
1484
  "version": "1.2.2",
1485
  "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
1486
  "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
1487
+ "dev": true,
1488
  "license": "MIT",
1489
  "engines": {
1490
  "node": ">=6.6.0"
 
1494
  "version": "2.8.5",
1495
  "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
1496
  "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
1497
+ "dev": true,
1498
  "license": "MIT",
1499
  "dependencies": {
1500
  "object-assign": "^4",
 
1508
  "version": "7.0.6",
1509
  "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
1510
  "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
1511
+ "dev": true,
1512
  "license": "MIT",
1513
  "dependencies": {
1514
  "path-key": "^3.1.0",
 
1637
  "version": "2.0.0",
1638
  "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
1639
  "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
1640
+ "dev": true,
1641
  "license": "MIT",
1642
  "engines": {
1643
  "node": ">= 0.8"
 
1672
  "version": "1.0.1",
1673
  "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
1674
  "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
1675
+ "dev": true,
1676
  "license": "MIT",
1677
  "dependencies": {
1678
  "call-bind-apply-helpers": "^1.0.1",
 
1687
  "version": "1.1.1",
1688
  "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
1689
  "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
1690
+ "dev": true,
1691
  "license": "MIT"
1692
  },
1693
  "node_modules/encodeurl": {
1694
  "version": "2.0.0",
1695
  "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
1696
  "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
1697
+ "dev": true,
1698
  "license": "MIT",
1699
  "engines": {
1700
  "node": ">= 0.8"
 
1770
  "version": "1.0.1",
1771
  "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
1772
  "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
1773
+ "dev": true,
1774
  "license": "MIT",
1775
  "engines": {
1776
  "node": ">= 0.4"
 
1780
  "version": "1.3.0",
1781
  "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
1782
  "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
1783
+ "dev": true,
1784
  "license": "MIT",
1785
  "engines": {
1786
  "node": ">= 0.4"
 
1790
  "version": "1.1.1",
1791
  "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
1792
  "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
1793
+ "dev": true,
1794
  "license": "MIT",
1795
  "dependencies": {
1796
  "es-errors": "^1.3.0"
 
1889
  "version": "1.0.3",
1890
  "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
1891
  "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
1892
+ "dev": true,
1893
  "license": "MIT"
1894
  },
1895
  "node_modules/escape-string-regexp": {
 
2209
  "version": "1.8.1",
2210
  "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
2211
  "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
2212
+ "dev": true,
2213
  "license": "MIT",
2214
  "engines": {
2215
  "node": ">= 0.6"
2216
  }
2217
  },
2218
  "node_modules/eventsource": {
2219
+ "version": "3.0.7",
2220
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
2221
+ "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
2222
+ "dev": true,
2223
  "license": "MIT",
2224
  "dependencies": {
2225
+ "eventsource-parser": "^3.0.1"
2226
  },
2227
  "engines": {
2228
  "node": ">=18.0.0"
2229
  }
2230
  },
2231
  "node_modules/eventsource-parser": {
2232
+ "version": "3.0.6",
2233
+ "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz",
2234
+ "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==",
2235
+ "dev": true,
2236
  "license": "MIT",
2237
  "engines": {
2238
  "node": ">=18.0.0"
 
2242
  "version": "5.1.0",
2243
  "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
2244
  "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
2245
+ "dev": true,
2246
  "license": "MIT",
2247
  "dependencies": {
2248
  "accepts": "^2.0.0",
 
2282
  }
2283
  },
2284
  "node_modules/express-rate-limit": {
2285
+ "version": "7.5.1",
2286
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz",
2287
+ "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==",
2288
+ "dev": true,
2289
  "license": "MIT",
2290
  "engines": {
2291
  "node": ">= 16"
 
2294
  "url": "https://github.com/sponsors/express-rate-limit"
2295
  },
2296
  "peerDependencies": {
2297
+ "express": ">= 4.11"
2298
  }
2299
  },
2300
  "node_modules/fast-deep-equal": {
2301
  "version": "3.1.3",
2302
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
2303
  "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
2304
+ "dev": true,
2305
  "license": "MIT"
2306
  },
2307
  "node_modules/fast-glob": {
 
2338
  "version": "2.1.0",
2339
  "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
2340
  "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
2341
+ "dev": true,
2342
  "license": "MIT"
2343
  },
2344
  "node_modules/fast-levenshtein": {
 
2388
  "version": "2.1.0",
2389
  "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
2390
  "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
2391
+ "dev": true,
2392
  "license": "MIT",
2393
  "dependencies": {
2394
  "debug": "^4.4.0",
 
2467
  "version": "0.2.0",
2468
  "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
2469
  "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
2470
+ "dev": true,
2471
  "license": "MIT",
2472
  "engines": {
2473
  "node": ">= 0.6"
 
2477
  "version": "2.0.0",
2478
  "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
2479
  "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
2480
+ "dev": true,
2481
  "license": "MIT",
2482
  "engines": {
2483
  "node": ">= 0.8"
 
2501
  "version": "1.1.2",
2502
  "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
2503
  "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
2504
+ "dev": true,
2505
  "license": "MIT",
2506
  "funding": {
2507
  "url": "https://github.com/sponsors/ljharb"
 
2542
  "version": "1.3.0",
2543
  "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
2544
  "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
2545
+ "dev": true,
2546
  "license": "MIT",
2547
  "dependencies": {
2548
  "call-bind-apply-helpers": "^1.0.2",
 
2567
  "version": "1.0.1",
2568
  "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
2569
  "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
2570
+ "dev": true,
2571
  "license": "MIT",
2572
  "dependencies": {
2573
  "dunder-proto": "^1.0.1",
 
2642
  "version": "1.2.0",
2643
  "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
2644
  "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
2645
+ "dev": true,
2646
  "license": "MIT",
2647
  "engines": {
2648
  "node": ">= 0.4"
 
2714
  "version": "1.1.0",
2715
  "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
2716
  "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
2717
+ "dev": true,
2718
  "license": "MIT",
2719
  "engines": {
2720
  "node": ">= 0.4"
 
2743
  "version": "2.0.2",
2744
  "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
2745
  "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
2746
+ "dev": true,
2747
  "license": "MIT",
2748
  "dependencies": {
2749
  "function-bind": "^1.1.2"
 
2756
  "version": "2.0.0",
2757
  "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
2758
  "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
2759
+ "dev": true,
2760
  "license": "MIT",
2761
  "dependencies": {
2762
  "depd": "2.0.0",
 
2769
  "node": ">= 0.8"
2770
  }
2771
  },
2772
+ "node_modules/http-errors/node_modules/statuses": {
2773
+ "version": "2.0.1",
2774
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
2775
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
2776
+ "dev": true,
2777
+ "license": "MIT",
2778
+ "engines": {
2779
+ "node": ">= 0.8"
2780
+ }
2781
+ },
2782
  "node_modules/iconv-lite": {
2783
  "version": "0.6.3",
2784
  "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
2785
  "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
2786
+ "dev": true,
2787
  "license": "MIT",
2788
  "dependencies": {
2789
  "safer-buffer": ">= 2.1.2 < 3.0.0"
 
2833
  "version": "2.0.4",
2834
  "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
2835
  "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
2836
+ "dev": true,
2837
  "license": "ISC"
2838
  },
2839
  "node_modules/internal-slot": {
 
2855
  "version": "1.9.1",
2856
  "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
2857
  "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
2858
+ "dev": true,
2859
  "license": "MIT",
2860
  "engines": {
2861
  "node": ">= 0.10"
 
3098
  "version": "4.0.0",
3099
  "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
3100
  "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
3101
+ "dev": true,
3102
  "license": "MIT"
3103
  },
3104
  "node_modules/is-regex": {
 
3257
  "version": "2.0.0",
3258
  "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
3259
  "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
3260
+ "dev": true,
3261
  "license": "ISC"
3262
  },
3263
  "node_modules/js-yaml": {
 
3284
  "version": "0.4.1",
3285
  "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
3286
  "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
3287
+ "dev": true,
3288
  "license": "MIT"
3289
  },
3290
  "node_modules/json-stable-stringify-without-jsonify": {
 
3365
  "version": "1.1.0",
3366
  "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
3367
  "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
3368
+ "dev": true,
3369
  "license": "MIT",
3370
  "engines": {
3371
  "node": ">= 0.4"
 
3375
  "version": "1.1.0",
3376
  "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
3377
  "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
3378
+ "dev": true,
3379
  "license": "MIT",
3380
  "engines": {
3381
  "node": ">= 0.8"
 
3385
  "version": "2.0.0",
3386
  "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
3387
  "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
3388
+ "dev": true,
3389
  "license": "MIT",
3390
  "engines": {
3391
  "node": ">=18"
 
3444
  "version": "1.54.0",
3445
  "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
3446
  "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
3447
+ "dev": true,
3448
  "license": "MIT",
3449
  "engines": {
3450
  "node": ">= 0.6"
 
3454
  "version": "3.0.1",
3455
  "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
3456
  "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
3457
+ "dev": true,
3458
  "license": "MIT",
3459
  "dependencies": {
3460
  "mime-db": "^1.54.0"
 
3503
  "version": "1.0.0",
3504
  "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
3505
  "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
3506
+ "dev": true,
3507
  "license": "MIT",
3508
  "engines": {
3509
  "node": ">= 0.6"
 
3513
  "version": "4.1.1",
3514
  "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
3515
  "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
3516
+ "dev": true,
3517
  "license": "MIT",
3518
  "engines": {
3519
  "node": ">=0.10.0"
 
3523
  "version": "1.13.4",
3524
  "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
3525
  "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
3526
+ "dev": true,
3527
  "license": "MIT",
3528
  "engines": {
3529
  "node": ">= 0.4"
 
3620
  "version": "2.4.1",
3621
  "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
3622
  "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
3623
+ "dev": true,
3624
  "license": "MIT",
3625
  "dependencies": {
3626
  "ee-first": "1.1.1"
 
3633
  "version": "1.4.0",
3634
  "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
3635
  "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
3636
+ "dev": true,
3637
  "license": "ISC",
3638
  "dependencies": {
3639
  "wrappy": "1"
 
3746
  "version": "1.3.3",
3747
  "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
3748
  "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
3749
+ "dev": true,
3750
  "license": "MIT",
3751
  "engines": {
3752
  "node": ">= 0.8"
 
3766
  "version": "3.1.1",
3767
  "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
3768
  "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
3769
+ "dev": true,
3770
  "license": "MIT",
3771
  "engines": {
3772
  "node": ">=8"
 
3783
  "version": "8.2.0",
3784
  "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
3785
  "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
3786
+ "dev": true,
3787
  "license": "MIT",
3788
  "engines": {
3789
  "node": ">=16"
 
3806
  "version": "5.0.0",
3807
  "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz",
3808
  "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==",
3809
+ "dev": true,
3810
  "license": "MIT",
3811
  "engines": {
3812
  "node": ">=16.20.0"
 
3866
  "version": "2.0.7",
3867
  "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
3868
  "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
3869
+ "dev": true,
3870
  "license": "MIT",
3871
  "dependencies": {
3872
  "forwarded": "0.2.0",
 
3880
  "version": "2.3.1",
3881
  "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
3882
  "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
3883
+ "dev": true,
3884
  "license": "MIT",
3885
  "engines": {
3886
  "node": ">=6"
 
3890
  "version": "6.14.0",
3891
  "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
3892
  "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
3893
+ "dev": true,
3894
  "license": "BSD-3-Clause",
3895
  "dependencies": {
3896
  "side-channel": "^1.1.0"
 
3927
  "version": "1.2.1",
3928
  "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
3929
  "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
3930
+ "dev": true,
3931
  "license": "MIT",
3932
  "engines": {
3933
  "node": ">= 0.6"
 
3937
  "version": "3.0.0",
3938
  "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
3939
  "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
3940
+ "dev": true,
3941
  "license": "MIT",
3942
  "dependencies": {
3943
  "bytes": "3.1.2",
 
4039
  "version": "2.2.0",
4040
  "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
4041
  "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
4042
+ "dev": true,
4043
  "license": "MIT",
4044
  "dependencies": {
4045
  "debug": "^4.4.0",
 
4100
  "version": "5.2.1",
4101
  "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
4102
  "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
4103
+ "dev": true,
4104
  "funding": [
4105
  {
4106
  "type": "github",
 
4156
  "version": "2.1.2",
4157
  "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
4158
  "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
4159
+ "dev": true,
4160
  "license": "MIT"
4161
  },
4162
  "node_modules/semver": {
 
4176
  "version": "1.2.0",
4177
  "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
4178
  "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
4179
+ "dev": true,
4180
  "license": "MIT",
4181
  "dependencies": {
4182
  "debug": "^4.3.5",
 
4199
  "version": "2.2.0",
4200
  "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
4201
  "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
4202
+ "dev": true,
4203
  "license": "MIT",
4204
  "dependencies": {
4205
  "encodeurl": "^2.0.0",
 
4264
  "version": "1.2.0",
4265
  "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
4266
  "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
4267
+ "dev": true,
4268
  "license": "ISC"
4269
  },
4270
  "node_modules/shebang-command": {
4271
  "version": "2.0.0",
4272
  "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
4273
  "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
4274
+ "dev": true,
4275
  "license": "MIT",
4276
  "dependencies": {
4277
  "shebang-regex": "^3.0.0"
 
4284
  "version": "3.0.0",
4285
  "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
4286
  "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
4287
+ "dev": true,
4288
  "license": "MIT",
4289
  "engines": {
4290
  "node": ">=8"
 
4294
  "version": "1.1.0",
4295
  "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
4296
  "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
4297
+ "dev": true,
4298
  "license": "MIT",
4299
  "dependencies": {
4300
  "es-errors": "^1.3.0",
 
4314
  "version": "1.0.0",
4315
  "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
4316
  "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
4317
+ "dev": true,
4318
  "license": "MIT",
4319
  "dependencies": {
4320
  "es-errors": "^1.3.0",
 
4331
  "version": "1.0.1",
4332
  "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
4333
  "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
4334
+ "dev": true,
4335
  "license": "MIT",
4336
  "dependencies": {
4337
  "call-bound": "^1.0.2",
 
4350
  "version": "1.0.2",
4351
  "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
4352
  "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
4353
+ "dev": true,
4354
  "license": "MIT",
4355
  "dependencies": {
4356
  "call-bound": "^1.0.2",
 
4367
  }
4368
  },
4369
  "node_modules/statuses": {
4370
+ "version": "2.0.2",
4371
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
4372
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
4373
+ "dev": true,
4374
  "license": "MIT",
4375
  "engines": {
4376
  "node": ">= 0.8"
 
4501
  "version": "1.0.1",
4502
  "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
4503
  "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
4504
+ "dev": true,
4505
  "license": "MIT",
4506
  "engines": {
4507
  "node": ">=0.6"
 
4550
  "version": "2.0.1",
4551
  "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
4552
  "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
4553
+ "dev": true,
4554
  "license": "MIT",
4555
  "dependencies": {
4556
  "content-type": "^1.0.5",
 
4683
  "version": "1.0.0",
4684
  "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
4685
  "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
4686
+ "dev": true,
4687
  "license": "MIT",
4688
  "engines": {
4689
  "node": ">= 0.8"
 
4693
  "version": "4.4.1",
4694
  "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
4695
  "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
4696
+ "dev": true,
4697
  "license": "BSD-2-Clause",
4698
  "dependencies": {
4699
  "punycode": "^2.1.0"
 
4703
  "version": "1.1.2",
4704
  "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
4705
  "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
4706
+ "dev": true,
4707
  "license": "MIT",
4708
  "engines": {
4709
  "node": ">= 0.8"
 
4713
  "version": "2.0.2",
4714
  "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
4715
  "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
4716
+ "dev": true,
4717
  "license": "ISC",
4718
  "dependencies": {
4719
  "isexe": "^2.0.0"
 
4828
  "version": "1.0.2",
4829
  "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
4830
  "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
4831
+ "dev": true,
4832
  "license": "ISC"
4833
  },
4834
  "node_modules/ws": {
 
4869
  "version": "3.24.2",
4870
  "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
4871
  "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==",
4872
+ "dev": true,
4873
  "license": "MIT",
4874
  "funding": {
4875
  "url": "https://github.com/sponsors/colinhacks"
 
4879
  "version": "3.24.4",
4880
  "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.4.tgz",
4881
  "integrity": "sha512-0uNlcvgabyrni9Ag8Vghj21drk7+7tp7VTwwR7KxxXXc/3pbXz2PHlDgj3cICahgF1kHm4dExBFj7BXrZJXzig==",
4882
+ "dev": true,
4883
  "license": "ISC",
4884
  "peerDependencies": {
4885
  "zod": "^3.24.1"
package.json CHANGED
@@ -38,21 +38,19 @@
38
  }
39
  },
40
  "dependencies": {
41
- "@modelcontextprotocol/sdk": "^1.16.0",
42
  "commander": "^13.1.0",
43
  "debug": "^4.4.1",
44
  "dotenv": "^17.2.0",
45
  "mime": "^4.0.7",
46
  "playwright": "1.56.0-alpha-1756505518000",
47
  "playwright-core": "1.56.0-alpha-1756505518000",
48
- "ws": "^8.18.1",
49
- "zod": "^3.24.1",
50
- "zod-to-json-schema": "^3.24.4"
51
  },
52
  "devDependencies": {
53
  "@anthropic-ai/sdk": "^0.57.0",
54
  "@eslint/eslintrc": "^3.2.0",
55
  "@eslint/js": "^9.19.0",
 
56
  "@playwright/test": "1.56.0-alpha-1756505518000",
57
  "@stylistic/eslint-plugin": "^3.0.1",
58
  "@types/debug": "^4.1.12",
@@ -66,7 +64,9 @@
66
  "eslint-plugin-import": "^2.31.0",
67
  "eslint-plugin-notice": "^1.0.0",
68
  "openai": "^5.10.2",
69
- "typescript": "^5.8.2"
 
 
70
  },
71
  "bin": {
72
  "mcp-server-playwright": "cli.js"
 
38
  }
39
  },
40
  "dependencies": {
 
41
  "commander": "^13.1.0",
42
  "debug": "^4.4.1",
43
  "dotenv": "^17.2.0",
44
  "mime": "^4.0.7",
45
  "playwright": "1.56.0-alpha-1756505518000",
46
  "playwright-core": "1.56.0-alpha-1756505518000",
47
+ "ws": "^8.18.1"
 
 
48
  },
49
  "devDependencies": {
50
  "@anthropic-ai/sdk": "^0.57.0",
51
  "@eslint/eslintrc": "^3.2.0",
52
  "@eslint/js": "^9.19.0",
53
+ "@modelcontextprotocol/sdk": "^1.16.0",
54
  "@playwright/test": "1.56.0-alpha-1756505518000",
55
  "@stylistic/eslint-plugin": "^3.0.1",
56
  "@types/debug": "^4.1.12",
 
64
  "eslint-plugin-import": "^2.31.0",
65
  "eslint-plugin-notice": "^1.0.0",
66
  "openai": "^5.10.2",
67
+ "typescript": "^5.8.2",
68
+ "zod": "^3.24.1",
69
+ "zod-to-json-schema": "^3.24.4"
70
  },
71
  "bin": {
72
  "mcp-server-playwright": "cli.js"
src/loop/main.ts CHANGED
@@ -19,10 +19,9 @@
19
  import path from 'path';
20
  import url from 'url';
21
  import dotenv from 'dotenv';
22
-
23
- import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
24
- import { Client } from '@modelcontextprotocol/sdk/client/index.js';
25
  import { program } from 'commander';
 
 
26
  import { OpenAIDelegate } from './loopOpenAI.js';
27
  import { ClaudeDelegate } from './loopClaude.js';
28
  import { runTask } from './loop.js';
@@ -34,7 +33,7 @@ dotenv.config();
34
  const __filename = url.fileURLToPath(import.meta.url);
35
 
36
  async function run(delegate: LLMDelegate) {
37
- const transport = new StdioClientTransport({
38
  command: 'node',
39
  args: [
40
  path.resolve(__filename, '../../../cli.js'),
@@ -45,7 +44,7 @@ async function run(delegate: LLMDelegate) {
45
  env: process.env as Record<string, string>,
46
  });
47
 
48
- const client = new Client({ name: 'test', version: '1.0.0' });
49
  await client.connect(transport);
50
  await client.ping();
51
 
 
19
  import path from 'path';
20
  import url from 'url';
21
  import dotenv from 'dotenv';
 
 
 
22
  import { program } from 'commander';
23
+
24
+ import * as mcpBundle from '../mcp/bundle.js';
25
  import { OpenAIDelegate } from './loopOpenAI.js';
26
  import { ClaudeDelegate } from './loopClaude.js';
27
  import { runTask } from './loop.js';
 
33
  const __filename = url.fileURLToPath(import.meta.url);
34
 
35
  async function run(delegate: LLMDelegate) {
36
+ const transport = new mcpBundle.StdioClientTransport({
37
  command: 'node',
38
  args: [
39
  path.resolve(__filename, '../../../cli.js'),
 
44
  env: process.env as Record<string, string>,
45
  });
46
 
47
+ const client = new mcpBundle.Client({ name: 'test', version: '1.0.0' });
48
  await client.connect(transport);
49
  await client.ping();
50
 
src/loopTools/context.ts CHANGED
@@ -14,7 +14,6 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { Client } from '@modelcontextprotocol/sdk/client/index.js';
18
  import { contextFactory } from '../browserContextFactory.js';
19
  import { BrowserServerBackend } from '../browserServerBackend.js';
20
  import { Context as BrowserContext } from '../context.js';
@@ -24,7 +23,9 @@ import { ClaudeDelegate } from '../loop/loopClaude.js';
24
  import { InProcessTransport } from '../mcp/inProcessTransport.js';
25
  import * as mcpServer from '../mcp/server.js';
26
  import { packageJSON } from '../utils/package.js';
 
27
 
 
28
  import type { LLMDelegate } from '../loop/loop.js';
29
  import type { FullConfig } from '../config.js';
30
 
@@ -45,7 +46,7 @@ export class Context {
45
  }
46
 
47
  static async create(config: FullConfig) {
48
- const client = new Client({ name: 'Playwright Proxy', version: packageJSON.version });
49
  const browserContextFactory = contextFactory(config);
50
  const server = mcpServer.createServer('Playwright Subagent', packageJSON.version, new BrowserServerBackend(config, browserContextFactory), false);
51
  await client.connect(new InProcessTransport(server));
 
14
  * limitations under the License.
15
  */
16
 
 
17
  import { contextFactory } from '../browserContextFactory.js';
18
  import { BrowserServerBackend } from '../browserServerBackend.js';
19
  import { Context as BrowserContext } from '../context.js';
 
23
  import { InProcessTransport } from '../mcp/inProcessTransport.js';
24
  import * as mcpServer from '../mcp/server.js';
25
  import { packageJSON } from '../utils/package.js';
26
+ import * as mcpBundle from '../mcp/bundle.js';
27
 
28
+ import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
29
  import type { LLMDelegate } from '../loop/loop.js';
30
  import type { FullConfig } from '../config.js';
31
 
 
46
  }
47
 
48
  static async create(config: FullConfig) {
49
+ const client = new mcpBundle.Client({ name: 'Playwright Proxy', version: packageJSON.version });
50
  const browserContextFactory = contextFactory(config);
51
  const server = mcpServer.createServer('Playwright Subagent', packageJSON.version, new BrowserServerBackend(config, browserContextFactory), false);
52
  await client.connect(new InProcessTransport(server));
src/loopTools/perform.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTool } from './tool.js';
19
 
20
  const performSchema = z.object({
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTool } from './tool.js';
19
 
20
  const performSchema = z.object({
src/loopTools/snapshot.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTool } from './tool.js';
19
 
20
  export const snapshot = defineTool({
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTool } from './tool.js';
19
 
20
  export const snapshot = defineTool({
src/mcp/bundle.ts ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ // @ts-ignore
18
+ import * as bundle from 'playwright/lib/mcpBundleImpl';
19
+
20
+ const zodToJsonSchema: typeof import('zod-to-json-schema').zodToJsonSchema = bundle.zodToJsonSchema;
21
+ const Client: typeof import('@modelcontextprotocol/sdk/client/index.js').Client = bundle.Client;
22
+ const Server: typeof import('@modelcontextprotocol/sdk/server/index.js').Server = bundle.Server;
23
+ const SSEServerTransport: typeof import('@modelcontextprotocol/sdk/server/sse.js').SSEServerTransport = bundle.SSEServerTransport;
24
+ const StdioClientTransport: typeof import('@modelcontextprotocol/sdk/client/stdio.js').StdioClientTransport = bundle.StdioClientTransport;
25
+ const StdioServerTransport: typeof import('@modelcontextprotocol/sdk/server/stdio.js').StdioServerTransport = bundle.StdioServerTransport;
26
+ const StreamableHTTPServerTransport: typeof import('@modelcontextprotocol/sdk/server/streamableHttp.js').StreamableHTTPServerTransport = bundle.StreamableHTTPServerTransport;
27
+ const StreamableHTTPClientTransport: typeof import('@modelcontextprotocol/sdk/client/streamableHttp.js').StreamableHTTPClientTransport = bundle.StreamableHTTPClientTransport;
28
+ const CallToolRequestSchema: typeof import('@modelcontextprotocol/sdk/types.js').CallToolRequestSchema = bundle.CallToolRequestSchema;
29
+ const ListRootsRequestSchema: typeof import('@modelcontextprotocol/sdk/types.js').ListRootsRequestSchema = bundle.ListRootsRequestSchema;
30
+ const ListToolsRequestSchema: typeof import('@modelcontextprotocol/sdk/types.js').ListToolsRequestSchema = bundle.ListToolsRequestSchema;
31
+ const PingRequestSchema: typeof import('@modelcontextprotocol/sdk/types.js').PingRequestSchema = bundle.PingRequestSchema;
32
+ const z: typeof import('zod') = bundle.z;
33
+
34
+ export {
35
+ zodToJsonSchema,
36
+ Client,
37
+ Server,
38
+ SSEServerTransport,
39
+ StdioClientTransport,
40
+ StdioServerTransport,
41
+ StreamableHTTPClientTransport,
42
+ StreamableHTTPServerTransport,
43
+ CallToolRequestSchema,
44
+ ListRootsRequestSchema,
45
+ ListToolsRequestSchema,
46
+ PingRequestSchema,
47
+ z,
48
+ };
src/mcp/http.ts CHANGED
@@ -21,11 +21,12 @@ import crypto from 'crypto';
21
 
22
  import debug from 'debug';
23
 
24
- import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
25
- import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
26
  import * as mcpServer from './server.js';
27
 
28
  import type { ServerBackendFactory } from './server.js';
 
 
29
 
30
  const testDebug = debug('pw:mcp:test');
31
 
@@ -86,7 +87,7 @@ async function handleSSE(serverBackendFactory: ServerBackendFactory, req: http.I
86
 
87
  return await transport.handlePostMessage(req, res);
88
  } else if (req.method === 'GET') {
89
- const transport = new SSEServerTransport('/sse', res);
90
  sessions.set(transport.sessionId, transport);
91
  testDebug(`create SSE session: ${transport.sessionId}`);
92
  await mcpServer.connect(serverBackendFactory, transport, false);
@@ -114,7 +115,7 @@ async function handleStreamable(serverBackendFactory: ServerBackendFactory, req:
114
  }
115
 
116
  if (req.method === 'POST') {
117
- const transport = new StreamableHTTPServerTransport({
118
  sessionIdGenerator: () => crypto.randomUUID(),
119
  onsessioninitialized: async sessionId => {
120
  testDebug(`create http session: ${transport.sessionId}`);
 
21
 
22
  import debug from 'debug';
23
 
24
+ import * as mcpBundle from './bundle.js';
 
25
  import * as mcpServer from './server.js';
26
 
27
  import type { ServerBackendFactory } from './server.js';
28
+ import type { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
29
+ import type { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
30
 
31
  const testDebug = debug('pw:mcp:test');
32
 
 
87
 
88
  return await transport.handlePostMessage(req, res);
89
  } else if (req.method === 'GET') {
90
+ const transport = new mcpBundle.SSEServerTransport('/sse', res);
91
  sessions.set(transport.sessionId, transport);
92
  testDebug(`create SSE session: ${transport.sessionId}`);
93
  await mcpServer.connect(serverBackendFactory, transport, false);
 
115
  }
116
 
117
  if (req.method === 'POST') {
118
+ const transport = new mcpBundle.StreamableHTTPServerTransport({
119
  sessionIdGenerator: () => crypto.randomUUID(),
120
  onsessioninitialized: async sessionId => {
121
  testDebug(`create http session: ${transport.sessionId}`);
src/mcp/mdb.ts CHANGED
@@ -15,23 +15,20 @@
15
  */
16
 
17
  import debug from 'debug';
18
- import { z } from 'zod';
19
-
20
- import { Client } from '@modelcontextprotocol/sdk/client/index.js';
21
- import { PingRequestSchema } from '@modelcontextprotocol/sdk/types.js';
22
- import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
23
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
24
 
25
  import { defineToolSchema } from './tool.js';
 
26
  import * as mcpServer from './server.js';
27
  import * as mcpHttp from './http.js';
28
  import { wrapInProcess } from './server.js';
29
  import { ManualPromise } from './manualPromise.js';
30
 
31
  import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
 
32
 
33
  const mdbDebug = debug('pw:mcp:mdb');
34
  const errorsDebug = debug('pw:mcp:errors');
 
35
 
36
  export class MDBBackend implements mcpServer.ServerBackend {
37
  private _stack: { client: Client, toolNames: string[], resultPromise: ManualPromise<mcpServer.CallToolResult> | undefined }[] = [];
@@ -107,15 +104,15 @@ export class MDBBackend implements mcpServer.ServerBackend {
107
 
108
  private async _pushTools(params: { mcpUrl: string, introMessage?: string }): Promise<mcpServer.CallToolResult> {
109
  mdbDebug('pushing tools to the stack', params.mcpUrl);
110
- const transport = new StreamableHTTPClientTransport(new URL(params.mcpUrl));
111
  await this._pushClient(transport, params.introMessage);
112
  return { content: [{ type: 'text', text: 'Tools pushed' }] };
113
  }
114
 
115
  private async _pushClient(transport: Transport, introMessage?: string): Promise<mcpServer.CallToolResult> {
116
  mdbDebug('pushing client to the stack');
117
- const client = new Client({ name: 'Internal client', version: '0.0.0' });
118
- client.setRequestHandler(PingRequestSchema, () => ({}));
119
  await client.connect(transport);
120
  mdbDebug('connected to the new client');
121
  const { tools } = await client.listTools();
@@ -162,7 +159,7 @@ export async function runMainBackend(backendFactory: mcpServer.ServerBackendFact
162
  return url;
163
 
164
  // Start stdio conditionally.
165
- await mcpServer.connect(factory, new StdioServerTransport(), false);
166
  }
167
 
168
  export async function runOnPauseBackendLoop(mdbUrl: string, backend: ServerBackendOnPause, introMessage: string) {
@@ -179,9 +176,9 @@ export async function runOnPauseBackendLoop(mdbUrl: string, backend: ServerBacke
179
  await mcpHttp.installHttpTransport(httpServer, factory);
180
  const url = mcpHttp.httpAddressToString(httpServer.address());
181
 
182
- const client = new Client({ name: 'Internal client', version: '0.0.0' });
183
- client.setRequestHandler(PingRequestSchema, () => ({}));
184
- const transport = new StreamableHTTPClientTransport(new URL(mdbUrl));
185
  await client.connect(transport);
186
 
187
  const pushToolsResult = await client.callTool({
 
15
  */
16
 
17
  import debug from 'debug';
 
 
 
 
 
 
18
 
19
  import { defineToolSchema } from './tool.js';
20
+ import * as mcpBundle from './bundle.js';
21
  import * as mcpServer from './server.js';
22
  import * as mcpHttp from './http.js';
23
  import { wrapInProcess } from './server.js';
24
  import { ManualPromise } from './manualPromise.js';
25
 
26
  import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
27
+ import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
28
 
29
  const mdbDebug = debug('pw:mcp:mdb');
30
  const errorsDebug = debug('pw:mcp:errors');
31
+ const z = mcpBundle.z;
32
 
33
  export class MDBBackend implements mcpServer.ServerBackend {
34
  private _stack: { client: Client, toolNames: string[], resultPromise: ManualPromise<mcpServer.CallToolResult> | undefined }[] = [];
 
104
 
105
  private async _pushTools(params: { mcpUrl: string, introMessage?: string }): Promise<mcpServer.CallToolResult> {
106
  mdbDebug('pushing tools to the stack', params.mcpUrl);
107
+ const transport = new mcpBundle.StreamableHTTPClientTransport(new URL(params.mcpUrl));
108
  await this._pushClient(transport, params.introMessage);
109
  return { content: [{ type: 'text', text: 'Tools pushed' }] };
110
  }
111
 
112
  private async _pushClient(transport: Transport, introMessage?: string): Promise<mcpServer.CallToolResult> {
113
  mdbDebug('pushing client to the stack');
114
+ const client = new mcpBundle.Client({ name: 'Internal client', version: '0.0.0' });
115
+ client.setRequestHandler(mcpBundle.PingRequestSchema, () => ({}));
116
  await client.connect(transport);
117
  mdbDebug('connected to the new client');
118
  const { tools } = await client.listTools();
 
159
  return url;
160
 
161
  // Start stdio conditionally.
162
+ await mcpServer.connect(factory, new mcpBundle.StdioServerTransport(), false);
163
  }
164
 
165
  export async function runOnPauseBackendLoop(mdbUrl: string, backend: ServerBackendOnPause, introMessage: string) {
 
176
  await mcpHttp.installHttpTransport(httpServer, factory);
177
  const url = mcpHttp.httpAddressToString(httpServer.address());
178
 
179
+ const client = new mcpBundle.Client({ name: 'Internal client', version: '0.0.0' });
180
+ client.setRequestHandler(mcpBundle.PingRequestSchema, () => ({}));
181
+ const transport = new mcpBundle.StreamableHTTPClientTransport(new URL(mdbUrl));
182
  await client.connect(transport);
183
 
184
  const pushToolsResult = await client.callTool({
src/mcp/proxyBackend.ts CHANGED
@@ -15,15 +15,13 @@
15
  */
16
 
17
  import debug from 'debug';
18
- import { z } from 'zod';
19
- import { zodToJsonSchema } from 'zod-to-json-schema';
20
 
21
- import { Client } from '@modelcontextprotocol/sdk/client/index.js';
22
- import { ListRootsRequestSchema, PingRequestSchema } from '@modelcontextprotocol/sdk/types.js';
23
 
24
  import type { ServerBackend, ClientVersion, Root, Server } from './server.js';
25
  import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
26
  import type { Tool, CallToolResult, CallToolRequest } from '@modelcontextprotocol/sdk/types.js';
 
27
 
28
  export type MCPProvider = {
29
  name: string;
@@ -32,6 +30,7 @@ export type MCPProvider = {
32
  };
33
 
34
  const errorsDebug = debug('pw:mcp:errors');
 
35
 
36
  export class ProxyBackend implements ServerBackend {
37
  private _mcpProviders: MCPProvider[];
@@ -112,14 +111,14 @@ export class ProxyBackend implements ServerBackend {
112
  await this._currentClient?.close();
113
  this._currentClient = undefined;
114
 
115
- const client = new Client({ name: 'Playwright MCP Proxy', version: '0.0.0' });
116
  client.registerCapabilities({
117
  roots: {
118
  listRoots: true,
119
  },
120
  });
121
- client.setRequestHandler(ListRootsRequestSchema, () => ({ roots: this._roots }));
122
- client.setRequestHandler(PingRequestSchema, () => ({}));
123
 
124
  const transport = await factory.connect();
125
  await client.connect(transport);
 
15
  */
16
 
17
  import debug from 'debug';
 
 
18
 
19
+ import * as mcpBundle from './bundle.js';
 
20
 
21
  import type { ServerBackend, ClientVersion, Root, Server } from './server.js';
22
  import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
23
  import type { Tool, CallToolResult, CallToolRequest } from '@modelcontextprotocol/sdk/types.js';
24
+ import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
25
 
26
  export type MCPProvider = {
27
  name: string;
 
30
  };
31
 
32
  const errorsDebug = debug('pw:mcp:errors');
33
+ const { z, zodToJsonSchema } = mcpBundle;
34
 
35
  export class ProxyBackend implements ServerBackend {
36
  private _mcpProviders: MCPProvider[];
 
111
  await this._currentClient?.close();
112
  this._currentClient = undefined;
113
 
114
+ const client = new mcpBundle.Client({ name: 'Playwright MCP Proxy', version: '0.0.0' });
115
  client.registerCapabilities({
116
  roots: {
117
  listRoots: true,
118
  },
119
  });
120
+ client.setRequestHandler(mcpBundle.ListRootsRequestSchema, () => ({ roots: this._roots }));
121
+ client.setRequestHandler(mcpBundle.PingRequestSchema, () => ({}));
122
 
123
  const transport = await factory.connect();
124
  await client.connect(transport);
src/mcp/server.ts CHANGED
@@ -16,9 +16,7 @@
16
 
17
  import debug from 'debug';
18
 
19
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
20
- import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
21
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
22
  import { httpAddressToString, installHttpTransport, startHttpServer } from './http.js';
23
  import { InProcessTransport } from './inProcessTransport.js';
24
 
@@ -26,6 +24,7 @@ import type { Tool, CallToolResult, CallToolRequest, Root } from '@modelcontextp
26
  import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
27
  export type { Server } from '@modelcontextprotocol/sdk/server/index.js';
28
  export type { Tool, CallToolResult, CallToolRequest, Root } from '@modelcontextprotocol/sdk/types.js';
 
29
 
30
  const serverDebug = debug('pw:mcp:server');
31
  const errorsDebug = debug('pw:mcp:errors');
@@ -59,13 +58,13 @@ export async function wrapInProcess(backend: ServerBackend): Promise<Transport>
59
  export function createServer(name: string, version: string, backend: ServerBackend, runHeartbeat: boolean): Server {
60
  let initializedPromiseResolve = () => {};
61
  const initializedPromise = new Promise<void>(resolve => initializedPromiseResolve = resolve);
62
- const server = new Server({ name, version }, {
63
  capabilities: {
64
  tools: {},
65
  }
66
  });
67
 
68
- server.setRequestHandler(ListToolsRequestSchema, async () => {
69
  serverDebug('listTools');
70
  await initializedPromise;
71
  const tools = await backend.listTools();
@@ -73,7 +72,7 @@ export function createServer(name: string, version: string, backend: ServerBacke
73
  });
74
 
75
  let heartbeatRunning = false;
76
- server.setRequestHandler(CallToolRequestSchema, async request => {
77
  serverDebug('callTool', request);
78
  await initializedPromise;
79
 
@@ -135,7 +134,7 @@ function addServerListener(server: Server, event: 'close' | 'initialized', liste
135
 
136
  export async function start(serverBackendFactory: ServerBackendFactory, options: { host?: string; port?: number }) {
137
  if (options.port === undefined) {
138
- await connect(serverBackendFactory, new StdioServerTransport(), false);
139
  return;
140
  }
141
 
 
16
 
17
  import debug from 'debug';
18
 
19
+ import * as mcpBundle from './bundle.js';
 
 
20
  import { httpAddressToString, installHttpTransport, startHttpServer } from './http.js';
21
  import { InProcessTransport } from './inProcessTransport.js';
22
 
 
24
  import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
25
  export type { Server } from '@modelcontextprotocol/sdk/server/index.js';
26
  export type { Tool, CallToolResult, CallToolRequest, Root } from '@modelcontextprotocol/sdk/types.js';
27
+ import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
28
 
29
  const serverDebug = debug('pw:mcp:server');
30
  const errorsDebug = debug('pw:mcp:errors');
 
58
  export function createServer(name: string, version: string, backend: ServerBackend, runHeartbeat: boolean): Server {
59
  let initializedPromiseResolve = () => {};
60
  const initializedPromise = new Promise<void>(resolve => initializedPromiseResolve = resolve);
61
+ const server = new mcpBundle.Server({ name, version }, {
62
  capabilities: {
63
  tools: {},
64
  }
65
  });
66
 
67
+ server.setRequestHandler(mcpBundle.ListToolsRequestSchema, async () => {
68
  serverDebug('listTools');
69
  await initializedPromise;
70
  const tools = await backend.listTools();
 
72
  });
73
 
74
  let heartbeatRunning = false;
75
+ server.setRequestHandler(mcpBundle.CallToolRequestSchema, async request => {
76
  serverDebug('callTool', request);
77
  await initializedPromise;
78
 
 
134
 
135
  export async function start(serverBackendFactory: ServerBackendFactory, options: { host?: string; port?: number }) {
136
  if (options.port === undefined) {
137
+ await connect(serverBackendFactory, new mcpBundle.StdioServerTransport(), false);
138
  return;
139
  }
140
 
src/mcp/tool.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { zodToJsonSchema } from 'zod-to-json-schema';
18
 
19
  import type { z } from 'zod';
20
  import type * as mcpServer from './server.js';
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { zodToJsonSchema } from '../mcp/bundle.js';
18
 
19
  import type { z } from 'zod';
20
  import type * as mcpServer from './server.js';
src/tools/DEPS.list CHANGED
@@ -1,2 +1,3 @@
1
  [*]
2
  ../utils/
 
 
1
  [*]
2
  ../utils/
3
+ ../mcp/
src/tools/common.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTabTool, defineTool } from './tool.js';
19
 
20
  const close = defineTool({
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTabTool, defineTool } from './tool.js';
19
 
20
  const close = defineTool({
src/tools/console.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTabTool } from './tool.js';
19
 
20
  const console = defineTabTool({
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTabTool } from './tool.js';
19
 
20
  const console = defineTabTool({
src/tools/dialogs.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTabTool } from './tool.js';
19
 
20
  const handleDialog = defineTabTool({
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTabTool } from './tool.js';
19
 
20
  const handleDialog = defineTabTool({
src/tools/evaluate.ts CHANGED
@@ -14,8 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
-
19
  import { defineTabTool } from './tool.js';
20
  import * as javascript from '../utils/codegen.js';
21
  import { generateLocator } from './utils.js';
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
 
18
  import { defineTabTool } from './tool.js';
19
  import * as javascript from '../utils/codegen.js';
20
  import { generateLocator } from './utils.js';
src/tools/files.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTabTool } from './tool.js';
19
 
20
  const uploadFile = defineTabTool({
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTabTool } from './tool.js';
19
 
20
  const uploadFile = defineTabTool({
src/tools/form.ts CHANGED
@@ -14,8 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
-
19
  import { defineTabTool } from './tool.js';
20
  import { generateLocator } from './utils.js';
21
  import * as javascript from '../utils/codegen.js';
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
 
18
  import { defineTabTool } from './tool.js';
19
  import { generateLocator } from './utils.js';
20
  import * as javascript from '../utils/codegen.js';
src/tools/install.ts CHANGED
@@ -16,10 +16,10 @@
16
 
17
  import { fork } from 'child_process';
18
  import path from 'path';
19
- import { fileURLToPath } from 'url';
20
- import { z } from 'zod';
21
- import { defineTool } from './tool.js';
22
 
 
 
23
 
24
  const install = defineTool({
25
  capability: 'core-install',
@@ -34,7 +34,7 @@ const install = defineTool({
34
  handle: async (context, params, response) => {
35
  const channel = context.config.browser?.launchOptions?.channel ?? context.config.browser?.browserName ?? 'chrome';
36
  const cliUrl = import.meta.resolve('playwright/package.json');
37
- const cliPath = path.join(fileURLToPath(cliUrl), '..', 'cli.js');
38
  const child = fork(cliPath, ['install', channel], {
39
  stdio: 'pipe',
40
  });
 
16
 
17
  import { fork } from 'child_process';
18
  import path from 'path';
19
+ import url from 'url';
 
 
20
 
21
+ import { z } from '../mcp/bundle.js';
22
+ import { defineTool } from './tool.js';
23
 
24
  const install = defineTool({
25
  capability: 'core-install',
 
34
  handle: async (context, params, response) => {
35
  const channel = context.config.browser?.launchOptions?.channel ?? context.config.browser?.browserName ?? 'chrome';
36
  const cliUrl = import.meta.resolve('playwright/package.json');
37
+ const cliPath = path.join(url.fileURLToPath(cliUrl), '..', 'cli.js');
38
  const child = fork(cliPath, ['install', channel], {
39
  stdio: 'pipe',
40
  });
src/tools/keyboard.ts CHANGED
@@ -14,8 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
-
19
  import { defineTabTool } from './tool.js';
20
  import { elementSchema } from './snapshot.js';
21
  import { generateLocator } from './utils.js';
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
 
18
  import { defineTabTool } from './tool.js';
19
  import { elementSchema } from './snapshot.js';
20
  import { generateLocator } from './utils.js';
src/tools/mouse.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTabTool } from './tool.js';
19
 
20
  const elementSchema = z.object({
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTabTool } from './tool.js';
19
 
20
  const elementSchema = z.object({
src/tools/navigate.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTool, defineTabTool } from './tool.js';
19
 
20
  const navigate = defineTool({
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTool, defineTabTool } from './tool.js';
19
 
20
  const navigate = defineTool({
src/tools/network.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTabTool } from './tool.js';
19
 
20
  import type * as playwright from 'playwright';
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTabTool } from './tool.js';
19
 
20
  import type * as playwright from 'playwright';
src/tools/pdf.ts CHANGED
@@ -14,9 +14,8 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTabTool } from './tool.js';
19
-
20
  import * as javascript from '../utils/codegen.js';
21
 
22
  const pdfSchema = z.object({
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTabTool } from './tool.js';
 
19
  import * as javascript from '../utils/codegen.js';
20
 
21
  const pdfSchema = z.object({
src/tools/screenshot.ts CHANGED
@@ -14,8 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
-
19
  import { defineTabTool } from './tool.js';
20
  import * as javascript from '../utils/codegen.js';
21
  import { generateLocator } from './utils.js';
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
 
18
  import { defineTabTool } from './tool.js';
19
  import * as javascript from '../utils/codegen.js';
20
  import { generateLocator } from './utils.js';
src/tools/snapshot.ts CHANGED
@@ -14,8 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
-
19
  import { defineTabTool, defineTool } from './tool.js';
20
  import * as javascript from '../utils/codegen.js';
21
  import { generateLocator } from './utils.js';
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
 
18
  import { defineTabTool, defineTool } from './tool.js';
19
  import * as javascript from '../utils/codegen.js';
20
  import { generateLocator } from './utils.js';
src/tools/tabs.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTool } from './tool.js';
19
 
20
  const browserTabs = defineTool({
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTool } from './tool.js';
19
 
20
  const browserTabs = defineTool({
src/tools/verify.ts CHANGED
@@ -14,8 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
-
19
  import { defineTabTool } from './tool.js';
20
  import * as javascript from '../utils/codegen.js';
21
  import { generateLocator } from './utils.js';
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
 
18
  import { defineTabTool } from './tool.js';
19
  import * as javascript from '../utils/codegen.js';
20
  import { generateLocator } from './utils.js';
src/tools/wait.ts CHANGED
@@ -14,7 +14,7 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { z } from 'zod';
18
  import { defineTool } from './tool.js';
19
 
20
  const wait = defineTool({
 
14
  * limitations under the License.
15
  */
16
 
17
+ import { z } from '../mcp/bundle.js';
18
  import { defineTool } from './tool.js';
19
 
20
  const wait = defineTool({
src/utils/fileUtils.ts CHANGED
@@ -14,8 +14,8 @@
14
  * limitations under the License.
15
  */
16
 
17
- import os from 'node:os';
18
- import path from 'node:path';
19
 
20
  export function cacheDir() {
21
  let cacheDirectory: string;
 
14
  * limitations under the License.
15
  */
16
 
17
+ import os from 'os';
18
+ import path from 'path';
19
 
20
  export function cacheDir() {
21
  let cacheDirectory: string;
src/vscode/host.ts CHANGED
@@ -14,15 +14,10 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { fileURLToPath } from 'url';
18
  import path from 'path';
19
- import { z } from 'zod';
20
- import { zodToJsonSchema } from 'zod-to-json-schema';
21
 
22
-
23
- import { Client } from '@modelcontextprotocol/sdk/client/index.js';
24
- import { ListRootsRequestSchema, PingRequestSchema } from '@modelcontextprotocol/sdk/types.js';
25
- import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
26
  import * as mcpServer from '../mcp/server.js';
27
  import { logUnhandledError } from '../utils/log.js';
28
  import { packageJSON } from '../utils/package.js';
@@ -30,10 +25,15 @@ import { packageJSON } from '../utils/package.js';
30
  import { FullConfig } from '../config.js';
31
  import { BrowserServerBackend } from '../browserServerBackend.js';
32
  import { contextFactory } from '../browserContextFactory.js';
 
 
33
  import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
34
  import type { ClientVersion, ServerBackend } from '../mcp/server.js';
35
  import type { Root, Tool, CallToolResult, CallToolRequest } from '@modelcontextprotocol/sdk/types.js';
36
  import type { Browser, BrowserContext, BrowserServer } from 'playwright';
 
 
 
37
 
38
  const contextSwitchOptions = z.object({
39
  connectionString: z.string().optional().describe('The connection string to use to connect to the browser'),
@@ -111,7 +111,7 @@ class VSCodeProxyBackend implements ServerBackend {
111
  return url.toString();
112
  }
113
 
114
- private async _callContextSwitchTool(params: z.infer<typeof contextSwitchOptions>): Promise<CallToolResult> {
115
  if (params.debugController) {
116
  const url = await this._getDebugControllerURL();
117
  const lines = [`### Result`];
@@ -133,11 +133,11 @@ class VSCodeProxyBackend implements ServerBackend {
133
  }
134
 
135
  await this._setCurrentClient(
136
- new StdioClientTransport({
137
  command: process.execPath,
138
  cwd: process.cwd(),
139
  args: [
140
- path.join(fileURLToPath(import.meta.url), '..', 'main.js'),
141
  JSON.stringify(this._config),
142
  params.connectionString,
143
  params.lib,
@@ -166,14 +166,14 @@ class VSCodeProxyBackend implements ServerBackend {
166
  await this._currentClient?.close();
167
  this._currentClient = undefined;
168
 
169
- const client = new Client(this._clientVersion!);
170
  client.registerCapabilities({
171
  roots: {
172
  listRoots: true,
173
  },
174
  });
175
- client.setRequestHandler(ListRootsRequestSchema, () => ({ roots: this._roots }));
176
- client.setRequestHandler(PingRequestSchema, () => ({}));
177
 
178
  await client.connect(transport);
179
  this._currentClient = client;
 
14
  * limitations under the License.
15
  */
16
 
17
+ import url from 'url';
18
  import path from 'path';
 
 
19
 
20
+ import * as mcpBundle from '../mcp/bundle.js';
 
 
 
21
  import * as mcpServer from '../mcp/server.js';
22
  import { logUnhandledError } from '../utils/log.js';
23
  import { packageJSON } from '../utils/package.js';
 
25
  import { FullConfig } from '../config.js';
26
  import { BrowserServerBackend } from '../browserServerBackend.js';
27
  import { contextFactory } from '../browserContextFactory.js';
28
+
29
+ import type { z as zod } from 'zod';
30
  import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
31
  import type { ClientVersion, ServerBackend } from '../mcp/server.js';
32
  import type { Root, Tool, CallToolResult, CallToolRequest } from '@modelcontextprotocol/sdk/types.js';
33
  import type { Browser, BrowserContext, BrowserServer } from 'playwright';
34
+ import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
35
+
36
+ const { z, zodToJsonSchema } = mcpBundle;
37
 
38
  const contextSwitchOptions = z.object({
39
  connectionString: z.string().optional().describe('The connection string to use to connect to the browser'),
 
111
  return url.toString();
112
  }
113
 
114
+ private async _callContextSwitchTool(params: zod.infer<typeof contextSwitchOptions>): Promise<CallToolResult> {
115
  if (params.debugController) {
116
  const url = await this._getDebugControllerURL();
117
  const lines = [`### Result`];
 
133
  }
134
 
135
  await this._setCurrentClient(
136
+ new mcpBundle.StdioClientTransport({
137
  command: process.execPath,
138
  cwd: process.cwd(),
139
  args: [
140
+ path.join(url.fileURLToPath(import.meta.url), '..', 'main.js'),
141
  JSON.stringify(this._config),
142
  params.connectionString,
143
  params.lib,
 
166
  await this._currentClient?.close();
167
  this._currentClient = undefined;
168
 
169
+ const client = new mcpBundle.Client(this._clientVersion!);
170
  client.registerCapabilities({
171
  roots: {
172
  listRoots: true,
173
  },
174
  });
175
+ client.setRequestHandler(mcpBundle.ListRootsRequestSchema, () => ({ roots: this._roots }));
176
+ client.setRequestHandler(mcpBundle.PingRequestSchema, () => ({}));
177
 
178
  await client.connect(transport);
179
  this._currentClient = client;
src/vscode/main.ts CHANGED
@@ -14,10 +14,11 @@
14
  * limitations under the License.
15
  */
16
 
17
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
18
  import * as mcpServer from '../mcp/server.js';
19
  import { BrowserServerBackend } from '../browserServerBackend.js';
20
  import { BrowserContextFactory, ClientInfo } from '../browserContextFactory.js';
 
21
  import type { FullConfig } from '../config.js';
22
  import type { BrowserContext } from 'playwright-core';
23
 
@@ -63,7 +64,7 @@ async function main(config: FullConfig, connectionString: string, lib: string) {
63
  create: () => new BrowserServerBackend(config, factory),
64
  version: 'unused'
65
  },
66
- new StdioServerTransport(),
67
  false
68
  );
69
  }
 
14
  * limitations under the License.
15
  */
16
 
17
+ import * as mcpBundle from '../mcp/bundle.js';
18
  import * as mcpServer from '../mcp/server.js';
19
  import { BrowserServerBackend } from '../browserServerBackend.js';
20
  import { BrowserContextFactory, ClientInfo } from '../browserContextFactory.js';
21
+
22
  import type { FullConfig } from '../config.js';
23
  import type { BrowserContext } from 'playwright-core';
24
 
 
64
  create: () => new BrowserServerBackend(config, factory),
65
  version: 'unused'
66
  },
67
+ new mcpBundle.StdioServerTransport(),
68
  false
69
  );
70
  }
utils/check-deps.js CHANGED
@@ -21,8 +21,12 @@
21
  import fs from 'fs';
22
  import ts from 'typescript';
23
  import path from 'path';
 
24
 
25
  const __dirname = path.dirname(new URL(import.meta.url).pathname);
 
 
 
26
 
27
  const depsCache = {};
28
  const packageRoot = path.resolve(__dirname, '..');
@@ -31,6 +35,13 @@ async function checkDeps() {
31
  const deps = new Set();
32
  const src = path.join(packageRoot, 'src');
33
 
 
 
 
 
 
 
 
34
  const program = ts.createProgram({
35
  options: {
36
  allowJs: true,
@@ -53,6 +64,25 @@ async function checkDeps() {
53
  process.exit(1);
54
  }
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  function visit(node, fileName, text) {
57
  if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
58
  if (node.importClause) {
@@ -94,10 +124,21 @@ async function checkDeps() {
94
  return;
95
  }
96
 
 
97
  if (importName.startsWith('@'))
98
- deps.add(importName.split('/').slice(0, 2).join('/'));
99
  else
100
- deps.add(importName.split('/')[0]);
 
 
 
 
 
 
 
 
 
 
101
  }
102
  ts.forEachChild(node, x => visit(x, fileName, text));
103
  }
@@ -154,6 +195,19 @@ async function checkDeps() {
154
  }
155
  return false;
156
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  }
158
 
159
  function listAllFiles(dir) {
 
21
  import fs from 'fs';
22
  import ts from 'typescript';
23
  import path from 'path';
24
+ import Module from 'module';
25
 
26
  const __dirname = path.dirname(new URL(import.meta.url).pathname);
27
+ const require = Module.createRequire(import.meta.url);
28
+
29
+ const builtins = new Set(Module.builtinModules);
30
 
31
  const depsCache = {};
32
  const packageRoot = path.resolve(__dirname, '..');
 
35
  const deps = new Set();
36
  const src = path.join(packageRoot, 'src');
37
 
38
+
39
+ let packageJSON;
40
+ try {
41
+ packageJSON = require(path.resolve(path.join(packageRoot, 'package.json')));
42
+ } catch {
43
+ }
44
+
45
  const program = ts.createProgram({
46
  options: {
47
  allowJs: true,
 
64
  process.exit(1);
65
  }
66
 
67
+ if (packageJSON) {
68
+ for (const dep of deps) {
69
+ const resolved = require.resolve(dep, { paths: [packageRoot] });
70
+ if (dep === resolved || !resolved.includes('node_modules'))
71
+ deps.delete(dep);
72
+ }
73
+ for (const dep of Object.keys(packageJSON.dependencies || {}))
74
+ deps.delete(dep);
75
+
76
+ if (deps.size) {
77
+ console.log('Dependencies are not declared in package.json:');
78
+ for (const dep of deps)
79
+ console.log(` ${dep}`);
80
+ process.exit(1);
81
+ }
82
+ }
83
+
84
+ return packageJSON;
85
+
86
  function visit(node, fileName, text) {
87
  if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
88
  if (node.importClause) {
 
124
  return;
125
  }
126
 
127
+ let depName;
128
  if (importName.startsWith('@'))
129
+ depName = importName.split('/').slice(0, 2).join('/');
130
  else
131
+ depName = importName.split('/')[0];
132
+ deps.add(depName);
133
+ try {
134
+ require.resolve(depName, { paths: [packageRoot] })
135
+ } catch (e) {
136
+ console.log(`Invalid dependency ${depName} in ${fileName}`);
137
+ process.exit(1);
138
+ }
139
+
140
+ if (!allowExternalImport(importName, packageJSON))
141
+ errors.push(`Disallowed external dependency ${importName} from ${path.relative(packageRoot, fileName)}`);
142
  }
143
  ts.forEachChild(node, x => visit(x, fileName, text));
144
  }
 
195
  }
196
  return false;
197
  }
198
+
199
+ function allowExternalImport(importName, packageJSON) {
200
+ // Only external imports are relevant. Files in src/web are bundled via webpack.
201
+ if (importName.startsWith('.') || (importName.startsWith('@') && !importName.startsWith('@playwright/')))
202
+ return true;
203
+ if (!packageJSON)
204
+ return false;
205
+ const match = importName.match(/(@[\w-]+\/)?([^/]+)/);
206
+ const dependency = match[1] ? match[1] + match[2] : match[2];
207
+ if (builtins.has(dependency))
208
+ return true;
209
+ return !!(packageJSON.dependencies || {})[dependency];
210
+ }
211
  }
212
 
213
  function listAllFiles(dir) {