iosctl
Use iosctl for native iOS Simulator build/run/proof loops.
Default stance:
- Prefer the
iosctlCLI over MCP-only iOS helper servers. - Prefer
--jsonfor agent work. - Treat MCP as optional transport, not source of truth.
- Prefer first-party Apple tools through
iosctlbefore third-party abstractions. - Prefer accessibility trees and identifiers before screenshot vision.
- Do not claim the app works unless there is a receipt, screenshot path, or result artifact.
- Do not pass secrets as command-line arguments.
skills.sh Package Shape
This skill is published from the nested path skills/iosctl/SKILL.md. Do not depend on a root
SKILL.md; Vercel's skills CLI lets a shallower SKILL.md shadow nested skills.
Install the skill with:
npx -y skills add -g danielgwilson/iosctl --skill iosctl
Use it without installing with:
npx -y skills use danielgwilson/iosctl@iosctl
Command Resolution
Use iosctl when it is already available on PATH. If it is missing and Node.js is available,
prefer the published package for one-off agent runs:
npx -y iosctl@latest doctor --json
Only ask the user to install globally when repeated local use is expected:
npm i -g iosctl
Sanity Checks
Start with:
iosctl doctor --json
iosctl devices --json
If iosctl is missing from PATH, use the published package for the same checks:
npx -y iosctl@latest doctor --json
npx -y iosctl@latest devices --json
For local development, use the repository checkout:
npm install
npm run build
npm link
Proof Loop
Use:
iosctl proof-run \
--project App.xcodeproj \
--scheme App \
--bundle com.example.app \
--device "iPhone 17 Pro" \
--json
Expected artifacts:
.iosctl/runs/<run-id>/receipt.json.iosctl/runs/<run-id>/summary.md- build log or result path
- app log path
- screenshot path
- optional UI tree path
If proof-run fails, inspect the returned error.artifact first. It should point at either receipt.json or the failing command log.
Fallback manually in this order only when the CLI cannot complete:
iosctl doctor --jsoniosctl devices --json- direct
xcodebuildbuild with explicit DerivedData and result paths - direct
xcrun simctl boot/install/launch - direct
xcrun simctl io ... screenshot - store commands and artifacts in a run directory
Semantic UI
Use semantic UI commands for app navigation:
iosctl ui snapshot --device <UDID> --json
iosctl ui find --text "Book appointment" --json
iosctl ui tap --text "Book appointment" --json
iosctl ui type --text-field "Ask anything..." --value "Can you help with scheduling?" --json
iosctl ui swipe --direction up --json
ui snapshot stores the full raw accessibility tree and normalized element list under .iosctl/ui/<snapshot-id>/. Use those artifacts when stdout is capped.
If the CLI cannot read the accessibility tree, use direct idb ui describe-all --nested --json before screenshot vision.
Contract Essentials
- With
--json, stdout must be exactly one JSON object. - Progress belongs on stderr.
- Exit codes:
0success1operation failed2invalid input, missing capability, or user action required3safety refusal
- Common error codes:
MISSING_TOOLCOMMAND_FAILEDINVALID_INPUTSAFETY_REFUSALNOT_IMPLEMENTEDXCODE_UNAVAILABLESIMULATOR_UNAVAILABLEDESTINATION_UNAVAILABLEAPP_NOT_FOUNDBUNDLE_LAUNCH_FAILEDUI_TREE_UNAVAILABLEUI_ELEMENT_NOT_FOUNDTIMEOUT
Safety
- Never commit
.iosctl/run artifacts unless explicitly sanitized. - Never paste full app logs, screenshots, or UI trees into public docs without review.
- Never pass API keys or auth tokens as CLI arguments.
- Treat screenshots and app logs as local private artifacts by default.
- Use synthetic examples in docs and tests.