strands-ios 📱
Give your agent an iPhone.
@tool decorated iOS device control for Strands Agents & DevDuck.
Drive any USB-connected iPhone/iPad from an LLM — read syslog, launch apps, take screenshots, simulate location, drive UI (via WebDriverAgent), pull crash logs, capture pcap.
Backed by pymobiledevice3 — the canonical pure-Python replacement for libimobiledevice.
🔌 Use as an MCP server
Use strands-ios from Claude Code, Claude Desktop, Cursor, Kiro, or any MCP client — the ios tool (device control, apps, screenshots, UI automation) becomes an MCP tool.
claude mcp add ios -- uvx strands-ios
Claude Desktop config:
{
"mcpServers": {
"ios": {
"command": "uvx",
"args": ["strands-ios"]
}
}
}
Options:
strands-ios --http --port 8000 # HTTP mode, multi-client
Install
pip install strands-ios
Optional extras:
pip install 'strands-ios[ui]' # facebook-wda for UI automation
pip install 'strands-ios[vision]' # Pillow for image manipulation
Setup
-
Trust the computer on your iPhone (plug it in → "Trust This Computer")
-
Enable Developer Mode on iOS 16+ (Settings → Privacy & Security → Developer Mode)
-
For iOS 17+ developer services (DVT, screenshot, launch/kill), start a tunnel:
sudo pymobiledevice3 remote tunneld
-
For UI automation (tap/swipe/type), install WebDriverAgent on the device and run it. Then
export WDA_URL=http://localhost:8100after port-forwarding (iproxy 8100 8100).
Quickstart
from strands import Agent
from strands_ios import ios
agent = Agent(tools=[ios])
agent("take a screenshot of my iphone and describe what's on screen")
DevDuck (1 line)
export DEVDUCK_TOOLS="strands_ios:ios;strands_tools:shell"
devduck "show me the last 50 lines of syslog from my iphone"
Actions
| Domain | Actions |
|---|---|
| device | list_devices, select_device, device_info, battery, storage |
| syslog | syslog, syslog_stream_start, syslog_stream_stop |
| screen | screenshot, screenrecord_start, screenrecord_stop |
| apps | list_apps, launch, kill, install, uninstall, current_app |
| files | afc_ls, afc_pull, afc_push |
| diag | crash_logs, pcap_start, pcap_stop |
| ui (WDA) | tap, swipe, type_text, press |
| misc | open_url, set_location, reboot |
👁️ Vision
screenshot returns a proper Converse API image block — the agent actually sees the screen:
agent("screenshot my iphone and tell me if there are unread messages")
# → ios(action="screenshot") returns PNG bytes in Converse image block
# → vision model reads it → "You have 3 unread iMessages from..."
Env vars
| Var | Purpose |
|---|---|
IOS_UDID |
default device UDID |
WDA_URL |
WebDriverAgent base URL (e.g. http://localhost:8100) |
PYMOBILEDEVICE3_BIN |
override pmd3 binary path |
Differences from strands-adb
iOS is not Android. Some honest trade-offs:
| Capability | Android (adb) | iOS (pymobiledevice3) |
|---|---|---|
| Arbitrary shell | ✅ adb shell |
❌ no userland shell |
| Screenshot | ✅ trivial | ⚠️ needs DVT + dev mode |
| UI automation | ✅ input tap |
⚠️ needs WebDriverAgent |
| App install | ✅ APK | ✅ IPA (properly signed) |
| File access | ✅ full fs (with root) | ⚠️ AFC only (sandboxed) |
| Syslog | ✅ logcat |
✅ syslog live |
| Pcap | ⚠️ needs root | ✅ native |
License
MIT
Metadata
Release files for strands-ios 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| strands_ios-0.1.0.tar.gz | 14.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| strands_ios-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.2 kB
Release files / strands_ios-0.1.0.tar.gz
| Download URL | strands_ios-0.1.0.tar.gz |
|---|---|
| Size | 14.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9fb2f00e15947f79244ad886844fc9e4eba0e693c0ffdbf3665119a8b7daaccf
|
|
BLAKE2b-256 checksum How to use checksums |
daadd30d2946d37565e41b08cfe3688749f421416c546b5a11cb9f6b52ea60a2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.11
|
Release files / strands_ios-0.1.0-py3-none-any.whl
| Download URL | strands_ios-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d2454fcce6814bdacaa107add614a6a909d202ac8bd7f4758d341e16d98a1257
|
|
BLAKE2b-256 checksum How to use checksums |
de8a230d270addd7e0ab0599e8fc4235ba3a66ca846a2198349dc0db1e160ba8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.11
|
Security for strands-ios 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.