@playwright/mcp 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/lib/context.js +1 -1
- package/lib/index.js +1 -0
- package/lib/program.js +1 -0
- package/lib/tools/common.js +1 -1
- package/lib/tools/screenshot.js +2 -2
- package/lib/tools/snapshot.js +29 -3
- package/lib/tools/utils.js +12 -3
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -224,6 +224,11 @@ The Playwright MCP provides a set of tools for browser automation. Here are all
|
|
|
224
224
|
- Description: Save page as PDF
|
|
225
225
|
- Parameters: None
|
|
226
226
|
|
|
227
|
+
- **browser_take_screenshot**
|
|
228
|
+
- Description: Capture screenshot of the page
|
|
229
|
+
- Parameters:
|
|
230
|
+
- `raw` (string): Optionally returns lossless PNG screenshot. JPEG by default.
|
|
231
|
+
|
|
227
232
|
- **browser_wait**
|
|
228
233
|
- Description: Wait for a specified time in seconds
|
|
229
234
|
- Parameters:
|
package/lib/context.js
CHANGED
package/lib/index.js
CHANGED
package/lib/program.js
CHANGED
|
@@ -39,6 +39,7 @@ commander_1.program
|
|
|
39
39
|
const server = (0, index_1.createServer)({
|
|
40
40
|
userDataDir: options.userDataDir ?? await userDataDir(),
|
|
41
41
|
launchOptions,
|
|
42
|
+
vision: !!options.vision,
|
|
42
43
|
});
|
|
43
44
|
setupExitWatchdog(server);
|
|
44
45
|
const transport = new stdio_js_1.StdioServerTransport();
|
package/lib/tools/common.js
CHANGED
|
@@ -118,7 +118,7 @@ exports.pdf = {
|
|
|
118
118
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(pdfSchema),
|
|
119
119
|
},
|
|
120
120
|
handle: async (context) => {
|
|
121
|
-
const page =
|
|
121
|
+
const page = context.existingPage();
|
|
122
122
|
const fileName = path_1.default.join(os_1.default.tmpdir(), `/page-${new Date().toISOString()}.pdf`);
|
|
123
123
|
await page.pdf({ path: fileName });
|
|
124
124
|
return {
|
package/lib/tools/screenshot.js
CHANGED
|
@@ -26,7 +26,7 @@ exports.screenshot = {
|
|
|
26
26
|
inputSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(zod_1.z.object({})),
|
|
27
27
|
},
|
|
28
28
|
handle: async (context) => {
|
|
29
|
-
const page =
|
|
29
|
+
const page = context.existingPage();
|
|
30
30
|
const screenshot = await page.screenshot({ type: 'jpeg', quality: 50, scale: 'css' });
|
|
31
31
|
return {
|
|
32
32
|
content: [{ type: 'image', data: screenshot.toString('base64'), mimeType: 'image/jpeg' }],
|
|
@@ -48,7 +48,7 @@ exports.moveMouse = {
|
|
|
48
48
|
},
|
|
49
49
|
handle: async (context, params) => {
|
|
50
50
|
const validatedParams = moveMouseSchema.parse(params);
|
|
51
|
-
const page =
|
|
51
|
+
const page = context.existingPage();
|
|
52
52
|
await page.mouse.move(validatedParams.x, validatedParams.y);
|
|
53
53
|
return {
|
|
54
54
|
content: [{ type: 'text', text: `Moved mouse to (${validatedParams.x}, ${validatedParams.y})` }],
|
package/lib/tools/snapshot.js
CHANGED
|
@@ -18,7 +18,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
18
18
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.selectOption = exports.type = exports.hover = exports.drag = exports.click = exports.snapshot = void 0;
|
|
21
|
+
exports.screenshot = exports.selectOption = exports.type = exports.hover = exports.drag = exports.click = exports.snapshot = void 0;
|
|
22
22
|
const zod_1 = require("zod");
|
|
23
23
|
const zod_to_json_schema_1 = __importDefault(require("zod-to-json-schema"));
|
|
24
24
|
const utils_1 = require("./utils");
|
|
@@ -29,7 +29,7 @@ exports.snapshot = {
|
|
|
29
29
|
inputSchema: (0, zod_to_json_schema_1.default)(zod_1.z.object({})),
|
|
30
30
|
},
|
|
31
31
|
handle: async (context) => {
|
|
32
|
-
return await (0, utils_1.captureAriaSnapshot)(
|
|
32
|
+
return await (0, utils_1.captureAriaSnapshot)(context.existingPage());
|
|
33
33
|
},
|
|
34
34
|
};
|
|
35
35
|
const elementSchema = zod_1.z.object({
|
|
@@ -116,6 +116,32 @@ exports.selectOption = {
|
|
|
116
116
|
}, true);
|
|
117
117
|
},
|
|
118
118
|
};
|
|
119
|
+
const screenshotSchema = zod_1.z.object({
|
|
120
|
+
raw: zod_1.z.boolean().optional().describe('Whether to return without compression (in PNG format). Default is false, which returns a JPEG image.'),
|
|
121
|
+
});
|
|
122
|
+
exports.screenshot = {
|
|
123
|
+
schema: {
|
|
124
|
+
name: 'browser_take_screenshot',
|
|
125
|
+
description: `Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.`,
|
|
126
|
+
inputSchema: (0, zod_to_json_schema_1.default)(screenshotSchema),
|
|
127
|
+
},
|
|
128
|
+
handle: async (context, params) => {
|
|
129
|
+
const validatedParams = screenshotSchema.parse(params);
|
|
130
|
+
const page = context.existingPage();
|
|
131
|
+
const options = validatedParams.raw ? { type: 'png', scale: 'css' } : { type: 'jpeg', quality: 50, scale: 'css' };
|
|
132
|
+
const screenshot = await page.screenshot(options);
|
|
133
|
+
return {
|
|
134
|
+
content: [{ type: 'image', data: screenshot.toString('base64'), mimeType: validatedParams.raw ? 'image/png' : 'image/jpeg' }],
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
};
|
|
119
138
|
function refLocator(page, ref) {
|
|
120
|
-
|
|
139
|
+
let frame = page.frames()[0];
|
|
140
|
+
const match = ref.match(/^f(\d+)(.*)/);
|
|
141
|
+
if (match) {
|
|
142
|
+
const frameIndex = parseInt(match[1], 10);
|
|
143
|
+
frame = page.frames()[frameIndex];
|
|
144
|
+
ref = match[2];
|
|
145
|
+
}
|
|
146
|
+
return frame.locator(`aria-ref=${ref}`);
|
|
121
147
|
}
|
package/lib/tools/utils.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.runAndWait = runAndWait;
|
|
19
|
+
exports.captureAllFrameSnapshot = captureAllFrameSnapshot;
|
|
19
20
|
exports.captureAriaSnapshot = captureAriaSnapshot;
|
|
20
21
|
async function waitForCompletion(page, callback) {
|
|
21
22
|
const requests = new Set();
|
|
@@ -65,21 +66,29 @@ async function waitForCompletion(page, callback) {
|
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
async function runAndWait(context, status, callback, snapshot = false) {
|
|
68
|
-
const page =
|
|
69
|
+
const page = context.existingPage();
|
|
69
70
|
await waitForCompletion(page, () => callback(page));
|
|
70
71
|
return snapshot ? captureAriaSnapshot(page, status) : {
|
|
71
72
|
content: [{ type: 'text', text: status }],
|
|
72
73
|
};
|
|
73
74
|
}
|
|
75
|
+
async function captureAllFrameSnapshot(page) {
|
|
76
|
+
const snapshots = await Promise.all(page.frames().map(frame => frame.locator('html').ariaSnapshot({ ref: true })));
|
|
77
|
+
const scopedSnapshots = snapshots.map((snapshot, frameIndex) => {
|
|
78
|
+
if (frameIndex === 0)
|
|
79
|
+
return snapshot;
|
|
80
|
+
return snapshot.replaceAll('[ref=', `[ref=f${frameIndex}`);
|
|
81
|
+
});
|
|
82
|
+
return scopedSnapshots.join('\n');
|
|
83
|
+
}
|
|
74
84
|
async function captureAriaSnapshot(page, status = '') {
|
|
75
|
-
const snapshot = await page.locator('html').ariaSnapshot({ ref: true });
|
|
76
85
|
return {
|
|
77
86
|
content: [{ type: 'text', text: `${status ? `${status}\n` : ''}
|
|
78
87
|
- Page URL: ${page.url()}
|
|
79
88
|
- Page Title: ${await page.title()}
|
|
80
89
|
- Page Snapshot
|
|
81
90
|
\`\`\`yaml
|
|
82
|
-
${
|
|
91
|
+
${await captureAllFrameSnapshot(page)}
|
|
83
92
|
\`\`\`
|
|
84
93
|
`
|
|
85
94
|
}],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playwright/mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Playwright Tools for MCP",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
"build": "tsc",
|
|
19
19
|
"lint": "eslint .",
|
|
20
20
|
"watch": "tsc --watch",
|
|
21
|
-
"test": "playwright test"
|
|
21
|
+
"test": "playwright test",
|
|
22
|
+
"clean": "rm -rf lib",
|
|
23
|
+
"publish": "npm run clean && npm run build && npm run test && npm publish"
|
|
22
24
|
},
|
|
23
25
|
"exports": {
|
|
24
26
|
"./package.json": "./package.json",
|