Getting started
Use Silan from your agent
Silan’s engine serves four ways in, all on the Mac that holds the devices, all through the same safety rules:
| Way in | For | Address |
|---|---|---|
| MCP server | AI apps and agents (Claude Code, Codex, Cursor, OpenCode, the Claude app, any MCP client) | silan mcp over stdio, or /mcp over HTTP with a key |
| Command line | Scripts and people in Terminal | silan inside Silan.app |
| REST API | Your own programs | http://127.0.0.1:47800/v1 |
| WebDriver endpoint | Appium-style test clients | http://127.0.0.1:47800/wd/hub |
The engine listens on this Mac only (127.0.0.1 and ::1). Every call needs a key, or a one-time Allow from you for an app connected through the Silan app.
Connect an AI app
Section titled “Connect an AI app”In Settings › Connections (or setup’s Your AI tools), press Connect next to the app:
| App | What Connect does |
|---|---|
| Claude Code | Writes Silan into Claude Code’s MCP settings. Start a new session. |
| Claude app | Writes Silan into the Claude app’s settings. Quit the app and open it again. |
| Codex | Writes Silan into Codex’s settings. Start Codex again. |
| Cursor | Writes Silan into Cursor’s settings. Quit Cursor and open it again. |
| OpenCode | Writes Silan into OpenCode’s settings. Start OpenCode again. |
For a coding app, Connect asks which tools it gets: the everyday set, or the testing set for testing an app you make. For any other MCP client, copy The setup text for other apps, a complete mcpServers entry, into that client’s settings.
The first time a connected app calls a tool, Silan asks you: Allow, Allow this time or Don’t allow. Silan names the app from the signature of the program that started it, so a program that only calls itself “Claude Code” is not Claude Code. Each app gets its own grant, and the Connections page shows what it did and when.
MCP server
Section titled “MCP server”silan mcp is a stdio MCP server. It speaks to the engine on this Mac and offers a profile of tools:
| Profile | Tools | For |
|---|---|---|
core (default) |
16 | Everyday tasks: look, tap, type, swipe, wait, open apps and links, hand over logins |
testing |
32 | App testing: core plus scenarios, recordings, checks, notifications, test pushes, installs, location, clipboard, rotation, text size |
full |
50 | Everything, including the built-in agent, routines and raw element queries |
Pick a profile with silan mcp --profile testing. The SILAN_MCP_PROFILE variable is read by the plugin launchers and the Claude app bundle, not by silan mcp itself. With --key or SILAN_API_KEY, silan mcp uses that key against the engine’s /mcp listener instead and asks you nothing.
Every tool is a direct mapping of one REST operation, so the two never differ. The MCP tools reference lists all 50 with their parameters.
The loop an agent runs
Section titled “The loop an agent runs”list_devices, thenclaim_devicesso no other agent uses the same device.observe: a screenshot plus a compact list of elements with refs.- Act on a ref:
tap,type_text,swipe,launch_app,open_url. wait_fora condition inside the engine (an element shows or goes, text, an app, a notification, a stable screen) instead of sleeping.release_deviceswhen done.
A risky step answers APPROVAL_REQUIRED until you say yes in Silan. Passwords never reach the agent: it calls fill_credential (your Vault, 1Password or Bitwarden) or request_person_login, and you type.
Plugins for Claude Code and Codex
Section titled “Plugins for Claude Code and Codex”The Silan plugin carries the MCP server config and the skills below. From a copy of the plugin folder:
claude plugin marketplace add /path/to/silan/Pluginsclaude plugin install silan@silanclaude mcp list then shows the Silan server connected while Silan runs. The Codex plugin and the Claude app bundle (silan.mcpb) exist in the same folder; the Connect buttons in the app are the proven path for those two today.
Skills
Section titled “Skills”Public skills, MIT licensed, teach an agent to drive phones well through Silan. The Claude Code and Codex plugins install them. To use one without the plugin, copy its folder into your agent’s skills folder, for example ~/.claude/skills/silan/.
| Skill | Teaches |
|---|---|
silan |
The observe-act loop, element refs before pixels, leases, capabilities, errors, tool profiles |
silan-text-entry |
Typing, editing, keyboards, pickers, one-time codes, and never typing passwords |
silan-waits |
Waiting for screens, loading and notifications with wait_for instead of sleeps |
silan-safety |
What an agent must not do alone: send, pay, post, delete, logins, other people’s data |
silan-app-guides |
Short maps of common iPhone and Android apps, plus patterns for shopping, forms and system prompts |
Bring your own model
Section titled “Bring your own model”The Examples/agent-loops folder has three small, complete phone agents that start silan mcp and use the skills as their system prompt: one on the Claude API, one on any OpenAI Responses model, and one on any OpenAI-compatible local server (Ollama, LM Studio, llama.cpp, vLLM).
Command line
Section titled “Command line”The silan command ships inside the app at /Applications/Silan.app/Contents/Helpers/silan. It is not on your PATH; call it by that path or link it yourself.
SILAN=/Applications/Silan.app/Contents/Helpers/silan$SILAN devices$SILAN observe ios:00008120-001A2B3C4D5E6F70 --elements interactive$SILAN tap ios:00008120-001A2B3C4D5E6F70 --text "Checkout"$SILAN stopThe command line reference lists every command. On this Mac, silan finds the engine and its local key by itself through ~/Library/Application Support/Silan/engine.json.
REST API
Section titled “REST API”The engine’s REST API is described by one OpenAPI 3.1 document with 64 operations. The REST reference is generated from it.
- Base address
http://127.0.0.1:47800(the real port is inengine.json). Loopback only. Authorization: Bearer silan_sk_...with a key you made on the Connections page under For developers. Thesilan keys createcommand answers403on the current release: make keys in the app.- Requests with an
Originheader are refused unless the origin is on the engine’s allow list. - Errors are RFC 9457 problem documents with a stable
code, such asTARGET_NOT_FOUNDorDEVICE_LEASED. - Any device call accepts
Prefer: respond-asyncand then returns202with a job. - A device under another holder’s lease returns
409 DEVICE_LEASED; pass your lease token in theSilan-Leaseheader.
KEY=silan_sk_...curl -s -H "Authorization: Bearer $KEY" http://127.0.0.1:47800/v1/devicescurl -s -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \ -d '{"action":{"type":"tap","target":{"query":{"text":"Checkout"}}}}' \ http://127.0.0.1:47800/v1/devices/ios:00008120-001A2B3C4D5E6F70/actionsKeys are scoped: which devices, which tool profile, which policy profile, and when they expire (30 days, 90 days, 1 year or never).
WebDriver endpoint
Section titled “WebDriver endpoint”/wd/hub is a W3C WebDriver endpoint in the Appium style, so an existing WebDriver client can open a session on a device, find elements (accessibility id, id, name, link text, partial link text, class name), act and take screenshots. It is not a full Appium server. Risky steps answer with a 500 until you approve them in Silan, then the same call works.
Python
Section titled “Python”A Python library lives in the repository at SDKs/python (standard library only, Python 3.9 or later). It is not published yet (coming soon). Its shape:
import silan
client = silan.Client() # finds the engine; the key comes from SILAN_API_KEYwith client.claim("ios:00008120-001A2B3C4D5E6F70") as lease: phone = lease.device() phone.tap(text="Checkout") assert phone.wait_for(text="Sent", timeout_ms=5000)Event stream
Section titled “Event stream”GET /v1/events is a server-sent event stream of device, approval, job and run events, for clients that follow a long task without polling.