Your devices stay yours
Simlock only shuts down, erases or deletes devices it created. Everything else is read-only to it.
Simlock
Simlock leases, serves and manages iOS and Android devices for your coding agents. Start on one Mac, then add machines behind a gateway when you need more. Free and open source.
One machine. Your agents lease its devices three ways:
the simlock CLI, agent-device, or HTTP.
CLIclaude code · on your-mac
$ simlock lease --platform ios
granted iPhone 17 Pro · warm
AGENT-DEVICEcodex · on your-mac
$ agent-device open MyApp --platform ios
streaming iPhone 17 Pro
HTTPci · → your-mac:4701
→ POST /v1/lease-requests
granted Pixel 8
gateway · gw.example
one URL for every agent
picks a machine with room
your-macmacOS
LIVEiPhone 17 Proclaude code
Works with iOS simulators, Android emulators, Physical iPhones, Physical Android phones, macOS workers, Linux workers, CLI, MCP, HTTP API, agent-device.
[01] How it works
Install the CLI. The daemon starts on demand, so there is no setup step.
$ npm i -g simlockAsk for a platform and a model. You get a booted, checked device no other agent will touch.
$ simlock lease --platform ios --device "iPhone 16"Run one daemon as a gateway, mint a join token, and point each Mac or Linux worker at it.
$ simlock --gateway token create --role workerSimlockzsh
simlock lease --platform ios --device "iPhone 16"
simlock simctl install <device.address> ./MyApp.app
simlock release <lease.id>
simlockFor agents on the machine itself. Lease results are one JSON line on stdout.Set up CLI
[02] Fleet
A gateway owns no devices. Workers dial out to it, so a Mac behind NAT joins with a URL and a token, and each request goes to a warm device first, then to the machine with the most room.
Simlockzsh
# on the gateway
simlock --gateway daemon start
simlock --gateway token create --role worker
# on each worker, Mac or Linux
simlock config set gateway '{"url":"wss://gw.example","token":"slk_..."}'
simlock daemon stop
simlock daemon start[03] Console
The daemon serves the console itself once HTTP is on. Sign in with an operator token, or through the sign-in proxy you already run, and watch every worker, lease and request on the gateway update within about a second.
Overview
Workersleasedreadybootingfree
WorkerPlatformsDevicesLeases
mac-studio-1iOS · Android1
mac-studio-2iOS · Android1
linux-ci-1Android1
Waiting1 request
1agent-4iPhone 17 Prostarting3s
Leases3 held
agent-114:42iPhone 17 Pro · mac-studio-1
ci-runner-314:51iPhone 17 Pro · mac-studio-2
agent-314:56Pixel 8 · linux-ci-1
ScreenLive
agent-1 iPhone 17 Pro · mac-studio-1
Expires in 14:42Stop
ActivityAll events
Every worker that joined: its CPU, memory and disk, and a square for each device slot.
Read moreWho holds which device on which worker, how long it has left, and its screen, live.
Read moreEach request still in line, how long it has waited, and why no worker has taken it yet.
Read moreDisconnected and drained workers, RAM over budget, quarantined, stalled and absent devices, long waits and leases about to end.
Read more[04] What you get
A device on lease belongs to one agent until it releases it or the TTL runs out.
Read moreNothing free that fits? Simlock creates one, up to what the machine’s CPU and RAM can hold.
Read morePast capacity, requests wait their turn instead of failing. Use --timeout or --no-wait to change that.
Keep the models you use booted and clean, so the first lease is granted without a boot.
Read moreAn unused device is shut down to free RAM, then deleted to free disk.
Read moreWhen a leased device dies, Simlock reboots it under the same lease and tells the holder.
Read moreEnroll iPhones and Android phones; on release, Simlock uninstalls the apps they did not have.
Read moreThe CLI, an MCP server, the HTTP API and a typed client, all on one contract.
Read more[05] Safe by default
Simlock only shuts down, erases or deletes devices it created. Everything else is read-only to it.
The HTTP API and the console listen on loopback only, and both ask for a token. Nothing is reachable from another machine until you change http.host.
Agents, operators and workers get their own tokens, hashed at rest and revocable.
simlock simctl and simlock adb refuse verbs that would change a device behind its lease.
[06] FAQ
simctl or avdmanager. What it does enforce is its own reach: it only shuts down, erases or deletes devices it created.simlock lease renews on a timer and releases when it exits, so a killed holder frees its device at once, and one that vanishes costs the device only until the TTL runs out.--timeout and --no-wait for callers that want something else.simlock --gateway token create --role worker, so a Mac behind NAT joins without an inbound port.android.emulator.headless, as on a Linux CI runner. iOS simulators need a Mac with Xcode.POST /v1/lease-requests on the gateway, then POST /v1/leases/{id}/exec to run simctl or adb on whichever worker holds the device. agent-device can use the gateway as its proxy too.