Metadata-Version: 2.4
Name: strands-ios
Version: 0.1.0
Summary: @tool decorated iOS device control for Strands Agents
Author: cagataycali
License: MIT
Project-URL: Homepage, https://github.com/cagataycali/strands-ios
Project-URL: Issues, https://github.com/cagataycali/strands-ios/issues
Keywords: strands,agent,ios,iphone,ipad,pymobiledevice3,devduck,llm-tools
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: strands-agents
Requires-Dist: pymobiledevice3>=4.0.0
Requires-Dist: strands-mcp-server
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Provides-Extra: vision
Requires-Dist: Pillow>=10; extra == "vision"
Provides-Extra: ui
Requires-Dist: facebook-wda>=1.4; extra == "ui"
Dynamic: license-file

<div align="center">
  <h1>strands-ios 📱</h1>
  <p><strong>Give your agent an iPhone.</strong></p>
</div>

`@tool` decorated iOS device control for [Strands Agents](https://strandsagents.com) & [DevDuck](https://dev.duck.nyc).

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](https://github.com/doronz88/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.

```bash
claude mcp add ios -- uvx strands-ios
```

Claude Desktop config:

```json
{
  "mcpServers": {
    "ios": {
      "command": "uvx",
      "args": ["strands-ios"]
    }
  }
}
```

Options:

```bash
strands-ios --http --port 8000   # HTTP mode, multi-client
```

---

## Install

```bash
pip install strands-ios
```

Optional extras:

```bash
pip install 'strands-ios[ui]'      # facebook-wda for UI automation
pip install 'strands-ios[vision]'  # Pillow for image manipulation
```

## Setup

1. Trust the computer on your iPhone (plug it in → "Trust This Computer")
2. Enable **Developer Mode** on iOS 16+ (Settings → Privacy & Security → Developer Mode)
3. For iOS 17+ developer services (DVT, screenshot, launch/kill), start a tunnel:

   ```bash
   sudo pymobiledevice3 remote tunneld
   ```

4. For UI automation (tap/swipe/type), install [WebDriverAgent](https://github.com/appium/WebDriverAgent) on the device and run it. Then `export WDA_URL=http://localhost:8100` after port-forwarding (`iproxy 8100 8100`).

## Quickstart

```python
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)

```bash
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:

```python
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
