@wdio/mcp 1.5.0 → 1.6.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/server.js +520 -213
- package/lib/server.js.map +1 -1
- package/package.json +4 -2
package/lib/server.js
CHANGED
|
@@ -7,13 +7,21 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
7
7
|
// src/tools/browser.tool.ts
|
|
8
8
|
import { remote } from "webdriverio";
|
|
9
9
|
import { z } from "zod";
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
var startBrowserToolDefinition = {
|
|
11
|
+
name: "start_browser",
|
|
12
|
+
description: "starts a browser session and sets it to the current state",
|
|
13
|
+
inputSchema: {
|
|
14
|
+
headless: z.boolean().optional(),
|
|
15
|
+
windowWidth: z.number().min(400).max(3840).optional(),
|
|
16
|
+
windowHeight: z.number().min(400).max(2160).optional()
|
|
17
|
+
}
|
|
14
18
|
};
|
|
15
|
-
var
|
|
16
|
-
|
|
19
|
+
var closeSessionToolDefinition = {
|
|
20
|
+
name: "close_session",
|
|
21
|
+
description: "closes or detaches from the current browser or app session",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
detach: z.boolean().optional().describe("If true, disconnect from session without terminating it (preserves app state). Default: false")
|
|
24
|
+
}
|
|
17
25
|
};
|
|
18
26
|
var state = {
|
|
19
27
|
browsers: /* @__PURE__ */ new Map(),
|
|
@@ -95,8 +103,12 @@ var closeSessionTool = async (args = {}) => {
|
|
|
95
103
|
|
|
96
104
|
// src/tools/navigate.tool.ts
|
|
97
105
|
import { z as z2 } from "zod";
|
|
98
|
-
var
|
|
99
|
-
|
|
106
|
+
var navigateToolDefinition = {
|
|
107
|
+
name: "navigate",
|
|
108
|
+
description: "navigates to a URL",
|
|
109
|
+
inputSchema: {
|
|
110
|
+
url: z2.string().min(1).describe("The URL to navigate to")
|
|
111
|
+
}
|
|
100
112
|
};
|
|
101
113
|
var navigateTool = async ({ url }) => {
|
|
102
114
|
try {
|
|
@@ -115,10 +127,23 @@ var navigateTool = async ({ url }) => {
|
|
|
115
127
|
// src/tools/click.tool.ts
|
|
116
128
|
import { z as z3 } from "zod";
|
|
117
129
|
var defaultTimeout = 3e3;
|
|
118
|
-
var
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
130
|
+
var clickToolDefinition = {
|
|
131
|
+
name: "click_element",
|
|
132
|
+
description: "clicks an element",
|
|
133
|
+
inputSchema: {
|
|
134
|
+
selector: z3.string().describe(`Value for the selector, in the form of css selector or xpath ("button.my-class" or "//button[@class='my-class']" or "button=Exact text with spaces" or "a*=Link containing text")`),
|
|
135
|
+
scrollToView: z3.boolean().optional().describe("Whether to scroll the element into view before clicking").default(true),
|
|
136
|
+
timeout: z3.number().optional().describe("Maximum time to wait for element in milliseconds")
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
var clickViaTextToolDefinition = {
|
|
140
|
+
name: "click_via_text",
|
|
141
|
+
description: "clicks an element",
|
|
142
|
+
inputSchema: {
|
|
143
|
+
selector: z3.string().describe(`Value for the selector, in the form of css selector or xpath ("button.my-class" or "//button[@class='my-class']" or "button=Exact text with spaces" or "a*=Link containing text")`),
|
|
144
|
+
scrollToView: z3.boolean().optional().describe("Whether to scroll the element into view before clicking").default(true),
|
|
145
|
+
timeout: z3.number().optional().describe("Maximum time to wait for element in milliseconds")
|
|
146
|
+
}
|
|
122
147
|
};
|
|
123
148
|
var clickAction = async (selector, timeout, scrollToView = true) => {
|
|
124
149
|
try {
|
|
@@ -143,11 +168,15 @@ var clickToolViaText = async ({ text, scrollToView, timeout = defaultTimeout })
|
|
|
143
168
|
// src/tools/set-value.tool.ts
|
|
144
169
|
import { z as z4 } from "zod";
|
|
145
170
|
var defaultTimeout2 = 3e3;
|
|
146
|
-
var
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
171
|
+
var setValueToolDefinition = {
|
|
172
|
+
name: "set_value",
|
|
173
|
+
description: "set value to an element, aka typing",
|
|
174
|
+
inputSchema: {
|
|
175
|
+
selector: z4.string().describe(`Value for the selector, in the form of css selector or xpath ("button.my-class" or "//button[@class='my-class']")`),
|
|
176
|
+
value: z4.string().describe("Text to enter into the element"),
|
|
177
|
+
scrollToView: z4.boolean().optional().describe("Whether to scroll the element into view before typing").default(true),
|
|
178
|
+
timeout: z4.number().optional().describe("Maximum time to wait for element in milliseconds")
|
|
179
|
+
}
|
|
151
180
|
};
|
|
152
181
|
var setValueTool = async ({ selector, value, scrollToView = true, timeout = defaultTimeout2 }) => {
|
|
153
182
|
try {
|
|
@@ -171,9 +200,13 @@ var setValueTool = async ({ selector, value, scrollToView = true, timeout = defa
|
|
|
171
200
|
// src/tools/find-element.tool.ts
|
|
172
201
|
import { z as z5 } from "zod";
|
|
173
202
|
var defaultTimeout3 = 3e3;
|
|
174
|
-
var
|
|
175
|
-
|
|
176
|
-
|
|
203
|
+
var findElementToolDefinition = {
|
|
204
|
+
name: "find_element",
|
|
205
|
+
description: "finds an element",
|
|
206
|
+
inputSchema: {
|
|
207
|
+
selector: z5.string().describe(`Value for the selector, in the form of css selector or xpath ("button.my-class" or "//button[@class='my-class']")`),
|
|
208
|
+
timeout: z5.number().optional().describe("Maximum time to wait for element in milliseconds")
|
|
209
|
+
}
|
|
177
210
|
};
|
|
178
211
|
var findElementTool = async ({ selector, timeout = defaultTimeout3 }) => {
|
|
179
212
|
try {
|
|
@@ -192,9 +225,13 @@ var findElementTool = async ({ selector, timeout = defaultTimeout3 }) => {
|
|
|
192
225
|
// src/tools/get-element-text.tool.ts
|
|
193
226
|
import { z as z6 } from "zod";
|
|
194
227
|
var defaultTimeout4 = 3e3;
|
|
195
|
-
var
|
|
196
|
-
|
|
197
|
-
|
|
228
|
+
var getElementTextToolDefinition = {
|
|
229
|
+
name: "get_element_text",
|
|
230
|
+
description: "gets the text content of an element",
|
|
231
|
+
inputSchema: {
|
|
232
|
+
selector: z6.string().describe(`Value for the selector, in the form of css selector or xpath ("button.my-class" or "//button[@class='my-class']")`),
|
|
233
|
+
timeout: z6.number().optional().describe("Maximum time to wait for element in milliseconds")
|
|
234
|
+
}
|
|
198
235
|
};
|
|
199
236
|
var getElementTextTool = async ({ selector, timeout = defaultTimeout4 }) => {
|
|
200
237
|
try {
|
|
@@ -214,9 +251,13 @@ var getElementTextTool = async ({ selector, timeout = defaultTimeout4 }) => {
|
|
|
214
251
|
// src/tools/is-displayed.tool.ts
|
|
215
252
|
import { z as z7 } from "zod";
|
|
216
253
|
var defaultTimeout5 = 3e3;
|
|
217
|
-
var
|
|
218
|
-
|
|
219
|
-
|
|
254
|
+
var isDisplayedToolDefinition = {
|
|
255
|
+
name: "is_displayed",
|
|
256
|
+
description: "checks if an element is displayed",
|
|
257
|
+
inputSchema: {
|
|
258
|
+
selector: z7.string().describe(`Value for the selector, in the form of css selector or xpath ("button.my-class" or "//button[@class='my-class']")`),
|
|
259
|
+
timeout: z7.number().optional().describe("Maximum time to wait for element in milliseconds")
|
|
260
|
+
}
|
|
220
261
|
};
|
|
221
262
|
var isDisplayedTool = async ({ selector, timeout = defaultTimeout5 }) => {
|
|
222
263
|
try {
|
|
@@ -238,8 +279,12 @@ var isDisplayedTool = async ({ selector, timeout = defaultTimeout5 }) => {
|
|
|
238
279
|
|
|
239
280
|
// src/tools/scroll-down.tool.ts
|
|
240
281
|
import { z as z8 } from "zod";
|
|
241
|
-
var
|
|
242
|
-
|
|
282
|
+
var scrollDownToolDefinition = {
|
|
283
|
+
name: "scroll_down",
|
|
284
|
+
description: "scrolls the page down by specified pixels",
|
|
285
|
+
inputSchema: {
|
|
286
|
+
pixels: z8.number().optional().default(500)
|
|
287
|
+
}
|
|
243
288
|
};
|
|
244
289
|
var scrollDownTool = async ({ pixels = 500 }) => {
|
|
245
290
|
try {
|
|
@@ -259,8 +304,12 @@ var scrollDownTool = async ({ pixels = 500 }) => {
|
|
|
259
304
|
|
|
260
305
|
// src/tools/scroll-up.tool.ts
|
|
261
306
|
import { z as z9 } from "zod";
|
|
262
|
-
var
|
|
263
|
-
|
|
307
|
+
var scrollUpToolDefinition = {
|
|
308
|
+
name: "scroll_up",
|
|
309
|
+
description: "scrolls the page up by specified pixels",
|
|
310
|
+
inputSchema: {
|
|
311
|
+
pixels: z9.number().optional().default(500)
|
|
312
|
+
}
|
|
264
313
|
};
|
|
265
314
|
var scrollUpTool = async ({ pixels = 500 }) => {
|
|
266
315
|
try {
|
|
@@ -1049,24 +1098,66 @@ function generateAllElementLocators(sourceXML, options) {
|
|
|
1049
1098
|
}
|
|
1050
1099
|
|
|
1051
1100
|
// src/utils/mobile-elements.ts
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1101
|
+
var LOCATOR_PRIORITY = [
|
|
1102
|
+
"accessibility-id",
|
|
1103
|
+
// Most stable, cross-platform
|
|
1104
|
+
"id",
|
|
1105
|
+
// Android resource-id
|
|
1106
|
+
"text",
|
|
1107
|
+
// Text-based (can be fragile but readable)
|
|
1108
|
+
"predicate-string",
|
|
1109
|
+
// iOS predicate
|
|
1110
|
+
"class-chain",
|
|
1111
|
+
// iOS class chain
|
|
1112
|
+
"uiautomator",
|
|
1113
|
+
// Android UiAutomator compound
|
|
1114
|
+
"xpath"
|
|
1115
|
+
// XPath (last resort, brittle)
|
|
1116
|
+
// 'class-name' intentionally excluded - too generic
|
|
1117
|
+
];
|
|
1118
|
+
function selectBestLocators(locators) {
|
|
1119
|
+
const selected = [];
|
|
1120
|
+
for (const strategy of LOCATOR_PRIORITY) {
|
|
1121
|
+
if (locators[strategy]) {
|
|
1122
|
+
selected.push(locators[strategy]);
|
|
1123
|
+
break;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
for (const strategy of LOCATOR_PRIORITY) {
|
|
1127
|
+
if (locators[strategy] && !selected.includes(locators[strategy])) {
|
|
1128
|
+
selected.push(locators[strategy]);
|
|
1129
|
+
break;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
return selected;
|
|
1133
|
+
}
|
|
1134
|
+
function toMobileElementInfo(element, includeBounds) {
|
|
1135
|
+
const selectedLocators = selectBestLocators(element.locators);
|
|
1136
|
+
const info = {
|
|
1137
|
+
selector: selectedLocators[0] || "",
|
|
1138
|
+
tagName: element.tagName,
|
|
1139
|
+
isInViewport: element.isInViewport
|
|
1069
1140
|
};
|
|
1141
|
+
if (element.text) {
|
|
1142
|
+
info.text = element.text;
|
|
1143
|
+
}
|
|
1144
|
+
if (element.resourceId) {
|
|
1145
|
+
info.resourceId = element.resourceId;
|
|
1146
|
+
}
|
|
1147
|
+
const accessId = element.accessibilityId || element.contentDesc;
|
|
1148
|
+
if (accessId) {
|
|
1149
|
+
info.accessibilityId = accessId;
|
|
1150
|
+
}
|
|
1151
|
+
if (!element.enabled) {
|
|
1152
|
+
info.isEnabled = false;
|
|
1153
|
+
}
|
|
1154
|
+
if (selectedLocators.length > 1) {
|
|
1155
|
+
info.alternativeSelectors = selectedLocators.slice(1);
|
|
1156
|
+
}
|
|
1157
|
+
if (includeBounds) {
|
|
1158
|
+
info.bounds = element.bounds;
|
|
1159
|
+
}
|
|
1160
|
+
return info;
|
|
1070
1161
|
}
|
|
1071
1162
|
async function getViewportSize(browser) {
|
|
1072
1163
|
try {
|
|
@@ -1077,7 +1168,7 @@ async function getViewportSize(browser) {
|
|
|
1077
1168
|
}
|
|
1078
1169
|
}
|
|
1079
1170
|
async function getMobileVisibleElements(browser, platform, options = {}) {
|
|
1080
|
-
const { includeContainers = false, filterOptions } = options;
|
|
1171
|
+
const { includeContainers = false, includeBounds = false, filterOptions } = options;
|
|
1081
1172
|
const viewportSize = await getViewportSize(browser);
|
|
1082
1173
|
const pageSource = await browser.getPageSource();
|
|
1083
1174
|
const filters = {
|
|
@@ -1089,7 +1180,7 @@ async function getMobileVisibleElements(browser, platform, options = {}) {
|
|
|
1089
1180
|
viewportSize,
|
|
1090
1181
|
filters
|
|
1091
1182
|
});
|
|
1092
|
-
return elements.map(toMobileElementInfo);
|
|
1183
|
+
return elements.map((el) => toMobileElementInfo(el, includeBounds));
|
|
1093
1184
|
}
|
|
1094
1185
|
|
|
1095
1186
|
// src/tools/get-visible-elements.tool.ts
|
|
@@ -1107,19 +1198,25 @@ function stripUndefinedFromArray(arr) {
|
|
|
1107
1198
|
}
|
|
1108
1199
|
|
|
1109
1200
|
// src/tools/get-visible-elements.tool.ts
|
|
1110
|
-
var
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1201
|
+
var getVisibleElementsToolDefinition = {
|
|
1202
|
+
name: "get_visible_elements",
|
|
1203
|
+
description: 'get a list of visible (in viewport & displayed) interactable elements on the page (buttons, links, inputs). Use elementType="visual" for images/SVGs. Must prefer this to take_screenshot for interactions',
|
|
1204
|
+
inputSchema: {
|
|
1205
|
+
inViewportOnly: z10.boolean().optional().describe(
|
|
1206
|
+
"Only return elements within the visible viewport. Default: true. Set to false to get ALL elements on the page."
|
|
1207
|
+
),
|
|
1208
|
+
includeContainers: z10.boolean().optional().describe(
|
|
1209
|
+
"Include layout containers (ViewGroup, FrameLayout, ScrollView, etc). Default: false. Set to true to see all elements including layouts."
|
|
1210
|
+
),
|
|
1211
|
+
includeBounds: z10.boolean().optional().describe(
|
|
1212
|
+
"Include element bounds/coordinates (x, y, width, height). Default: false. Set to true for coordinate-based interactions or layout debugging."
|
|
1213
|
+
),
|
|
1214
|
+
elementType: z10.enum(["interactable", "visual", "all"]).optional().describe(
|
|
1215
|
+
'Type of elements to return: "interactable" (default) for buttons/links/inputs, "visual" for images/SVGs, "all" for both.'
|
|
1216
|
+
),
|
|
1217
|
+
limit: z10.number().optional().describe("Maximum number of elements to return. Default: 0 (unlimited)."),
|
|
1218
|
+
offset: z10.number().optional().describe("Number of elements to skip (for pagination). Default: 0.")
|
|
1219
|
+
}
|
|
1123
1220
|
};
|
|
1124
1221
|
var getVisibleElementsTool = async (args) => {
|
|
1125
1222
|
try {
|
|
@@ -1127,34 +1224,37 @@ var getVisibleElementsTool = async (args) => {
|
|
|
1127
1224
|
const {
|
|
1128
1225
|
inViewportOnly = true,
|
|
1129
1226
|
includeContainers = false,
|
|
1227
|
+
includeBounds = false,
|
|
1130
1228
|
elementType = "interactable",
|
|
1131
|
-
limit = 0
|
|
1229
|
+
limit = 0,
|
|
1230
|
+
offset = 0
|
|
1132
1231
|
} = args || {};
|
|
1232
|
+
let elements;
|
|
1133
1233
|
if (browser.isAndroid || browser.isIOS) {
|
|
1134
1234
|
const platform = browser.isAndroid ? "android" : "ios";
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
elements2 = elements2.filter((el) => el.isInViewport);
|
|
1140
|
-
}
|
|
1141
|
-
if (limit > 0 && elements2.length > limit) {
|
|
1142
|
-
elements2 = elements2.slice(0, limit);
|
|
1143
|
-
}
|
|
1144
|
-
return {
|
|
1145
|
-
content: [{ type: "text", text: encode(elements2) }]
|
|
1146
|
-
};
|
|
1235
|
+
elements = await getMobileVisibleElements(browser, platform, { includeContainers, includeBounds });
|
|
1236
|
+
} else {
|
|
1237
|
+
const raw = await browser.execute(get_interactable_elements_default, elementType);
|
|
1238
|
+
elements = stripUndefinedFromArray(raw);
|
|
1147
1239
|
}
|
|
1148
|
-
let elements = await browser.execute(get_interactable_elements_default, elementType);
|
|
1149
1240
|
if (inViewportOnly) {
|
|
1150
1241
|
elements = elements.filter((el) => el.isInViewport !== false);
|
|
1151
1242
|
}
|
|
1152
|
-
|
|
1243
|
+
const total = elements.length;
|
|
1244
|
+
if (offset > 0) {
|
|
1245
|
+
elements = elements.slice(offset);
|
|
1246
|
+
}
|
|
1247
|
+
if (limit > 0) {
|
|
1153
1248
|
elements = elements.slice(0, limit);
|
|
1154
1249
|
}
|
|
1155
|
-
const
|
|
1250
|
+
const result = {
|
|
1251
|
+
total,
|
|
1252
|
+
showing: elements.length,
|
|
1253
|
+
hasMore: offset + elements.length < total,
|
|
1254
|
+
elements
|
|
1255
|
+
};
|
|
1156
1256
|
return {
|
|
1157
|
-
content: [{ type: "text", text: encode(
|
|
1257
|
+
content: [{ type: "text", text: encode(result) }]
|
|
1158
1258
|
};
|
|
1159
1259
|
} catch (e) {
|
|
1160
1260
|
return {
|
|
@@ -1165,8 +1265,12 @@ var getVisibleElementsTool = async (args) => {
|
|
|
1165
1265
|
|
|
1166
1266
|
// src/tools/take-screenshot.tool.ts
|
|
1167
1267
|
import { z as z11 } from "zod";
|
|
1168
|
-
var
|
|
1169
|
-
|
|
1268
|
+
var takeScreenshotToolDefinition = {
|
|
1269
|
+
name: "take_screenshot",
|
|
1270
|
+
description: "captures a screenshot of the current page",
|
|
1271
|
+
inputSchema: {
|
|
1272
|
+
outputPath: z11.string().optional().describe("Optional path where to save the screenshot. If not provided, returns base64 data.")
|
|
1273
|
+
}
|
|
1170
1274
|
};
|
|
1171
1275
|
var takeScreenshotTool = async ({ outputPath }) => {
|
|
1172
1276
|
try {
|
|
@@ -1194,8 +1298,12 @@ var takeScreenshotTool = async ({ outputPath }) => {
|
|
|
1194
1298
|
|
|
1195
1299
|
// src/tools/cookies.tool.ts
|
|
1196
1300
|
import { z as z12 } from "zod";
|
|
1197
|
-
var
|
|
1198
|
-
name:
|
|
1301
|
+
var getCookiesToolDefinition = {
|
|
1302
|
+
name: "get_cookies",
|
|
1303
|
+
description: "gets all cookies or a specific cookie by name",
|
|
1304
|
+
inputSchema: {
|
|
1305
|
+
name: z12.string().optional().describe("Optional cookie name to retrieve a specific cookie. If not provided, returns all cookies")
|
|
1306
|
+
}
|
|
1199
1307
|
};
|
|
1200
1308
|
var getCookiesTool = async ({ name }) => {
|
|
1201
1309
|
try {
|
|
@@ -1226,15 +1334,19 @@ var getCookiesTool = async ({ name }) => {
|
|
|
1226
1334
|
};
|
|
1227
1335
|
}
|
|
1228
1336
|
};
|
|
1229
|
-
var
|
|
1230
|
-
name:
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1337
|
+
var setCookieToolDefinition = {
|
|
1338
|
+
name: "set_cookie",
|
|
1339
|
+
description: "sets a cookie with specified name, value, and optional attributes",
|
|
1340
|
+
inputSchema: {
|
|
1341
|
+
name: z12.string().describe("Cookie name"),
|
|
1342
|
+
value: z12.string().describe("Cookie value"),
|
|
1343
|
+
domain: z12.string().optional().describe("Cookie domain (defaults to current domain)"),
|
|
1344
|
+
path: z12.string().optional().describe('Cookie path (defaults to "/")'),
|
|
1345
|
+
expires: z12.number().optional().describe("Expiry date as Unix timestamp in seconds"),
|
|
1346
|
+
httpOnly: z12.boolean().optional().describe("HttpOnly flag"),
|
|
1347
|
+
secure: z12.boolean().optional().describe("Secure flag"),
|
|
1348
|
+
sameSite: z12.enum(["Strict", "Lax", "None"]).optional().describe("SameSite attribute")
|
|
1349
|
+
}
|
|
1238
1350
|
};
|
|
1239
1351
|
var setCookieTool = async ({
|
|
1240
1352
|
name,
|
|
@@ -1268,8 +1380,12 @@ var setCookieTool = async ({
|
|
|
1268
1380
|
};
|
|
1269
1381
|
}
|
|
1270
1382
|
};
|
|
1271
|
-
var
|
|
1272
|
-
name:
|
|
1383
|
+
var deleteCookiesToolDefinition = {
|
|
1384
|
+
name: "delete_cookies",
|
|
1385
|
+
description: "deletes all cookies or a specific cookie by name",
|
|
1386
|
+
inputSchema: {
|
|
1387
|
+
name: z12.string().optional().describe("Optional cookie name to delete a specific cookie. If not provided, deletes all cookies")
|
|
1388
|
+
}
|
|
1273
1389
|
};
|
|
1274
1390
|
var deleteCookiesTool = async ({ name }) => {
|
|
1275
1391
|
try {
|
|
@@ -1294,10 +1410,15 @@ var deleteCookiesTool = async ({ name }) => {
|
|
|
1294
1410
|
// src/tools/get-accessibility-tree.tool.ts
|
|
1295
1411
|
import { encode as encode2 } from "@toon-format/toon";
|
|
1296
1412
|
import { z as z13 } from "zod";
|
|
1297
|
-
var
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1413
|
+
var getAccessibilityToolDefinition = {
|
|
1414
|
+
name: "get_accessibility",
|
|
1415
|
+
description: "gets accessibility tree snapshot with semantic information about page elements (roles, names, states). Browser-only - use when get_visible_elements does not return expected elements.",
|
|
1416
|
+
inputSchema: {
|
|
1417
|
+
limit: z13.number().optional().describe("Maximum number of nodes to return. Default: 100. Use 0 for unlimited."),
|
|
1418
|
+
offset: z13.number().optional().describe("Number of nodes to skip (for pagination). Default: 0."),
|
|
1419
|
+
roles: z13.array(z13.string()).optional().describe('Filter to specific roles (e.g., ["button", "link", "textbox"]). Default: all roles.'),
|
|
1420
|
+
namedOnly: z13.boolean().optional().describe("Only return nodes with a name/label. Default: true. Filters out anonymous containers.")
|
|
1421
|
+
}
|
|
1301
1422
|
};
|
|
1302
1423
|
function flattenAccessibilityTree(node, result = []) {
|
|
1303
1424
|
if (!node) return result;
|
|
@@ -1348,7 +1469,7 @@ var getAccessibilityTreeTool = async (args) => {
|
|
|
1348
1469
|
}]
|
|
1349
1470
|
};
|
|
1350
1471
|
}
|
|
1351
|
-
const { limit = 100, roles, namedOnly = true } = args || {};
|
|
1472
|
+
const { limit = 100, offset = 0, roles, namedOnly = true } = args || {};
|
|
1352
1473
|
const puppeteer = await browser.getPuppeteer();
|
|
1353
1474
|
const pages = await puppeteer.pages();
|
|
1354
1475
|
if (pages.length === 0) {
|
|
@@ -1374,14 +1495,21 @@ var getAccessibilityTreeTool = async (args) => {
|
|
|
1374
1495
|
const roleSet = new Set(roles.map((r) => r.toLowerCase()));
|
|
1375
1496
|
nodes = nodes.filter((n) => n.role && roleSet.has(n.role.toLowerCase()));
|
|
1376
1497
|
}
|
|
1377
|
-
|
|
1498
|
+
const total = nodes.length;
|
|
1499
|
+
if (offset > 0) {
|
|
1500
|
+
nodes = nodes.slice(offset);
|
|
1501
|
+
}
|
|
1502
|
+
if (limit > 0) {
|
|
1378
1503
|
nodes = nodes.slice(0, limit);
|
|
1379
1504
|
}
|
|
1505
|
+
const result = {
|
|
1506
|
+
total,
|
|
1507
|
+
showing: nodes.length,
|
|
1508
|
+
hasMore: offset + nodes.length < total,
|
|
1509
|
+
nodes
|
|
1510
|
+
};
|
|
1380
1511
|
return {
|
|
1381
|
-
content: [{
|
|
1382
|
-
type: "text",
|
|
1383
|
-
text: encode2(nodes)
|
|
1384
|
-
}]
|
|
1512
|
+
content: [{ type: "text", text: encode2(result) }]
|
|
1385
1513
|
};
|
|
1386
1514
|
} catch (e) {
|
|
1387
1515
|
return {
|
|
@@ -1472,22 +1600,26 @@ function buildAndroidCapabilities(appPath, options) {
|
|
|
1472
1600
|
}
|
|
1473
1601
|
|
|
1474
1602
|
// src/tools/app-session.tool.ts
|
|
1475
|
-
var
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1603
|
+
var startAppToolDefinition = {
|
|
1604
|
+
name: "start_app_session",
|
|
1605
|
+
description: "starts a mobile app session (iOS/Android) via Appium",
|
|
1606
|
+
inputSchema: {
|
|
1607
|
+
platform: z14.enum(["iOS", "Android"]).describe("Mobile platform"),
|
|
1608
|
+
appPath: z14.string().optional().describe("Path to the app file (.app/.apk/.ipa). Required unless noReset=true (connecting to already-running app)"),
|
|
1609
|
+
deviceName: z14.string().describe("Device/emulator/simulator name"),
|
|
1610
|
+
platformVersion: z14.string().optional().describe('OS version (e.g., "17.0", "14")'),
|
|
1611
|
+
automationName: z14.enum(["XCUITest", "UiAutomator2", "Espresso"]).optional().describe("Automation driver name"),
|
|
1612
|
+
appiumHost: z14.string().optional().describe("Appium server hostname (overrides APPIUM_URL env var)"),
|
|
1613
|
+
appiumPort: z14.number().optional().describe("Appium server port (overrides APPIUM_URL_PORT env var)"),
|
|
1614
|
+
appiumPath: z14.string().optional().describe("Appium server path (overrides APPIUM_PATH env var)"),
|
|
1615
|
+
autoGrantPermissions: z14.boolean().optional().describe("Auto-grant app permissions (default: true)"),
|
|
1616
|
+
autoAcceptAlerts: z14.boolean().optional().describe("Auto-accept alerts (default: true)"),
|
|
1617
|
+
autoDismissAlerts: z14.boolean().optional().describe('Auto-dismiss alerts (default: false, will override "autoAcceptAlerts" to undefined if set)'),
|
|
1618
|
+
appWaitActivity: z14.string().optional().describe("Activity to wait for on launch (Android only)"),
|
|
1619
|
+
udid: z14.string().optional().describe('Unique Device Identifier for iOS real device testing (e.g., "00008030-001234567890002E")'),
|
|
1620
|
+
noReset: z14.boolean().optional().describe("Do not reset app state before session (preserves app data). Default: false"),
|
|
1621
|
+
fullReset: z14.boolean().optional().describe("Uninstall app before/after session. Default: true. Set to false with noReset=true to preserve app state completely")
|
|
1622
|
+
}
|
|
1491
1623
|
};
|
|
1492
1624
|
var getState = () => {
|
|
1493
1625
|
const sharedState = getBrowser.__state;
|
|
@@ -1588,10 +1720,14 @@ Appium Server: ${serverConfig.hostname}:${serverConfig.port}${serverConfig.path}
|
|
|
1588
1720
|
|
|
1589
1721
|
// src/tools/gestures.tool.ts
|
|
1590
1722
|
import { z as z15 } from "zod";
|
|
1591
|
-
var
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1723
|
+
var tapElementToolDefinition = {
|
|
1724
|
+
name: "tap_element",
|
|
1725
|
+
description: "taps an element by selector or coordinates (mobile)",
|
|
1726
|
+
inputSchema: {
|
|
1727
|
+
selector: z15.string().optional().describe("Element selector (CSS, XPath, accessibility ID, or UiAutomator)"),
|
|
1728
|
+
x: z15.number().optional().describe("X coordinate for tap (if no selector provided)"),
|
|
1729
|
+
y: z15.number().optional().describe("Y coordinate for tap (if no selector provided)")
|
|
1730
|
+
}
|
|
1595
1731
|
};
|
|
1596
1732
|
var tapElementTool = async (args) => {
|
|
1597
1733
|
try {
|
|
@@ -1622,12 +1758,16 @@ var tapElementTool = async (args) => {
|
|
|
1622
1758
|
};
|
|
1623
1759
|
}
|
|
1624
1760
|
};
|
|
1625
|
-
var
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1761
|
+
var swipeToolDefinition = {
|
|
1762
|
+
name: "swipe",
|
|
1763
|
+
description: "performs a swipe gesture in specified direction (mobile)",
|
|
1764
|
+
inputSchema: {
|
|
1765
|
+
direction: z15.enum(["up", "down", "left", "right"]).describe("Swipe direction"),
|
|
1766
|
+
duration: z15.number().min(100).max(5e3).optional().describe("Swipe duration in milliseconds (default: 500)"),
|
|
1767
|
+
startX: z15.number().optional().describe("Start X coordinate (optional, uses screen center)"),
|
|
1768
|
+
startY: z15.number().optional().describe("Start Y coordinate (optional, uses screen center)"),
|
|
1769
|
+
distance: z15.number().optional().describe("Swipe distance in pixels (optional, uses percentage of screen)")
|
|
1770
|
+
}
|
|
1631
1771
|
};
|
|
1632
1772
|
var swipeTool = async (args) => {
|
|
1633
1773
|
try {
|
|
@@ -1675,11 +1815,15 @@ var swipeTool = async (args) => {
|
|
|
1675
1815
|
};
|
|
1676
1816
|
}
|
|
1677
1817
|
};
|
|
1678
|
-
var
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1818
|
+
var longPressToolDefinition = {
|
|
1819
|
+
name: "long_press",
|
|
1820
|
+
description: "performs a long press on element or coordinates (mobile)",
|
|
1821
|
+
inputSchema: {
|
|
1822
|
+
selector: z15.string().optional().describe("Element selector (CSS, XPath, accessibility ID, or UiAutomator)"),
|
|
1823
|
+
x: z15.number().optional().describe("X coordinate for long press (if no selector provided)"),
|
|
1824
|
+
y: z15.number().optional().describe("Y coordinate for long press (if no selector provided)"),
|
|
1825
|
+
duration: z15.number().min(500).max(1e4).optional().describe("Long press duration in milliseconds (default: 1000)")
|
|
1826
|
+
}
|
|
1683
1827
|
};
|
|
1684
1828
|
var longPressTool = async (args) => {
|
|
1685
1829
|
try {
|
|
@@ -1714,14 +1858,18 @@ var longPressTool = async (args) => {
|
|
|
1714
1858
|
};
|
|
1715
1859
|
}
|
|
1716
1860
|
};
|
|
1717
|
-
var
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1861
|
+
var dragAndDropToolDefinition = {
|
|
1862
|
+
name: "drag_and_drop",
|
|
1863
|
+
description: "drags from one location to another (mobile)",
|
|
1864
|
+
inputSchema: {
|
|
1865
|
+
fromSelector: z15.string().optional().describe("Source element selector"),
|
|
1866
|
+
fromX: z15.number().optional().describe("Source X coordinate"),
|
|
1867
|
+
fromY: z15.number().optional().describe("Source Y coordinate"),
|
|
1868
|
+
toSelector: z15.string().optional().describe("Target element selector"),
|
|
1869
|
+
toX: z15.number().optional().describe("Target X coordinate"),
|
|
1870
|
+
toY: z15.number().optional().describe("Target Y coordinate"),
|
|
1871
|
+
duration: z15.number().min(100).max(5e3).optional().describe("Drag duration in milliseconds (default: 500)")
|
|
1872
|
+
}
|
|
1725
1873
|
};
|
|
1726
1874
|
var dragAndDropTool = async (args) => {
|
|
1727
1875
|
try {
|
|
@@ -1782,8 +1930,12 @@ var dragAndDropTool = async (args) => {
|
|
|
1782
1930
|
|
|
1783
1931
|
// src/tools/app-actions.tool.ts
|
|
1784
1932
|
import { z as z16 } from "zod";
|
|
1785
|
-
var
|
|
1786
|
-
|
|
1933
|
+
var getAppStateToolDefinition = {
|
|
1934
|
+
name: "get_app_state",
|
|
1935
|
+
description: "gets the state of an app (not installed, not running, background, foreground)",
|
|
1936
|
+
inputSchema: {
|
|
1937
|
+
bundleId: z16.string().describe("App bundle ID (e.g., com.example.app)")
|
|
1938
|
+
}
|
|
1787
1939
|
};
|
|
1788
1940
|
var getAppStateTool = async (args) => {
|
|
1789
1941
|
try {
|
|
@@ -1812,8 +1964,12 @@ var getAppStateTool = async (args) => {
|
|
|
1812
1964
|
};
|
|
1813
1965
|
}
|
|
1814
1966
|
};
|
|
1815
|
-
var
|
|
1816
|
-
|
|
1967
|
+
var activateAppToolDefinition = {
|
|
1968
|
+
name: "activate_app",
|
|
1969
|
+
description: "activates/brings an app to foreground",
|
|
1970
|
+
inputSchema: {
|
|
1971
|
+
bundleId: z16.string().describe("App bundle ID to activate (e.g., com.example.app)")
|
|
1972
|
+
}
|
|
1817
1973
|
};
|
|
1818
1974
|
var activateAppTool = async (args) => {
|
|
1819
1975
|
try {
|
|
@@ -1830,8 +1986,12 @@ var activateAppTool = async (args) => {
|
|
|
1830
1986
|
};
|
|
1831
1987
|
}
|
|
1832
1988
|
};
|
|
1833
|
-
var
|
|
1834
|
-
|
|
1989
|
+
var terminateAppToolDefinition = {
|
|
1990
|
+
name: "terminate_app",
|
|
1991
|
+
description: "terminates a running app",
|
|
1992
|
+
inputSchema: {
|
|
1993
|
+
bundleId: z16.string().describe("App bundle ID to terminate (e.g., com.example.app)")
|
|
1994
|
+
}
|
|
1835
1995
|
};
|
|
1836
1996
|
var terminateAppTool = async (args) => {
|
|
1837
1997
|
try {
|
|
@@ -1851,6 +2011,25 @@ var terminateAppTool = async (args) => {
|
|
|
1851
2011
|
|
|
1852
2012
|
// src/tools/context.tool.ts
|
|
1853
2013
|
import { z as z17 } from "zod";
|
|
2014
|
+
var getContextsToolDefinition = {
|
|
2015
|
+
name: "get_contexts",
|
|
2016
|
+
description: "lists available contexts (NATIVE_APP, WEBVIEW)",
|
|
2017
|
+
inputSchema: {}
|
|
2018
|
+
};
|
|
2019
|
+
var getCurrentContextToolDefinition = {
|
|
2020
|
+
name: "get_current_context",
|
|
2021
|
+
description: "shows the currently active context",
|
|
2022
|
+
inputSchema: {}
|
|
2023
|
+
};
|
|
2024
|
+
var switchContextToolDefinition = {
|
|
2025
|
+
name: "switch_context",
|
|
2026
|
+
description: "switches between native and webview contexts",
|
|
2027
|
+
inputSchema: {
|
|
2028
|
+
context: z17.string().describe(
|
|
2029
|
+
'Context name to switch to (e.g., "NATIVE_APP", "WEBVIEW_com.example.app", or use index from get_contexts)'
|
|
2030
|
+
)
|
|
2031
|
+
}
|
|
2032
|
+
};
|
|
1854
2033
|
var getContextsTool = async () => {
|
|
1855
2034
|
try {
|
|
1856
2035
|
const browser = getBrowser();
|
|
@@ -1883,11 +2062,6 @@ var getCurrentContextTool = async () => {
|
|
|
1883
2062
|
};
|
|
1884
2063
|
}
|
|
1885
2064
|
};
|
|
1886
|
-
var switchContextToolArguments = {
|
|
1887
|
-
context: z17.string().describe(
|
|
1888
|
-
'Context name to switch to (e.g., "NATIVE_APP", "WEBVIEW_com.example.app", or use index from get_contexts)'
|
|
1889
|
-
)
|
|
1890
|
-
};
|
|
1891
2065
|
var switchContextTool = async (args) => {
|
|
1892
2066
|
try {
|
|
1893
2067
|
const browser = getBrowser();
|
|
@@ -1922,6 +2096,86 @@ var switchContextTool = async (args) => {
|
|
|
1922
2096
|
|
|
1923
2097
|
// src/tools/device.tool.ts
|
|
1924
2098
|
import { z as z18 } from "zod";
|
|
2099
|
+
var getDeviceInfoToolDefinition = {
|
|
2100
|
+
name: "get_device_info",
|
|
2101
|
+
description: "gets device information (platform, version, screen size)",
|
|
2102
|
+
inputSchema: {}
|
|
2103
|
+
};
|
|
2104
|
+
var getOrientationToolDefinition = {
|
|
2105
|
+
name: "get_orientation",
|
|
2106
|
+
description: "gets current device orientation",
|
|
2107
|
+
inputSchema: {}
|
|
2108
|
+
};
|
|
2109
|
+
var lockDeviceToolDefinition = {
|
|
2110
|
+
name: "lock_device",
|
|
2111
|
+
description: "locks the device screen",
|
|
2112
|
+
inputSchema: {}
|
|
2113
|
+
};
|
|
2114
|
+
var unlockDeviceToolDefinition = {
|
|
2115
|
+
name: "unlock_device",
|
|
2116
|
+
description: "unlocks the device screen",
|
|
2117
|
+
inputSchema: {}
|
|
2118
|
+
};
|
|
2119
|
+
var isDeviceLockedToolDefinition = {
|
|
2120
|
+
name: "is_device_locked",
|
|
2121
|
+
description: "checks if device is locked",
|
|
2122
|
+
inputSchema: {}
|
|
2123
|
+
};
|
|
2124
|
+
var shakeDeviceToolDefinition = {
|
|
2125
|
+
name: "shake_device",
|
|
2126
|
+
description: "shakes the device (iOS only)",
|
|
2127
|
+
inputSchema: {}
|
|
2128
|
+
};
|
|
2129
|
+
var hideKeyboardToolDefinition = {
|
|
2130
|
+
name: "hide_keyboard",
|
|
2131
|
+
description: "hides the on-screen keyboard",
|
|
2132
|
+
inputSchema: {}
|
|
2133
|
+
};
|
|
2134
|
+
var isKeyboardShownToolDefinition = {
|
|
2135
|
+
name: "is_keyboard_shown",
|
|
2136
|
+
description: "checks if keyboard is visible",
|
|
2137
|
+
inputSchema: {}
|
|
2138
|
+
};
|
|
2139
|
+
var openNotificationsToolDefinition = {
|
|
2140
|
+
name: "open_notifications",
|
|
2141
|
+
description: "opens the notifications panel (Android only)",
|
|
2142
|
+
inputSchema: {}
|
|
2143
|
+
};
|
|
2144
|
+
var getGeolocationToolDefinition = {
|
|
2145
|
+
name: "get_geolocation",
|
|
2146
|
+
description: "gets current device geolocation",
|
|
2147
|
+
inputSchema: {}
|
|
2148
|
+
};
|
|
2149
|
+
var rotateDeviceToolDefinition = {
|
|
2150
|
+
name: "rotate_device",
|
|
2151
|
+
description: "rotates device to portrait or landscape orientation",
|
|
2152
|
+
inputSchema: {
|
|
2153
|
+
orientation: z18.enum(["PORTRAIT", "LANDSCAPE"]).describe("Device orientation")
|
|
2154
|
+
}
|
|
2155
|
+
};
|
|
2156
|
+
var sendKeysToolDefinition = {
|
|
2157
|
+
name: "send_keys",
|
|
2158
|
+
description: "sends keys to the app (Android only)",
|
|
2159
|
+
inputSchema: {
|
|
2160
|
+
keys: z18.array(z18.string()).describe('Array of keys to send (e.g., ["h", "e", "l", "l", "o"])')
|
|
2161
|
+
}
|
|
2162
|
+
};
|
|
2163
|
+
var pressKeyCodeToolDefinition = {
|
|
2164
|
+
name: "press_key_code",
|
|
2165
|
+
description: "presses an Android key code (Android only)",
|
|
2166
|
+
inputSchema: {
|
|
2167
|
+
keyCode: z18.number().describe("Android key code (e.g., 4 for BACK, 3 for HOME)")
|
|
2168
|
+
}
|
|
2169
|
+
};
|
|
2170
|
+
var setGeolocationToolDefinition = {
|
|
2171
|
+
name: "set_geolocation",
|
|
2172
|
+
description: "sets device geolocation (latitude, longitude, altitude)",
|
|
2173
|
+
inputSchema: {
|
|
2174
|
+
latitude: z18.number().min(-90).max(90).describe("Latitude coordinate"),
|
|
2175
|
+
longitude: z18.number().min(-180).max(180).describe("Longitude coordinate"),
|
|
2176
|
+
altitude: z18.number().optional().describe("Altitude in meters (optional)")
|
|
2177
|
+
}
|
|
2178
|
+
};
|
|
1925
2179
|
var getDeviceInfoTool = async () => {
|
|
1926
2180
|
try {
|
|
1927
2181
|
const browser = getBrowser();
|
|
@@ -1949,9 +2203,6 @@ ${Object.entries(info).map(([key, value]) => ` ${key}: ${value}`).join("\n")}`
|
|
|
1949
2203
|
};
|
|
1950
2204
|
}
|
|
1951
2205
|
};
|
|
1952
|
-
var rotateDeviceToolArguments = {
|
|
1953
|
-
orientation: z18.enum(["PORTRAIT", "LANDSCAPE"]).describe("Device orientation")
|
|
1954
|
-
};
|
|
1955
2206
|
var rotateDeviceTool = async (args) => {
|
|
1956
2207
|
try {
|
|
1957
2208
|
const browser = getBrowser();
|
|
@@ -2031,9 +2282,6 @@ var shakeDeviceTool = async () => {
|
|
|
2031
2282
|
};
|
|
2032
2283
|
}
|
|
2033
2284
|
};
|
|
2034
|
-
var sendKeysToolArguments = {
|
|
2035
|
-
keys: z18.array(z18.string()).describe('Array of keys to send (e.g., ["h", "e", "l", "l", "o"])')
|
|
2036
|
-
};
|
|
2037
2285
|
var sendKeysTool = async (args) => {
|
|
2038
2286
|
try {
|
|
2039
2287
|
const browser = getBrowser();
|
|
@@ -2048,9 +2296,6 @@ var sendKeysTool = async (args) => {
|
|
|
2048
2296
|
};
|
|
2049
2297
|
}
|
|
2050
2298
|
};
|
|
2051
|
-
var pressKeyCodeToolArguments = {
|
|
2052
|
-
keyCode: z18.number().describe("Android key code (e.g., 4 for BACK, 3 for HOME)")
|
|
2053
|
-
};
|
|
2054
2299
|
var pressKeyCodeTool = async (args) => {
|
|
2055
2300
|
try {
|
|
2056
2301
|
const browser = getBrowser();
|
|
@@ -2125,11 +2370,6 @@ var getGeolocationTool = async () => {
|
|
|
2125
2370
|
};
|
|
2126
2371
|
}
|
|
2127
2372
|
};
|
|
2128
|
-
var setGeolocationToolArguments = {
|
|
2129
|
-
latitude: z18.number().min(-90).max(90).describe("Latitude coordinate"),
|
|
2130
|
-
longitude: z18.number().min(-180).max(180).describe("Longitude coordinate"),
|
|
2131
|
-
altitude: z18.number().optional().describe("Altitude in meters (optional)")
|
|
2132
|
-
};
|
|
2133
2373
|
var setGeolocationTool = async (args) => {
|
|
2134
2374
|
try {
|
|
2135
2375
|
const browser = getBrowser();
|
|
@@ -2153,62 +2393,129 @@ var setGeolocationTool = async (args) => {
|
|
|
2153
2393
|
}
|
|
2154
2394
|
};
|
|
2155
2395
|
|
|
2396
|
+
// package.json
|
|
2397
|
+
var package_default = {
|
|
2398
|
+
name: "@wdio/mcp",
|
|
2399
|
+
author: "Vince Graics",
|
|
2400
|
+
repository: {
|
|
2401
|
+
type: "git",
|
|
2402
|
+
url: "git://github.com/webdriverio/mcp.git"
|
|
2403
|
+
},
|
|
2404
|
+
version: "1.5.1",
|
|
2405
|
+
description: "MCP server with WebdriverIO for browser and mobile app automation (iOS/Android via Appium)",
|
|
2406
|
+
main: "./lib/server.js",
|
|
2407
|
+
module: "./lib/server.js",
|
|
2408
|
+
types: "./lib/server.d.ts",
|
|
2409
|
+
bin: {
|
|
2410
|
+
"wdio-mcp": "lib/server.js"
|
|
2411
|
+
},
|
|
2412
|
+
license: "MIT",
|
|
2413
|
+
publishConfig: {
|
|
2414
|
+
access: "public"
|
|
2415
|
+
},
|
|
2416
|
+
type: "module",
|
|
2417
|
+
files: [
|
|
2418
|
+
"lib",
|
|
2419
|
+
"README.md"
|
|
2420
|
+
],
|
|
2421
|
+
scripts: {
|
|
2422
|
+
prebundle: "rimraf lib --glob ./*.tgz",
|
|
2423
|
+
bundle: "tsup && shx chmod +x lib/server.js",
|
|
2424
|
+
postbundle: "npm pack",
|
|
2425
|
+
lint: "eslint src/ --fix && tsc --noEmit",
|
|
2426
|
+
start: "node lib/server.js",
|
|
2427
|
+
dev: "tsx --watch src/server.ts",
|
|
2428
|
+
prepare: "husky"
|
|
2429
|
+
},
|
|
2430
|
+
dependencies: {
|
|
2431
|
+
"@modelcontextprotocol/sdk": "1.25",
|
|
2432
|
+
"@toon-format/toon": "^2.1.0",
|
|
2433
|
+
"@wdio/protocols": "^9.16.2",
|
|
2434
|
+
"@xmldom/xmldom": "^0.8.11",
|
|
2435
|
+
"puppeteer-core": "^24.35.0",
|
|
2436
|
+
webdriverio: "9.23",
|
|
2437
|
+
zod: "^4.3.5"
|
|
2438
|
+
},
|
|
2439
|
+
devDependencies: {
|
|
2440
|
+
"@release-it/conventional-changelog": "^10.0.4",
|
|
2441
|
+
"@types/node": "^20.11.0",
|
|
2442
|
+
"@wdio/eslint": "^0.1.3",
|
|
2443
|
+
"@wdio/types": "^9.20.0",
|
|
2444
|
+
eslint: "^9.39.2",
|
|
2445
|
+
husky: "^9.1.7",
|
|
2446
|
+
"release-it": "^19.2.3",
|
|
2447
|
+
rimraf: "^6.1.2",
|
|
2448
|
+
shx: "^0.4.0",
|
|
2449
|
+
tsup: "^8.5.1",
|
|
2450
|
+
tsx: "^4.21.0",
|
|
2451
|
+
typescript: "5.9"
|
|
2452
|
+
},
|
|
2453
|
+
packageManager: "pnpm@10.12.4"
|
|
2454
|
+
};
|
|
2455
|
+
|
|
2156
2456
|
// src/server.ts
|
|
2157
2457
|
console.log = (...args) => console.error("[LOG]", ...args);
|
|
2158
2458
|
console.info = (...args) => console.error("[INFO]", ...args);
|
|
2159
2459
|
console.warn = (...args) => console.error("[WARN]", ...args);
|
|
2160
2460
|
console.debug = (...args) => console.error("[DEBUG]", ...args);
|
|
2161
2461
|
var server = new McpServer({
|
|
2162
|
-
|
|
2163
|
-
|
|
2462
|
+
title: "WebdriverIO MCP Server",
|
|
2463
|
+
name: package_default.name,
|
|
2464
|
+
version: package_default.version,
|
|
2465
|
+
description: package_default.description,
|
|
2466
|
+
websiteUrl: "https://github.com/webdriverio/mcp"
|
|
2164
2467
|
}, {
|
|
2468
|
+
instructions: "MCP server for browser and mobile app automation using WebDriverIO. Supports Chrome browser control (headed/headless) and iOS/Android native app testing via Appium.",
|
|
2165
2469
|
capabilities: {
|
|
2166
|
-
resources: {},
|
|
2167
2470
|
tools: {}
|
|
2168
2471
|
}
|
|
2169
2472
|
});
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2473
|
+
var registerTool = (definition, callback) => server.registerTool(definition.name, {
|
|
2474
|
+
description: definition.description,
|
|
2475
|
+
inputSchema: definition.inputSchema
|
|
2476
|
+
}, callback);
|
|
2477
|
+
registerTool(startBrowserToolDefinition, startBrowserTool);
|
|
2478
|
+
registerTool(startAppToolDefinition, startAppTool);
|
|
2479
|
+
registerTool(closeSessionToolDefinition, closeSessionTool);
|
|
2480
|
+
registerTool(navigateToolDefinition, navigateTool);
|
|
2481
|
+
registerTool(getVisibleElementsToolDefinition, getVisibleElementsTool);
|
|
2482
|
+
registerTool(getAccessibilityToolDefinition, getAccessibilityTreeTool);
|
|
2483
|
+
registerTool(scrollDownToolDefinition, scrollDownTool);
|
|
2484
|
+
registerTool(scrollUpToolDefinition, scrollUpTool);
|
|
2485
|
+
registerTool(findElementToolDefinition, findElementTool);
|
|
2486
|
+
registerTool(clickToolDefinition, clickTool);
|
|
2487
|
+
registerTool(clickViaTextToolDefinition, clickToolViaText);
|
|
2488
|
+
registerTool(setValueToolDefinition, setValueTool);
|
|
2489
|
+
registerTool(getElementTextToolDefinition, getElementTextTool);
|
|
2490
|
+
registerTool(isDisplayedToolDefinition, isDisplayedTool);
|
|
2491
|
+
registerTool(takeScreenshotToolDefinition, takeScreenshotTool);
|
|
2492
|
+
registerTool(getCookiesToolDefinition, getCookiesTool);
|
|
2493
|
+
registerTool(setCookieToolDefinition, setCookieTool);
|
|
2494
|
+
registerTool(deleteCookiesToolDefinition, deleteCookiesTool);
|
|
2495
|
+
registerTool(tapElementToolDefinition, tapElementTool);
|
|
2496
|
+
registerTool(swipeToolDefinition, swipeTool);
|
|
2497
|
+
registerTool(longPressToolDefinition, longPressTool);
|
|
2498
|
+
registerTool(dragAndDropToolDefinition, dragAndDropTool);
|
|
2499
|
+
registerTool(getAppStateToolDefinition, getAppStateTool);
|
|
2500
|
+
registerTool(activateAppToolDefinition, activateAppTool);
|
|
2501
|
+
registerTool(terminateAppToolDefinition, terminateAppTool);
|
|
2502
|
+
registerTool(getContextsToolDefinition, getContextsTool);
|
|
2503
|
+
registerTool(getCurrentContextToolDefinition, getCurrentContextTool);
|
|
2504
|
+
registerTool(switchContextToolDefinition, switchContextTool);
|
|
2505
|
+
registerTool(getDeviceInfoToolDefinition, getDeviceInfoTool);
|
|
2506
|
+
registerTool(rotateDeviceToolDefinition, rotateDeviceTool);
|
|
2507
|
+
registerTool(getOrientationToolDefinition, getOrientationTool);
|
|
2508
|
+
registerTool(lockDeviceToolDefinition, lockDeviceTool);
|
|
2509
|
+
registerTool(unlockDeviceToolDefinition, unlockDeviceTool);
|
|
2510
|
+
registerTool(isDeviceLockedToolDefinition, isDeviceLockedTool);
|
|
2511
|
+
registerTool(shakeDeviceToolDefinition, shakeDeviceTool);
|
|
2512
|
+
registerTool(sendKeysToolDefinition, sendKeysTool);
|
|
2513
|
+
registerTool(pressKeyCodeToolDefinition, pressKeyCodeTool);
|
|
2514
|
+
registerTool(hideKeyboardToolDefinition, hideKeyboardTool);
|
|
2515
|
+
registerTool(isKeyboardShownToolDefinition, isKeyboardShownTool);
|
|
2516
|
+
registerTool(openNotificationsToolDefinition, openNotificationsTool);
|
|
2517
|
+
registerTool(getGeolocationToolDefinition, getGeolocationTool);
|
|
2518
|
+
registerTool(setGeolocationToolDefinition, setGeolocationTool);
|
|
2212
2519
|
async function main() {
|
|
2213
2520
|
const transport = new StdioServerTransport();
|
|
2214
2521
|
await server.connect(transport);
|