appium-mcp 1.26.0 → 1.27.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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [1.27.0](https://github.com/appium/appium-mcp/compare/v1.26.0...v1.27.0) (2026-03-14)
2
+
3
+ ### Features
4
+
5
+ * add geolocation tools (set, get, reset) ([#206](https://github.com/appium/appium-mcp/issues/206)) ([78bcca7](https://github.com/appium/appium-mcp/commit/78bcca78f2eb6ede8c667e82a2b23a898960f32b))
6
+
1
7
  ## [1.26.0](https://github.com/appium/appium-mcp/compare/v1.25.0...v1.26.0) (2026-03-11)
2
8
 
3
9
  ### Features
package/README.md CHANGED
@@ -280,6 +280,9 @@ MCP Appium provides a comprehensive set of tools organized into the following ca
280
280
  | `appium_get_page_source` | Get the page source (XML) from the current screen |
281
281
  | `appium_get_orientation` | Get the current device/screen orientation (LANDSCAPE or PORTRAIT). |
282
282
  | `appium_set_orientation` | Set the device/screen orientation to LANDSCAPE or PORTRAIT (rotate screen). |
283
+ | `appium_set_geolocation` | Set the GPS coordinates (latitude, longitude, altitude) of the device. |
284
+ | `appium_get_geolocation` | Get the current GPS coordinates (latitude, longitude, altitude) of the device. |
285
+ | `appium_reset_geolocation` | Reset the simulated/mocked geolocation back to the system default. On iOS, clears the simulated location. On Android real devices, removes the mock location provider. Not supported on Android emulators. |
283
286
 
284
287
  ### App Management
285
288
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AA2ClC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAkI3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAgDlC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAqI3D"}
@@ -9,6 +9,7 @@ import selectPlatform from './session/select-platform.js';
9
9
  import selectDevice from './session/select-device.js';
10
10
  import openNotifications from './session/open-notifications.js';
11
11
  import { lockDevice, unlockDevice } from './session/lock.js';
12
+ import { setGeolocation, getGeolocation, resetGeolocation, } from './session/geolocation.js';
12
13
  import bootSimulator from './ios/boot-simulator.js';
13
14
  import setupWDA from './ios/setup-wda.js';
14
15
  import installWDA from './ios/install-wda.js';
@@ -111,6 +112,9 @@ export default function registerTools(server) {
111
112
  openNotifications(server);
112
113
  lockDevice(server);
113
114
  unlockDevice(server);
115
+ setGeolocation(server);
116
+ getGeolocation(server);
117
+ resetGeolocation(server);
114
118
  // iOS Setup
115
119
  bootSimulator(server);
116
120
  setupWDA(server);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAeA,OAAO,GAAG,MAAM,cAAc,CAAC;AAC/B,OAAO,YAAY,MAAM,kCAAkC,CAAC;AAC5D,OAAO,aAAa,MAAM,6BAA6B,CAAC;AACxD,OAAO,aAAa,MAAM,6BAA6B,CAAC;AACxD,OAAO,YAAY,MAAM,4BAA4B,CAAC;AACtD,OAAO,aAAa,MAAM,6BAA6B,CAAC;AACxD,OAAO,gBAAgB,MAAM,+BAA+B,CAAC;AAC7D,OAAO,cAAc,MAAM,8BAA8B,CAAC;AAC1D,OAAO,YAAY,MAAM,4BAA4B,CAAC;AACtD,OAAO,iBAAiB,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,aAAa,MAAM,yBAAyB,CAAC;AACpD,OAAO,QAAQ,MAAM,oBAAoB,CAAC;AAC1C,OAAO,UAAU,MAAM,sBAAsB,CAAC;AAC9C,OAAO,YAAY,MAAM,qCAAqC,CAAC;AAC/D,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,eAAe,MAAM,oCAAoC,CAAC;AACjE,OAAO,KAAK,MAAM,wBAAwB,CAAC;AAC3C,OAAO,WAAW,MAAM,wBAAwB,CAAC;AACjD,OAAO,YAAY,MAAM,yBAAyB,CAAC;AACnD,OAAO,SAAS,MAAM,8BAA8B,CAAC;AACrD,OAAO,SAAS,MAAM,8BAA8B,CAAC;AACrD,OAAO,WAAW,MAAM,iCAAiC,CAAC;AAC1D,OAAO,KAAK,MAAM,yBAAyB,CAAC;AAC5C,OAAO,QAAQ,MAAM,6BAA6B,CAAC;AACnD,OAAO,QAAQ,MAAM,6BAA6B,CAAC;AACnD,OAAO,OAAO,MAAM,4BAA4B,CAAC;AACjD,OAAO,gBAAgB,MAAM,kCAAkC,CAAC;AAChE,OAAO,aAAa,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/E,OAAO,WAAW,MAAM,gCAAgC,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,WAAW,MAAM,kCAAkC,CAAC;AAC3D,OAAO,UAAU,MAAM,iCAAiC,CAAC;AACzD,OAAO,YAAY,MAAM,mCAAmC,CAAC;AAC7D,OAAO,YAAY,MAAM,mCAAmC,CAAC;AAC7D,OAAO,QAAQ,MAAM,+BAA+B,CAAC;AACrD,OAAO,cAAc,MAAM,sCAAsC,CAAC;AAClE,OAAO,QAAQ,MAAM,+BAA+B,CAAC;AACrD,OAAO,WAAW,MAAM,2BAA2B,CAAC;AACpD,OAAO,aAAa,MAAM,6BAA6B,CAAC;AAExD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAe;IACnD,uDAAuD;IACvD,MAAM,eAAe,GAAI,MAAc,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAc,CAAC,OAAO,GAAG,CAAC,OAAY,EAAE,EAAE;QACzC,MAAM,QAAQ,GAAG,OAAO,EAAE,IAAI,IAAI,cAAc,CAAC;QACjD,MAAM,eAAe,GAAG,OAAO,EAAE,OAAO,CAAC;QACzC,IAAI,OAAO,eAAe,KAAK,UAAU,EAAE,CAAC;YAC1C,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;QACD,MAAM,cAAc,GAAG;YACrB,UAAU;YACV,OAAO;YACP,aAAa;YACb,eAAe;YACf,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,cAAc;SACf,CAAC;QACF,MAAM,UAAU,GAAG,CAAC,GAAQ,EAAE,EAAE;YAC9B,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CACf,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;oBACjC,IACE,GAAG;wBACH,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EACzD,CAAC;wBACD,OAAO,YAAY,CAAC;oBACtB,CAAC;oBACD,gDAAgD;oBAChD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;wBAC9D,OAAO,WAAW,KAAK,CAAC,MAAM,GAAG,CAAC;oBACpC,CAAC;oBACD,IACE,KAAK;wBACL,OAAO,MAAM,KAAK,WAAW;wBAC7B,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EACtB,CAAC;wBACD,OAAO,WAAY,KAAgB,CAAC,MAAM,GAAG,CAAC;oBAChD,CAAC;oBACD,OAAO,KAAK,CAAC;gBACf,CAAC,CAAC,CACH,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,uBAAuB,CAAC;YACjC,CAAC;QACH,CAAC,CAAC;QACF,OAAO,eAAe,CAAC;YACrB,GAAG,OAAO;YACV,OAAO,EAAE,KAAK,EAAE,IAAS,EAAE,OAAY,EAAE,EAAE;gBACzC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACzB,GAAG,CAAC,IAAI,CAAC,gBAAgB,QAAQ,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;gBACvD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;oBACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;oBACpC,GAAG,CAAC,IAAI,CAAC,cAAc,QAAQ,KAAK,QAAQ,KAAK,CAAC,CAAC;oBACnD,OAAO,MAAM,CAAC;gBAChB,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;oBACpC,MAAM,GAAG,GAAG,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;oBACtD,GAAG,CAAC,KAAK,CAAC,gBAAgB,QAAQ,KAAK,QAAQ,QAAQ,GAAG,EAAE,CAAC,CAAC;oBAC9D,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,qBAAqB;IACrB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,UAAU,CAAC,MAAM,CAAC,CAAC;IACnB,YAAY,CAAC,MAAM,CAAC,CAAC;IAErB,YAAY;IACZ,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjB,UAAU,CAAC,MAAM,CAAC,CAAC;IAEnB,aAAa;IACb,MAAM,CAAC,MAAM,CAAC,CAAC;IACf,eAAe,CAAC,MAAM,CAAC,CAAC;IACxB,KAAK,CAAC,MAAM,CAAC,CAAC;IAEd,uBAAuB;IACvB,qCAAqC;IACrC,8EAA8E;IAC9E,sEAAsE;IACtE,mFAAmF;IACnF,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,SAAS,CAAC,MAAM,CAAC,CAAC;IAClB,SAAS,CAAC,MAAM,CAAC,CAAC;IAClB,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,KAAK,CAAC,MAAM,CAAC,CAAC;IACd,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjB,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjB,OAAO,CAAC,MAAM,CAAC,CAAC;IAChB,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,CAAC,MAAM,CAAC,CAAC;IACnB,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE1B,iBAAiB;IACjB,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,CAAC,MAAM,CAAC,CAAC;IACnB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEjB,qBAAqB;IACrB,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,aAAa,CAAC,MAAM,CAAC,CAAC;IAEtB,kBAAkB;IAClB,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,YAAY,CAAC,MAAM,CAAC,CAAC;IAErB,gBAAgB;IAChB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAeA,OAAO,GAAG,MAAM,cAAc,CAAC;AAC/B,OAAO,YAAY,MAAM,kCAAkC,CAAC;AAC5D,OAAO,aAAa,MAAM,6BAA6B,CAAC;AACxD,OAAO,aAAa,MAAM,6BAA6B,CAAC;AACxD,OAAO,YAAY,MAAM,4BAA4B,CAAC;AACtD,OAAO,aAAa,MAAM,6BAA6B,CAAC;AACxD,OAAO,gBAAgB,MAAM,+BAA+B,CAAC;AAC7D,OAAO,cAAc,MAAM,8BAA8B,CAAC;AAC1D,OAAO,YAAY,MAAM,4BAA4B,CAAC;AACtD,OAAO,iBAAiB,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,aAAa,MAAM,yBAAyB,CAAC;AACpD,OAAO,QAAQ,MAAM,oBAAoB,CAAC;AAC1C,OAAO,UAAU,MAAM,sBAAsB,CAAC;AAC9C,OAAO,YAAY,MAAM,qCAAqC,CAAC;AAC/D,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,eAAe,MAAM,oCAAoC,CAAC;AACjE,OAAO,KAAK,MAAM,wBAAwB,CAAC;AAC3C,OAAO,WAAW,MAAM,wBAAwB,CAAC;AACjD,OAAO,YAAY,MAAM,yBAAyB,CAAC;AACnD,OAAO,SAAS,MAAM,8BAA8B,CAAC;AACrD,OAAO,SAAS,MAAM,8BAA8B,CAAC;AACrD,OAAO,WAAW,MAAM,iCAAiC,CAAC;AAC1D,OAAO,KAAK,MAAM,yBAAyB,CAAC;AAC5C,OAAO,QAAQ,MAAM,6BAA6B,CAAC;AACnD,OAAO,QAAQ,MAAM,6BAA6B,CAAC;AACnD,OAAO,OAAO,MAAM,4BAA4B,CAAC;AACjD,OAAO,gBAAgB,MAAM,kCAAkC,CAAC;AAChE,OAAO,aAAa,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/E,OAAO,WAAW,MAAM,gCAAgC,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,WAAW,MAAM,kCAAkC,CAAC;AAC3D,OAAO,UAAU,MAAM,iCAAiC,CAAC;AACzD,OAAO,YAAY,MAAM,mCAAmC,CAAC;AAC7D,OAAO,YAAY,MAAM,mCAAmC,CAAC;AAC7D,OAAO,QAAQ,MAAM,+BAA+B,CAAC;AACrD,OAAO,cAAc,MAAM,sCAAsC,CAAC;AAClE,OAAO,QAAQ,MAAM,+BAA+B,CAAC;AACrD,OAAO,WAAW,MAAM,2BAA2B,CAAC;AACpD,OAAO,aAAa,MAAM,6BAA6B,CAAC;AAExD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAe;IACnD,uDAAuD;IACvD,MAAM,eAAe,GAAI,MAAc,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAc,CAAC,OAAO,GAAG,CAAC,OAAY,EAAE,EAAE;QACzC,MAAM,QAAQ,GAAG,OAAO,EAAE,IAAI,IAAI,cAAc,CAAC;QACjD,MAAM,eAAe,GAAG,OAAO,EAAE,OAAO,CAAC;QACzC,IAAI,OAAO,eAAe,KAAK,UAAU,EAAE,CAAC;YAC1C,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;QACD,MAAM,cAAc,GAAG;YACrB,UAAU;YACV,OAAO;YACP,aAAa;YACb,eAAe;YACf,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,cAAc;SACf,CAAC;QACF,MAAM,UAAU,GAAG,CAAC,GAAQ,EAAE,EAAE;YAC9B,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CACf,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;oBACjC,IACE,GAAG;wBACH,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EACzD,CAAC;wBACD,OAAO,YAAY,CAAC;oBACtB,CAAC;oBACD,gDAAgD;oBAChD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;wBAC9D,OAAO,WAAW,KAAK,CAAC,MAAM,GAAG,CAAC;oBACpC,CAAC;oBACD,IACE,KAAK;wBACL,OAAO,MAAM,KAAK,WAAW;wBAC7B,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EACtB,CAAC;wBACD,OAAO,WAAY,KAAgB,CAAC,MAAM,GAAG,CAAC;oBAChD,CAAC;oBACD,OAAO,KAAK,CAAC;gBACf,CAAC,CAAC,CACH,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,uBAAuB,CAAC;YACjC,CAAC;QACH,CAAC,CAAC;QACF,OAAO,eAAe,CAAC;YACrB,GAAG,OAAO;YACV,OAAO,EAAE,KAAK,EAAE,IAAS,EAAE,OAAY,EAAE,EAAE;gBACzC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACzB,GAAG,CAAC,IAAI,CAAC,gBAAgB,QAAQ,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;gBACvD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;oBACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;oBACpC,GAAG,CAAC,IAAI,CAAC,cAAc,QAAQ,KAAK,QAAQ,KAAK,CAAC,CAAC;oBACnD,OAAO,MAAM,CAAC;gBAChB,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;oBACpC,MAAM,GAAG,GAAG,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;oBACtD,GAAG,CAAC,KAAK,CAAC,gBAAgB,QAAQ,KAAK,QAAQ,QAAQ,GAAG,EAAE,CAAC,CAAC;oBAC9D,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,qBAAqB;IACrB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,UAAU,CAAC,MAAM,CAAC,CAAC;IACnB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAEzB,YAAY;IACZ,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjB,UAAU,CAAC,MAAM,CAAC,CAAC;IAEnB,aAAa;IACb,MAAM,CAAC,MAAM,CAAC,CAAC;IACf,eAAe,CAAC,MAAM,CAAC,CAAC;IACxB,KAAK,CAAC,MAAM,CAAC,CAAC;IAEd,uBAAuB;IACvB,qCAAqC;IACrC,8EAA8E;IAC9E,sEAAsE;IACtE,mFAAmF;IACnF,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,SAAS,CAAC,MAAM,CAAC,CAAC;IAClB,SAAS,CAAC,MAAM,CAAC,CAAC;IAClB,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,KAAK,CAAC,MAAM,CAAC,CAAC;IACd,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjB,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjB,OAAO,CAAC,MAAM,CAAC,CAAC;IAChB,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,CAAC,MAAM,CAAC,CAAC;IACnB,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE1B,iBAAiB;IACjB,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,CAAC,MAAM,CAAC,CAAC;IACnB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjB,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEjB,qBAAqB;IACrB,WAAW,CAAC,MAAM,CAAC,CAAC;IACpB,aAAa,CAAC,MAAM,CAAC,CAAC;IAEtB,kBAAkB;IAClB,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,YAAY,CAAC,MAAM,CAAC,CAAC;IAErB,gBAAgB;IAChB,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { FastMCP } from 'fastmcp';
2
+ export declare function setGeolocation(server: FastMCP): void;
3
+ export declare function getGeolocation(server: FastMCP): void;
4
+ export declare function resetGeolocation(server: FastMCP): void;
5
+ //# sourceMappingURL=geolocation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geolocation.d.ts","sourceRoot":"","sources":["../../../src/tools/session/geolocation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,OAAO,EAAE,MAAM,SAAS,CAAC;AAKtD,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAiFpD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAuDpD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAwDtD"}
@@ -0,0 +1,174 @@
1
+ import { z } from 'zod';
2
+ import { getDriver, getPlatformName, PLATFORM } from '../../session-store.js';
3
+ import { execute } from '../../command.js';
4
+ export function setGeolocation(server) {
5
+ const setGeolocationSchema = z.object({
6
+ latitude: z
7
+ .number()
8
+ .min(-90)
9
+ .max(90)
10
+ .describe('Latitude value (-90 to 90). Measurement of distance north or south of the Equator.'),
11
+ longitude: z
12
+ .number()
13
+ .min(-180)
14
+ .max(180)
15
+ .describe('Longitude value (-180 to 180). Measurement of distance east or west of the prime meridian.'),
16
+ altitude: z
17
+ .number()
18
+ .optional()
19
+ .describe('Altitude value in meters. Android only. Defaults to 0.'),
20
+ });
21
+ server.addTool({
22
+ name: 'appium_set_geolocation',
23
+ description: 'Set the geolocation (GPS coordinates) of the device. Works on both iOS (simulators and real devices) and Android (emulators and real devices with mock location enabled).',
24
+ parameters: setGeolocationSchema,
25
+ annotations: {
26
+ readOnlyHint: false,
27
+ openWorldHint: false,
28
+ },
29
+ execute: async (args, _context) => {
30
+ const driver = getDriver();
31
+ if (!driver) {
32
+ throw new Error('No driver found');
33
+ }
34
+ try {
35
+ const platform = getPlatformName(driver);
36
+ const { latitude, longitude, altitude } = args;
37
+ if (platform === PLATFORM.ios) {
38
+ await execute(driver, 'mobile: setSimulatedLocation', {
39
+ latitude,
40
+ longitude,
41
+ });
42
+ }
43
+ else if (platform === PLATFORM.android) {
44
+ await execute(driver, 'mobile: setGeolocation', {
45
+ latitude,
46
+ longitude,
47
+ ...(altitude !== undefined && { altitude }),
48
+ });
49
+ }
50
+ else {
51
+ throw new Error(`Unsupported platform: ${platform}. Only Android and iOS are supported.`);
52
+ }
53
+ return {
54
+ content: [
55
+ {
56
+ type: 'text',
57
+ text: `Successfully set geolocation to latitude=${latitude}, longitude=${longitude}${altitude !== undefined ? `, altitude=${altitude}` : ''}.`,
58
+ },
59
+ ],
60
+ };
61
+ }
62
+ catch (err) {
63
+ return {
64
+ content: [
65
+ {
66
+ type: 'text',
67
+ text: `Failed to set geolocation. Error: ${err.toString()}`,
68
+ },
69
+ ],
70
+ };
71
+ }
72
+ },
73
+ });
74
+ }
75
+ export function getGeolocation(server) {
76
+ const getGeolocationSchema = z.object({});
77
+ server.addTool({
78
+ name: 'appium_get_geolocation',
79
+ description: 'Get the current geolocation (GPS coordinates) of the device. Returns latitude, longitude, and altitude.',
80
+ parameters: getGeolocationSchema,
81
+ annotations: {
82
+ readOnlyHint: true,
83
+ openWorldHint: false,
84
+ },
85
+ execute: async (_args, _context) => {
86
+ const driver = getDriver();
87
+ if (!driver) {
88
+ throw new Error('No driver found');
89
+ }
90
+ try {
91
+ const platform = getPlatformName(driver);
92
+ let result;
93
+ if (platform === PLATFORM.ios) {
94
+ result = await execute(driver, 'mobile: getSimulatedLocation', {});
95
+ }
96
+ else if (platform === PLATFORM.android) {
97
+ result = await execute(driver, 'mobile: getGeolocation', {});
98
+ }
99
+ else {
100
+ throw new Error(`Unsupported platform: ${platform}. Only Android and iOS are supported.`);
101
+ }
102
+ return {
103
+ content: [
104
+ {
105
+ type: 'text',
106
+ text: `Current geolocation: latitude=${result.latitude}, longitude=${result.longitude}${result.altitude !== undefined ? `, altitude=${result.altitude}` : ''}.`,
107
+ },
108
+ ],
109
+ };
110
+ }
111
+ catch (err) {
112
+ return {
113
+ content: [
114
+ {
115
+ type: 'text',
116
+ text: `Failed to get geolocation. Error: ${err.toString()}`,
117
+ },
118
+ ],
119
+ };
120
+ }
121
+ },
122
+ });
123
+ }
124
+ export function resetGeolocation(server) {
125
+ const resetGeolocationSchema = z.object({});
126
+ server.addTool({
127
+ name: 'appium_reset_geolocation',
128
+ description: 'Reset the geolocation to the default/system value. On iOS, resets the simulated location. On Android real devices, resets the mocked geolocation provider (note: GPS cache behavior varies by device — the mocked location may persist until the cache refreshes). On Android emulators, reset is not supported — use appium_set_geolocation to manually set the desired coordinates instead.',
129
+ parameters: resetGeolocationSchema,
130
+ annotations: {
131
+ readOnlyHint: false,
132
+ openWorldHint: false,
133
+ },
134
+ execute: async (_args, _context) => {
135
+ const driver = getDriver();
136
+ if (!driver) {
137
+ throw new Error('No driver found');
138
+ }
139
+ try {
140
+ const platform = getPlatformName(driver);
141
+ if (platform === PLATFORM.ios) {
142
+ await execute(driver, 'mobile: resetSimulatedLocation', {});
143
+ }
144
+ else if (platform === PLATFORM.android) {
145
+ await execute(driver, 'mobile: resetGeolocation', {});
146
+ // Refresh GPS cache
147
+ await execute(driver, 'mobile: refreshGpsCache', {});
148
+ }
149
+ else {
150
+ throw new Error(`Unsupported platform: ${platform}. Only Android and iOS are supported.`);
151
+ }
152
+ return {
153
+ content: [
154
+ {
155
+ type: 'text',
156
+ text: 'Successfully reset geolocation to default.',
157
+ },
158
+ ],
159
+ };
160
+ }
161
+ catch (err) {
162
+ return {
163
+ content: [
164
+ {
165
+ type: 'text',
166
+ text: `Failed to reset geolocation. Error: ${err.toString()}`,
167
+ },
168
+ ],
169
+ };
170
+ }
171
+ },
172
+ });
173
+ }
174
+ //# sourceMappingURL=geolocation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geolocation.js","sourceRoot":"","sources":["../../../src/tools/session/geolocation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "appium-mcp",
3
3
  "mcpName": "io.github.appium/appium-mcp",
4
- "version": "1.26.0",
4
+ "version": "1.27.0",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",
package/server.json CHANGED
@@ -3,12 +3,12 @@
3
3
  "name": "io.github.appium/appium-mcp",
4
4
  "title": "MCP Appium - Mobile Development and Automation Server",
5
5
  "description": "MCP server for Appium mobile automation on iOS and Android devices with test creation tools.",
6
- "version": "1.26.0",
6
+ "version": "1.27.0",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "npm",
10
10
  "identifier": "appium-mcp",
11
- "version": "1.26.0",
11
+ "version": "1.27.0",
12
12
  "transport": {
13
13
  "type": "stdio"
14
14
  }
@@ -24,6 +24,11 @@ import selectPlatform from './session/select-platform.js';
24
24
  import selectDevice from './session/select-device.js';
25
25
  import openNotifications from './session/open-notifications.js';
26
26
  import { lockDevice, unlockDevice } from './session/lock.js';
27
+ import {
28
+ setGeolocation,
29
+ getGeolocation,
30
+ resetGeolocation,
31
+ } from './session/geolocation.js';
27
32
  import bootSimulator from './ios/boot-simulator.js';
28
33
  import setupWDA from './ios/setup-wda.js';
29
34
  import installWDA from './ios/install-wda.js';
@@ -132,6 +137,9 @@ export default function registerTools(server: FastMCP): void {
132
137
  openNotifications(server);
133
138
  lockDevice(server);
134
139
  unlockDevice(server);
140
+ setGeolocation(server);
141
+ getGeolocation(server);
142
+ resetGeolocation(server);
135
143
 
136
144
  // iOS Setup
137
145
  bootSimulator(server);
@@ -0,0 +1,202 @@
1
+ import type { ContentResult, FastMCP } from 'fastmcp';
2
+ import { z } from 'zod';
3
+ import { getDriver, getPlatformName, PLATFORM } from '../../session-store.js';
4
+ import { execute } from '../../command.js';
5
+
6
+ export function setGeolocation(server: FastMCP): void {
7
+ const setGeolocationSchema = z.object({
8
+ latitude: z
9
+ .number()
10
+ .min(-90)
11
+ .max(90)
12
+ .describe(
13
+ 'Latitude value (-90 to 90). Measurement of distance north or south of the Equator.'
14
+ ),
15
+ longitude: z
16
+ .number()
17
+ .min(-180)
18
+ .max(180)
19
+ .describe(
20
+ 'Longitude value (-180 to 180). Measurement of distance east or west of the prime meridian.'
21
+ ),
22
+ altitude: z
23
+ .number()
24
+ .optional()
25
+ .describe('Altitude value in meters. Android only. Defaults to 0.'),
26
+ });
27
+
28
+ server.addTool({
29
+ name: 'appium_set_geolocation',
30
+ description:
31
+ 'Set the geolocation (GPS coordinates) of the device. Works on both iOS (simulators and real devices) and Android (emulators and real devices with mock location enabled).',
32
+ parameters: setGeolocationSchema,
33
+ annotations: {
34
+ readOnlyHint: false,
35
+ openWorldHint: false,
36
+ },
37
+ execute: async (
38
+ args: z.infer<typeof setGeolocationSchema>,
39
+ _context: Record<string, unknown> | undefined
40
+ ): Promise<ContentResult> => {
41
+ const driver = getDriver();
42
+ if (!driver) {
43
+ throw new Error('No driver found');
44
+ }
45
+
46
+ try {
47
+ const platform = getPlatformName(driver);
48
+ const { latitude, longitude, altitude } = args;
49
+
50
+ if (platform === PLATFORM.ios) {
51
+ await execute(driver, 'mobile: setSimulatedLocation', {
52
+ latitude,
53
+ longitude,
54
+ });
55
+ } else if (platform === PLATFORM.android) {
56
+ await execute(driver, 'mobile: setGeolocation', {
57
+ latitude,
58
+ longitude,
59
+ ...(altitude !== undefined && { altitude }),
60
+ });
61
+ } else {
62
+ throw new Error(
63
+ `Unsupported platform: ${platform}. Only Android and iOS are supported.`
64
+ );
65
+ }
66
+
67
+ return {
68
+ content: [
69
+ {
70
+ type: 'text',
71
+ text: `Successfully set geolocation to latitude=${latitude}, longitude=${longitude}${altitude !== undefined ? `, altitude=${altitude}` : ''}.`,
72
+ },
73
+ ],
74
+ };
75
+ } catch (err: any) {
76
+ return {
77
+ content: [
78
+ {
79
+ type: 'text',
80
+ text: `Failed to set geolocation. Error: ${err.toString()}`,
81
+ },
82
+ ],
83
+ };
84
+ }
85
+ },
86
+ });
87
+ }
88
+
89
+ export function getGeolocation(server: FastMCP): void {
90
+ const getGeolocationSchema = z.object({});
91
+
92
+ server.addTool({
93
+ name: 'appium_get_geolocation',
94
+ description:
95
+ 'Get the current geolocation (GPS coordinates) of the device. Returns latitude, longitude, and altitude.',
96
+ parameters: getGeolocationSchema,
97
+ annotations: {
98
+ readOnlyHint: true,
99
+ openWorldHint: false,
100
+ },
101
+ execute: async (
102
+ _args: z.infer<typeof getGeolocationSchema>,
103
+ _context: Record<string, unknown> | undefined
104
+ ): Promise<ContentResult> => {
105
+ const driver = getDriver();
106
+ if (!driver) {
107
+ throw new Error('No driver found');
108
+ }
109
+
110
+ try {
111
+ const platform = getPlatformName(driver);
112
+ let result: Record<string, any>;
113
+
114
+ if (platform === PLATFORM.ios) {
115
+ result = await execute(driver, 'mobile: getSimulatedLocation', {});
116
+ } else if (platform === PLATFORM.android) {
117
+ result = await execute(driver, 'mobile: getGeolocation', {});
118
+ } else {
119
+ throw new Error(
120
+ `Unsupported platform: ${platform}. Only Android and iOS are supported.`
121
+ );
122
+ }
123
+
124
+ return {
125
+ content: [
126
+ {
127
+ type: 'text',
128
+ text: `Current geolocation: latitude=${result.latitude}, longitude=${result.longitude}${result.altitude !== undefined ? `, altitude=${result.altitude}` : ''}.`,
129
+ },
130
+ ],
131
+ };
132
+ } catch (err: any) {
133
+ return {
134
+ content: [
135
+ {
136
+ type: 'text',
137
+ text: `Failed to get geolocation. Error: ${err.toString()}`,
138
+ },
139
+ ],
140
+ };
141
+ }
142
+ },
143
+ });
144
+ }
145
+
146
+ export function resetGeolocation(server: FastMCP): void {
147
+ const resetGeolocationSchema = z.object({});
148
+
149
+ server.addTool({
150
+ name: 'appium_reset_geolocation',
151
+ description:
152
+ 'Reset the geolocation to the default/system value. On iOS, resets the simulated location. On Android real devices, resets the mocked geolocation provider (note: GPS cache behavior varies by device — the mocked location may persist until the cache refreshes). On Android emulators, reset is not supported — use appium_set_geolocation to manually set the desired coordinates instead.',
153
+ parameters: resetGeolocationSchema,
154
+ annotations: {
155
+ readOnlyHint: false,
156
+ openWorldHint: false,
157
+ },
158
+ execute: async (
159
+ _args: z.infer<typeof resetGeolocationSchema>,
160
+ _context: Record<string, unknown> | undefined
161
+ ): Promise<ContentResult> => {
162
+ const driver = getDriver();
163
+ if (!driver) {
164
+ throw new Error('No driver found');
165
+ }
166
+
167
+ try {
168
+ const platform = getPlatformName(driver);
169
+
170
+ if (platform === PLATFORM.ios) {
171
+ await execute(driver, 'mobile: resetSimulatedLocation', {});
172
+ } else if (platform === PLATFORM.android) {
173
+ await execute(driver, 'mobile: resetGeolocation', {});
174
+ // Refresh GPS cache
175
+ await execute(driver, 'mobile: refreshGpsCache', {});
176
+ } else {
177
+ throw new Error(
178
+ `Unsupported platform: ${platform}. Only Android and iOS are supported.`
179
+ );
180
+ }
181
+
182
+ return {
183
+ content: [
184
+ {
185
+ type: 'text',
186
+ text: 'Successfully reset geolocation to default.',
187
+ },
188
+ ],
189
+ };
190
+ } catch (err: any) {
191
+ return {
192
+ content: [
193
+ {
194
+ type: 'text',
195
+ text: `Failed to reset geolocation. Error: ${err.toString()}`,
196
+ },
197
+ ],
198
+ };
199
+ }
200
+ },
201
+ });
202
+ }