custom-ui-automator 1.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/README.md +89 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +794 -0
- package/dist/server.js.map +1 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# custom-ui-automator
|
|
2
|
+
|
|
3
|
+
A Playwright-based MCP (Model Context Protocol) server for browser UI automation.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install custom-ui-automator
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
After installation, you need to install Playwright browsers:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx playwright install chromium
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### With Claude Desktop
|
|
20
|
+
|
|
21
|
+
Add this to your Claude Desktop configuration (`claude_desktop_config.json`):
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"mcpServers": {
|
|
26
|
+
"custom-ui-automator": {
|
|
27
|
+
"command": "npx",
|
|
28
|
+
"args": ["custom-ui-automator"]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### With Claude Code
|
|
35
|
+
|
|
36
|
+
Add this to your `.mcp.json`:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"mcpServers": {
|
|
41
|
+
"custom-ui-automator": {
|
|
42
|
+
"command": "npx",
|
|
43
|
+
"args": ["custom-ui-automator"]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Available Tools
|
|
50
|
+
|
|
51
|
+
| Tool | Description |
|
|
52
|
+
|------|-------------|
|
|
53
|
+
| `navigate_to` | Navigate the browser to a specified URL |
|
|
54
|
+
| `go_back` | Navigate back to the previous page |
|
|
55
|
+
| `click` | Click an element using CSS selector |
|
|
56
|
+
| `double_click` | Double click an element |
|
|
57
|
+
| `right_click` | Right click (context click) an element |
|
|
58
|
+
| `type_text` | Type text into an input field |
|
|
59
|
+
| `drag_and_drop` | Drag and drop elements |
|
|
60
|
+
| `wait_for_element` | Wait for an element to reach a specific state |
|
|
61
|
+
| `select_option` | Select option(s) from a dropdown |
|
|
62
|
+
| `execute_javascript` | Execute JavaScript in the browser context |
|
|
63
|
+
| `browser_handle_dialog` | Handle modal dialogs (alert, confirm, prompt) |
|
|
64
|
+
| `browser_upload_file` | Upload files via file chooser |
|
|
65
|
+
| `resize_window` | Resize the browser window |
|
|
66
|
+
| `press_key` | Press keyboard keys or combinations |
|
|
67
|
+
| `hover` | Hover over an element |
|
|
68
|
+
| `close_browser` | Close the browser instance |
|
|
69
|
+
|
|
70
|
+
## CSS Selector Priority
|
|
71
|
+
|
|
72
|
+
When selecting elements, follow this priority order:
|
|
73
|
+
|
|
74
|
+
1. `data-dgat` attribute: `[data-dgat="value"]`
|
|
75
|
+
2. `data-testid` attribute: `[data-testid="value"]`
|
|
76
|
+
3. `id` attribute: `#id`
|
|
77
|
+
4. `class` or complex CSS selectors (last resort)
|
|
78
|
+
|
|
79
|
+
## Example Usage
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
Navigate to https://example.com
|
|
83
|
+
Click the login button using [data-testid="login-btn"]
|
|
84
|
+
Type "user@example.com" into the email field
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## License
|
|
88
|
+
|
|
89
|
+
MIT
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":""}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,794 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { chromium } from "playwright";
|
|
5
|
+
import z from "zod";
|
|
6
|
+
const server = new McpServer({
|
|
7
|
+
name: "custom-ui-automator",
|
|
8
|
+
version: "1.0.0",
|
|
9
|
+
});
|
|
10
|
+
// Output schemas
|
|
11
|
+
const NavigationResultSchema = z.object({
|
|
12
|
+
url: z.string(),
|
|
13
|
+
title: z.string(),
|
|
14
|
+
});
|
|
15
|
+
const ClickResultSchema = z.object({
|
|
16
|
+
description: z.string(),
|
|
17
|
+
locator: z.string(),
|
|
18
|
+
});
|
|
19
|
+
const TypeResultSchema = z.object({
|
|
20
|
+
description: z.string(),
|
|
21
|
+
locator: z.string(),
|
|
22
|
+
text: z.string(),
|
|
23
|
+
});
|
|
24
|
+
const ExecuteJavaScriptResultSchema = z.object({
|
|
25
|
+
result: z.any(),
|
|
26
|
+
});
|
|
27
|
+
// Browser management
|
|
28
|
+
let browser = null;
|
|
29
|
+
let page = null;
|
|
30
|
+
async function getBrowser() {
|
|
31
|
+
if (!browser) {
|
|
32
|
+
browser = await chromium.launch({ headless: false });
|
|
33
|
+
}
|
|
34
|
+
return browser;
|
|
35
|
+
}
|
|
36
|
+
async function getPage() {
|
|
37
|
+
if (!page) {
|
|
38
|
+
const browserInstance = await getBrowser();
|
|
39
|
+
page = await browserInstance.newPage();
|
|
40
|
+
}
|
|
41
|
+
return page;
|
|
42
|
+
}
|
|
43
|
+
// Navigate to URL tool
|
|
44
|
+
server.registerTool("navigate_to", {
|
|
45
|
+
title: "Navigate to URL",
|
|
46
|
+
description: "Navigate the browser to a specified URL",
|
|
47
|
+
inputSchema: {
|
|
48
|
+
url: z.string().url().describe("The URL to navigate to"),
|
|
49
|
+
},
|
|
50
|
+
outputSchema: NavigationResultSchema.shape,
|
|
51
|
+
}, async ({ url }) => {
|
|
52
|
+
try {
|
|
53
|
+
const currentPage = await getPage();
|
|
54
|
+
await currentPage.goto(url, { waitUntil: "domcontentloaded", timeout: 30000 });
|
|
55
|
+
const currentUrl = currentPage.url();
|
|
56
|
+
const title = await currentPage.title();
|
|
57
|
+
return {
|
|
58
|
+
content: [
|
|
59
|
+
{
|
|
60
|
+
type: "text",
|
|
61
|
+
text: `Successfully navigated to: ${currentUrl}\nPage title: ${title}`,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
structuredContent: { url: currentUrl, title },
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
return {
|
|
69
|
+
content: [
|
|
70
|
+
{
|
|
71
|
+
type: "text",
|
|
72
|
+
text: `Error navigating to URL: ${error instanceof Error ? error.message : String(error)}`,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
isError: true,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
// Go back tool
|
|
80
|
+
server.registerTool("go_back", {
|
|
81
|
+
title: "Go Back",
|
|
82
|
+
description: "Navigate back to the previous page in browser history",
|
|
83
|
+
inputSchema: {},
|
|
84
|
+
outputSchema: NavigationResultSchema.shape,
|
|
85
|
+
}, async () => {
|
|
86
|
+
try {
|
|
87
|
+
const currentPage = await getPage();
|
|
88
|
+
await currentPage.goBack({ waitUntil: "domcontentloaded", timeout: 30000 });
|
|
89
|
+
const currentUrl = currentPage.url();
|
|
90
|
+
const title = await currentPage.title();
|
|
91
|
+
return {
|
|
92
|
+
content: [
|
|
93
|
+
{
|
|
94
|
+
type: "text",
|
|
95
|
+
text: `Successfully navigated back to: ${currentUrl}\nPage title: ${title}`,
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
structuredContent: { url: currentUrl, title },
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
return {
|
|
103
|
+
content: [
|
|
104
|
+
{
|
|
105
|
+
type: "text",
|
|
106
|
+
text: `Error going back: ${error instanceof Error ? error.message : String(error)}`,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
isError: true,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
// Click element tool
|
|
114
|
+
server.registerTool("click", {
|
|
115
|
+
title: "Click Element",
|
|
116
|
+
description: "Click an element on the page using a CSS selector. Priority order: 1. data-dgat [data-dgat=\"value\"], 2. data-testid [data-testid=\"value\"], 3. id #id, 4. class or complex CSS (last resort)",
|
|
117
|
+
inputSchema: {
|
|
118
|
+
selector: z.string().describe("CSS selector for the element to click. Follow priority: 1. [data-dgat=\"value\"] (FIRST), 2. [data-testid=\"value\"] (if no data-dgat), 3. #id (if no data attributes), 4. .class or complex CSS (last resort)"),
|
|
119
|
+
frameSelector: z.string().optional().describe("Optional CSS selector for the iframe containing the element (e.g., 'iframe#my-frame', 'iframe[name=\"content\"]')"),
|
|
120
|
+
timeout: z.number().optional().describe("Timeout in milliseconds (default: 5000)"),
|
|
121
|
+
},
|
|
122
|
+
outputSchema: ClickResultSchema.shape,
|
|
123
|
+
}, async ({ selector, frameSelector, timeout }) => {
|
|
124
|
+
try {
|
|
125
|
+
const currentPage = await getPage();
|
|
126
|
+
const locator = frameSelector
|
|
127
|
+
? currentPage.frameLocator(frameSelector).locator(selector)
|
|
128
|
+
: currentPage.locator(selector);
|
|
129
|
+
await locator.click({ timeout: timeout ?? 5000 });
|
|
130
|
+
return {
|
|
131
|
+
content: [
|
|
132
|
+
{
|
|
133
|
+
type: "text",
|
|
134
|
+
text: `Successfully clicked element using selector: ${selector}${frameSelector ? ` in iframe: ${frameSelector}` : ''}`,
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
structuredContent: { description: selector, locator: selector },
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
return {
|
|
142
|
+
content: [
|
|
143
|
+
{
|
|
144
|
+
type: "text",
|
|
145
|
+
text: `Error clicking element: ${error instanceof Error ? error.message : String(error)}`,
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
isError: true,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
// Double click element tool
|
|
153
|
+
server.registerTool("double_click", {
|
|
154
|
+
title: "Double Click Element",
|
|
155
|
+
description: "Double click an element on the page using a CSS selector. Priority order: 1. data-dgat [data-dgat=\"value\"], 2. data-testid [data-testid=\"value\"], 3. id #id, 4. class or complex CSS (last resort)",
|
|
156
|
+
inputSchema: {
|
|
157
|
+
selector: z.string().describe("CSS selector for the element to double click. Follow priority: 1. [data-dgat=\"value\"] (FIRST), 2. [data-testid=\"value\"] (if no data-dgat), 3. #id (if no data attributes), 4. .class or complex CSS (last resort)"),
|
|
158
|
+
frameSelector: z.string().optional().describe("Optional CSS selector for the iframe containing the element (e.g., 'iframe#my-frame', 'iframe[name=\"content\"]')"),
|
|
159
|
+
timeout: z.number().optional().describe("Timeout in milliseconds (default: 5000)"),
|
|
160
|
+
},
|
|
161
|
+
outputSchema: ClickResultSchema.shape,
|
|
162
|
+
}, async ({ selector, frameSelector, timeout }) => {
|
|
163
|
+
try {
|
|
164
|
+
const currentPage = await getPage();
|
|
165
|
+
const locator = frameSelector
|
|
166
|
+
? currentPage.frameLocator(frameSelector).locator(selector)
|
|
167
|
+
: currentPage.locator(selector);
|
|
168
|
+
await locator.dblclick({ timeout: timeout ?? 5000 });
|
|
169
|
+
return {
|
|
170
|
+
content: [
|
|
171
|
+
{
|
|
172
|
+
type: "text",
|
|
173
|
+
text: `Successfully double clicked element using selector: ${selector}${frameSelector ? ` in iframe: ${frameSelector}` : ''}`,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
structuredContent: { description: selector, locator: selector },
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
return {
|
|
181
|
+
content: [
|
|
182
|
+
{
|
|
183
|
+
type: "text",
|
|
184
|
+
text: `Error double clicking element: ${error instanceof Error ? error.message : String(error)}`,
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
isError: true,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
// Right click element tool
|
|
192
|
+
server.registerTool("right_click", {
|
|
193
|
+
title: "Right Click Element",
|
|
194
|
+
description: "Right click (context click) an element on the page using a CSS selector. Priority order: 1. data-dgat [data-dgat=\"value\"], 2. data-testid [data-testid=\"value\"], 3. id #id, 4. class or complex CSS (last resort)",
|
|
195
|
+
inputSchema: {
|
|
196
|
+
selector: z.string().describe("CSS selector for the element to right click. Follow priority: 1. [data-dgat=\"value\"] (FIRST), 2. [data-testid=\"value\"] (if no data-dgat), 3. #id (if no data attributes), 4. .class or complex CSS (last resort)"),
|
|
197
|
+
frameSelector: z.string().optional().describe("Optional CSS selector for the iframe containing the element (e.g., 'iframe#my-frame', 'iframe[name=\"content\"]')"),
|
|
198
|
+
timeout: z.number().optional().describe("Timeout in milliseconds (default: 5000)"),
|
|
199
|
+
},
|
|
200
|
+
outputSchema: ClickResultSchema.shape,
|
|
201
|
+
}, async ({ selector, frameSelector, timeout }) => {
|
|
202
|
+
try {
|
|
203
|
+
const currentPage = await getPage();
|
|
204
|
+
const locator = frameSelector
|
|
205
|
+
? currentPage.frameLocator(frameSelector).locator(selector)
|
|
206
|
+
: currentPage.locator(selector);
|
|
207
|
+
await locator.click({ button: 'right', timeout: timeout ?? 5000 });
|
|
208
|
+
return {
|
|
209
|
+
content: [
|
|
210
|
+
{
|
|
211
|
+
type: "text",
|
|
212
|
+
text: `Successfully right clicked element using selector: ${selector}${frameSelector ? ` in iframe: ${frameSelector}` : ''}`,
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
structuredContent: { description: selector, locator: selector },
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
return {
|
|
220
|
+
content: [
|
|
221
|
+
{
|
|
222
|
+
type: "text",
|
|
223
|
+
text: `Error right clicking element: ${error instanceof Error ? error.message : String(error)}`,
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
isError: true,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
// Type text tool
|
|
231
|
+
server.registerTool("type_text", {
|
|
232
|
+
title: "Type Text",
|
|
233
|
+
description: "Type text into an input field using a CSS selector. Priority order: 1. data-dgat [data-dgat=\"value\"], 2. data-testid [data-testid=\"value\"], 3. id #id, 4. class or complex CSS (last resort)",
|
|
234
|
+
inputSchema: {
|
|
235
|
+
selector: z.string().describe("CSS selector for the input field. Follow priority: 1. [data-dgat=\"value\"] (FIRST), 2. [data-testid=\"value\"] (if no data-dgat), 3. #id (if no data attributes), 4. .class or complex CSS (last resort)"),
|
|
236
|
+
text: z.string().describe("Text to type into the field"),
|
|
237
|
+
frameSelector: z.string().optional().describe("Optional CSS selector for the iframe containing the element (e.g., 'iframe#my-frame', 'iframe[name=\"content\"]')"),
|
|
238
|
+
timeout: z.number().optional().describe("Timeout in milliseconds (default: 5000)"),
|
|
239
|
+
clearFirst: z.boolean().optional().describe("Clear the field before typing (default: true)"),
|
|
240
|
+
},
|
|
241
|
+
outputSchema: TypeResultSchema.shape,
|
|
242
|
+
}, async ({ selector, text, frameSelector, timeout, clearFirst }) => {
|
|
243
|
+
try {
|
|
244
|
+
const currentPage = await getPage();
|
|
245
|
+
const locator = frameSelector
|
|
246
|
+
? currentPage.frameLocator(frameSelector).locator(selector)
|
|
247
|
+
: currentPage.locator(selector);
|
|
248
|
+
// Use fill to type text (replaces deprecated type method)
|
|
249
|
+
if (clearFirst !== false) {
|
|
250
|
+
// Clear first then type
|
|
251
|
+
await locator.fill(text, { timeout: timeout ?? 5000 });
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
// Append text without clearing
|
|
255
|
+
await locator.pressSequentially(text, { timeout: timeout ?? 5000 });
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
content: [
|
|
259
|
+
{
|
|
260
|
+
type: "text",
|
|
261
|
+
text: `Successfully typed "${text}" into field using selector: ${selector}${frameSelector ? ` in iframe: ${frameSelector}` : ''}`,
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
structuredContent: { description: selector, locator: selector, text },
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
return {
|
|
269
|
+
content: [
|
|
270
|
+
{
|
|
271
|
+
type: "text",
|
|
272
|
+
text: `Error typing text: ${error instanceof Error ? error.message : String(error)}`,
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
isError: true,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
// Drag and drop tool
|
|
280
|
+
server.registerTool("drag_and_drop", {
|
|
281
|
+
title: "Drag and Drop",
|
|
282
|
+
description: "Drag an element and drop it onto another element. Priority order: 1. data-dgat [data-dgat=\"value\"], 2. data-testid [data-testid=\"value\"], 3. id #id, 4. class or complex CSS (last resort)",
|
|
283
|
+
inputSchema: {
|
|
284
|
+
sourceSelector: z.string().describe("CSS selector for the element to drag. Follow priority: 1. [data-dgat=\"value\"] (FIRST), 2. [data-testid=\"value\"] (if no data-dgat), 3. #id (if no data attributes), 4. .class or complex CSS (last resort)"),
|
|
285
|
+
targetSelector: z.string().describe("CSS selector for the element to drop onto. Follow priority: 1. [data-dgat=\"value\"] (FIRST), 2. [data-testid=\"value\"] (if no data-dgat), 3. #id (if no data attributes), 4. .class or complex CSS (last resort)"),
|
|
286
|
+
sourceFrameSelector: z.string().optional().describe("Optional CSS selector for the iframe containing the source element"),
|
|
287
|
+
targetFrameSelector: z.string().optional().describe("Optional CSS selector for the iframe containing the target element (defaults to sourceFrameSelector if not provided)"),
|
|
288
|
+
timeout: z.number().optional().describe("Timeout in milliseconds (default: 5000)"),
|
|
289
|
+
},
|
|
290
|
+
outputSchema: z.object({
|
|
291
|
+
success: z.boolean(),
|
|
292
|
+
sourceSelector: z.string(),
|
|
293
|
+
targetSelector: z.string(),
|
|
294
|
+
}).shape,
|
|
295
|
+
}, async ({ sourceSelector, targetSelector, sourceFrameSelector, targetFrameSelector, timeout }) => {
|
|
296
|
+
try {
|
|
297
|
+
const currentPage = await getPage();
|
|
298
|
+
const sourceLocator = sourceFrameSelector
|
|
299
|
+
? currentPage.frameLocator(sourceFrameSelector).locator(sourceSelector)
|
|
300
|
+
: currentPage.locator(sourceSelector);
|
|
301
|
+
const targetFrame = targetFrameSelector ?? sourceFrameSelector;
|
|
302
|
+
const targetLocator = targetFrame
|
|
303
|
+
? currentPage.frameLocator(targetFrame).locator(targetSelector)
|
|
304
|
+
: currentPage.locator(targetSelector);
|
|
305
|
+
await sourceLocator.dragTo(targetLocator, { timeout: timeout ?? 5000 });
|
|
306
|
+
return {
|
|
307
|
+
content: [
|
|
308
|
+
{
|
|
309
|
+
type: "text",
|
|
310
|
+
text: `Successfully dragged "${sourceSelector}"${sourceFrameSelector ? ` from iframe: ${sourceFrameSelector}` : ''} to "${targetSelector}"${targetFrame ? ` in iframe: ${targetFrame}` : ''}`,
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
structuredContent: {
|
|
314
|
+
success: true,
|
|
315
|
+
sourceSelector,
|
|
316
|
+
targetSelector,
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
return {
|
|
322
|
+
content: [
|
|
323
|
+
{
|
|
324
|
+
type: "text",
|
|
325
|
+
text: `Error during drag and drop: ${error instanceof Error ? error.message : String(error)}`,
|
|
326
|
+
},
|
|
327
|
+
],
|
|
328
|
+
isError: true,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
// Wait for element tool
|
|
333
|
+
server.registerTool("wait_for_element", {
|
|
334
|
+
title: "Wait For Element",
|
|
335
|
+
description: "Wait for an element to reach a specific state. Priority order: 1. data-dgat [data-dgat=\"value\"], 2. data-testid [data-testid=\"value\"], 3. id #id, 4. class or complex CSS (last resort)",
|
|
336
|
+
inputSchema: {
|
|
337
|
+
selector: z.string().describe("CSS selector for the element to wait for. Follow priority: 1. [data-dgat=\"value\"] (FIRST), 2. [data-testid=\"value\"] (if no data-dgat), 3. #id (if no data attributes), 4. .class or complex CSS (last resort)"),
|
|
338
|
+
state: z.enum(['visible', 'hidden', 'attached', 'detached']).optional().describe("The state to wait for: 'visible' (default) - element is visible, 'hidden' - element is not visible, 'attached' - element is in DOM, 'detached' - element is removed from DOM"),
|
|
339
|
+
frameSelector: z.string().optional().describe("Optional CSS selector for the iframe containing the element (e.g., 'iframe#my-frame', 'iframe[name=\"content\"]')"),
|
|
340
|
+
timeout: z.number().optional().describe("Timeout in milliseconds (default: 30000)"),
|
|
341
|
+
},
|
|
342
|
+
outputSchema: z.object({
|
|
343
|
+
success: z.boolean(),
|
|
344
|
+
selector: z.string(),
|
|
345
|
+
state: z.string(),
|
|
346
|
+
}).shape,
|
|
347
|
+
}, async ({ selector, state, frameSelector, timeout }) => {
|
|
348
|
+
try {
|
|
349
|
+
const currentPage = await getPage();
|
|
350
|
+
const locator = frameSelector
|
|
351
|
+
? currentPage.frameLocator(frameSelector).locator(selector)
|
|
352
|
+
: currentPage.locator(selector);
|
|
353
|
+
const waitState = state ?? 'visible';
|
|
354
|
+
await locator.waitFor({ state: waitState, timeout: timeout ?? 30000 });
|
|
355
|
+
return {
|
|
356
|
+
content: [
|
|
357
|
+
{
|
|
358
|
+
type: "text",
|
|
359
|
+
text: `Element "${selector}" is now ${waitState}${frameSelector ? ` in iframe: ${frameSelector}` : ''}`,
|
|
360
|
+
},
|
|
361
|
+
],
|
|
362
|
+
structuredContent: {
|
|
363
|
+
success: true,
|
|
364
|
+
selector,
|
|
365
|
+
state: waitState,
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
return {
|
|
371
|
+
content: [
|
|
372
|
+
{
|
|
373
|
+
type: "text",
|
|
374
|
+
text: `Error waiting for element: ${error instanceof Error ? error.message : String(error)}`,
|
|
375
|
+
},
|
|
376
|
+
],
|
|
377
|
+
isError: true,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
// Select dropdown option tool
|
|
382
|
+
server.registerTool("select_option", {
|
|
383
|
+
title: "Select Option",
|
|
384
|
+
description: "Select option(s) from a dropdown/select element. Supports both single and multi-select dropdowns. Priority order: 1. data-dgat [data-dgat=\"value\"], 2. data-testid [data-testid=\"value\"], 3. id #id, 4. class or complex CSS (last resort)",
|
|
385
|
+
inputSchema: {
|
|
386
|
+
selector: z.string().describe("CSS selector for the select element. Follow priority: 1. [data-dgat=\"value\"] (FIRST), 2. [data-testid=\"value\"] (if no data-dgat), 3. #id (if no data attributes), 4. .class or complex CSS (last resort)"),
|
|
387
|
+
values: z.array(z.string()).optional().describe("Array of option values to select (uses the 'value' attribute of <option>)"),
|
|
388
|
+
labels: z.array(z.string()).optional().describe("Array of option labels to select (uses the visible text of <option>)"),
|
|
389
|
+
indices: z.array(z.number()).optional().describe("Array of option indices to select (0-based)"),
|
|
390
|
+
frameSelector: z.string().optional().describe("Optional CSS selector for the iframe containing the element (e.g., 'iframe#my-frame', 'iframe[name=\"content\"]')"),
|
|
391
|
+
timeout: z.number().optional().describe("Timeout in milliseconds (default: 5000)"),
|
|
392
|
+
},
|
|
393
|
+
outputSchema: z.object({
|
|
394
|
+
success: z.boolean(),
|
|
395
|
+
selectedOptions: z.array(z.string()),
|
|
396
|
+
}).shape,
|
|
397
|
+
}, async ({ selector, values, labels, indices, frameSelector, timeout }) => {
|
|
398
|
+
try {
|
|
399
|
+
const currentPage = await getPage();
|
|
400
|
+
const locator = frameSelector
|
|
401
|
+
? currentPage.frameLocator(frameSelector).locator(selector)
|
|
402
|
+
: currentPage.locator(selector);
|
|
403
|
+
// Build the selection criteria
|
|
404
|
+
let selectOptions = [];
|
|
405
|
+
if (values && values.length > 0) {
|
|
406
|
+
selectOptions = values.map(value => ({ value }));
|
|
407
|
+
}
|
|
408
|
+
else if (labels && labels.length > 0) {
|
|
409
|
+
selectOptions = labels.map(label => ({ label }));
|
|
410
|
+
}
|
|
411
|
+
else if (indices && indices.length > 0) {
|
|
412
|
+
selectOptions = indices.map(index => ({ index }));
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
throw new Error("Must provide at least one of: values, labels, or indices");
|
|
416
|
+
}
|
|
417
|
+
const selectedValues = await locator.selectOption(selectOptions, { timeout: timeout ?? 5000 });
|
|
418
|
+
return {
|
|
419
|
+
content: [
|
|
420
|
+
{
|
|
421
|
+
type: "text",
|
|
422
|
+
text: `Successfully selected option(s): ${selectedValues.join(', ')} from dropdown: ${selector}${frameSelector ? ` in iframe: ${frameSelector}` : ''}`,
|
|
423
|
+
},
|
|
424
|
+
],
|
|
425
|
+
structuredContent: {
|
|
426
|
+
success: true,
|
|
427
|
+
selectedOptions: selectedValues,
|
|
428
|
+
},
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
return {
|
|
433
|
+
content: [
|
|
434
|
+
{
|
|
435
|
+
type: "text",
|
|
436
|
+
text: `Error selecting option: ${error instanceof Error ? error.message : String(error)}`,
|
|
437
|
+
},
|
|
438
|
+
],
|
|
439
|
+
isError: true,
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
// Execute JavaScript tool
|
|
444
|
+
server.registerTool("execute_javascript", {
|
|
445
|
+
title: "Execute JavaScript",
|
|
446
|
+
description: "Execute arbitrary JavaScript code in the browser context and return the result. This tool should primarily be used for fetching CSS from DOM, accessing DOM elements, or reading page state. For performing clicks, use the 'click', 'double_click', or 'right_click' tools. For filling text, use the 'type_text' tool. For other interactions, use the corresponding dedicated tools.",
|
|
447
|
+
inputSchema: {
|
|
448
|
+
code: z.string().describe("JavaScript code to execute in the browser context"),
|
|
449
|
+
},
|
|
450
|
+
outputSchema: ExecuteJavaScriptResultSchema.shape,
|
|
451
|
+
}, async ({ code }) => {
|
|
452
|
+
try {
|
|
453
|
+
const currentPage = await getPage();
|
|
454
|
+
const result = await currentPage.evaluate((codeToRun) => {
|
|
455
|
+
return eval(codeToRun);
|
|
456
|
+
}, code);
|
|
457
|
+
return {
|
|
458
|
+
content: [
|
|
459
|
+
{
|
|
460
|
+
type: "text",
|
|
461
|
+
text: `JavaScript executed successfully.\nResult: ${JSON.stringify(result, null, 2)}`,
|
|
462
|
+
},
|
|
463
|
+
],
|
|
464
|
+
structuredContent: { result },
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
return {
|
|
469
|
+
content: [
|
|
470
|
+
{
|
|
471
|
+
type: "text",
|
|
472
|
+
text: `Error executing JavaScript: ${error instanceof Error ? error.message : String(error)}`,
|
|
473
|
+
},
|
|
474
|
+
],
|
|
475
|
+
isError: true,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
// Handle dialog tool - for handling modal dialogs
|
|
480
|
+
server.registerTool("browser_handle_dialog", {
|
|
481
|
+
title: "Handle Dialog",
|
|
482
|
+
description: "Handle a modal dialog (alert, confirm, prompt) by accepting or dismissing it",
|
|
483
|
+
inputSchema: {
|
|
484
|
+
action: z.enum(['accept', 'dismiss']).describe("Whether to accept or dismiss the dialog"),
|
|
485
|
+
promptText: z.string().optional().describe("Text to enter in a prompt dialog (only used if dialog is a prompt)"),
|
|
486
|
+
},
|
|
487
|
+
outputSchema: z.object({
|
|
488
|
+
success: z.boolean(),
|
|
489
|
+
dialogType: z.string(),
|
|
490
|
+
message: z.string(),
|
|
491
|
+
}).shape,
|
|
492
|
+
}, async ({ action, promptText }) => {
|
|
493
|
+
try {
|
|
494
|
+
const currentPage = await getPage();
|
|
495
|
+
// Set up a one-time dialog handler
|
|
496
|
+
const dialogPromise = new Promise((resolve, reject) => {
|
|
497
|
+
const timeout = setTimeout(() => reject(new Error("No dialog appeared within timeout")), 5000);
|
|
498
|
+
currentPage.once('dialog', async (dialog) => {
|
|
499
|
+
clearTimeout(timeout);
|
|
500
|
+
const dialogType = dialog.type();
|
|
501
|
+
const dialogMessage = dialog.message();
|
|
502
|
+
if (action === 'accept') {
|
|
503
|
+
if (dialogType === 'prompt' && promptText !== undefined) {
|
|
504
|
+
await dialog.accept(promptText);
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
await dialog.accept();
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
await dialog.dismiss();
|
|
512
|
+
}
|
|
513
|
+
resolve({ type: dialogType, message: dialogMessage });
|
|
514
|
+
});
|
|
515
|
+
});
|
|
516
|
+
const result = await dialogPromise;
|
|
517
|
+
return {
|
|
518
|
+
content: [
|
|
519
|
+
{
|
|
520
|
+
type: "text",
|
|
521
|
+
text: `Dialog ${action}ed successfully.\nDialog type: ${result.type}\nDialog message: ${result.message}`,
|
|
522
|
+
},
|
|
523
|
+
],
|
|
524
|
+
structuredContent: {
|
|
525
|
+
success: true,
|
|
526
|
+
dialogType: result.type,
|
|
527
|
+
message: result.message,
|
|
528
|
+
},
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
catch (error) {
|
|
532
|
+
return {
|
|
533
|
+
content: [
|
|
534
|
+
{
|
|
535
|
+
type: "text",
|
|
536
|
+
text: `Error handling dialog: ${error instanceof Error ? error.message : String(error)}`,
|
|
537
|
+
},
|
|
538
|
+
],
|
|
539
|
+
isError: true,
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
// File upload tool - for handling file chooser dialogs
|
|
544
|
+
server.registerTool("browser_upload_file", {
|
|
545
|
+
title: "Upload File",
|
|
546
|
+
description: "Upload a file when a file chooser dialog is present",
|
|
547
|
+
inputSchema: {
|
|
548
|
+
filePaths: z.array(z.string()).describe("Array of file paths to upload"),
|
|
549
|
+
},
|
|
550
|
+
outputSchema: z.object({
|
|
551
|
+
success: z.boolean(),
|
|
552
|
+
uploadedFiles: z.array(z.string()),
|
|
553
|
+
}).shape,
|
|
554
|
+
}, async ({ filePaths }) => {
|
|
555
|
+
try {
|
|
556
|
+
const currentPage = await getPage();
|
|
557
|
+
// Wait for file chooser and set files
|
|
558
|
+
const [fileChooser] = await Promise.all([
|
|
559
|
+
currentPage.waitForEvent('filechooser', { timeout: 5000 }),
|
|
560
|
+
]);
|
|
561
|
+
await fileChooser.setFiles(filePaths);
|
|
562
|
+
return {
|
|
563
|
+
content: [
|
|
564
|
+
{
|
|
565
|
+
type: "text",
|
|
566
|
+
text: `Files uploaded successfully: ${filePaths.join(', ')}`,
|
|
567
|
+
},
|
|
568
|
+
],
|
|
569
|
+
structuredContent: {
|
|
570
|
+
success: true,
|
|
571
|
+
uploadedFiles: filePaths,
|
|
572
|
+
},
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
catch (error) {
|
|
576
|
+
return {
|
|
577
|
+
content: [
|
|
578
|
+
{
|
|
579
|
+
type: "text",
|
|
580
|
+
text: `Error uploading file: ${error instanceof Error ? error.message : String(error)}`,
|
|
581
|
+
},
|
|
582
|
+
],
|
|
583
|
+
isError: true,
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
// Resize browser window tool
|
|
588
|
+
server.registerTool("resize_window", {
|
|
589
|
+
title: "Resize Window",
|
|
590
|
+
description: "Resize the browser window to specified dimensions",
|
|
591
|
+
inputSchema: {
|
|
592
|
+
width: z.number().describe("The width of the browser window in pixels"),
|
|
593
|
+
height: z.number().describe("The height of the browser window in pixels"),
|
|
594
|
+
},
|
|
595
|
+
outputSchema: z.object({
|
|
596
|
+
success: z.boolean(),
|
|
597
|
+
width: z.number(),
|
|
598
|
+
height: z.number(),
|
|
599
|
+
}).shape,
|
|
600
|
+
}, async ({ width, height }) => {
|
|
601
|
+
try {
|
|
602
|
+
const currentPage = await getPage();
|
|
603
|
+
await currentPage.setViewportSize({ width, height });
|
|
604
|
+
return {
|
|
605
|
+
content: [
|
|
606
|
+
{
|
|
607
|
+
type: "text",
|
|
608
|
+
text: `Browser window resized to ${width}x${height} pixels.`,
|
|
609
|
+
},
|
|
610
|
+
],
|
|
611
|
+
structuredContent: {
|
|
612
|
+
success: true,
|
|
613
|
+
width,
|
|
614
|
+
height,
|
|
615
|
+
},
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
catch (error) {
|
|
619
|
+
return {
|
|
620
|
+
content: [
|
|
621
|
+
{
|
|
622
|
+
type: "text",
|
|
623
|
+
text: `Error resizing window: ${error instanceof Error ? error.message : String(error)}`,
|
|
624
|
+
},
|
|
625
|
+
],
|
|
626
|
+
isError: true,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
// Press keyboard key tool
|
|
631
|
+
server.registerTool("press_key", {
|
|
632
|
+
title: "Press Key",
|
|
633
|
+
description: "Press a keyboard key or key combination (e.g., 'Enter', 'Escape', 'Control+C', 'Shift+Tab')",
|
|
634
|
+
inputSchema: {
|
|
635
|
+
key: z.string().describe("The key to press (e.g., 'Enter', 'Escape', 'Tab', 'ArrowDown', 'Control+A', 'Shift+Tab')"),
|
|
636
|
+
selector: z.string().optional().describe("Optional CSS selector for the element to focus before pressing the key"),
|
|
637
|
+
frameSelector: z.string().optional().describe("Optional CSS selector for the iframe containing the element (e.g., 'iframe#my-frame', 'iframe[name=\"content\"]')"),
|
|
638
|
+
timeout: z.number().optional().describe("Timeout in milliseconds (default: 5000)"),
|
|
639
|
+
},
|
|
640
|
+
outputSchema: z.object({
|
|
641
|
+
success: z.boolean(),
|
|
642
|
+
key: z.string(),
|
|
643
|
+
}).shape,
|
|
644
|
+
}, async ({ key, selector, frameSelector, timeout }) => {
|
|
645
|
+
try {
|
|
646
|
+
const currentPage = await getPage();
|
|
647
|
+
if (selector) {
|
|
648
|
+
const locator = frameSelector
|
|
649
|
+
? currentPage.frameLocator(frameSelector).locator(selector)
|
|
650
|
+
: currentPage.locator(selector);
|
|
651
|
+
await locator.press(key, { timeout: timeout ?? 5000 });
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
await currentPage.keyboard.press(key);
|
|
655
|
+
}
|
|
656
|
+
return {
|
|
657
|
+
content: [
|
|
658
|
+
{
|
|
659
|
+
type: "text",
|
|
660
|
+
text: `Successfully pressed key: ${key}${selector ? ` on element: ${selector}` : ''}${frameSelector ? ` in iframe: ${frameSelector}` : ''}`,
|
|
661
|
+
},
|
|
662
|
+
],
|
|
663
|
+
structuredContent: {
|
|
664
|
+
success: true,
|
|
665
|
+
key,
|
|
666
|
+
},
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
catch (error) {
|
|
670
|
+
return {
|
|
671
|
+
content: [
|
|
672
|
+
{
|
|
673
|
+
type: "text",
|
|
674
|
+
text: `Error pressing key: ${error instanceof Error ? error.message : String(error)}`,
|
|
675
|
+
},
|
|
676
|
+
],
|
|
677
|
+
isError: true,
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
// Hover mouse tool
|
|
682
|
+
server.registerTool("hover", {
|
|
683
|
+
title: "Hover Element",
|
|
684
|
+
description: "Hover the mouse over an element using a CSS selector. Priority order: 1. data-dgat [data-dgat=\"value\"], 2. data-testid [data-testid=\"value\"], 3. id #id, 4. class or complex CSS (last resort)",
|
|
685
|
+
inputSchema: {
|
|
686
|
+
selector: z.string().describe("CSS selector for the element to hover. Follow priority: 1. [data-dgat=\"value\"] (FIRST), 2. [data-testid=\"value\"] (if no data-dgat), 3. #id (if no data attributes), 4. .class or complex CSS (last resort)"),
|
|
687
|
+
frameSelector: z.string().optional().describe("Optional CSS selector for the iframe containing the element (e.g., 'iframe#my-frame', 'iframe[name=\"content\"]')"),
|
|
688
|
+
timeout: z.number().optional().describe("Timeout in milliseconds (default: 5000)"),
|
|
689
|
+
},
|
|
690
|
+
outputSchema: z.object({
|
|
691
|
+
success: z.boolean(),
|
|
692
|
+
selector: z.string(),
|
|
693
|
+
}).shape,
|
|
694
|
+
}, async ({ selector, frameSelector, timeout }) => {
|
|
695
|
+
try {
|
|
696
|
+
const currentPage = await getPage();
|
|
697
|
+
const locator = frameSelector
|
|
698
|
+
? currentPage.frameLocator(frameSelector).locator(selector)
|
|
699
|
+
: currentPage.locator(selector);
|
|
700
|
+
await locator.hover({ timeout: timeout ?? 5000 });
|
|
701
|
+
return {
|
|
702
|
+
content: [
|
|
703
|
+
{
|
|
704
|
+
type: "text",
|
|
705
|
+
text: `Successfully hovered over element: ${selector}${frameSelector ? ` in iframe: ${frameSelector}` : ''}`,
|
|
706
|
+
},
|
|
707
|
+
],
|
|
708
|
+
structuredContent: {
|
|
709
|
+
success: true,
|
|
710
|
+
selector,
|
|
711
|
+
},
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
catch (error) {
|
|
715
|
+
return {
|
|
716
|
+
content: [
|
|
717
|
+
{
|
|
718
|
+
type: "text",
|
|
719
|
+
text: `Error hovering element: ${error instanceof Error ? error.message : String(error)}`,
|
|
720
|
+
},
|
|
721
|
+
],
|
|
722
|
+
isError: true,
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
// Close browser tool
|
|
727
|
+
server.registerTool("close_browser", {
|
|
728
|
+
title: "Close Browser",
|
|
729
|
+
description: "Close the browser instance and clean up resources",
|
|
730
|
+
inputSchema: {},
|
|
731
|
+
outputSchema: z.object({
|
|
732
|
+
success: z.boolean(),
|
|
733
|
+
message: z.string(),
|
|
734
|
+
}).shape,
|
|
735
|
+
}, async () => {
|
|
736
|
+
try {
|
|
737
|
+
if (browser) {
|
|
738
|
+
await browser.close();
|
|
739
|
+
browser = null;
|
|
740
|
+
page = null;
|
|
741
|
+
return {
|
|
742
|
+
content: [
|
|
743
|
+
{
|
|
744
|
+
type: "text",
|
|
745
|
+
text: "Browser closed successfully.",
|
|
746
|
+
},
|
|
747
|
+
],
|
|
748
|
+
structuredContent: {
|
|
749
|
+
success: true,
|
|
750
|
+
message: "Browser closed successfully",
|
|
751
|
+
},
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
else {
|
|
755
|
+
return {
|
|
756
|
+
content: [
|
|
757
|
+
{
|
|
758
|
+
type: "text",
|
|
759
|
+
text: "No browser instance was open.",
|
|
760
|
+
},
|
|
761
|
+
],
|
|
762
|
+
structuredContent: {
|
|
763
|
+
success: true,
|
|
764
|
+
message: "No browser instance was open",
|
|
765
|
+
},
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
catch (error) {
|
|
770
|
+
return {
|
|
771
|
+
content: [
|
|
772
|
+
{
|
|
773
|
+
type: "text",
|
|
774
|
+
text: `Error closing browser: ${error instanceof Error ? error.message : String(error)}`,
|
|
775
|
+
},
|
|
776
|
+
],
|
|
777
|
+
isError: true,
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
// Cleanup on exit
|
|
782
|
+
process.on("SIGINT", async () => {
|
|
783
|
+
if (browser) {
|
|
784
|
+
await browser.close();
|
|
785
|
+
}
|
|
786
|
+
process.exit(0);
|
|
787
|
+
});
|
|
788
|
+
// Start the server
|
|
789
|
+
(async () => {
|
|
790
|
+
const transport = new StdioServerTransport();
|
|
791
|
+
await server.connect(transport);
|
|
792
|
+
console.error("Playwright Browser MCP Server running on stdio");
|
|
793
|
+
})();
|
|
794
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "custom-ui-automator",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A Playwright browser MCP server for UI automation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/server.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"custom-ui-automator": "dist/server.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"package.json"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"model-context-protocol",
|
|
22
|
+
"playwright",
|
|
23
|
+
"browser-automation",
|
|
24
|
+
"ui-automation",
|
|
25
|
+
"testing",
|
|
26
|
+
"web-automation"
|
|
27
|
+
],
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@modelcontextprotocol/sdk": "^1.20.2",
|
|
30
|
+
"playwright": "^1.57.0",
|
|
31
|
+
"zod": "^3.23.8"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@playwright/test": "^1.57.0",
|
|
35
|
+
"@types/node": "^24.9.1",
|
|
36
|
+
"tsx": "^4.19.1",
|
|
37
|
+
"typescript": "^5.6.3"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18.0.0"
|
|
41
|
+
},
|
|
42
|
+
"author": "Atul Bharadwaj",
|
|
43
|
+
"license": "MIT"
|
|
44
|
+
}
|