
Ios Device Toolkit
- 26 installs
- 52 repo stars
- Updated June 24, 2026
- 0xbigboss/claude-code
ios-device-toolkit is a Claude Code skill that drives a USB-attached iOS device via pymobiledevice3 for screenshots, logs, crash reports, app management, file transfer, and diagnostics.
About
ios-device-toolkit drives a physical iOS device over USB using pymobiledevice3. A developer uses it to take screenshots, tail syslog, pull crash reports, install and launch apps, transfer sandbox files, monitor performance, and forward TCP ports. It documents iOS 17+ requirements such as the tunneld daemon and the DVT screenshot path, plus common connection gotchas.
- Drives a USB-attached iOS device with pymobiledevice3
- Covers screenshots, syslog, crash reports, app install/launch/pull, and file transfer
- Includes iOS 17+ gotchas like requiring a tunneld daemon and the DVT screenshot path
Ios Device Toolkit by the numbers
- 26 all-time installs (skills.sh)
- Ranked #678 of 1,039 Mobile Development skills by installs in the Skillselion catalog
- Data as of Jul 30, 2026 (Skillselion catalog sync)
ios-device-toolkit capabilities & compatibility
Free; installs the open-source pymobiledevice3 CLI, no API keys required
- Capabilities
- ios device control · screenshot capture · crash report pull · app install launch · device diagnostics
- Platforms
- macOS · Linux
- Pricing
- Free
What ios-device-toolkit says it does
Drive a physical iOS device over USB with `pymobiledevice3`. This skill covers the high-value workflows; deep reference per area is in `references/`.
**iOS 17+ only**: a long-running `tunneld` daemon is required for any developer-mode service (screenshots, DVT instruments, debugserver, pcap-with-process, etc.).
npx skills add https://github.com/0xbigboss/claude-code --skill ios-device-toolkitAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 26 |
|---|---|
| repo stars | ★ 52 |
| Last updated | June 24, 2026 |
| Repository | 0xbigboss/claude-code ↗ |
What it does
Drive a USB-attached iOS device with pymobiledevice3 for screenshots, logs, crash reports, app install/launch, file transfer, and performance monitoring.
Who is it for?
Driving a physical iOS device over USB for capture, app management, and diagnostics
Skip if: iOS Simulator workflows or devices without Developer Mode enabled
When should I use this skill?
Interacting with USB-attached iOS devices via pymobiledevice3
What you get
Reliable USB device workflows for capture, app lifecycle, file transfer, and diagnostics, with the iOS 17+ tunneld and DVT gotchas handled.
By the numbers
- Tested at pymobiledevice3 version 7.0.7
- Ships with 3 reference files: capture, apps-files, diagnostics-perf
Files
iOS Device Toolkit
Drive a physical iOS device over USB with pymobiledevice3. This skill covers the high-value workflows; deep reference per area is in references/.
- Capture, logs, crashes →
references/capture.md - Apps, app sandbox files, AFC media, debugserver →
references/apps-files.md - Device info, perf, springboard, webinspector, tunneling →
references/diagnostics-perf.md
Install
# uv (preferred) or pipx
uv tool install pymobiledevice3
pipx install pymobiledevice3
pymobiledevice3 version # confirm; tested at 7.0.7Prerequisites
1. Physical iOS device attached via USB (or Wi-Fi-paired through usbmuxd). 2. Developer Mode enabled on device (Settings → Privacy & Security → Developer Mode). Verify with pymobiledevice3 mounter query-developer-mode-status. 3. Trusted computer — accept "Trust This Computer" prompt on the device after first connect. 4. iOS 17+ only: a long-running tunneld daemon is required for any developer-mode service (screenshots, DVT instruments, debugserver, pcap-with-process, etc.). Start it once per boot:
sudo pymobiledevice3 remote tunneldThe CLI auto-retries developer commands through tunneld; you no longer need --tunnel "" on every call in 7.x, though it still works.
Device selection
For a single attached device, no flag is needed. For multiple, scope every call with one of:
--udid <UDID>— usbmux-discovered device--tunnel <UDID>— tunneld-discovered device (developer services on iOS 17+)PYMOBILEDEVICE3_UDID=<UDID>/PYMOBILEDEVICE3_TUNNEL=<UDID>env vars — set once, all subsequent invocations inherit
Discover UDIDs:
pymobiledevice3 usbmux list # USB + Wi-Fi devices known to usbmuxd
xcrun devicectl list devices # Apple's own listing (macOS)
pymobiledevice3 lockdown info | head # full lockdown dump for the default deviceCaveat: --tunnel "" (empty string) prompts interactively. In non-interactive shells, pass the UDID directly.
Quick reference
# --- Device info ---
pymobiledevice3 usbmux list
pymobiledevice3 lockdown info
pymobiledevice3 diagnostics battery
pymobiledevice3 mounter list
# --- Capture ---
# Screenshot (iOS 17+, DVT path — works where the deprecated developer screenshot fails)
pymobiledevice3 developer dvt screenshot ~/Desktop/shot.png
# Live syslog
pymobiledevice3 syslog live
# Crash reports
pymobiledevice3 crash ls
pymobiledevice3 crash pull ~/ios-crashes
# Packet capture (filter by process is optional)
pymobiledevice3 pcap --out trace.pcap --process Safari
# --- Apps ---
pymobiledevice3 apps list --user # only user-installed
pymobiledevice3 apps install ./MyApp.ipa
pymobiledevice3 apps uninstall com.example.MyApp
pymobiledevice3 developer dvt launch com.example.MyApp
pymobiledevice3 developer dvt process-id-for-bundle-id com.example.MyApp
pymobiledevice3 developer dvt kill <PID>
# --- Files (app sandbox + media) ---
pymobiledevice3 apps pull com.example.MyApp Documents/log.txt ./log.txt
pymobiledevice3 apps push com.example.MyApp ./seed.json Documents/seed.json
pymobiledevice3 afc pull DCIM/100APPLE/IMG_0001.HEIC ./
pymobiledevice3 afc ls -r DCIM
# --- Perf ---
pymobiledevice3 developer dvt sysmon system # one-shot system stats
pymobiledevice3 developer dvt sysmon process # per-process loop
pymobiledevice3 developer dvt proclist # PID + start times
pymobiledevice3 developer dvt energy <PID> [<PID>...]
# --- Networking / port forwarding ---
pymobiledevice3 usbmux forward 8080 8080 # local:8080 -> device:8080
pymobiledevice3 webinspector opened-tabs # requires Safari Web Inspector enabled on device
pymobiledevice3 webinspector cdp # CDP server for WebView debuggingCommon gotchas
- "InvalidServiceError" / "Failed to start service" on iOS 17+ → tunneld is not running. Start
sudo pymobiledevice3 remote tunneldand retry. Confirm withps aux | grep tunneld. - "DeveloperDiskImage not mounted" →
pymobiledevice3 mounter auto-mount. - Deprecated screenshot API hangs on iOS 17+ → use the DVT variant:
developer dvt screenshot(notdeveloper screenshot). - `--tunnel ""` hangs in scripts → empty string means interactive picker; pass the UDID explicitly.
- Permissions on Linux → usbmuxd typically needs to be running; on macOS it's built in.
- Pairing lost after iOS update →
pymobiledevice3 lockdown unpair && pymobiledevice3 lockdown pair.
Scripting tips
- Set
PYMOBILEDEVICE3_UDID(andPYMOBILEDEVICE3_TUNNELfor developer services) once at the top of a script to avoid repeating flags. - For capture-and-open recipes (screenshot +
open, syslog tail +grep, etc.), wrap in a shell function rather than re-typing the full path each time. - Most subcommands accept
--rsd HOST PORTas an alternative to--tunnel, useful when you already have an RSD address from a manualpymobiledevice3 remote start-tunnel.
Apps and Files
App lifecycle (list, install, launch, kill), app sandbox file I/O, AFC media access, and debugserver. Most app-lifecycle operations and the app-sandbox AFC require a tunneld session on iOS 17+.
Listing and querying apps
# All apps (system + user)
pymobiledevice3 apps list
# Filter flags
pymobiledevice3 apps list --user # only user-installed
pymobiledevice3 apps list --system # only system-installed
pymobiledevice3 apps list --hidden # include hidden
# Metadata for a specific bundle ID (returns dict: version, signing, paths, entitlements)
pymobiledevice3 apps query com.example.MyApp
# Via DVT — different shape; useful when you want the same set the Instruments target picker sees
pymobiledevice3 developer dvt applistInstall / uninstall
apps install accepts .ipa, an unpacked .app bundle, or .ipcc carrier bundles. The IPA must be signed for the target device's profile (development or enterprise) — App Store signed builds will be refused.
pymobiledevice3 apps install ./build/MyApp.ipa
pymobiledevice3 apps uninstall com.example.MyAppLaunch, kill, signal
These go through DVT. On iOS 17+ you'll want a tunneld session running.
# Launch (returns PID)
pymobiledevice3 developer dvt launch com.example.MyApp
# Resolve a running bundle ID to its PID (empty if not running)
pymobiledevice3 developer dvt process-id-for-bundle-id com.example.MyApp
# Kill by PID
pymobiledevice3 developer dvt kill 1234
# Kill by name substring
pymobiledevice3 developer dvt pkill MyApp
# Send arbitrary signal (e.g. SIGSTOP=17, SIGCONT=19)
pymobiledevice3 developer dvt signal 1234 --signal-name SIGSTOPmemlimitoff raises a specific PID's jetsam limit — useful for diagnosing low-memory kills during instrumentation:
pymobiledevice3 developer dvt memlimitoff 1234App sandbox files (the common case)
pymobiledevice3 apps {pull,push,rm,afc} go directly into a specific app's container — no need to know the on-device path layout. The container exposes Documents/, Library/, tmp/, SystemData/, etc.
# Pull a single file
pymobiledevice3 apps pull com.example.MyApp Documents/app.sqlite ./app.sqlite
# Push (overwrites if present)
pymobiledevice3 apps push com.example.MyApp ./seed.json Documents/seed.json
# Remove
pymobiledevice3 apps rm com.example.MyApp Documents/stale.log
# Interactive shell into the container — useful for exploration
pymobiledevice3 apps afc com.example.MyApp
# Restrict to Documents only (UIFileSharingEnabled apps)
pymobiledevice3 apps afc com.example.MyApp --documentsApp must support file sharing (UIFileSharingEnabled in Info.plist) for non-developer builds; development builds expose the full container regardless.
AFC: device media root
Plain afc mounts /var/mobile/Media — photos, ringtones, downloads, etc. No tunneld needed (it's a lockdown service).
pymobiledevice3 afc ls
pymobiledevice3 afc ls -r DCIM
pymobiledevice3 afc pull DCIM/100APPLE/IMG_0001.HEIC ./
pymobiledevice3 afc push ./song.m4a iTunes_Control/Music/
pymobiledevice3 afc shell # interactivedebugserver (LLDB attach)
For attaching lldb to a running app or launching one under the debugger. iOS 17+ uses RSD (so tunneld); older releases go over usbmux.
# Show which apps debugserver can target
pymobiledevice3 developer debugserver applist
# Start the server and print the LLDB connect string
pymobiledevice3 developer debugserver start-server
# In another terminal, paste the printed connect string into lldb:
# (lldb) process connect connect://[FE80::...]:PORT
# (lldb) process attach --pid 1234The lldb subcommand automates this for an Xcode project:
pymobiledevice3 developer debugserver lldb /path/to/MyApp.xcodeprojXCUITest
xcuitest lets you drive a UI test runner against a built .app without Xcode. Mostly relevant for headless CI work.
pymobiledevice3 developer dvt xcuitest --bundle-id com.example.MyAppUITests.xctrunner ./test-runner.appRefer to upstream docs for the full argument set — semantics evolve with iOS releases.
Profile / provisioning
Install configuration profiles (MDM payloads, Wi-Fi, certs) and provisioning profiles. Profile install requires the user to approve from Settings → General → VPN & Device Management.
# Configuration profiles
pymobiledevice3 profile list
pymobiledevice3 profile install ./MyConfig.mobileconfig
pymobiledevice3 profile remove <profile-identifier>
# Provisioning profiles (for sideloaded dev builds)
pymobiledevice3 provision list
pymobiledevice3 provision install ./Dev.mobileprovision
pymobiledevice3 provision remove <UUID>Capture: screenshots, screen content, logs, crashes, traffic
Reference for the read-only capture surface of pymobiledevice3. See SKILL.md for prerequisites (Developer Mode + tunneld for iOS 17+).
Screenshots
The modern, iOS 17+-friendly path is the DVT variant — it goes through the developer instrumentation channel and works where the legacy developer screenshot (marked Deprecated in the CLI) silently fails.
# Recommended
pymobiledevice3 developer dvt screenshot ~/Desktop/shot.png
# Specific device when multiple are attached
PYMOBILEDEVICE3_TUNNEL=00008101-001E05A41144001E \
pymobiledevice3 developer dvt screenshot ~/Desktop/shot.png
# Legacy (older iOS / fallback only)
pymobiledevice3 developer screenshot ~/Desktop/shot.pngTimestamped capture-and-open one-liner (macOS):
OUT="$HOME/Desktop/ios-$(date +%Y%m%d-%H%M%S).png"
pymobiledevice3 developer dvt screenshot "$OUT" && open "$OUT"No native screen-recording subcommand exists in pymobiledevice3 today; for video, use QuickTime's "Movie Recording → device as camera" over USB on macOS.
Springboard / wallpaper / icon captures
These don't need tunneld — they're plain lockdown services.
# Save an app's icon PNG
pymobiledevice3 springboard icon com.example.MyApp ./icon.png
# Save the homescreen wallpaper PNG
pymobiledevice3 springboard wallpaper-home-screen ./wallpaper.png
# Current orientation (portrait/landscape*)
pymobiledevice3 springboard orientationLive syslog
syslog live streams the device's unified log over usbmux. Cheap and stable; first stop when diagnosing crashes that aren't producing crash reports yet, or when watching app lifecycle.
# Stream forever; ctrl-c to stop
pymobiledevice3 syslog live
# Filter at the shell — pymobiledevice3 doesn't take predicates
pymobiledevice3 syslog live | grep -i 'MyApp\|fault\|error'
# Capture to a .logarchive for later inspection with `log show` / Console.app
pymobiledevice3 syslog collect ~/ios-logsFor richer logs (more fields, includes oslog metadata) the DVT-backed variant exists but is flaky:
pymobiledevice3 developer dvt oslogPrefer syslog live unless you specifically need oslog fields.
Crash reports
The CrashReporter service surfaces both fresh and historical reports. Reports include .ips (newer) and .crash (older) formats. Symbolicate with Xcode if you need readable stacks.
# Flush queued reports from the on-device mover into CrashReports/
pymobiledevice3 crash flush
# List
pymobiledevice3 crash ls
# Pull all crashes to a local directory
pymobiledevice3 crash pull ~/ios-crashes
# Watch for new reports as they're generated
pymobiledevice3 crash watch
# Capture a full sysdiagnose (requires holding volume buttons on device — user gesture)
pymobiledevice3 crash sysdiagnose ~/sysdiagnosecrash shell opens an interactive AFC shell into the crash directory if you want to navigate before pulling.
Packet capture
The pcap service taps interface-level traffic on the device. Output is a standard .pcap you can open in Wireshark.
# Capture everything to a file
pymobiledevice3 pcap --out trace.pcap
# Limit by packet count
pymobiledevice3 pcap --out trace.pcap --count 500
# Filter to a single process — invaluable for diagnosing a misbehaving app's traffic
pymobiledevice3 pcap --out safari.pcap --process Safari
# Filter to an interface (e.g. en0 Wi-Fi)
pymobiledevice3 pcap --out wifi.pcap --interface en0Note: TLS payloads are encrypted at the wire. To see decrypted HTTP/HTTPS, install a CA on the device and route through an MITM proxy (mitmproxy/Charles) — pcap alone won't help.
Location simulation
Spoof GPS for the entire device (not just an app). Useful for region-gated features and map QA.
# Set a fixed coordinate
pymobiledevice3 developer simulate-location set 37.7749 -122.4194
# Clear and return to real GPS
pymobiledevice3 developer simulate-location clear
# Replay a GPX route (e.g. exported from Maps or recorded with a fitness app)
pymobiledevice3 developer simulate-location play ./route.gpxsimulate-location also exists under developer dvt with the same semantics; prefer the top-level one.
HAR logging (network from app perspective)
har enables network logging at the CFNetwork layer for a target app — closer to "developer tools network tab" than to pcap. Output is HAR JSON.
pymobiledevice3 developer dvt har --process com.example.MyApp --out app.harCaveat: only HTTPS/HTTP traffic going through CFNetwork shows up; sockets and lower-level APIs do not.
Diagnostics, Performance, and Networking
Reference for device introspection (lockdown, diagnostics, mounter), live performance metrics (sysmon, processes, energy), SpringBoard control, WebInspector/CDP, and port forwarding.
Device info
lockdown returns the canonical device record — everything Apple's MobileLockdown daemon exposes. Most of this is unauthenticated (no developer mode needed).
# Full dump (long, paginate)
pymobiledevice3 lockdown info | less
# A single field by domain + key
pymobiledevice3 lockdown get --domain com.apple.disk_usage --key TotalDataAvailable
pymobiledevice3 lockdown get --key ProductVersion # iOS version
pymobiledevice3 lockdown get --key DeviceName
# Get/set device name
pymobiledevice3 lockdown device-name # read
pymobiledevice3 lockdown device-name "Test iPhone" # write
# Locale and language
pymobiledevice3 lockdown locale
pymobiledevice3 lockdown languageThe MobileGestalt corpus (huge key/value store backing most Settings fields) is reachable via diagnostics:
pymobiledevice3 diagnostics mg # all known keys
pymobiledevice3 diagnostics mg DeviceColor RegionInfobonjour can discover Wi-Fi-reachable devices without USB:
pymobiledevice3 bonjour browsePower, battery, hardware diagnostics
# Battery health, cycle count, design vs current capacity
pymobiledevice3 diagnostics battery
# IORegistry dump — every hardware service the kernel exposes (huge)
pymobiledevice3 diagnostics ioregistry
# General diagnostics info
pymobiledevice3 diagnostics infoPower assertions prevent screen sleep / display dim while running e.g. long instrumentation captures:
pymobiledevice3 power-assertion --type PreventUserIdleSystemSleep
# (runs until ctrl-c)Reboot / shutdown / sleep are blunt:
pymobiledevice3 diagnostics restart
pymobiledevice3 diagnostics shutdown
pymobiledevice3 diagnostics sleepDeveloperDiskImage state
# Is developer mode on?
pymobiledevice3 mounter query-developer-mode-status
# What images are mounted?
pymobiledevice3 mounter list
# Auto-mount the correct image for the running iOS version
pymobiledevice3 mounter auto-mount
# Manual mount/unmount
pymobiledevice3 mounter mount-developer ...
pymobiledevice3 mounter umount-developerauto-mount is what you want 95% of the time after a fresh iOS update — Xcode would normally do this on first connect, but pymobiledevice3 can do it headless.
Live system performance (sysmon)
developer dvt sysmon is the live equivalent of Activity Monitor. Requires tunneld on iOS 17+.
# One-shot system stats: CPU%, mem pressure, thermal state, uptime
pymobiledevice3 developer dvt sysmon system
# Per-process polling loop — top-like view of CPU/memory per PID
pymobiledevice3 developer dvt sysmon processFor PID enumeration and runtime checks:
pymobiledevice3 developer dvt proclist # PIDs + names + start times
pymobiledevice3 developer dvt is-running-pid 1234
pymobiledevice3 processes # alternate (diagnosticsd-backed) listingEnergy monitoring (Instruments' Energy Log equivalent) needs explicit PIDs:
pymobiledevice3 developer dvt energy 1234 5678Graphics / FPS sampling and notification monitoring:
pymobiledevice3 developer dvt graphics # FPS, GPU%, draw call rates
pymobiledevice3 developer dvt notifications # memory + app lifecycle eventsNetwork / port forwarding
usbmux forward is the most useful piece for development: tunnel a TCP port from your host through usbmuxd to the device. Local-only, no tunneld needed. Survives ctrl-c only if you background it.
# Forward localhost:8080 -> device:8080 (e.g. a dev server inside an app)
pymobiledevice3 usbmux forward 8080 8080
# Different local port to avoid collisions
pymobiledevice3 usbmux forward 9090 8080
# Target a specific device by UDID
pymobiledevice3 usbmux forward --udid 00008101-... 8080 8080For developer-service tunnels (e.g. to talk RemoteXPC directly):
# Print the RSD HOST:PORT for use with --rsd
pymobiledevice3 remote start-tunnelWebInspector (Safari + WKWebView debugging)
Requires Safari → Settings → Advanced → "Web Inspector" enabled on the device, and a Mac with the matching Safari Develop menu enabled. cdp exposes a Chrome DevTools Protocol endpoint, which is useful for headless WebView automation (Playwright, Puppeteer-style harnesses).
# See what's debuggable
pymobiledevice3 webinspector opened-tabs
# Open a URL in Safari
pymobiledevice3 webinspector launch https://example.com
# JavaScript REPL bound to a remote target
pymobiledevice3 webinspector js-shell
# Start a CDP server (default port printed on stdout) — point Chrome DevTools or CDP clients at it
pymobiledevice3 webinspector cdpwebinspector shell drops you into an IPython shell with a WebView handle for ad-hoc scripting.
Notifications
The Darwin notification proxy lets you observe or post system-wide notifications. Useful for triggering app-side handlers (e.g. wallpaper changed, low memory).
# Observe notifications by name
pymobiledevice3 notifications observe com.apple.UIKit.userActivityActive
# Post a notification (limited — most names require entitlements)
pymobiledevice3 notifications post com.example.MyNotificationForce device conditions (DVT)
Simulate constrained network, low battery, or thermal pressure for testing — same conditions Xcode's "Devices and Simulators → Conditions" exposes.
# Network conditioning (predefined profiles)
pymobiledevice3 developer developer ...The developer developer subcommand handles conditions; see pymobiledevice3 developer developer --help for the current profile names — Apple changes them between iOS releases.
Arbitration
When multiple tools (Xcode, Instruments, automation harnesses) compete for the device, mark/unmark in-use to avoid collisions:
pymobiledevice3 developer arbitration check-in
pymobiledevice3 developer arbitration check-outRelated skills
FAQ
Why does 'Failed to start service' appear on iOS 17+?
tunneld is not running; start 'sudo pymobiledevice3 remote tunneld' and retry, confirming with 'ps aux | grep tunneld'.
Why does the screenshot API hang on iOS 17+?
The deprecated developer screenshot hangs; use the DVT variant 'developer dvt screenshot' instead.