@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,113 +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.LongStandingScope = exports.ManualPromise = void 0;
19
- class ManualPromise extends Promise {
20
- constructor() {
21
- let resolve;
22
- let reject;
23
- super((f, r) => {
24
- resolve = f;
25
- reject = r;
26
- });
27
- this._isDone = false;
28
- this._resolve = resolve;
29
- this._reject = reject;
30
- }
31
- isDone() {
32
- return this._isDone;
33
- }
34
- resolve(t) {
35
- this._isDone = true;
36
- this._resolve(t);
37
- }
38
- reject(e) {
39
- this._isDone = true;
40
- this._reject(e);
41
- }
42
- static get [Symbol.species]() {
43
- return Promise;
44
- }
45
- get [Symbol.toStringTag]() {
46
- return 'ManualPromise';
47
- }
48
- }
49
- exports.ManualPromise = ManualPromise;
50
- class LongStandingScope {
51
- constructor() {
52
- this._terminatePromises = new Map();
53
- this._isClosed = false;
54
- }
55
- reject(error) {
56
- this._isClosed = true;
57
- this._terminateError = error;
58
- for (const p of this._terminatePromises.keys())
59
- p.resolve(error);
60
- }
61
- close(error) {
62
- this._isClosed = true;
63
- this._closeError = error;
64
- for (const [p, frames] of this._terminatePromises)
65
- p.resolve(cloneError(error, frames));
66
- }
67
- isClosed() {
68
- return this._isClosed;
69
- }
70
- static async raceMultiple(scopes, promise) {
71
- return Promise.race(scopes.map(s => s.race(promise)));
72
- }
73
- async race(promise) {
74
- return this._race(Array.isArray(promise) ? promise : [promise], false);
75
- }
76
- async safeRace(promise, defaultValue) {
77
- return this._race([promise], true, defaultValue);
78
- }
79
- async _race(promises, safe, defaultValue) {
80
- const terminatePromise = new ManualPromise();
81
- const frames = captureRawStack();
82
- if (this._terminateError)
83
- terminatePromise.resolve(this._terminateError);
84
- if (this._closeError)
85
- terminatePromise.resolve(cloneError(this._closeError, frames));
86
- this._terminatePromises.set(terminatePromise, frames);
87
- try {
88
- return await Promise.race([
89
- terminatePromise.then(e => safe ? defaultValue : Promise.reject(e)),
90
- ...promises
91
- ]);
92
- }
93
- finally {
94
- this._terminatePromises.delete(terminatePromise);
95
- }
96
- }
97
- }
98
- exports.LongStandingScope = LongStandingScope;
99
- function cloneError(error, frames) {
100
- const clone = new Error();
101
- clone.name = error.name;
102
- clone.message = error.message;
103
- clone.stack = [error.name + ':' + error.message, ...frames].join('\n');
104
- return clone;
105
- }
106
- function captureRawStack() {
107
- const stackTraceLimit = Error.stackTraceLimit;
108
- Error.stackTraceLimit = 50;
109
- const error = new Error();
110
- const stack = error.stack || '';
111
- Error.stackTraceLimit = stackTraceLimit;
112
- return stack.split('\n');
113
- }
package/lib/sdk/mdb.js DELETED
@@ -1,237 +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.MDBBackend = void 0;
55
- exports.runMainBackend = runMainBackend;
56
- exports.runOnPauseBackendLoop = runOnPauseBackendLoop;
57
- const debug_1 = __importDefault(require("debug"));
58
- const tool_1 = require("./tool");
59
- const mcpBundle = __importStar(require("./bundle"));
60
- const mcpServer = __importStar(require("./server"));
61
- const mcpHttp = __importStar(require("./http"));
62
- const server_1 = require("./server");
63
- const manualPromise_1 = require("./manualPromise");
64
- const mdbDebug = (0, debug_1.default)('pw:mcp:mdb');
65
- const errorsDebug = (0, debug_1.default)('pw:mcp:errors');
66
- const z = mcpBundle.z;
67
- class MDBBackend {
68
- constructor(topLevelBackend) {
69
- this._stack = [];
70
- this._initialized = false;
71
- this._topLevelBackend = topLevelBackend;
72
- }
73
- async initialize(server) {
74
- if (this._initialized)
75
- return;
76
- this._initialized = true;
77
- const transport = await (0, server_1.wrapInProcess)(this._topLevelBackend);
78
- await this._pushClient(transport);
79
- }
80
- async listTools() {
81
- const response = await this._client().listTools();
82
- return response.tools;
83
- }
84
- async callTool(name, args) {
85
- if (name === pushToolsSchema.name)
86
- return await this._pushTools(pushToolsSchema.inputSchema.parse(args || {}));
87
- const interruptPromise = new manualPromise_1.ManualPromise();
88
- this._interruptPromise = interruptPromise;
89
- let [entry] = this._stack;
90
- // Pop the client while the tool is not found.
91
- while (entry && !entry.toolNames.includes(name)) {
92
- mdbDebug('popping client from stack for ', name);
93
- this._stack.shift();
94
- await entry.client.close();
95
- entry = this._stack[0];
96
- }
97
- if (!entry)
98
- throw new Error(`Tool ${name} not found in the tool stack`);
99
- const resultPromise = new manualPromise_1.ManualPromise();
100
- entry.resultPromise = resultPromise;
101
- this._client().callTool({
102
- name,
103
- arguments: args,
104
- }).then(result => {
105
- resultPromise.resolve(result);
106
- }).catch(e => {
107
- mdbDebug('error in client call', e);
108
- if (this._stack.length < 2)
109
- throw e;
110
- this._stack.shift();
111
- const prevEntry = this._stack[0];
112
- void prevEntry.resultPromise.then(result => resultPromise.resolve(result));
113
- });
114
- const result = await Promise.race([interruptPromise, resultPromise]);
115
- if (interruptPromise.isDone())
116
- mdbDebug('client call intercepted', result);
117
- else
118
- mdbDebug('client call result', result);
119
- return result;
120
- }
121
- _client() {
122
- const [entry] = this._stack;
123
- if (!entry)
124
- throw new Error('No debugging backend available');
125
- return entry.client;
126
- }
127
- async _pushTools(params) {
128
- mdbDebug('pushing tools to the stack', params.mcpUrl);
129
- const transport = new mcpBundle.StreamableHTTPClientTransport(new URL(params.mcpUrl));
130
- await this._pushClient(transport, params.introMessage);
131
- return { content: [{ type: 'text', text: 'Tools pushed' }] };
132
- }
133
- async _pushClient(transport, introMessage) {
134
- var _a;
135
- mdbDebug('pushing client to the stack');
136
- const client = new mcpBundle.Client({ name: 'Internal client', version: '0.0.0' });
137
- client.setRequestHandler(mcpBundle.PingRequestSchema, () => ({}));
138
- await client.connect(transport);
139
- mdbDebug('connected to the new client');
140
- const { tools } = await client.listTools();
141
- this._stack.unshift({ client, toolNames: tools.map(tool => tool.name), resultPromise: undefined });
142
- mdbDebug('new tools added to the stack:', tools.map(tool => tool.name));
143
- mdbDebug('interrupting current call:', !!this._interruptPromise);
144
- (_a = this._interruptPromise) === null || _a === void 0 ? void 0 : _a.resolve({
145
- content: [{
146
- type: 'text',
147
- text: introMessage || '',
148
- }],
149
- });
150
- this._interruptPromise = undefined;
151
- return { content: [{ type: 'text', text: 'Tools pushed' }] };
152
- }
153
- }
154
- exports.MDBBackend = MDBBackend;
155
- const pushToolsSchema = (0, tool_1.defineToolSchema)({
156
- name: 'mdb_push_tools',
157
- title: 'Push MCP tools to the tools stack',
158
- description: 'Push MCP tools to the tools stack',
159
- inputSchema: z.object({
160
- mcpUrl: z.string(),
161
- introMessage: z.string().optional(),
162
- }),
163
- type: 'readOnly',
164
- });
165
- async function runMainBackend(backendFactory, options) {
166
- const mdbBackend = new MDBBackend(backendFactory.create());
167
- // Start HTTP unconditionally.
168
- const factory = {
169
- ...backendFactory,
170
- create: () => mdbBackend
171
- };
172
- const url = await startAsHttp(factory, { port: (options === null || options === void 0 ? void 0 : options.port) || 0 });
173
- process.env.PLAYWRIGHT_DEBUGGER_MCP = url;
174
- if ((options === null || options === void 0 ? void 0 : options.port) !== undefined)
175
- return url;
176
- // Start stdio conditionally.
177
- await mcpServer.connect(factory, new mcpBundle.StdioServerTransport(), false);
178
- }
179
- async function runOnPauseBackendLoop(mdbUrl, backend, introMessage) {
180
- const wrappedBackend = new OnceTimeServerBackendWrapper(backend);
181
- const factory = {
182
- name: 'on-pause-backend',
183
- nameInConfig: 'on-pause-backend',
184
- version: '0.0.0',
185
- create: () => wrappedBackend,
186
- };
187
- const httpServer = await mcpHttp.startHttpServer({ port: 0 });
188
- await mcpHttp.installHttpTransport(httpServer, factory);
189
- const url = mcpHttp.httpAddressToString(httpServer.address());
190
- const client = new mcpBundle.Client({ name: 'Internal client', version: '0.0.0' });
191
- client.setRequestHandler(mcpBundle.PingRequestSchema, () => ({}));
192
- const transport = new mcpBundle.StreamableHTTPClientTransport(new URL(mdbUrl));
193
- await client.connect(transport);
194
- const pushToolsResult = await client.callTool({
195
- name: pushToolsSchema.name,
196
- arguments: {
197
- mcpUrl: url,
198
- introMessage,
199
- },
200
- });
201
- if (pushToolsResult.isError)
202
- errorsDebug('Failed to push tools', pushToolsResult.content);
203
- await transport.terminateSession();
204
- await client.close();
205
- await wrappedBackend.waitForClosed();
206
- httpServer.close();
207
- }
208
- async function startAsHttp(backendFactory, options) {
209
- const httpServer = await mcpHttp.startHttpServer(options);
210
- await mcpHttp.installHttpTransport(httpServer, backendFactory);
211
- return mcpHttp.httpAddressToString(httpServer.address());
212
- }
213
- class OnceTimeServerBackendWrapper {
214
- constructor(backend) {
215
- this._selfDestructPromise = new manualPromise_1.ManualPromise();
216
- this._backend = backend;
217
- this._backend.requestSelfDestruct = () => this._selfDestructPromise.resolve();
218
- }
219
- async initialize(server, clientVersion, roots) {
220
- var _a, _b;
221
- await ((_b = (_a = this._backend).initialize) === null || _b === void 0 ? void 0 : _b.call(_a, server, clientVersion, roots));
222
- }
223
- async listTools() {
224
- return this._backend.listTools();
225
- }
226
- async callTool(name, args) {
227
- return this._backend.callTool(name, args);
228
- }
229
- serverClosed(server) {
230
- var _a, _b;
231
- (_b = (_a = this._backend).serverClosed) === null || _b === void 0 ? void 0 : _b.call(_a, server);
232
- this._selfDestructPromise.resolve();
233
- }
234
- async waitForClosed() {
235
- await this._selfDestructPromise;
236
- }
237
- }
@@ -1,141 +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.ProxyBackend = void 0;
55
- const debug_1 = __importDefault(require("debug"));
56
- const mcpBundle = __importStar(require("./bundle"));
57
- const errorsDebug = (0, debug_1.default)('pw:mcp:errors');
58
- const { z, zodToJsonSchema } = mcpBundle;
59
- class ProxyBackend {
60
- constructor(mcpProviders) {
61
- this._roots = [];
62
- this._mcpProviders = mcpProviders;
63
- this._contextSwitchTool = this._defineContextSwitchTool();
64
- }
65
- async initialize(server, clientVersion, roots) {
66
- this._roots = roots;
67
- await this._setCurrentClient(this._mcpProviders[0]);
68
- }
69
- async listTools() {
70
- const response = await this._currentClient.listTools();
71
- if (this._mcpProviders.length === 1)
72
- return response.tools;
73
- return [
74
- ...response.tools,
75
- this._contextSwitchTool,
76
- ];
77
- }
78
- async callTool(name, args) {
79
- if (name === this._contextSwitchTool.name)
80
- return this._callContextSwitchTool(args);
81
- return await this._currentClient.callTool({
82
- name,
83
- arguments: args,
84
- });
85
- }
86
- serverClosed() {
87
- var _a;
88
- void ((_a = this._currentClient) === null || _a === void 0 ? void 0 : _a.close().catch(errorsDebug));
89
- }
90
- async _callContextSwitchTool(params) {
91
- try {
92
- const factory = this._mcpProviders.find(factory => factory.name === params.name);
93
- if (!factory)
94
- throw new Error('Unknown connection method: ' + params.name);
95
- await this._setCurrentClient(factory);
96
- return {
97
- content: [{ type: 'text', text: '### Result\nSuccessfully changed connection method.\n' }],
98
- };
99
- }
100
- catch (error) {
101
- return {
102
- content: [{ type: 'text', text: `### Result\nError: ${error}\n` }],
103
- isError: true,
104
- };
105
- }
106
- }
107
- _defineContextSwitchTool() {
108
- return {
109
- name: 'browser_connect',
110
- description: [
111
- 'Connect to a browser using one of the available methods:',
112
- ...this._mcpProviders.map(factory => `- "${factory.name}": ${factory.description}`),
113
- ].join('\n'),
114
- inputSchema: zodToJsonSchema(z.object({
115
- name: z.enum(this._mcpProviders.map(factory => factory.name)).default(this._mcpProviders[0].name).describe('The method to use to connect to the browser'),
116
- }), { strictUnions: true }),
117
- annotations: {
118
- title: 'Connect to a browser context',
119
- readOnlyHint: true,
120
- openWorldHint: false,
121
- },
122
- };
123
- }
124
- async _setCurrentClient(factory) {
125
- var _a;
126
- await ((_a = this._currentClient) === null || _a === void 0 ? void 0 : _a.close());
127
- this._currentClient = undefined;
128
- const client = new mcpBundle.Client({ name: 'Playwright MCP Proxy', version: '0.0.0' });
129
- client.registerCapabilities({
130
- roots: {
131
- listRoots: true,
132
- },
133
- });
134
- client.setRequestHandler(mcpBundle.ListRootsRequestSchema, () => ({ roots: this._roots }));
135
- client.setRequestHandler(mcpBundle.PingRequestSchema, () => ({}));
136
- const transport = await factory.connect();
137
- await client.connect(transport);
138
- this._currentClient = client;
139
- }
140
- }
141
- exports.ProxyBackend = ProxyBackend;
package/lib/sdk/server.js DELETED
@@ -1,164 +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.connect = connect;
55
- exports.wrapInProcess = wrapInProcess;
56
- exports.createServer = createServer;
57
- exports.start = start;
58
- const debug_1 = __importDefault(require("debug"));
59
- const mcpBundle = __importStar(require("./bundle"));
60
- const http_1 = require("./http");
61
- const inProcessTransport_1 = require("./inProcessTransport");
62
- const serverDebug = (0, debug_1.default)('pw:mcp:server');
63
- const errorsDebug = (0, debug_1.default)('pw:mcp:errors');
64
- async function connect(factory, transport, runHeartbeat) {
65
- const server = createServer(factory.name, factory.version, factory.create(), runHeartbeat);
66
- await server.connect(transport);
67
- }
68
- async function wrapInProcess(backend) {
69
- const server = createServer('Internal', '0.0.0', backend, false);
70
- return new inProcessTransport_1.InProcessTransport(server);
71
- }
72
- function createServer(name, version, backend, runHeartbeat) {
73
- let initializedPromiseResolve = () => { };
74
- const initializedPromise = new Promise(resolve => initializedPromiseResolve = resolve);
75
- const server = new mcpBundle.Server({ name, version }, {
76
- capabilities: {
77
- tools: {},
78
- }
79
- });
80
- server.setRequestHandler(mcpBundle.ListToolsRequestSchema, async () => {
81
- serverDebug('listTools');
82
- await initializedPromise;
83
- const tools = await backend.listTools();
84
- return { tools };
85
- });
86
- let heartbeatRunning = false;
87
- server.setRequestHandler(mcpBundle.CallToolRequestSchema, async (request) => {
88
- serverDebug('callTool', request);
89
- await initializedPromise;
90
- if (runHeartbeat && !heartbeatRunning) {
91
- heartbeatRunning = true;
92
- startHeartbeat(server);
93
- }
94
- try {
95
- return await backend.callTool(request.params.name, request.params.arguments || {});
96
- }
97
- catch (error) {
98
- return {
99
- content: [{ type: 'text', text: '### Result\n' + String(error) }],
100
- isError: true,
101
- };
102
- }
103
- });
104
- addServerListener(server, 'initialized', async () => {
105
- var _a, _b;
106
- try {
107
- const capabilities = server.getClientCapabilities();
108
- let clientRoots = [];
109
- if (capabilities === null || capabilities === void 0 ? void 0 : capabilities.roots) {
110
- const { roots } = await server.listRoots(undefined, { timeout: 2000 }).catch(() => ({ roots: [] }));
111
- clientRoots = roots;
112
- }
113
- const clientVersion = (_a = server.getClientVersion()) !== null && _a !== void 0 ? _a : { name: 'unknown', version: 'unknown' };
114
- await ((_b = backend.initialize) === null || _b === void 0 ? void 0 : _b.call(backend, server, clientVersion, clientRoots));
115
- initializedPromiseResolve();
116
- }
117
- catch (e) {
118
- errorsDebug(e);
119
- }
120
- });
121
- addServerListener(server, 'close', () => { var _a; return (_a = backend.serverClosed) === null || _a === void 0 ? void 0 : _a.call(backend, server); });
122
- return server;
123
- }
124
- const startHeartbeat = (server) => {
125
- const beat = () => {
126
- Promise.race([
127
- server.ping(),
128
- new Promise((_, reject) => setTimeout(() => reject(new Error('ping timeout')), 5000)),
129
- ]).then(() => {
130
- setTimeout(beat, 3000);
131
- }).catch(() => {
132
- void server.close();
133
- });
134
- };
135
- beat();
136
- };
137
- function addServerListener(server, event, listener) {
138
- const oldListener = server[`on${event}`];
139
- server[`on${event}`] = () => {
140
- oldListener === null || oldListener === void 0 ? void 0 : oldListener();
141
- listener();
142
- };
143
- }
144
- async function start(serverBackendFactory, options) {
145
- if (options.port === undefined) {
146
- await connect(serverBackendFactory, new mcpBundle.StdioServerTransport(), false);
147
- return;
148
- }
149
- const httpServer = await (0, http_1.startHttpServer)(options);
150
- await (0, http_1.installHttpTransport)(httpServer, serverBackendFactory);
151
- const url = (0, http_1.httpAddressToString)(httpServer.address());
152
- const mcpConfig = { mcpServers: {} };
153
- mcpConfig.mcpServers[serverBackendFactory.nameInConfig] = {
154
- url: `${url}/mcp`
155
- };
156
- const message = [
157
- `Listening on ${url}`,
158
- 'Put this in your client config:',
159
- JSON.stringify(mcpConfig, undefined, 2),
160
- 'For legacy SSE transport support, you can use the /sse endpoint instead.',
161
- ].join('\n');
162
- // eslint-disable-next-line no-console
163
- console.error(message);
164
- }
package/lib/sdk/tool.js DELETED
@@ -1,36 +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.toMcpTool = toMcpTool;
19
- exports.defineToolSchema = defineToolSchema;
20
- const bundle_1 = require("../sdk/bundle");
21
- function toMcpTool(tool) {
22
- return {
23
- name: tool.name,
24
- description: tool.description,
25
- inputSchema: (0, bundle_1.zodToJsonSchema)(tool.inputSchema, { strictUnions: true }),
26
- annotations: {
27
- title: tool.title,
28
- readOnlyHint: tool.type === 'readOnly',
29
- destructiveHint: tool.type === 'destructive',
30
- openWorldHint: true,
31
- },
32
- };
33
- }
34
- function defineToolSchema(tool) {
35
- return tool;
36
- }