@playwright/mcp 0.0.36-alpha-2025-09-04 → 0.0.37-alpha-2025-09-08

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +81 -46
  2. package/cli.js +7 -1
  3. package/config.d.ts +24 -0
  4. package/index.js +1 -1
  5. package/package.json +14 -39
  6. package/lib/browser/browserContextFactory.js +0 -251
  7. package/lib/browser/browserServerBackend.js +0 -79
  8. package/lib/browser/codegen.js +0 -54
  9. package/lib/browser/config.js +0 -263
  10. package/lib/browser/context.js +0 -223
  11. package/lib/browser/response.js +0 -165
  12. package/lib/browser/sessionLog.js +0 -126
  13. package/lib/browser/tab.js +0 -251
  14. package/lib/browser/tools/common.js +0 -57
  15. package/lib/browser/tools/console.js +0 -35
  16. package/lib/browser/tools/dialogs.js +0 -49
  17. package/lib/browser/tools/evaluate.js +0 -88
  18. package/lib/browser/tools/files.js +0 -46
  19. package/lib/browser/tools/form.js +0 -92
  20. package/lib/browser/tools/install.js +0 -57
  21. package/lib/browser/tools/keyboard.js +0 -113
  22. package/lib/browser/tools/mouse.js +0 -101
  23. package/lib/browser/tools/navigate.js +0 -56
  24. package/lib/browser/tools/network.js +0 -43
  25. package/lib/browser/tools/pdf.js +0 -76
  26. package/lib/browser/tools/screenshot.js +0 -115
  27. package/lib/browser/tools/snapshot.js +0 -175
  28. package/lib/browser/tools/tabs.js +0 -61
  29. package/lib/browser/tools/tool.js +0 -37
  30. package/lib/browser/tools/utils.js +0 -79
  31. package/lib/browser/tools/verify.js +0 -172
  32. package/lib/browser/tools/wait.js +0 -57
  33. package/lib/browser/tools.js +0 -61
  34. package/lib/extension/cdpRelay.js +0 -395
  35. package/lib/extension/extensionContextFactory.js +0 -93
  36. package/lib/extension/protocol.js +0 -21
  37. package/lib/index.js +0 -75
  38. package/lib/log.js +0 -28
  39. package/lib/package.js +0 -24
  40. package/lib/program.js +0 -161
  41. package/lib/sdk/bundle.js +0 -79
  42. package/lib/sdk/http.js +0 -175
  43. package/lib/sdk/inProcessTransport.js +0 -67
  44. package/lib/sdk/manualPromise.js +0 -113
  45. package/lib/sdk/mdb.js +0 -237
  46. package/lib/sdk/proxyBackend.js +0 -141
  47. package/lib/sdk/server.js +0 -164
  48. package/lib/sdk/tool.js +0 -36
  49. package/lib/vscode/host.js +0 -199
  50. package/lib/vscode/main.js +0 -97
