lazy-ios
Automates iOS build and test workflows, including building and installing apps, managing simulator leases, driving UI interactions, and collecting screenshots and accessibility evidence on simulators and physical devices.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@lazy-iosRun the UI test flow for MyApp on a simulator and release the device."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
lazy-ios
One MCP server for iOS build/test automation. Replaces three moving parts —
appium-mcp, xcrun mcpbridge, and the baguette CLI driven by hand — with a
single process that owns the whole lifecycle.
The merge is not packaging convenience. Both defects that motivated it are ownership problems, and no individual server could fix either, because each one only ever saw its own slice.
defect | measured before | cause | fix |
simulator leak | 14 simulators, 5 booted, none reclaimed | nothing recorded who created a device, so nothing dared delete one | ledger-backed leases; only devices lazy-ios created can be shut down or deleted |
real device fails every time | 5 consecutive | the RemoteXPC tunnel for the UDID was never registered; the driver's error text blames the session | preflight checks the registry by UDID before a session is attempted and names the missing step |
helper process leak | 5 orphan | one helper per client connection, none supervised | one supervised Appium server, recorded by pid, adopted on reconnect |
Install
bun installRegister it (this replaces the appium and xcode entries):
{
"mcpServers": {
"lazy-ios": {
"type": "stdio",
"command": "bun",
"args": ["/path/to/lazy-ios/src/index.ts"],
"timeout": 1800000
}
}
}Requires Xcode 26+, baguette >= 0.1.96 (brew install baguette), and — for
physical devices only — Appium with the XCUITest driver.
Related MCP server: SilbercueSwift
The lazy path
// ios_run
{
"path": "/path/to/MyApp",
"steps": [
{ "expect": "Sign in" },
{ "tap": "login.button" },
{ "text": "hello@example.com" },
{ "expect": "Welcome" }
]
}That single call discovers the project, resolves a scheme, builds, takes a simulator under lease (reusing an idle scratch device when one matches), installs, launches, waits for the accessibility tree to populate, runs the steps, writes screenshot + AX evidence, and releases the device. The release runs even when a phase throws, and a failed release fails the run.
Measured on this machine, Fixtures/LazyProbe:
discover 0.6s target 18.3s (created) build 7.0s install 7.0s
launch 0.6s settle 3.7s steps 3.7s release 3.2s → 45sSecond run against the same device type:
target 2.3s (reused) → 26s totalTools
tool | purpose |
| build → launch → drive → evidence → release, in one call |
| every precondition, measured; |
| simulators and phones annotated with the lease that holds them |
| open/close a leased target for interactive work |
| describe / find / tap / swipe / text / screenshot, same verbs on both backends |
| schemes, configurations, targets |
| reclaim leases whose holder is gone |
| just the real-device chain, with the exact fix for each failure |
Ownership rule
The rule the whole codebase is built on:
lazy-ios may shut down or delete only a device it created itself and recorded in the ledger. A device that already existed is adopted: usable, never destroyed, never even shut down unless lazy-ios was the one that booted it.
~/.lazy-ios/ledger.json records provenance (created / adopted), the
holding pid, and a lease deadline. Four independent triggers return a device:
an explicit close, the end of ios_run, an idle sweep, and process exit. A
lease whose holder pid is gone is reclaimable by the next run, which is the
backstop for kill -9.
Foreign booted simulators are reported by ios_doctor, with the simctl
command to shut them down — and never touched.
Real devices
The preflight encodes what was diagnosed in
folio-v2/Docs/ios-real-device-automation-setup.md:
device connected, paired, developer mode on
appium-ios-remotexpcimportable fromAPPIUM_HOMEappium-ios-tuntapnative module builta tunnel registered for this exact UDID in the registry on port 42314
no Appium server older than the remotexpc install — the driver caches "module unavailable" for the lifetime of the process
Step 4 needs root. lazy-ios never runs sudo; it prints the command:
sudo env APPIUM_HOME="$HOME/.appium" $(command -v appium) \
driver run xcuitest tunnel-creation --udid <UDID>Leave that running. Port 42314 is Appium's own registry —
pymobiledevice3 remote tunneld on 49151 is a different thing and does not
satisfy the driver.
Without it, ios_session open kind:device refuses in under a second with that
exact instruction, instead of spending 180 s to fail with a message that blames
the session.
Backends
simulator | physical device | |
UI |
| WebDriverAgent over Appium |
install |
|
|
coordinates | AX points from | AX points from |
text entry | pasteboard |
|
Text entry never uses HID keystrokes: with a Korean keyboard active, typing
" abc123" has been measured to land as 뮻123 because the keystrokes pass
through the IME.
Coordinates are always accessibility points from the same tree describe
returns. Screenshot pixels are 3× larger and feeding them to a tap silently
misses.
Fixture
Fixtures/LazyProbe is a ~40-line SwiftUI app used to verify the pipeline
itself. Its status text changes on tap, so a passing smoke run proves the tap
reached the app rather than proving only that a screen rendered.
cd Fixtures/LazyProbe && xcodegen generateThis server cannot be deployed
Maintenance
Related MCP Connectors
Build, run, and inspect iOS apps in disposable hosted Simulators from cloud coding agents.
MCP server for Appcircle mobile CI/CD platform.
- LimrunOAuthcom.limrun
Cloud iOS simulators and Android emulators your agent can create, drive, and throw away.
Create App Store screenshots, icons, ASO copy, localization, and revisions via hosted MCP.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceAn MCP server that provides comprehensive tools for managing iOS simulators, including device control, app lifecycle management, and UI automation. It enables developers to boot devices, install apps, capture screenshots, and simulate user interactions through natural language commands.3MIT

SilbercueSwiftofficial
AlicenseNot gradedqualityBmaintenanceHigh-performance MCP server for iOS development and test automation. Gives AI coding assistants direct access to iOS simulators with sub-20ms screenshots, UI interaction, building, testing, and an intelligent operator mode.8MIT- FlicenseNot gradedqualityDmaintenanceEnables AI to control iOS simulators through the MCP protocol. Supports device management, UI automation, and network interception including screenshot capture, text input, and HTTP request mocking.-
- AlicenseNot gradedqualityCmaintenanceMCP server to control iOS simulators for automation, enabling device management, input control, and screen capture via Facebook IDB.10MIT