App X-ray
App X-ray opens an app on your iPhone, taps through every control that opens a screen, and hands back a map: the screens it reached, how they connect, the paywalls it found with their plans and prices, and the numbers for the run. It calls no model, so it costs nothing in model spend and needs no key. It is a task like any other. It uses your plan, waits in line when the iPhone is busy, shows each tap in the run view and ends when you press Stop.Run it
In Mobster for Mac, open Apps. Under Jobs, Map an app, screen by screen has a Map an app button: it lists the apps on your iPhone, and the one you pick starts the map. In Terminal:APP is the app’s bundle ID, or its name on the phone. The command prints each step and then the answer:
Exit codes: 0 mapped, 1 stopped or mapped nothing, 2 usage, 3 couldn’t run (no phone, no plan, app not found, or an app X-ray doesn’t map), 130
ctrl+c.
What you get
The result is a finished task with three cards (Results):- Screens: a gallery of the screens it reached, each with its name. At most 60.
- Paywall plans: a table with the screen, plan, price, period and trial of every plan it read on a paywall. Left out when it found no paywall.
- How it went: the screens, links, taps, time, why it stopped, how many controls it left alone, and where the files are.
~/Library/Application Support/app.mobster.desktop/xray/apps/<bundle ID>/<date>-<time>/, a folder only you can open:
What it taps and what it leaves alone
It fails closed. It taps a control only when its shape says it opens a screen (a row in a list, a tab, a link with a chevron, a tall card or a full-width row of data like a weather forecast’s days) and its words name no act. It leaves alone:- anything that names an act: delete, sign out, send, post, buy, subscribe, start a trial, allow. Words that are also what an app shows count only as a label’s first word, so “Feels like 67°” and “Software Update” are tapped and “Like” and “Update Now” aren’t;
- a row with its own info button, like a Wi-Fi network or a Bluetooth device in Settings: tapping the row joins or connects;
- switches, sliders, pickers, text fields and a row that holds a switch;
- everything on a paywall: it reads the plans and backs out;
- a system dialog, except one it can close with “Not Now”, “Cancel” or “Close”. When only you can answer, it stops and says so;
- a tap that changed the screen in place. It leaves the rest of that screen alone, in case it set something.
Compare two maps
Run it again after an update, then compare:map.json or the folder that holds it. It needs no phone and no plan, and prints what changed:
--json prints the comparison as JSON.
Start it from a script
POST /api/xray/app starts the same task:
appId is required. It answers 201 {"runId": "..."}. The run’s events and result come from the task API, like any task. The same phone rules apply: it queues when the phone is held, and the plan check applies first. It answers 422 for an app X-ray doesn’t map and 400 for an app that isn’t on the phone. A request with the same key returns the same run.
Network X-ray
Open Devices and press Network X-ray on a phone’s card. The recorder opens under your phones, on the same page. Choose 30 s, 60 s or 2 min (60 s is the default), press Record and use the apps you want to look at. The apps and the companies they talk to, with their logos, fill in as they appear. When it ends, Open the report opens it as a finished task. From a terminal:mobster xray network --from prints for the synthetic capture Mobster’s tests use (mobile_agent/tests/netxray_synthetic.py), whose Flashlight Pro is a made-up app. A recording first prints Recording <phone> over the cable for 60 s. Use the apps you want to look at. ctrl+c stops early., then one line for each app that used the network.
Each line counts domains Mobster saw in that app’s traffic, groups them by the company that runs them, and counts the ones on Mobster’s own list of ad, analytics and attribution services. The list is short: Mobster wrote it from the SDK vendors’ own documentation and from hostnames real recordings left unnamed. A domain on no line gets its own name as its company and no category.
What you get
They are in the data folder under
xray/network/<YYYYmmdd-HHMMSS>/, readable only by you. In the Mac app the result also shows as a task with two tables, Who your apps talked to (an app, a company with its logo, what it does, domains, KB sent and received) and Every domain, and a note on what Mobster read and what it couldn’t see. You can sort, filter and export them like any result.
Which apps and which phone
Mobster reads the phone’s app list and matches each process in the capture to an app by its executable name. A match shows as the app’s name on your phone. Some processes are parts of iOS itself, such asnsurlsessiond or mDNSResponder. Mobster labels those iOS and lists the process name in the details. A name it can’t match shows as that name and says it is a process. When iOS does a lookup or a download for an app, the traffic counts for the app.
When the capture has no process name for a packet or a connection, Mobster doesn’t guess. That traffic goes to a line called Unattributed with its bytes and a sentence: “Mobster couldn’t tell which app sent this traffic, so it isn’t counted for any app.”
Mobster records one phone, the one you name with --device (its id, UDID or name, as in Several phones). With no name, it uses the one iPhone that is connected. With two or more connected and no name, it stops and lists them. It refuses simulators, because only a real iPhone has the capture service.
The cable
Network X-ray records over the cable. iOS offers its packet capture service only on a USB connection: over Wi-Fi it refuses the service (measured on an iPhone 15 Pro with iOS 26.0.1, 15 Oct 2026). When the phone you pick is on Wi-Fi only, Mobster says so in one sentence and asks you to plug it in.--wifi asks for Wi-Fi even with the cable in, and today ends with that sentence.
What a recording costs, measured on 15 Oct 2026 on an Apple M5 Max with the iPhone 15 Pro on its cable, over two 90-second recordings of six and four apps:
The capture travels over the cable, so it adds nothing to the phone’s own network traffic.
Options
ctrl+c ends the recording early and still writes the report. Exit codes: 0 done, 1 the capture failed, 2 usage, 3 couldn’t run (no such iPhone, a simulator, no capture tool). Recording a phone needs a plan, like any task that uses one (Plans).
--from reads a pcapng that records the process behind each packet: one mobster-pcap wrote, or one macOS tcpdump -P wrote on a rvi0 interface. A classic .pcap has no place for the process, so Mobster refuses it and says so.
Start it from another program
The Mac app starts a capture withPOST /api/xray/network and reads it with GET /api/xray/network/{jobId}. Only the Mac app’s own session can: an API token alone can’t record your phone’s traffic, and the capture is not an agent or MCP tool.
What leaves your Mac
Nothing. The capture, the report files and the report’s task stay on this Mac. Mobster makes no share link of the task, sends it to no destination and leaves it out of a feedback report. The local task API (GET /api/runs) shows it only to the Mac app, so an agent over MCP or Mobster Remote can’t read it. Privacy lists what Mobster reads and keeps.
What Network X-ray doesn’t see
- Names sent through encrypted DNS appear only when the connection itself names the server.
- iCloud Private Relay hides the real servers behind Apple’s relay.
- Encrypted Client Hello hides the server’s name in the handshake. Mobster counts those connections without a name.
- It decrypts nothing, so it shows who an app contacted and how much, never what it sent.
How well the matching holds up
Measured on two 90-second recordings on an iPhone 15 Pro (iOS 26.0.1), 15 Oct 2026: 10 apps opened one after another, 211 hostnames, labelled by hand afterwards.- Apps. All 10 apps were named as they are on the phone, even when the process has another name.
- Ads, analytics and attribution, as the list stood before those recordings. Per app, 26 of the 31 flags were right (84%), and it caught 26 of the 33 trackers (79%). It missed Nielsen, Kevel, Zefr, Tealium, Mapbox’s telemetry and Apple’s Search Ads attribution. It flagged Firebase Installations and Remote Config, which are plumbing, not measurement.
- After adding those to the list, the same two recordings score 33 of 34 flags right and all 33 trackers caught. That is measured on the recordings the additions came from, so it is not an independent test. The one wrong flag is
graph.facebook.cominside an app Meta makes, which is Meta talking to itself. - Companies. Every hostname the list names had the right company. The list now names 160 of the 211 hostnames. The rest show their own domain as the company, which is right for an app’s own servers.