@@ -1,57 +0,0 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) Microsoft Corporation.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- const bundle_1 = require("../../sdk/bundle");
19
- const tool_1 = require("./tool");
20
- const wait = (0, tool_1.defineTool)({
21
- capability: 'core',
22
- schema: {
23
- name: 'browser_wait_for',
24
- title: 'Wait for',
25
- description: 'Wait for text to appear or disappear or a specified time to pass',
26
- inputSchema: bundle_1.z.object({
27
- time: bundle_1.z.number().optional().describe('The time to wait in seconds'),
28
- text: bundle_1.z.string().optional().describe('The text to wait for'),
29
- textGone: bundle_1.z.string().optional().describe('The text to wait for to disappear'),
30
- }),
31
- type: 'readOnly',
32
- },
33
- handle: async (context, params, response) => {
34
- if (!params.text && !params.textGone && !params.time)
35
- throw new Error('Either time, text or textGone must be provided');
36
- if (params.time) {
37
- response.addCode(`await new Promise(f => setTimeout(f, ${params.time} * 1000));`);
38
- await new Promise(f => setTimeout(f, Math.min(30000, params.time * 1000)));
39
- }
40
- const tab = context.currentTabOrDie();
41
- const locator = params.text ? tab.page.getByText(params.text).first() : undefined;
42
- const goneLocator = params.textGone ? tab.page.getByText(params.textGone).first() : undefined;
43
- if (goneLocator) {
44
- response.addCode(`await page.getByText(${JSON.stringify(params.textGone)}).first().waitFor({ state: 'hidden' });`);
45
- await goneLocator.waitFor({ state: 'hidden' });
46
- }
47
- if (locator) {
48
- response.addCode(`await page.getByText(${JSON.stringify(params.text)}).first().waitFor({ state: 'visible' });`);
49
- await locator.waitFor({ state: 'visible' });
50
- }
51
- response.addResult(`Waited for ${params.text || params.textGone || params.time}`);
52
- response.setIncludeSnapshot();
53
- },
54
- });
55
- exports.default = [
56
- wait,
57
- ];
@@ -1,61 +0,0 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) Microsoft Corporation.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
- var __importDefault = (this && this.__importDefault) || function (mod) {
18
- return (mod && mod.__esModule) ? mod : { "default": mod };
19
- };
20
- Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.allTools = void 0;
22
- exports.filteredTools = filteredTools;
23
- const common_1 = __importDefault(require("./tools/common"));
24
- const console_1 = __importDefault(require("./tools/console"));
25
- const dialogs_1 = __importDefault(require("./tools/dialogs"));
26
- const evaluate_1 = __importDefault(require("./tools/evaluate"));
27
- const files_1 = __importDefault(require("./tools/files"));
28
- const form_1 = __importDefault(require("./tools/form"));
29
- const install_1 = __importDefault(require("./tools/install"));
30
- const keyboard_1 = __importDefault(require("./tools/keyboard"));
31
- const mouse_1 = __importDefault(require("./tools/mouse"));
32
- const navigate_1 = __importDefault(require("./tools/navigate"));
33
- const network_1 = __importDefault(require("./tools/network"));
34
- const pdf_1 = __importDefault(require("./tools/pdf"));
35
- const snapshot_1 = __importDefault(require("./tools/snapshot"));
36
- const tabs_1 = __importDefault(require("./tools/tabs"));
37
- const screenshot_1 = __importDefault(require("./tools/screenshot"));
38
- const wait_1 = __importDefault(require("./tools/wait"));
39
- const verify_1 = __importDefault(require("./tools/verify"));
40
- exports.allTools = [
41
- ...common_1.default,
42
- ...console_1.default,
43
- ...dialogs_1.default,
44
- ...evaluate_1.default,
45
- ...files_1.default,
46
- ...form_1.default,
47
- ...install_1.default,
48
- ...keyboard_1.default,
49
- ...navigate_1.default,
50
- ...network_1.default,
51
- ...mouse_1.default,
52
- ...pdf_1.default,
53
- ...screenshot_1.default,
54
- ...snapshot_1.default,
55
- ...tabs_1.default,
56
- ...wait_1.default,
57
- ...verify_1.default,
58
- ];
59
- function filteredTools(config) {
60
- return exports.allTools.filter(tool => { var _a; return tool.capability.startsWith('core') || ((_a = config.capabilities) === null || _a === void 0 ? void 0 : _a.includes(tool.capability)); });
61
- }
@@ -1,395 +0,0 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) Microsoft Corporation.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
- if (k2 === undefined) k2 = k;
19
- var desc = Object.getOwnPropertyDescriptor(m, k);
20
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
- desc = { enumerable: true, get: function() { return m[k]; } };
22
- }
23
- Object.defineProperty(o, k2, desc);
24
- }) : (function(o, m, k, k2) {
25
- if (k2 === undefined) k2 = k;
26
- o[k2] = m[k];
27
- }));
28
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
- Object.defineProperty(o, "default", { enumerable: true, value: v });
30
- }) : function(o, v) {
31
- o["default"] = v;
32
- });
33
- var __importStar = (this && this.__importStar) || (function () {
34
- var ownKeys = function(o) {
35
- ownKeys = Object.getOwnPropertyNames || function (o) {
36
- var ar = [];
37
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
38
- return ar;
39
- };
40
- return ownKeys(o);
41
- };
42
- return function (mod) {
43
- if (mod && mod.__esModule) return mod;
44
- var result = {};
45
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
46
- __setModuleDefault(result, mod);
47
- return result;
48
- };
49
- })();
50
- var __importDefault = (this && this.__importDefault) || function (mod) {
51
- return (mod && mod.__esModule) ? mod : { "default": mod };
52
- };
53
- Object.defineProperty(exports, "__esModule", { value: true });
54
- exports.CDPRelayServer = void 0;
55
- /**
56
- * WebSocket server that bridges Playwright MCP and Chrome Extension
57
- *
58
- * Endpoints:
59
- * - /cdp/guid - Full CDP interface for Playwright MCP
60
- * - /extension/guid - Extension connection for chrome.debugger forwarding
61
- */
62
- const child_process_1 = require("child_process");
63
- const debug_1 = __importDefault(require("debug"));
64
- const ws_1 = require("ws");
65
- // @ts-ignore
66
- const index_1 = require("playwright-core/lib/server/registry/index");
67
- const http_1 = require("../sdk/http");
68
- const log_1 = require("../log");
69
- const manualPromise_1 = require("../sdk/manualPromise");
70
- const protocol = __importStar(require("./protocol"));
71
- const debugLogger = (0, debug_1.default)('pw:mcp:relay');
72
- class CDPRelayServer {
73
- constructor(server, browserChannel, userDataDir, executablePath) {
74
- this._playwrightConnection = null;
75
- this._extensionConnection = null;
76
- this._nextSessionId = 1;
77
- this._wsHost = (0, http_1.httpAddressToString)(server.address()).replace(/^http/, 'ws');
78
- this._browserChannel = browserChannel;
79
- this._userDataDir = userDataDir;
80
- this._executablePath = executablePath;
81
- const uuid = crypto.randomUUID();
82
- this._cdpPath = `/cdp/${uuid}`;
83
- this._extensionPath = `/extension/${uuid}`;
84
- this._resetExtensionConnection();
85
- this._wss = new ws_1.WebSocketServer({ server });
86
- this._wss.on('connection', this._onConnection.bind(this));
87
- }
88
- cdpEndpoint() {
89
- return `${this._wsHost}${this._cdpPath}`;
90
- }
91
- extensionEndpoint() {
92
- return `${this._wsHost}${this._extensionPath}`;
93
- }
94
- async ensureExtensionConnectionForMCPContext(clientInfo, abortSignal, toolName) {
95
- debugLogger('Ensuring extension connection for MCP context');
96
- if (this._extensionConnection)
97
- return;
98
- this._connectBrowser(clientInfo, toolName);
99
- debugLogger('Waiting for incoming extension connection');
100
- await Promise.race([
101
- this._extensionConnectionPromise,
102
- new Promise((_, reject) => setTimeout(() => {
103
- reject(new Error(`Extension connection timeout. Make sure the "Playwright MCP Bridge" extension is installed. See https://github.com/microsoft/playwright-mcp/blob/main/extension/README.md for installation instructions.`));
104
- }, process.env.PWMCP_TEST_CONNECTION_TIMEOUT ? parseInt(process.env.PWMCP_TEST_CONNECTION_TIMEOUT, 10) : 5000)),
105
- new Promise((_, reject) => abortSignal.addEventListener('abort', reject))
106
- ]);
107
- debugLogger('Extension connection established');
108
- }
109
- _connectBrowser(clientInfo, toolName) {
110
- var _a;
111
- const mcpRelayEndpoint = `${this._wsHost}${this._extensionPath}`;
112
- // Need to specify "key" in the manifest.json to make the id stable when loading from file.
113
- const url = new URL('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html');
114
- url.searchParams.set('mcpRelayUrl', mcpRelayEndpoint);
115
- const client = {
116
- name: clientInfo.name,
117
- version: clientInfo.version,
118
- };
119
- url.searchParams.set('client', JSON.stringify(client));
120
- url.searchParams.set('protocolVersion', (_a = process.env.PWMCP_TEST_PROTOCOL_VERSION) !== null && _a !== void 0 ? _a : protocol.VERSION.toString());
121
- if (toolName)
122
- url.searchParams.set('newTab', String(toolName === 'browser_navigate'));
123
- const href = url.toString();
124
- let executablePath = this._executablePath;
125
- if (!executablePath) {
126
- const executableInfo = index_1.registry.findExecutable(this._browserChannel);
127
- if (!executableInfo)
128
- throw new Error(`Unsupported channel: "${this._browserChannel}"`);
129
- executablePath = executableInfo.executablePath();
130
- if (!executablePath)
131
- throw new Error(`"${this._browserChannel}" executable not found. Make sure it is installed at a standard location.`);
132
- }
133
- const args = [];
134
- if (this._userDataDir)
135
- args.push(`--user-data-dir=${this._userDataDir}`);
136
- args.push(href);
137
- (0, child_process_1.spawn)(executablePath, args, {
138
- windowsHide: true,
139
- detached: true,
140
- shell: false,
141
- stdio: 'ignore',
142
- });
143
- }
144
- stop() {
145
- this.closeConnections('Server stopped');
146
- this._wss.close();
147
- }
148
- closeConnections(reason) {
149
- this._closePlaywrightConnection(reason);
150
- this._closeExtensionConnection(reason);
151
- }
152
- _onConnection(ws, request) {
153
- const url = new URL(`http://localhost${request.url}`);
154
- debugLogger(`New connection to ${url.pathname}`);
155
- if (url.pathname === this._cdpPath) {
156
- this._handlePlaywrightConnection(ws);
157
- }
158
- else if (url.pathname === this._extensionPath) {
159
- this._handleExtensionConnection(ws);
160
- }
161
- else {
162
- debugLogger(`Invalid path: ${url.pathname}`);
163
- ws.close(4004, 'Invalid path');
164
- }
165
- }
166
- _handlePlaywrightConnection(ws) {
167
- if (this._playwrightConnection) {
168
- debugLogger('Rejecting second Playwright connection');
169
- ws.close(1000, 'Another CDP client already connected');
170
- return;
171
- }
172
- this._playwrightConnection = ws;
173
- ws.on('message', async (data) => {
174
- try {
175
- const message = JSON.parse(data.toString());
176
- await this._handlePlaywrightMessage(message);
177
- }
178
- catch (error) {
179
- debugLogger(`Error while handling Playwright message\n${data.toString()}\n`, error);
180
- }
181
- });
182
- ws.on('close', () => {
183
- if (this._playwrightConnection !== ws)
184
- return;
185
- this._playwrightConnection = null;
186
- this._closeExtensionConnection('Playwright client disconnected');
187
- debugLogger('Playwright WebSocket closed');
188
- });
189
- ws.on('error', error => {
190
- debugLogger('Playwright WebSocket error:', error);
191
- });
192
- debugLogger('Playwright MCP connected');
193
- }
194
- _closeExtensionConnection(reason) {
195
- var _a;
196
- (_a = this._extensionConnection) === null || _a === void 0 ? void 0 : _a.close(reason);
197
- this._extensionConnectionPromise.reject(new Error(reason));
198
- this._resetExtensionConnection();
199
- }
200
- _resetExtensionConnection() {
201
- this._connectedTabInfo = undefined;
202
- this._extensionConnection = null;
203
- this._extensionConnectionPromise = new manualPromise_1.ManualPromise();
204
- void this._extensionConnectionPromise.catch(log_1.logUnhandledError);
205
- }
206
- _closePlaywrightConnection(reason) {
207
- var _a;
208
- if (((_a = this._playwrightConnection) === null || _a === void 0 ? void 0 : _a.readyState) === ws_1.WebSocket.OPEN)
209
- this._playwrightConnection.close(1000, reason);
210
- this._playwrightConnection = null;
211
- }
212
- _handleExtensionConnection(ws) {
213
- if (this._extensionConnection) {
214
- ws.close(1000, 'Another extension connection already established');
215
- return;
216
- }
217
- this._extensionConnection = new ExtensionConnection(ws);
218
- this._extensionConnection.onclose = (c, reason) => {
219
- debugLogger('Extension WebSocket closed:', reason, c === this._extensionConnection);
220
- if (this._extensionConnection !== c)
221
- return;
222
- this._resetExtensionConnection();
223
- this._closePlaywrightConnection(`Extension disconnected: ${reason}`);
224
- };
225
- this._extensionConnection.onmessage = this._handleExtensionMessage.bind(this);
226
- this._extensionConnectionPromise.resolve();
227
- }
228
- _handleExtensionMessage(method, params) {
229
- var _a;
230
- switch (method) {
231
- case 'forwardCDPEvent':
232
- const sessionId = params.sessionId || ((_a = this._connectedTabInfo) === null || _a === void 0 ? void 0 : _a.sessionId);
233
- this._sendToPlaywright({
234
- sessionId,
235
- method: params.method,
236
- params: params.params
237
- });
238
- break;
239
- }
240
- }
241
- async _handlePlaywrightMessage(message) {
242
- debugLogger('← Playwright:', `${message.method} (id=${message.id})`);
243
- const { id, sessionId, method, params } = message;
244
- try {
245
- const result = await this._handleCDPCommand(method, params, sessionId);
246
- this._sendToPlaywright({ id, sessionId, result });
247
- }
248
- catch (e) {
249
- debugLogger('Error in the extension:', e);
250
- this._sendToPlaywright({
251
- id,
252
- sessionId,
253
- error: { message: e.message }
254
- });
255
- }
256
- }
257
- async _handleCDPCommand(method, params, sessionId) {
258
- var _a;
259
- switch (method) {
260
- case 'Browser.getVersion': {
261
- return {
262
- protocolVersion: '1.3',
263
- product: 'Chrome/Extension-Bridge',
264
- userAgent: 'CDP-Bridge-Server/1.0.0',
265
- };
266
- }
267
- case 'Browser.setDownloadBehavior': {
268
- return {};
269
- }
270
- case 'Target.setAutoAttach': {
271
- // Forward child session handling.
272
- if (sessionId)
273
- break;
274
- // Simulate auto-attach behavior with real target info
275
- const { targetInfo } = await this._extensionConnection.send('attachToTab', {});
276
- this._connectedTabInfo = {
277
- targetInfo,
278
- sessionId: `pw-tab-${this._nextSessionId++}`,
279
- };
280
- debugLogger('Simulating auto-attach');
281
- this._sendToPlaywright({
282
- method: 'Target.attachedToTarget',
283
- params: {
284
- sessionId: this._connectedTabInfo.sessionId,
285
- targetInfo: {
286
- ...this._connectedTabInfo.targetInfo,
287
- attached: true,
288
- },
289
- waitingForDebugger: false
290
- }
291
- });
292
- return {};
293
- }
294
- case 'Target.getTargetInfo': {
295
- return (_a = this._connectedTabInfo) === null || _a === void 0 ? void 0 : _a.targetInfo;
296
- }
297
- }
298
- return await this._forwardToExtension(method, params, sessionId);
299
- }
300
- async _forwardToExtension(method, params, sessionId) {
301
- var _a;
302
- if (!this._extensionConnection)
303
- throw new Error('Extension not connected');
304
- // Top level sessionId is only passed between the relay and the client.
305
- if (((_a = this._connectedTabInfo) === null || _a === void 0 ? void 0 : _a.sessionId) === sessionId)
306
- sessionId = undefined;
307
- return await this._extensionConnection.send('forwardCDPCommand', { sessionId, method, params });
308
- }
309
- _sendToPlaywright(message) {
310
- var _a, _b;
311
- debugLogger('→ Playwright:', `${(_a = message.method) !== null && _a !== void 0 ? _a : `response(id=${message.id})`}`);
312
- (_b = this._playwrightConnection) === null || _b === void 0 ? void 0 : _b.send(JSON.stringify(message));
313
- }
314
- }
315
- exports.CDPRelayServer = CDPRelayServer;
316
- class ExtensionConnection {
317
- constructor(ws) {
318
- this._callbacks = new Map();
319
- this._lastId = 0;
320
- this._ws = ws;
321
- this._ws.on('message', this._onMessage.bind(this));
322
- this._ws.on('close', this._onClose.bind(this));
323
- this._ws.on('error', this._onError.bind(this));
324
- }
325
- async send(method, params) {
326
- if (this._ws.readyState !== ws_1.WebSocket.OPEN)
327
- throw new Error(`Unexpected WebSocket state: ${this._ws.readyState}`);
328
- const id = ++this._lastId;
329
- this._ws.send(JSON.stringify({ id, method, params }));
330
- const error = new Error(`Protocol error: ${method}`);
331
- return new Promise((resolve, reject) => {
332
- this._callbacks.set(id, { resolve, reject, error });
333
- });
334
- }
335
- close(message) {
336
- debugLogger('closing extension connection:', message);
337
- if (this._ws.readyState === ws_1.WebSocket.OPEN)
338
- this._ws.close(1000, message);
339
- }
340
- _onMessage(event) {
341
- const eventData = event.toString();
342
- let parsedJson;
343
- try {
344
- parsedJson = JSON.parse(eventData);
345
- }
346
- catch (e) {
347
- debugLogger(`<closing ws> Closing websocket due to malformed JSON. eventData=${eventData} e=${e === null || e === void 0 ? void 0 : e.message}`);
348
- this._ws.close();
349
- return;
350
- }
351
- try {
352
- this._handleParsedMessage(parsedJson);
353
- }
354
- catch (e) {
355
- debugLogger(`<closing ws> Closing websocket due to failed onmessage callback. eventData=${eventData} e=${e === null || e === void 0 ? void 0 : e.message}`);
356
- this._ws.close();
357
- }
358
- }
359
- _handleParsedMessage(object) {
360
- var _a;
361
- if (object.id && this._callbacks.has(object.id)) {
362
- const callback = this._callbacks.get(object.id);
363
- this._callbacks.delete(object.id);
364
- if (object.error) {
365
- const error = callback.error;
366
- error.message = object.error;
367
- callback.reject(error);
368
- }
369
- else {
370
- callback.resolve(object.result);
371
- }
372
- }
373
- else if (object.id) {
374
- debugLogger('← Extension: unexpected response', object);
375
- }
376
- else {
377
- (_a = this.onmessage) === null || _a === void 0 ? void 0 : _a.call(this, object.method, object.params);
378
- }
379
- }
380
- _onClose(event) {
381
- var _a;
382
- debugLogger(`<ws closed> code=${event.code} reason=${event.reason}`);
383
- this._dispose();
384
- (_a = this.onclose) === null || _a === void 0 ? void 0 : _a.call(this, this, event.reason);
385
- }
386
- _onError(event) {
387
- debugLogger(`<ws error> message=${event.message} type=${event.type} target=${event.target}`);
388
- this._dispose();
389
- }
390
- _dispose() {
391
- for (const callback of this._callbacks.values())
392
- callback.reject(new Error('WebSocket closed'));
393
- this._callbacks.clear();
394
- }
395
- }
@@ -1,93 +0,0 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) Microsoft Corporation.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
- if (k2 === undefined) k2 = k;
19
- var desc = Object.getOwnPropertyDescriptor(m, k);
20
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
- desc = { enumerable: true, get: function() { return m[k]; } };
22
- }
23
- Object.defineProperty(o, k2, desc);
24
- }) : (function(o, m, k, k2) {
25
- if (k2 === undefined) k2 = k;
26
- o[k2] = m[k];
27
- }));
28
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
- Object.defineProperty(o, "default", { enumerable: true, value: v });
30
- }) : function(o, v) {
31
- o["default"] = v;
32
- });
33
- var __importStar = (this && this.__importStar) || (function () {
34
- var ownKeys = function(o) {
35
- ownKeys = Object.getOwnPropertyNames || function (o) {
36
- var ar = [];
37
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
38
- return ar;
39
- };
40
- return ownKeys(o);
41
- };
42
- return function (mod) {
43
- if (mod && mod.__esModule) return mod;
44
- var result = {};
45
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
46
- __setModuleDefault(result, mod);
47
- return result;
48
- };
49
- })();
50
- var __importDefault = (this && this.__importDefault) || function (mod) {
51
- return (mod && mod.__esModule) ? mod : { "default": mod };
52
- };
53
- Object.defineProperty(exports, "__esModule", { value: true });
54
- exports.ExtensionContextFactory = void 0;
55
- const debug_1 = __importDefault(require("debug"));
56
- const playwright = __importStar(require("playwright"));
57
- const http_1 = require("../sdk/http");
58
- const cdpRelay_1 = require("./cdpRelay");
59
- const debugLogger = (0, debug_1.default)('pw:mcp:relay');
60
- class ExtensionContextFactory {
61
- constructor(browserChannel, userDataDir, executablePath) {
62
- this._browserChannel = browserChannel;
63
- this._userDataDir = userDataDir;
64
- this._executablePath = executablePath;
65
- }
66
- async createContext(clientInfo, abortSignal, toolName) {
67
- const browser = await this._obtainBrowser(clientInfo, abortSignal, toolName);
68
- return {
69
- browserContext: browser.contexts()[0],
70
- close: async () => {
71
- debugLogger('close() called for browser context');
72
- await browser.close();
73
- }
74
- };
75
- }
76
- async _obtainBrowser(clientInfo, abortSignal, toolName) {
77
- const relay = await this._startRelay(abortSignal);
78
- await relay.ensureExtensionConnectionForMCPContext(clientInfo, abortSignal, toolName);
79
- return await playwright.chromium.connectOverCDP(relay.cdpEndpoint());
80
- }
81
- async _startRelay(abortSignal) {
82
- const httpServer = await (0, http_1.startHttpServer)({});
83
- if (abortSignal.aborted) {
84
- httpServer.close();
85
- throw new Error(abortSignal.reason);
86
- }
87
- const cdpRelayServer = new cdpRelay_1.CDPRelayServer(httpServer, this._browserChannel, this._userDataDir, this._executablePath);
88
- abortSignal.addEventListener('abort', () => cdpRelayServer.stop());
89
- debugLogger(`CDP relay server started, extension endpoint: ${cdpRelayServer.extensionEndpoint()}.`);
90
- return cdpRelayServer;
91
- }
92
- }
93
- exports.ExtensionContextFactory = ExtensionContextFactory;
@@ -1,21 +0,0 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) Microsoft Corporation.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.VERSION = void 0;
19
- // Whenever the commands/events change, the version must be updated. The latest
20
- // extension version should be compatible with the old MCP clients.
21
- exports.VERSION = 1;