@midscene/ios 1.5.3 → 1.5.4-beta-20260310030546.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/dist/es/bin.mjs CHANGED
@@ -741,6 +741,17 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
741
741
  }
742
742
  return this;
743
743
  }
744
+ async terminate(bundleId) {
745
+ const resolved = this.resolveBundleId(bundleId) ?? bundleId;
746
+ try {
747
+ debugDevice(`Terminating app: ${resolved}`);
748
+ await this.wdaBackend.terminateApp(resolved);
749
+ debugDevice(`Successfully terminated: ${resolved}`);
750
+ } catch (error) {
751
+ debugDevice(`Error terminating ${resolved}: ${error}`);
752
+ throw new Error(`Failed to terminate ${resolved}: ${error.message}`);
753
+ }
754
+ }
744
755
  async getElementsInfo() {
745
756
  return [];
746
757
  }
@@ -1139,6 +1150,7 @@ const runWdaRequestParamSchema = z.object({
1139
1150
  data: z.object({}).passthrough().optional().describe('Optional request body data as JSON object')
1140
1151
  });
1141
1152
  const launchParamSchema = z.string().describe('App name, bundle ID, or URL to launch. Prioritize using the exact bundle ID or URL the user has provided. If none provided, use the accurate app name.');
1153
+ const terminateParamSchema = z.string().describe('Bundle ID of the app to terminate (close). Use the exact bundle ID, e.g. com.apple.Preferences.');
1142
1154
  const createPlatformActions = (device)=>({
1143
1155
  RunWdaRequest: defineAction({
1144
1156
  name: 'RunWdaRequest',
@@ -1156,6 +1168,15 @@ const createPlatformActions = (device)=>({
1156
1168
  await device.launch(param);
1157
1169
  }
1158
1170
  }),
1171
+ Terminate: defineAction({
1172
+ name: 'Terminate',
1173
+ description: 'Terminate (close) an iOS app by its bundle ID',
1174
+ interfaceAlias: 'terminate',
1175
+ paramSchema: terminateParamSchema,
1176
+ call: async (param)=>{
1177
+ await device.terminate(param);
1178
+ }
1179
+ }),
1159
1180
  IOSHomeButton: defineAction({
1160
1181
  name: 'IOSHomeButton',
1161
1182
  description: 'Trigger the system "home" operation on iOS devices',
@@ -1188,11 +1209,12 @@ class IOSAgent extends Agent {
1188
1209
  return (...args)=>action(args[0]);
1189
1210
  }
1190
1211
  constructor(device, opts){
1191
- super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1212
+ super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "terminate", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1192
1213
  this.appNameMapping = mergeAndNormalizeAppNameMapping(defaultAppNameMapping, opts?.appNameMapping);
1193
1214
  device.setAppNameMapping(this.appNameMapping);
1194
1215
  this.launch = this.createActionWrapper('Launch');
1195
1216
  this.runWdaRequest = this.createActionWrapper('RunWdaRequest');
1217
+ this.terminate = this.createActionWrapper('Terminate');
1196
1218
  this.home = this.createActionWrapper('IOSHomeButton');
1197
1219
  this.appSwitcher = this.createActionWrapper('IOSAppSwitcher');
1198
1220
  }
package/dist/es/cli.mjs CHANGED
@@ -739,6 +739,17 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
739
739
  }
740
740
  return this;
741
741
  }
742
+ async terminate(bundleId) {
743
+ const resolved = this.resolveBundleId(bundleId) ?? bundleId;
744
+ try {
745
+ debugDevice(`Terminating app: ${resolved}`);
746
+ await this.wdaBackend.terminateApp(resolved);
747
+ debugDevice(`Successfully terminated: ${resolved}`);
748
+ } catch (error) {
749
+ debugDevice(`Error terminating ${resolved}: ${error}`);
750
+ throw new Error(`Failed to terminate ${resolved}: ${error.message}`);
751
+ }
752
+ }
742
753
  async getElementsInfo() {
743
754
  return [];
744
755
  }
@@ -1137,6 +1148,7 @@ const runWdaRequestParamSchema = z.object({
1137
1148
  data: z.object({}).passthrough().optional().describe('Optional request body data as JSON object')
1138
1149
  });
1139
1150
  const launchParamSchema = z.string().describe('App name, bundle ID, or URL to launch. Prioritize using the exact bundle ID or URL the user has provided. If none provided, use the accurate app name.');
1151
+ const terminateParamSchema = z.string().describe('Bundle ID of the app to terminate (close). Use the exact bundle ID, e.g. com.apple.Preferences.');
1140
1152
  const createPlatformActions = (device)=>({
1141
1153
  RunWdaRequest: defineAction({
1142
1154
  name: 'RunWdaRequest',
@@ -1154,6 +1166,15 @@ const createPlatformActions = (device)=>({
1154
1166
  await device.launch(param);
1155
1167
  }
1156
1168
  }),
1169
+ Terminate: defineAction({
1170
+ name: 'Terminate',
1171
+ description: 'Terminate (close) an iOS app by its bundle ID',
1172
+ interfaceAlias: 'terminate',
1173
+ paramSchema: terminateParamSchema,
1174
+ call: async (param)=>{
1175
+ await device.terminate(param);
1176
+ }
1177
+ }),
1157
1178
  IOSHomeButton: defineAction({
1158
1179
  name: 'IOSHomeButton',
1159
1180
  description: 'Trigger the system "home" operation on iOS devices',
@@ -1186,11 +1207,12 @@ class IOSAgent extends Agent {
1186
1207
  return (...args)=>action(args[0]);
1187
1208
  }
1188
1209
  constructor(device, opts){
1189
- super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1210
+ super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "terminate", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1190
1211
  this.appNameMapping = mergeAndNormalizeAppNameMapping(defaultAppNameMapping, opts?.appNameMapping);
1191
1212
  device.setAppNameMapping(this.appNameMapping);
1192
1213
  this.launch = this.createActionWrapper('Launch');
1193
1214
  this.runWdaRequest = this.createActionWrapper('RunWdaRequest');
1215
+ this.terminate = this.createActionWrapper('Terminate');
1194
1216
  this.home = this.createActionWrapper('IOSHomeButton');
1195
1217
  this.appSwitcher = this.createActionWrapper('IOSAppSwitcher');
1196
1218
  }
package/dist/es/index.mjs CHANGED
@@ -8,6 +8,7 @@ import { getDebug } from "@midscene/shared/logger";
8
8
  import { mergeAndNormalizeAppNameMapping, normalizeForComparison } from "@midscene/shared/utils";
9
9
  import { WDAManager, WebDriverClient } from "@midscene/webdriver";
10
10
  import { Agent } from "@midscene/core/agent";
11
+ import { BaseMidsceneTools } from "@midscene/shared/mcp";
11
12
  import { overrideAIConfig } from "@midscene/shared/env";
12
13
  import { exec } from "node:child_process";
13
14
  import { platform } from "node:os";
@@ -557,6 +558,17 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
557
558
  }
558
559
  return this;
559
560
  }
561
+ async terminate(bundleId) {
562
+ const resolved = this.resolveBundleId(bundleId) ?? bundleId;
563
+ try {
564
+ debugDevice(`Terminating app: ${resolved}`);
565
+ await this.wdaBackend.terminateApp(resolved);
566
+ debugDevice(`Successfully terminated: ${resolved}`);
567
+ } catch (error) {
568
+ debugDevice(`Error terminating ${resolved}: ${error}`);
569
+ throw new Error(`Failed to terminate ${resolved}: ${error.message}`);
570
+ }
571
+ }
560
572
  async getElementsInfo() {
561
573
  return [];
562
574
  }
@@ -955,6 +967,7 @@ const runWdaRequestParamSchema = z.object({
955
967
  data: z.object({}).passthrough().optional().describe('Optional request body data as JSON object')
956
968
  });
957
969
  const launchParamSchema = z.string().describe('App name, bundle ID, or URL to launch. Prioritize using the exact bundle ID or URL the user has provided. If none provided, use the accurate app name.');
970
+ const terminateParamSchema = z.string().describe('Bundle ID of the app to terminate (close). Use the exact bundle ID, e.g. com.apple.Preferences.');
958
971
  const createPlatformActions = (device)=>({
959
972
  RunWdaRequest: defineAction({
960
973
  name: 'RunWdaRequest',
@@ -972,6 +985,15 @@ const createPlatformActions = (device)=>({
972
985
  await device.launch(param);
973
986
  }
974
987
  }),
988
+ Terminate: defineAction({
989
+ name: 'Terminate',
990
+ description: 'Terminate (close) an iOS app by its bundle ID',
991
+ interfaceAlias: 'terminate',
992
+ paramSchema: terminateParamSchema,
993
+ call: async (param)=>{
994
+ await device.terminate(param);
995
+ }
996
+ }),
975
997
  IOSHomeButton: defineAction({
976
998
  name: 'IOSHomeButton',
977
999
  description: 'Trigger the system "home" operation on iOS devices',
@@ -1188,11 +1210,12 @@ class IOSAgent extends Agent {
1188
1210
  return (...args)=>action(args[0]);
1189
1211
  }
1190
1212
  constructor(device, opts){
1191
- super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1213
+ super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "terminate", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1192
1214
  this.appNameMapping = mergeAndNormalizeAppNameMapping(defaultAppNameMapping, opts?.appNameMapping);
1193
1215
  device.setAppNameMapping(this.appNameMapping);
1194
1216
  this.launch = this.createActionWrapper('Launch');
1195
1217
  this.runWdaRequest = this.createActionWrapper('RunWdaRequest');
1218
+ this.terminate = this.createActionWrapper('Terminate');
1196
1219
  this.home = this.createActionWrapper('IOSHomeButton');
1197
1220
  this.appSwitcher = this.createActionWrapper('IOSAppSwitcher');
1198
1221
  }
@@ -1203,6 +1226,49 @@ async function agentFromWebDriverAgent(opts) {
1203
1226
  await device.connect();
1204
1227
  return new IOSAgent(device, opts);
1205
1228
  }
1229
+ const debug = getDebug('mcp:ios-tools');
1230
+ class IOSMidsceneTools extends BaseMidsceneTools {
1231
+ createTemporaryDevice() {
1232
+ return new IOSDevice({});
1233
+ }
1234
+ async ensureAgent() {
1235
+ if (this.agent) return this.agent;
1236
+ debug('Creating iOS agent with WebDriverAgent');
1237
+ this.agent = await agentFromWebDriverAgent({
1238
+ autoDismissKeyboard: false
1239
+ });
1240
+ return this.agent;
1241
+ }
1242
+ preparePlatformTools() {
1243
+ return [
1244
+ {
1245
+ name: 'ios_connect',
1246
+ description: 'Connect to iOS device or simulator via WebDriverAgent',
1247
+ schema: {},
1248
+ handler: async ()=>{
1249
+ const agent = await this.ensureAgent();
1250
+ const screenshot = await agent.page.screenshotBase64();
1251
+ return {
1252
+ content: [
1253
+ {
1254
+ type: 'text',
1255
+ text: 'Connected to iOS device'
1256
+ },
1257
+ ...this.buildScreenshotContent(screenshot)
1258
+ ],
1259
+ isError: false
1260
+ };
1261
+ }
1262
+ },
1263
+ {
1264
+ name: 'ios_disconnect',
1265
+ description: 'Disconnect from current iOS device and release WebDriverAgent resources',
1266
+ schema: {},
1267
+ handler: this.createDisconnectHandler('iOS device')
1268
+ }
1269
+ ];
1270
+ }
1271
+ }
1206
1272
  const execAsync = promisify(exec);
1207
1273
  const debugUtils = getDebug('ios:utils');
1208
1274
  function checkMacOSPlatform() {
@@ -1249,4 +1315,4 @@ async function checkIOSEnvironment() {
1249
1315
  };
1250
1316
  }
1251
1317
  }
1252
- export { IOSAgent, IOSDevice, IOSWebDriverClient, agentFromWebDriverAgent, checkIOSEnvironment, overrideAIConfig };
1318
+ export { IOSAgent, IOSDevice, IOSMidsceneTools, IOSWebDriverClient, agentFromWebDriverAgent, checkIOSEnvironment, overrideAIConfig };
@@ -738,6 +738,17 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
738
738
  }
739
739
  return this;
740
740
  }
741
+ async terminate(bundleId) {
742
+ const resolved = this.resolveBundleId(bundleId) ?? bundleId;
743
+ try {
744
+ debugDevice(`Terminating app: ${resolved}`);
745
+ await this.wdaBackend.terminateApp(resolved);
746
+ debugDevice(`Successfully terminated: ${resolved}`);
747
+ } catch (error) {
748
+ debugDevice(`Error terminating ${resolved}: ${error}`);
749
+ throw new Error(`Failed to terminate ${resolved}: ${error.message}`);
750
+ }
751
+ }
741
752
  async getElementsInfo() {
742
753
  return [];
743
754
  }
@@ -1136,6 +1147,7 @@ const runWdaRequestParamSchema = z.object({
1136
1147
  data: z.object({}).passthrough().optional().describe('Optional request body data as JSON object')
1137
1148
  });
1138
1149
  const launchParamSchema = z.string().describe('App name, bundle ID, or URL to launch. Prioritize using the exact bundle ID or URL the user has provided. If none provided, use the accurate app name.');
1150
+ const terminateParamSchema = z.string().describe('Bundle ID of the app to terminate (close). Use the exact bundle ID, e.g. com.apple.Preferences.');
1139
1151
  const createPlatformActions = (device)=>({
1140
1152
  RunWdaRequest: defineAction({
1141
1153
  name: 'RunWdaRequest',
@@ -1153,6 +1165,15 @@ const createPlatformActions = (device)=>({
1153
1165
  await device.launch(param);
1154
1166
  }
1155
1167
  }),
1168
+ Terminate: defineAction({
1169
+ name: 'Terminate',
1170
+ description: 'Terminate (close) an iOS app by its bundle ID',
1171
+ interfaceAlias: 'terminate',
1172
+ paramSchema: terminateParamSchema,
1173
+ call: async (param)=>{
1174
+ await device.terminate(param);
1175
+ }
1176
+ }),
1156
1177
  IOSHomeButton: defineAction({
1157
1178
  name: 'IOSHomeButton',
1158
1179
  description: 'Trigger the system "home" operation on iOS devices',
@@ -1185,11 +1206,12 @@ class IOSAgent extends Agent {
1185
1206
  return (...args)=>action(args[0]);
1186
1207
  }
1187
1208
  constructor(device, opts){
1188
- super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1209
+ super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "terminate", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1189
1210
  this.appNameMapping = mergeAndNormalizeAppNameMapping(defaultAppNameMapping, opts?.appNameMapping);
1190
1211
  device.setAppNameMapping(this.appNameMapping);
1191
1212
  this.launch = this.createActionWrapper('Launch');
1192
1213
  this.runWdaRequest = this.createActionWrapper('RunWdaRequest');
1214
+ this.terminate = this.createActionWrapper('Terminate');
1193
1215
  this.home = this.createActionWrapper('IOSHomeButton');
1194
1216
  this.appSwitcher = this.createActionWrapper('IOSAppSwitcher');
1195
1217
  }
@@ -1250,7 +1272,7 @@ class IOSMCPServer extends BaseMCPServer {
1250
1272
  constructor(toolsManager){
1251
1273
  super({
1252
1274
  name: '@midscene/ios-mcp',
1253
- version: "1.5.3",
1275
+ version: "1.5.4-beta-20260310030546.0",
1254
1276
  description: 'Control the iOS device using natural language commands'
1255
1277
  }, toolsManager);
1256
1278
  }
package/dist/lib/bin.js CHANGED
@@ -766,6 +766,17 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
766
766
  }
767
767
  return this;
768
768
  }
769
+ async terminate(bundleId) {
770
+ const resolved = this.resolveBundleId(bundleId) ?? bundleId;
771
+ try {
772
+ debugDevice(`Terminating app: ${resolved}`);
773
+ await this.wdaBackend.terminateApp(resolved);
774
+ debugDevice(`Successfully terminated: ${resolved}`);
775
+ } catch (error) {
776
+ debugDevice(`Error terminating ${resolved}: ${error}`);
777
+ throw new Error(`Failed to terminate ${resolved}: ${error.message}`);
778
+ }
779
+ }
769
780
  async getElementsInfo() {
770
781
  return [];
771
782
  }
@@ -1164,6 +1175,7 @@ const runWdaRequestParamSchema = core_namespaceObject.z.object({
1164
1175
  data: core_namespaceObject.z.object({}).passthrough().optional().describe('Optional request body data as JSON object')
1165
1176
  });
1166
1177
  const launchParamSchema = core_namespaceObject.z.string().describe('App name, bundle ID, or URL to launch. Prioritize using the exact bundle ID or URL the user has provided. If none provided, use the accurate app name.');
1178
+ const terminateParamSchema = core_namespaceObject.z.string().describe('Bundle ID of the app to terminate (close). Use the exact bundle ID, e.g. com.apple.Preferences.');
1167
1179
  const createPlatformActions = (device)=>({
1168
1180
  RunWdaRequest: (0, device_namespaceObject.defineAction)({
1169
1181
  name: 'RunWdaRequest',
@@ -1181,6 +1193,15 @@ const createPlatformActions = (device)=>({
1181
1193
  await device.launch(param);
1182
1194
  }
1183
1195
  }),
1196
+ Terminate: (0, device_namespaceObject.defineAction)({
1197
+ name: 'Terminate',
1198
+ description: 'Terminate (close) an iOS app by its bundle ID',
1199
+ interfaceAlias: 'terminate',
1200
+ paramSchema: terminateParamSchema,
1201
+ call: async (param)=>{
1202
+ await device.terminate(param);
1203
+ }
1204
+ }),
1184
1205
  IOSHomeButton: (0, device_namespaceObject.defineAction)({
1185
1206
  name: 'IOSHomeButton',
1186
1207
  description: 'Trigger the system "home" operation on iOS devices',
@@ -1213,11 +1234,12 @@ class IOSAgent extends agent_namespaceObject.Agent {
1213
1234
  return (...args)=>action(args[0]);
1214
1235
  }
1215
1236
  constructor(device, opts){
1216
- super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1237
+ super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "terminate", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1217
1238
  this.appNameMapping = (0, utils_namespaceObject.mergeAndNormalizeAppNameMapping)(defaultAppNameMapping, opts?.appNameMapping);
1218
1239
  device.setAppNameMapping(this.appNameMapping);
1219
1240
  this.launch = this.createActionWrapper('Launch');
1220
1241
  this.runWdaRequest = this.createActionWrapper('RunWdaRequest');
1242
+ this.terminate = this.createActionWrapper('Terminate');
1221
1243
  this.home = this.createActionWrapper('IOSHomeButton');
1222
1244
  this.appSwitcher = this.createActionWrapper('IOSAppSwitcher');
1223
1245
  }
package/dist/lib/cli.js CHANGED
@@ -763,6 +763,17 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
763
763
  }
764
764
  return this;
765
765
  }
766
+ async terminate(bundleId) {
767
+ const resolved = this.resolveBundleId(bundleId) ?? bundleId;
768
+ try {
769
+ debugDevice(`Terminating app: ${resolved}`);
770
+ await this.wdaBackend.terminateApp(resolved);
771
+ debugDevice(`Successfully terminated: ${resolved}`);
772
+ } catch (error) {
773
+ debugDevice(`Error terminating ${resolved}: ${error}`);
774
+ throw new Error(`Failed to terminate ${resolved}: ${error.message}`);
775
+ }
776
+ }
766
777
  async getElementsInfo() {
767
778
  return [];
768
779
  }
@@ -1161,6 +1172,7 @@ const runWdaRequestParamSchema = core_namespaceObject.z.object({
1161
1172
  data: core_namespaceObject.z.object({}).passthrough().optional().describe('Optional request body data as JSON object')
1162
1173
  });
1163
1174
  const launchParamSchema = core_namespaceObject.z.string().describe('App name, bundle ID, or URL to launch. Prioritize using the exact bundle ID or URL the user has provided. If none provided, use the accurate app name.');
1175
+ const terminateParamSchema = core_namespaceObject.z.string().describe('Bundle ID of the app to terminate (close). Use the exact bundle ID, e.g. com.apple.Preferences.');
1164
1176
  const createPlatformActions = (device)=>({
1165
1177
  RunWdaRequest: (0, device_namespaceObject.defineAction)({
1166
1178
  name: 'RunWdaRequest',
@@ -1178,6 +1190,15 @@ const createPlatformActions = (device)=>({
1178
1190
  await device.launch(param);
1179
1191
  }
1180
1192
  }),
1193
+ Terminate: (0, device_namespaceObject.defineAction)({
1194
+ name: 'Terminate',
1195
+ description: 'Terminate (close) an iOS app by its bundle ID',
1196
+ interfaceAlias: 'terminate',
1197
+ paramSchema: terminateParamSchema,
1198
+ call: async (param)=>{
1199
+ await device.terminate(param);
1200
+ }
1201
+ }),
1181
1202
  IOSHomeButton: (0, device_namespaceObject.defineAction)({
1182
1203
  name: 'IOSHomeButton',
1183
1204
  description: 'Trigger the system "home" operation on iOS devices',
@@ -1210,11 +1231,12 @@ class IOSAgent extends agent_namespaceObject.Agent {
1210
1231
  return (...args)=>action(args[0]);
1211
1232
  }
1212
1233
  constructor(device, opts){
1213
- super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1234
+ super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "terminate", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1214
1235
  this.appNameMapping = (0, utils_namespaceObject.mergeAndNormalizeAppNameMapping)(defaultAppNameMapping, opts?.appNameMapping);
1215
1236
  device.setAppNameMapping(this.appNameMapping);
1216
1237
  this.launch = this.createActionWrapper('Launch');
1217
1238
  this.runWdaRequest = this.createActionWrapper('RunWdaRequest');
1239
+ this.terminate = this.createActionWrapper('Terminate');
1218
1240
  this.home = this.createActionWrapper('IOSHomeButton');
1219
1241
  this.appSwitcher = this.createActionWrapper('IOSAppSwitcher');
1220
1242
  }
package/dist/lib/index.js CHANGED
@@ -33,9 +33,10 @@ var __webpack_require__ = {};
33
33
  var __webpack_exports__ = {};
34
34
  __webpack_require__.r(__webpack_exports__);
35
35
  __webpack_require__.d(__webpack_exports__, {
36
- overrideAIConfig: ()=>env_namespaceObject.overrideAIConfig,
36
+ IOSMidsceneTools: ()=>IOSMidsceneTools,
37
37
  IOSAgent: ()=>IOSAgent,
38
38
  checkIOSEnvironment: ()=>checkIOSEnvironment,
39
+ overrideAIConfig: ()=>env_namespaceObject.overrideAIConfig,
39
40
  IOSDevice: ()=>IOSDevice,
40
41
  IOSWebDriverClient: ()=>IOSWebDriverClient,
41
42
  agentFromWebDriverAgent: ()=>agentFromWebDriverAgent
@@ -595,6 +596,17 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
595
596
  }
596
597
  return this;
597
598
  }
599
+ async terminate(bundleId) {
600
+ const resolved = this.resolveBundleId(bundleId) ?? bundleId;
601
+ try {
602
+ debugDevice(`Terminating app: ${resolved}`);
603
+ await this.wdaBackend.terminateApp(resolved);
604
+ debugDevice(`Successfully terminated: ${resolved}`);
605
+ } catch (error) {
606
+ debugDevice(`Error terminating ${resolved}: ${error}`);
607
+ throw new Error(`Failed to terminate ${resolved}: ${error.message}`);
608
+ }
609
+ }
598
610
  async getElementsInfo() {
599
611
  return [];
600
612
  }
@@ -993,6 +1005,7 @@ const runWdaRequestParamSchema = core_namespaceObject.z.object({
993
1005
  data: core_namespaceObject.z.object({}).passthrough().optional().describe('Optional request body data as JSON object')
994
1006
  });
995
1007
  const launchParamSchema = core_namespaceObject.z.string().describe('App name, bundle ID, or URL to launch. Prioritize using the exact bundle ID or URL the user has provided. If none provided, use the accurate app name.');
1008
+ const terminateParamSchema = core_namespaceObject.z.string().describe('Bundle ID of the app to terminate (close). Use the exact bundle ID, e.g. com.apple.Preferences.');
996
1009
  const createPlatformActions = (device)=>({
997
1010
  RunWdaRequest: (0, device_namespaceObject.defineAction)({
998
1011
  name: 'RunWdaRequest',
@@ -1010,6 +1023,15 @@ const createPlatformActions = (device)=>({
1010
1023
  await device.launch(param);
1011
1024
  }
1012
1025
  }),
1026
+ Terminate: (0, device_namespaceObject.defineAction)({
1027
+ name: 'Terminate',
1028
+ description: 'Terminate (close) an iOS app by its bundle ID',
1029
+ interfaceAlias: 'terminate',
1030
+ paramSchema: terminateParamSchema,
1031
+ call: async (param)=>{
1032
+ await device.terminate(param);
1033
+ }
1034
+ }),
1013
1035
  IOSHomeButton: (0, device_namespaceObject.defineAction)({
1014
1036
  name: 'IOSHomeButton',
1015
1037
  description: 'Trigger the system "home" operation on iOS devices',
@@ -1227,11 +1249,12 @@ class IOSAgent extends agent_namespaceObject.Agent {
1227
1249
  return (...args)=>action(args[0]);
1228
1250
  }
1229
1251
  constructor(device, opts){
1230
- super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1252
+ super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "terminate", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1231
1253
  this.appNameMapping = (0, shared_utils_namespaceObject.mergeAndNormalizeAppNameMapping)(defaultAppNameMapping, opts?.appNameMapping);
1232
1254
  device.setAppNameMapping(this.appNameMapping);
1233
1255
  this.launch = this.createActionWrapper('Launch');
1234
1256
  this.runWdaRequest = this.createActionWrapper('RunWdaRequest');
1257
+ this.terminate = this.createActionWrapper('Terminate');
1235
1258
  this.home = this.createActionWrapper('IOSHomeButton');
1236
1259
  this.appSwitcher = this.createActionWrapper('IOSAppSwitcher');
1237
1260
  }
@@ -1242,6 +1265,50 @@ async function agentFromWebDriverAgent(opts) {
1242
1265
  await device.connect();
1243
1266
  return new IOSAgent(device, opts);
1244
1267
  }
1268
+ const mcp_namespaceObject = require("@midscene/shared/mcp");
1269
+ const debug = (0, logger_namespaceObject.getDebug)('mcp:ios-tools');
1270
+ class IOSMidsceneTools extends mcp_namespaceObject.BaseMidsceneTools {
1271
+ createTemporaryDevice() {
1272
+ return new IOSDevice({});
1273
+ }
1274
+ async ensureAgent() {
1275
+ if (this.agent) return this.agent;
1276
+ debug('Creating iOS agent with WebDriverAgent');
1277
+ this.agent = await agentFromWebDriverAgent({
1278
+ autoDismissKeyboard: false
1279
+ });
1280
+ return this.agent;
1281
+ }
1282
+ preparePlatformTools() {
1283
+ return [
1284
+ {
1285
+ name: 'ios_connect',
1286
+ description: 'Connect to iOS device or simulator via WebDriverAgent',
1287
+ schema: {},
1288
+ handler: async ()=>{
1289
+ const agent = await this.ensureAgent();
1290
+ const screenshot = await agent.page.screenshotBase64();
1291
+ return {
1292
+ content: [
1293
+ {
1294
+ type: 'text',
1295
+ text: 'Connected to iOS device'
1296
+ },
1297
+ ...this.buildScreenshotContent(screenshot)
1298
+ ],
1299
+ isError: false
1300
+ };
1301
+ }
1302
+ },
1303
+ {
1304
+ name: 'ios_disconnect',
1305
+ description: 'Disconnect from current iOS device and release WebDriverAgent resources',
1306
+ schema: {},
1307
+ handler: this.createDisconnectHandler('iOS device')
1308
+ }
1309
+ ];
1310
+ }
1311
+ }
1245
1312
  const env_namespaceObject = require("@midscene/shared/env");
1246
1313
  const external_node_child_process_namespaceObject = require("node:child_process");
1247
1314
  const external_node_os_namespaceObject = require("node:os");
@@ -1294,6 +1361,7 @@ async function checkIOSEnvironment() {
1294
1361
  }
1295
1362
  exports.IOSAgent = __webpack_exports__.IOSAgent;
1296
1363
  exports.IOSDevice = __webpack_exports__.IOSDevice;
1364
+ exports.IOSMidsceneTools = __webpack_exports__.IOSMidsceneTools;
1297
1365
  exports.IOSWebDriverClient = __webpack_exports__.IOSWebDriverClient;
1298
1366
  exports.agentFromWebDriverAgent = __webpack_exports__.agentFromWebDriverAgent;
1299
1367
  exports.checkIOSEnvironment = __webpack_exports__.checkIOSEnvironment;
@@ -1301,6 +1369,7 @@ exports.overrideAIConfig = __webpack_exports__.overrideAIConfig;
1301
1369
  for(var __rspack_i in __webpack_exports__)if (-1 === [
1302
1370
  "IOSAgent",
1303
1371
  "IOSDevice",
1372
+ "IOSMidsceneTools",
1304
1373
  "IOSWebDriverClient",
1305
1374
  "agentFromWebDriverAgent",
1306
1375
  "checkIOSEnvironment",
@@ -778,6 +778,17 @@ ScreenSize: ${size.width}x${size.height} (DPR: ${size.scale})
778
778
  }
779
779
  return this;
780
780
  }
781
+ async terminate(bundleId) {
782
+ const resolved = this.resolveBundleId(bundleId) ?? bundleId;
783
+ try {
784
+ debugDevice(`Terminating app: ${resolved}`);
785
+ await this.wdaBackend.terminateApp(resolved);
786
+ debugDevice(`Successfully terminated: ${resolved}`);
787
+ } catch (error) {
788
+ debugDevice(`Error terminating ${resolved}: ${error}`);
789
+ throw new Error(`Failed to terminate ${resolved}: ${error.message}`);
790
+ }
791
+ }
781
792
  async getElementsInfo() {
782
793
  return [];
783
794
  }
@@ -1176,6 +1187,7 @@ const runWdaRequestParamSchema = core_namespaceObject.z.object({
1176
1187
  data: core_namespaceObject.z.object({}).passthrough().optional().describe('Optional request body data as JSON object')
1177
1188
  });
1178
1189
  const launchParamSchema = core_namespaceObject.z.string().describe('App name, bundle ID, or URL to launch. Prioritize using the exact bundle ID or URL the user has provided. If none provided, use the accurate app name.');
1190
+ const terminateParamSchema = core_namespaceObject.z.string().describe('Bundle ID of the app to terminate (close). Use the exact bundle ID, e.g. com.apple.Preferences.');
1179
1191
  const createPlatformActions = (device)=>({
1180
1192
  RunWdaRequest: (0, device_namespaceObject.defineAction)({
1181
1193
  name: 'RunWdaRequest',
@@ -1193,6 +1205,15 @@ const createPlatformActions = (device)=>({
1193
1205
  await device.launch(param);
1194
1206
  }
1195
1207
  }),
1208
+ Terminate: (0, device_namespaceObject.defineAction)({
1209
+ name: 'Terminate',
1210
+ description: 'Terminate (close) an iOS app by its bundle ID',
1211
+ interfaceAlias: 'terminate',
1212
+ paramSchema: terminateParamSchema,
1213
+ call: async (param)=>{
1214
+ await device.terminate(param);
1215
+ }
1216
+ }),
1196
1217
  IOSHomeButton: (0, device_namespaceObject.defineAction)({
1197
1218
  name: 'IOSHomeButton',
1198
1219
  description: 'Trigger the system "home" operation on iOS devices',
@@ -1225,11 +1246,12 @@ class IOSAgent extends agent_namespaceObject.Agent {
1225
1246
  return (...args)=>action(args[0]);
1226
1247
  }
1227
1248
  constructor(device, opts){
1228
- super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1249
+ super(device, opts), agent_define_property(this, "launch", void 0), agent_define_property(this, "runWdaRequest", void 0), agent_define_property(this, "terminate", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "appSwitcher", void 0), agent_define_property(this, "appNameMapping", void 0);
1229
1250
  this.appNameMapping = (0, utils_namespaceObject.mergeAndNormalizeAppNameMapping)(defaultAppNameMapping, opts?.appNameMapping);
1230
1251
  device.setAppNameMapping(this.appNameMapping);
1231
1252
  this.launch = this.createActionWrapper('Launch');
1232
1253
  this.runWdaRequest = this.createActionWrapper('RunWdaRequest');
1254
+ this.terminate = this.createActionWrapper('Terminate');
1233
1255
  this.home = this.createActionWrapper('IOSHomeButton');
1234
1256
  this.appSwitcher = this.createActionWrapper('IOSAppSwitcher');
1235
1257
  }
@@ -1290,7 +1312,7 @@ class IOSMCPServer extends mcp_namespaceObject.BaseMCPServer {
1290
1312
  constructor(toolsManager){
1291
1313
  super({
1292
1314
  name: '@midscene/ios-mcp',
1293
- version: "1.5.3",
1315
+ version: "1.5.4-beta-20260310030546.0",
1294
1316
  description: 'Control the iOS device using natural language commands'
1295
1317
  }, toolsManager);
1296
1318
  }