mcp-accessibility-scanner 1.1.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browserContextFactory.js +212 -0
- package/lib/browserContextFactory.js.map +1 -0
- package/lib/browserServerBackend.js +78 -0
- package/lib/browserServerBackend.js.map +1 -0
- package/lib/config.js +247 -0
- package/lib/config.js.map +1 -0
- package/lib/context.js +227 -0
- package/lib/context.js.map +1 -0
- package/lib/extension/cdpRelay.js +359 -0
- package/lib/extension/cdpRelay.js.map +1 -0
- package/lib/extension/extensionContextFactory.js +57 -0
- package/lib/extension/extensionContextFactory.js.map +1 -0
- package/lib/extension/protocol.js +19 -0
- package/lib/extension/protocol.js.map +1 -0
- package/lib/index.js +41 -0
- package/lib/index.js.map +1 -0
- package/lib/mcp/http.js +136 -0
- package/lib/mcp/http.js.map +1 -0
- package/lib/mcp/inProcessTransport.js +73 -0
- package/lib/mcp/inProcessTransport.js.map +1 -0
- package/lib/mcp/manualPromise.js +112 -0
- package/lib/mcp/manualPromise.js.map +1 -0
- package/lib/mcp/mdb.js +199 -0
- package/lib/mcp/mdb.js.map +1 -0
- package/lib/mcp/proxyBackend.js +105 -0
- package/lib/mcp/proxyBackend.js.map +1 -0
- package/lib/mcp/server.js +124 -0
- package/lib/mcp/server.js.map +1 -0
- package/lib/mcp/tool.js +33 -0
- package/lib/mcp/tool.js.map +1 -0
- package/lib/program.js +127 -0
- package/lib/program.js.map +1 -0
- package/lib/response.js +166 -0
- package/lib/response.js.map +1 -0
- package/lib/sessionLog.js +122 -0
- package/lib/sessionLog.js.map +1 -0
- package/lib/tab.js +250 -0
- package/lib/tab.js.map +1 -0
- package/lib/tools/common.js +56 -0
- package/lib/tools/common.js.map +1 -0
- package/lib/tools/console.js +34 -0
- package/lib/tools/console.js.map +1 -0
- package/lib/tools/dialogs.js +48 -0
- package/lib/tools/dialogs.js.map +1 -0
- package/lib/tools/evaluate.js +54 -0
- package/lib/tools/evaluate.js.map +1 -0
- package/lib/tools/files.js +45 -0
- package/lib/tools/files.js.map +1 -0
- package/lib/tools/form.js +58 -0
- package/lib/tools/form.js.map +1 -0
- package/lib/tools/install.js +54 -0
- package/lib/tools/install.js.map +1 -0
- package/lib/tools/keyboard.js +79 -0
- package/lib/tools/keyboard.js.map +1 -0
- package/lib/tools/mouse.js +100 -0
- package/lib/tools/mouse.js.map +1 -0
- package/lib/tools/navigate.js +55 -0
- package/lib/tools/navigate.js.map +1 -0
- package/lib/tools/network.js +42 -0
- package/lib/tools/network.js.map +1 -0
- package/lib/tools/pdf.js +41 -0
- package/lib/tools/pdf.js.map +1 -0
- package/lib/tools/screenshot.js +80 -0
- package/lib/tools/screenshot.js.map +1 -0
- package/lib/tools/snapshot.js +194 -0
- package/lib/tools/snapshot.js.map +1 -0
- package/lib/tools/tabs.js +60 -0
- package/lib/tools/tabs.js.map +1 -0
- package/lib/tools/tool.js +34 -0
- package/lib/tools/tool.js.map +1 -0
- package/lib/tools/utils.js +75 -0
- package/lib/tools/utils.js.map +1 -0
- package/lib/tools/verify.js +138 -0
- package/lib/tools/verify.js.map +1 -0
- package/lib/tools/wait.js +56 -0
- package/lib/tools/wait.js.map +1 -0
- package/lib/tools.js +55 -0
- package/lib/tools.js.map +1 -0
- package/lib/utils/codegen.js +50 -0
- package/lib/utils/codegen.js.map +1 -0
- package/lib/utils/fileUtils.js +37 -0
- package/lib/utils/fileUtils.js.map +1 -0
- package/lib/utils/guid.js +23 -0
- package/lib/utils/guid.js.map +1 -0
- package/lib/utils/log.js +22 -0
- package/lib/utils/log.js.map +1 -0
- package/lib/utils/package.js +21 -0
- package/lib/utils/package.js.map +1 -0
- package/lib/vscode/host.js +129 -0
- package/lib/vscode/host.js.map +1 -0
- package/lib/vscode/main.js +63 -0
- package/lib/vscode/main.js.map +1 -0
- package/package.json +19 -19
package/lib/mcp/mdb.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
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
|
+
import debug from 'debug';
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
19
|
+
import { PingRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
20
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
21
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
22
|
+
import { defineToolSchema } from './tool.js';
|
|
23
|
+
import * as mcpServer from './server.js';
|
|
24
|
+
import * as mcpHttp from './http.js';
|
|
25
|
+
import { wrapInProcess } from './server.js';
|
|
26
|
+
import { ManualPromise } from './manualPromise.js';
|
|
27
|
+
const mdbDebug = debug('pw:mcp:mdb');
|
|
28
|
+
const errorsDebug = debug('pw:mcp:errors');
|
|
29
|
+
export class MDBBackend {
|
|
30
|
+
_stack = [];
|
|
31
|
+
_interruptPromise;
|
|
32
|
+
_topLevelBackend;
|
|
33
|
+
_initialized = false;
|
|
34
|
+
constructor(topLevelBackend) {
|
|
35
|
+
this._topLevelBackend = topLevelBackend;
|
|
36
|
+
}
|
|
37
|
+
async initialize(server) {
|
|
38
|
+
if (this._initialized)
|
|
39
|
+
return;
|
|
40
|
+
this._initialized = true;
|
|
41
|
+
const transport = await wrapInProcess(this._topLevelBackend);
|
|
42
|
+
await this._pushClient(transport);
|
|
43
|
+
}
|
|
44
|
+
async listTools() {
|
|
45
|
+
const response = await this._client().listTools();
|
|
46
|
+
return response.tools;
|
|
47
|
+
}
|
|
48
|
+
async callTool(name, args) {
|
|
49
|
+
if (name === pushToolsSchema.name)
|
|
50
|
+
return await this._pushTools(pushToolsSchema.inputSchema.parse(args || {}));
|
|
51
|
+
const interruptPromise = new ManualPromise();
|
|
52
|
+
this._interruptPromise = interruptPromise;
|
|
53
|
+
let [entry] = this._stack;
|
|
54
|
+
// Pop the client while the tool is not found.
|
|
55
|
+
while (entry && !entry.toolNames.includes(name)) {
|
|
56
|
+
mdbDebug('popping client from stack for ', name);
|
|
57
|
+
this._stack.shift();
|
|
58
|
+
await entry.client.close();
|
|
59
|
+
entry = this._stack[0];
|
|
60
|
+
}
|
|
61
|
+
if (!entry)
|
|
62
|
+
throw new Error(`Tool ${name} not found in the tool stack`);
|
|
63
|
+
const resultPromise = new ManualPromise();
|
|
64
|
+
entry.resultPromise = resultPromise;
|
|
65
|
+
this._client().callTool({
|
|
66
|
+
name,
|
|
67
|
+
arguments: args,
|
|
68
|
+
}).then(result => {
|
|
69
|
+
resultPromise.resolve(result);
|
|
70
|
+
}).catch(e => {
|
|
71
|
+
mdbDebug('error in client call', e);
|
|
72
|
+
if (this._stack.length < 2)
|
|
73
|
+
throw e;
|
|
74
|
+
this._stack.shift();
|
|
75
|
+
const prevEntry = this._stack[0];
|
|
76
|
+
void prevEntry.resultPromise.then(result => resultPromise.resolve(result));
|
|
77
|
+
});
|
|
78
|
+
const result = await Promise.race([interruptPromise, resultPromise]);
|
|
79
|
+
if (interruptPromise.isDone())
|
|
80
|
+
mdbDebug('client call intercepted', result);
|
|
81
|
+
else
|
|
82
|
+
mdbDebug('client call result', result);
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
_client() {
|
|
86
|
+
const [entry] = this._stack;
|
|
87
|
+
if (!entry)
|
|
88
|
+
throw new Error('No debugging backend available');
|
|
89
|
+
return entry.client;
|
|
90
|
+
}
|
|
91
|
+
async _pushTools(params) {
|
|
92
|
+
mdbDebug('pushing tools to the stack', params.mcpUrl);
|
|
93
|
+
const transport = new StreamableHTTPClientTransport(new URL(params.mcpUrl));
|
|
94
|
+
await this._pushClient(transport, params.introMessage);
|
|
95
|
+
return { content: [{ type: 'text', text: 'Tools pushed' }] };
|
|
96
|
+
}
|
|
97
|
+
async _pushClient(transport, introMessage) {
|
|
98
|
+
mdbDebug('pushing client to the stack');
|
|
99
|
+
const client = new Client({ name: 'Internal client', version: '0.0.0' });
|
|
100
|
+
client.setRequestHandler(PingRequestSchema, () => ({}));
|
|
101
|
+
await client.connect(transport);
|
|
102
|
+
mdbDebug('connected to the new client');
|
|
103
|
+
const { tools } = await client.listTools();
|
|
104
|
+
this._stack.unshift({ client, toolNames: tools.map(tool => tool.name), resultPromise: undefined });
|
|
105
|
+
mdbDebug('new tools added to the stack:', tools.map(tool => tool.name));
|
|
106
|
+
mdbDebug('interrupting current call:', !!this._interruptPromise);
|
|
107
|
+
this._interruptPromise?.resolve({
|
|
108
|
+
content: [{
|
|
109
|
+
type: 'text',
|
|
110
|
+
text: introMessage || '',
|
|
111
|
+
}],
|
|
112
|
+
});
|
|
113
|
+
this._interruptPromise = undefined;
|
|
114
|
+
return { content: [{ type: 'text', text: 'Tools pushed' }] };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const pushToolsSchema = defineToolSchema({
|
|
118
|
+
name: 'mdb_push_tools',
|
|
119
|
+
title: 'Push MCP tools to the tools stack',
|
|
120
|
+
description: 'Push MCP tools to the tools stack',
|
|
121
|
+
inputSchema: z.object({
|
|
122
|
+
mcpUrl: z.string(),
|
|
123
|
+
introMessage: z.string().optional(),
|
|
124
|
+
}),
|
|
125
|
+
type: 'readOnly',
|
|
126
|
+
});
|
|
127
|
+
export async function runMainBackend(backendFactory, options) {
|
|
128
|
+
const mdbBackend = new MDBBackend(backendFactory.create());
|
|
129
|
+
// Start HTTP unconditionally.
|
|
130
|
+
const factory = {
|
|
131
|
+
...backendFactory,
|
|
132
|
+
create: () => mdbBackend
|
|
133
|
+
};
|
|
134
|
+
const url = await startAsHttp(factory, { port: options?.port || 0 });
|
|
135
|
+
process.env.PLAYWRIGHT_DEBUGGER_MCP = url;
|
|
136
|
+
if (options?.port !== undefined)
|
|
137
|
+
return url;
|
|
138
|
+
// Start stdio conditionally.
|
|
139
|
+
await mcpServer.connect(factory, new StdioServerTransport(), false);
|
|
140
|
+
}
|
|
141
|
+
export async function runOnPauseBackendLoop(mdbUrl, backend, introMessage) {
|
|
142
|
+
const wrappedBackend = new OnceTimeServerBackendWrapper(backend);
|
|
143
|
+
const factory = {
|
|
144
|
+
name: 'on-pause-backend',
|
|
145
|
+
nameInConfig: 'on-pause-backend',
|
|
146
|
+
version: '0.0.0',
|
|
147
|
+
create: () => wrappedBackend,
|
|
148
|
+
};
|
|
149
|
+
const httpServer = await mcpHttp.startHttpServer({ port: 0 });
|
|
150
|
+
await mcpHttp.installHttpTransport(httpServer, factory);
|
|
151
|
+
const url = mcpHttp.httpAddressToString(httpServer.address());
|
|
152
|
+
const client = new Client({ name: 'Internal client', version: '0.0.0' });
|
|
153
|
+
client.setRequestHandler(PingRequestSchema, () => ({}));
|
|
154
|
+
const transport = new StreamableHTTPClientTransport(new URL(mdbUrl));
|
|
155
|
+
await client.connect(transport);
|
|
156
|
+
const pushToolsResult = await client.callTool({
|
|
157
|
+
name: pushToolsSchema.name,
|
|
158
|
+
arguments: {
|
|
159
|
+
mcpUrl: url,
|
|
160
|
+
introMessage,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
if (pushToolsResult.isError)
|
|
164
|
+
errorsDebug('Failed to push tools', pushToolsResult.content);
|
|
165
|
+
await transport.terminateSession();
|
|
166
|
+
await client.close();
|
|
167
|
+
await wrappedBackend.waitForClosed();
|
|
168
|
+
httpServer.close();
|
|
169
|
+
}
|
|
170
|
+
async function startAsHttp(backendFactory, options) {
|
|
171
|
+
const httpServer = await mcpHttp.startHttpServer(options);
|
|
172
|
+
await mcpHttp.installHttpTransport(httpServer, backendFactory);
|
|
173
|
+
return mcpHttp.httpAddressToString(httpServer.address());
|
|
174
|
+
}
|
|
175
|
+
class OnceTimeServerBackendWrapper {
|
|
176
|
+
_backend;
|
|
177
|
+
_selfDestructPromise = new ManualPromise();
|
|
178
|
+
constructor(backend) {
|
|
179
|
+
this._backend = backend;
|
|
180
|
+
this._backend.requestSelfDestruct = () => this._selfDestructPromise.resolve();
|
|
181
|
+
}
|
|
182
|
+
async initialize(server, clientVersion, roots) {
|
|
183
|
+
await this._backend.initialize?.(server, clientVersion, roots);
|
|
184
|
+
}
|
|
185
|
+
async listTools() {
|
|
186
|
+
return this._backend.listTools();
|
|
187
|
+
}
|
|
188
|
+
async callTool(name, args) {
|
|
189
|
+
return this._backend.callTool(name, args);
|
|
190
|
+
}
|
|
191
|
+
serverClosed(server) {
|
|
192
|
+
this._backend.serverClosed?.(server);
|
|
193
|
+
this._selfDestructPromise.resolve();
|
|
194
|
+
}
|
|
195
|
+
async waitForClosed() {
|
|
196
|
+
await this._selfDestructPromise;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=mdb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mdb.js","sourceRoot":"","sources":["../../src/mcp/mdb.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
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
|
+
import debug from 'debug';
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
19
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
20
|
+
import { ListRootsRequestSchema, PingRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
21
|
+
const errorsDebug = debug('pw:mcp:errors');
|
|
22
|
+
export class ProxyBackend {
|
|
23
|
+
_mcpProviders;
|
|
24
|
+
_currentClient;
|
|
25
|
+
_contextSwitchTool;
|
|
26
|
+
_roots = [];
|
|
27
|
+
constructor(mcpProviders) {
|
|
28
|
+
this._mcpProviders = mcpProviders;
|
|
29
|
+
this._contextSwitchTool = this._defineContextSwitchTool();
|
|
30
|
+
}
|
|
31
|
+
async initialize(server, clientVersion, roots) {
|
|
32
|
+
this._roots = roots;
|
|
33
|
+
await this._setCurrentClient(this._mcpProviders[0]);
|
|
34
|
+
}
|
|
35
|
+
async listTools() {
|
|
36
|
+
const response = await this._currentClient.listTools();
|
|
37
|
+
if (this._mcpProviders.length === 1)
|
|
38
|
+
return response.tools;
|
|
39
|
+
return [
|
|
40
|
+
...response.tools,
|
|
41
|
+
this._contextSwitchTool,
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
async callTool(name, args) {
|
|
45
|
+
if (name === this._contextSwitchTool.name)
|
|
46
|
+
return this._callContextSwitchTool(args);
|
|
47
|
+
return await this._currentClient.callTool({
|
|
48
|
+
name,
|
|
49
|
+
arguments: args,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
serverClosed() {
|
|
53
|
+
void this._currentClient?.close().catch(errorsDebug);
|
|
54
|
+
}
|
|
55
|
+
async _callContextSwitchTool(params) {
|
|
56
|
+
try {
|
|
57
|
+
const factory = this._mcpProviders.find(factory => factory.name === params.name);
|
|
58
|
+
if (!factory)
|
|
59
|
+
throw new Error('Unknown connection method: ' + params.name);
|
|
60
|
+
await this._setCurrentClient(factory);
|
|
61
|
+
return {
|
|
62
|
+
content: [{ type: 'text', text: '### Result\nSuccessfully changed connection method.\n' }],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
return {
|
|
67
|
+
content: [{ type: 'text', text: `### Result\nError: ${error}\n` }],
|
|
68
|
+
isError: true,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
_defineContextSwitchTool() {
|
|
73
|
+
return {
|
|
74
|
+
name: 'browser_connect',
|
|
75
|
+
description: [
|
|
76
|
+
'Connect to a browser using one of the available methods:',
|
|
77
|
+
...this._mcpProviders.map(factory => `- "${factory.name}": ${factory.description}`),
|
|
78
|
+
].join('\n'),
|
|
79
|
+
inputSchema: zodToJsonSchema(z.object({
|
|
80
|
+
name: z.enum(this._mcpProviders.map(factory => factory.name)).default(this._mcpProviders[0].name).describe('The method to use to connect to the browser'),
|
|
81
|
+
}), { strictUnions: true }),
|
|
82
|
+
annotations: {
|
|
83
|
+
title: 'Connect to a browser context',
|
|
84
|
+
readOnlyHint: true,
|
|
85
|
+
openWorldHint: false,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
async _setCurrentClient(factory) {
|
|
90
|
+
await this._currentClient?.close();
|
|
91
|
+
this._currentClient = undefined;
|
|
92
|
+
const client = new Client({ name: 'Playwright MCP Proxy', version: '0.0.0' });
|
|
93
|
+
client.registerCapabilities({
|
|
94
|
+
roots: {
|
|
95
|
+
listRoots: true,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
client.setRequestHandler(ListRootsRequestSchema, () => ({ roots: this._roots }));
|
|
99
|
+
client.setRequestHandler(PingRequestSchema, () => ({}));
|
|
100
|
+
const transport = await factory.connect();
|
|
101
|
+
await client.connect(transport);
|
|
102
|
+
this._currentClient = client;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=proxyBackend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxyBackend.js","sourceRoot":"","sources":["../../src/mcp/proxyBackend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
import debug from 'debug';
|
|
17
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
18
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
19
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
20
|
+
import { httpAddressToString, installHttpTransport, startHttpServer } from './http.js';
|
|
21
|
+
import { InProcessTransport } from './inProcessTransport.js';
|
|
22
|
+
const serverDebug = debug('pw:mcp:server');
|
|
23
|
+
const errorsDebug = debug('pw:mcp:errors');
|
|
24
|
+
export async function connect(factory, transport, runHeartbeat) {
|
|
25
|
+
const server = createServer(factory.name, factory.version, factory.create(), runHeartbeat);
|
|
26
|
+
await server.connect(transport);
|
|
27
|
+
}
|
|
28
|
+
export async function wrapInProcess(backend) {
|
|
29
|
+
const server = createServer('Internal', '0.0.0', backend, false);
|
|
30
|
+
return new InProcessTransport(server);
|
|
31
|
+
}
|
|
32
|
+
export function createServer(name, version, backend, runHeartbeat) {
|
|
33
|
+
let initializedPromiseResolve = () => { };
|
|
34
|
+
const initializedPromise = new Promise(resolve => initializedPromiseResolve = resolve);
|
|
35
|
+
const server = new Server({ name, version }, {
|
|
36
|
+
capabilities: {
|
|
37
|
+
tools: {},
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
41
|
+
serverDebug('listTools');
|
|
42
|
+
await initializedPromise;
|
|
43
|
+
const tools = await backend.listTools();
|
|
44
|
+
return { tools };
|
|
45
|
+
});
|
|
46
|
+
let heartbeatRunning = false;
|
|
47
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
48
|
+
serverDebug('callTool', request);
|
|
49
|
+
await initializedPromise;
|
|
50
|
+
if (runHeartbeat && !heartbeatRunning) {
|
|
51
|
+
heartbeatRunning = true;
|
|
52
|
+
startHeartbeat(server);
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
return await backend.callTool(request.params.name, request.params.arguments || {});
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
return {
|
|
59
|
+
content: [{ type: 'text', text: '### Result\n' + String(error) }],
|
|
60
|
+
isError: true,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
addServerListener(server, 'initialized', async () => {
|
|
65
|
+
try {
|
|
66
|
+
const capabilities = server.getClientCapabilities();
|
|
67
|
+
let clientRoots = [];
|
|
68
|
+
if (capabilities?.roots) {
|
|
69
|
+
const { roots } = await server.listRoots(undefined, { timeout: 2_000 }).catch(() => ({ roots: [] }));
|
|
70
|
+
clientRoots = roots;
|
|
71
|
+
}
|
|
72
|
+
const clientVersion = server.getClientVersion() ?? { name: 'unknown', version: 'unknown' };
|
|
73
|
+
await backend.initialize?.(server, clientVersion, clientRoots);
|
|
74
|
+
initializedPromiseResolve();
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
errorsDebug(e);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
addServerListener(server, 'close', () => backend.serverClosed?.(server));
|
|
81
|
+
return server;
|
|
82
|
+
}
|
|
83
|
+
const startHeartbeat = (server) => {
|
|
84
|
+
const beat = () => {
|
|
85
|
+
Promise.race([
|
|
86
|
+
server.ping(),
|
|
87
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('ping timeout')), 5000)),
|
|
88
|
+
]).then(() => {
|
|
89
|
+
setTimeout(beat, 3000);
|
|
90
|
+
}).catch(() => {
|
|
91
|
+
void server.close();
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
beat();
|
|
95
|
+
};
|
|
96
|
+
function addServerListener(server, event, listener) {
|
|
97
|
+
const oldListener = server[`on${event}`];
|
|
98
|
+
server[`on${event}`] = () => {
|
|
99
|
+
oldListener?.();
|
|
100
|
+
listener();
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export async function start(serverBackendFactory, options) {
|
|
104
|
+
if (options.port === undefined) {
|
|
105
|
+
await connect(serverBackendFactory, new StdioServerTransport(), false);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const httpServer = await startHttpServer(options);
|
|
109
|
+
await installHttpTransport(httpServer, serverBackendFactory);
|
|
110
|
+
const url = httpAddressToString(httpServer.address());
|
|
111
|
+
const mcpConfig = { mcpServers: {} };
|
|
112
|
+
mcpConfig.mcpServers[serverBackendFactory.nameInConfig] = {
|
|
113
|
+
url: `${url}/mcp`
|
|
114
|
+
};
|
|
115
|
+
const message = [
|
|
116
|
+
`Listening on ${url}`,
|
|
117
|
+
'Put this in your client config:',
|
|
118
|
+
JSON.stringify(mcpConfig, undefined, 2),
|
|
119
|
+
'For legacy SSE transport support, you can use the /sse endpoint instead.',
|
|
120
|
+
].join('\n');
|
|
121
|
+
// eslint-disable-next-line no-console
|
|
122
|
+
console.error(message);
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
package/lib/mcp/tool.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
17
|
+
export function toMcpTool(tool) {
|
|
18
|
+
return {
|
|
19
|
+
name: tool.name,
|
|
20
|
+
description: tool.description,
|
|
21
|
+
inputSchema: zodToJsonSchema(tool.inputSchema, { strictUnions: true }),
|
|
22
|
+
annotations: {
|
|
23
|
+
title: tool.title,
|
|
24
|
+
readOnlyHint: tool.type === 'readOnly',
|
|
25
|
+
destructiveHint: tool.type === 'destructive',
|
|
26
|
+
openWorldHint: true,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function defineToolSchema(tool) {
|
|
31
|
+
return tool;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/mcp/tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAarD,MAAM,UAAU,SAAS,CAAC,IAAqB;IAC7C,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAkC;QACvG,WAAW,EAAE;YACX,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,YAAY,EAAE,IAAI,CAAC,IAAI,KAAK,UAAU;YACtC,eAAe,EAAE,IAAI,CAAC,IAAI,KAAK,aAAa;YAC5C,aAAa,EAAE,IAAI;SACpB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAyB,IAAuB;IAC9E,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/lib/program.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
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
|
+
import { program, Option } from 'commander';
|
|
17
|
+
import * as mcpServer from './mcp/server.js';
|
|
18
|
+
import { commaSeparatedList, resolveCLIConfig, semicolonSeparatedList } from './config.js';
|
|
19
|
+
import { packageJSON } from './utils/package.js';
|
|
20
|
+
import { Context } from './context.js';
|
|
21
|
+
import { contextFactory } from './browserContextFactory.js';
|
|
22
|
+
import { ProxyBackend } from './mcp/proxyBackend.js';
|
|
23
|
+
import { BrowserServerBackend } from './browserServerBackend.js';
|
|
24
|
+
import { ExtensionContextFactory } from './extension/extensionContextFactory.js';
|
|
25
|
+
import { runVSCodeTools } from './vscode/host.js';
|
|
26
|
+
program
|
|
27
|
+
.version('Version ' + packageJSON.version)
|
|
28
|
+
.name(packageJSON.name)
|
|
29
|
+
.option('--allowed-origins <origins>', 'semicolon-separated list of origins to allow the browser to request. Default is to allow all.', semicolonSeparatedList)
|
|
30
|
+
.option('--blocked-origins <origins>', 'semicolon-separated list of origins to block the browser from requesting. Blocklist is evaluated before allowlist. If used without the allowlist, requests not matching the blocklist are still allowed.', semicolonSeparatedList)
|
|
31
|
+
.option('--block-service-workers', 'block service workers')
|
|
32
|
+
.option('--browser <browser>', 'browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.')
|
|
33
|
+
.option('--caps <caps>', 'comma-separated list of additional capabilities to enable, possible values: vision, pdf.', commaSeparatedList)
|
|
34
|
+
.option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.')
|
|
35
|
+
.option('--config <path>', 'path to the configuration file.')
|
|
36
|
+
.option('--device <device>', 'device to emulate, for example: "iPhone 15"')
|
|
37
|
+
.option('--executable-path <path>', 'path to the browser executable.')
|
|
38
|
+
.option('--extension', 'Connect to a running browser instance (Edge/Chrome only). Requires the "Playwright MCP Bridge" browser extension to be installed.')
|
|
39
|
+
.option('--headless', 'run browser in headless mode, headed by default')
|
|
40
|
+
.option('--host <host>', 'host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.')
|
|
41
|
+
.option('--ignore-https-errors', 'ignore https errors')
|
|
42
|
+
.option('--isolated', 'keep the browser profile in memory, do not save it to disk.')
|
|
43
|
+
.option('--image-responses <mode>', 'whether to send image responses to the client. Can be "allow" or "omit", Defaults to "allow".')
|
|
44
|
+
.option('--no-sandbox', 'disable the sandbox for all process types that are normally sandboxed.')
|
|
45
|
+
.option('--output-dir <path>', 'path to the directory for output files.')
|
|
46
|
+
.option('--port <port>', 'port to listen on for SSE transport.')
|
|
47
|
+
.option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"')
|
|
48
|
+
.option('--proxy-server <proxy>', 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"')
|
|
49
|
+
.option('--save-session', 'Whether to save the Playwright MCP session into the output directory.')
|
|
50
|
+
.option('--save-trace', 'Whether to save the Playwright Trace of the session into the output directory.')
|
|
51
|
+
.option('--storage-state <path>', 'path to the storage state file for isolated sessions.')
|
|
52
|
+
.option('--user-agent <ua string>', 'specify user agent string')
|
|
53
|
+
.option('--user-data-dir <path>', 'path to the user data directory. If not specified, a temporary directory will be created.')
|
|
54
|
+
.option('--viewport-size <size>', 'specify browser viewport size in pixels, for example "1280, 720"')
|
|
55
|
+
.addOption(new Option('--connect-tool', 'Allow to switch between different browser connection methods.').hideHelp())
|
|
56
|
+
.addOption(new Option('--vscode', 'VS Code tools.').hideHelp())
|
|
57
|
+
.addOption(new Option('--vision', 'Legacy option, use --caps=vision instead').hideHelp())
|
|
58
|
+
.action(async (options) => {
|
|
59
|
+
setupExitWatchdog();
|
|
60
|
+
if (options.vision) {
|
|
61
|
+
// eslint-disable-next-line no-console
|
|
62
|
+
console.error('The --vision option is deprecated, use --caps=vision instead');
|
|
63
|
+
options.caps = 'vision';
|
|
64
|
+
}
|
|
65
|
+
const config = await resolveCLIConfig(options);
|
|
66
|
+
const browserContextFactory = contextFactory(config);
|
|
67
|
+
const extensionContextFactory = new ExtensionContextFactory(config.browser.launchOptions.channel || 'chrome', config.browser.userDataDir, config.browser.launchOptions.executablePath);
|
|
68
|
+
if (options.extension) {
|
|
69
|
+
const serverBackendFactory = {
|
|
70
|
+
name: 'Playwright w/ extension',
|
|
71
|
+
nameInConfig: 'playwright-extension',
|
|
72
|
+
version: packageJSON.version,
|
|
73
|
+
create: () => new BrowserServerBackend(config, extensionContextFactory)
|
|
74
|
+
};
|
|
75
|
+
await mcpServer.start(serverBackendFactory, config.server);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (options.vscode) {
|
|
79
|
+
await runVSCodeTools(config);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (options.connectTool) {
|
|
83
|
+
const providers = [
|
|
84
|
+
{
|
|
85
|
+
name: 'default',
|
|
86
|
+
description: 'Starts standalone browser',
|
|
87
|
+
connect: () => mcpServer.wrapInProcess(new BrowserServerBackend(config, browserContextFactory)),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'extension',
|
|
91
|
+
description: 'Connect to a browser using the Playwright MCP extension',
|
|
92
|
+
connect: () => mcpServer.wrapInProcess(new BrowserServerBackend(config, extensionContextFactory)),
|
|
93
|
+
},
|
|
94
|
+
];
|
|
95
|
+
const factory = {
|
|
96
|
+
name: 'Playwright w/ switch',
|
|
97
|
+
nameInConfig: 'playwright-switch',
|
|
98
|
+
version: packageJSON.version,
|
|
99
|
+
create: () => new ProxyBackend(providers),
|
|
100
|
+
};
|
|
101
|
+
await mcpServer.start(factory, config.server);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const factory = {
|
|
105
|
+
name: 'Playwright',
|
|
106
|
+
nameInConfig: 'playwright',
|
|
107
|
+
version: packageJSON.version,
|
|
108
|
+
create: () => new BrowserServerBackend(config, browserContextFactory)
|
|
109
|
+
};
|
|
110
|
+
await mcpServer.start(factory, config.server);
|
|
111
|
+
});
|
|
112
|
+
function setupExitWatchdog() {
|
|
113
|
+
let isExiting = false;
|
|
114
|
+
const handleExit = async () => {
|
|
115
|
+
if (isExiting)
|
|
116
|
+
return;
|
|
117
|
+
isExiting = true;
|
|
118
|
+
setTimeout(() => process.exit(0), 15000);
|
|
119
|
+
await Context.disposeAll();
|
|
120
|
+
process.exit(0);
|
|
121
|
+
};
|
|
122
|
+
process.stdin.on('close', handleExit);
|
|
123
|
+
process.on('SIGINT', handleExit);
|
|
124
|
+
process.on('SIGTERM', handleExit);
|
|
125
|
+
}
|
|
126
|
+
void program.parseAsync(process.argv);
|
|
127
|
+
//# sourceMappingURL=program.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.js","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"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"}
|