Skip to content

feature: launch apps with arguments (deep links & launch arguments) #370

Description

@wxxion

Is your feature request related to a problem?

mobile_launch_app currently accepts only packageName and an optional locale, so there's no way to launch an app into a specific state. Three common testing flows are impossible today:

  1. Deep links — open the app directly on a screen via a custom scheme (e.g. myapp://product/123), instead of tapping through the UI.
  2. App Links / Universal Links — open an https:// URL that a verified app handles.
  3. Launch arguments / feature flags at start — pass a feature-flag override or a mock/staging server URL so the app boots into a known configuration. On iOS this is exactly Xcode's "Arguments Passed On Launch" (Scheme → Run → Arguments).

All are native capabilities of the tools mobile-mcp already shells out to (am start, simctl launch / simctl openurl, go-ios).

Example prompts I'd expect to use

Deep link (both platforms):

  • "Launch com.example.shop with the deep link myapp://product/123"

App Link / Universal Link (both platforms):

  • "Open https://example.com/checkout in the app"

Launch arguments / feature flags:

  • iOS: "Launch com.example.app with launch arguments -FeatureXEnabled YES -apiBaseURL https://staging.example.com" (same as Xcode's Arguments Passed On Launch)
  • Android: "Launch com.example.app with extras FeatureXEnabled=true and apiBaseURL=https://staging.example.com"

Describe the solution you'd like

Add optional parameters to mobile_launch_app, mirroring how the optional locale parameter already works — so there is no breaking change and the default path is untouched:

  • url (string) — a deep link / URL to open the app with.
  • extras / launchArgs (key/value map) — flags passed to the app at launch.

Preserve current behavior when no args are supplied. On Android, keep monkey -p <pkg> -c LAUNCHER 1 as the default; only switch to am start when args are present (resolving the launcher activity via the query the repo already uses — see
src/android.ts:121).

Per-platform semantics (there is an important asymmetry):

  • iOS Simulatorextras become launch arguments: simctl launch <bundleid> -Key Value.
    This is identical to Xcode's Arguments Passed On Launch and the OS parses -key value into UserDefaults, so an app already using launch-argument feature flags works with zero code changes. URLs use simctl openurl. (Strongest, most transparent case.)
  • iOS physical devicego-ios already supports this: ios launch <bundleID> --arg <a>... --env <e>... passes launch arguments (and env vars) through the instruments ProcessControl service, the same mechanism Xcode uses — so it behaves like Xcode's Arguments Passed On Launch on real devices too. (Requires the Developer Disk Image mounted, as with other go-ios instruments features.)
  • Androidextras become intent extras: am start -n <pkg>/<activity> --es k v. mobile-mcp delivers the extra, but the app must read it from the launch intent (getIntent().getBooleanExtra(...)) — it's app-cooperative, unlike iOS's automatic UserDefaults. Android extras are also typed (--es string / --ez bool / --ei int), so the map may need typed values rather than string-only. Emulator and physical device behave identically here — everything runs through the same adb -s <serial> shell path, so there's no emulator/device split (unlike iOS's simctl vs. go-ios backends). Note the url case is largely already implemented: src/android.ts:398 already runs am start -a android.intent.action.VIEW -d <url> (with an escapeShellText helper for shell safety), so the net-new Android work is mainly the typed-extras path.
  • App Links / Universal Links — firing an https:// URL only lands in the app if the app has declared/verified the domain (Android App Links autoVerify, iOS AASA); otherwise it falls back to the browser. That's app configuration, not something mobile-mcp controls.

Inputs flow into adb shell / simctl, so they'd be validated with a dedicated helper alongside the existing validateLocale / validatePackageName in src/utils.ts (reject shell metacharacters, constrain URL characters).

Additional context

This is the same shape as the recently-added optional duration parameter (#244 → PR #247): an optional parameter on an existing tool, with a safe default. Happy to send a PR if the design looks good.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions