---
name: lusor
description: Connect Lusor so an AI agent can run agents on real phones and control them directly, through the Lusor MCP server (https://mcp.lusor.ai/mcp) or the REST API (https://api.lusor.ai/v1). Use when a task needs to operate an Android phone or iPhone, run a mobile-app task and read the result, or set up Lusor credentials.
---

# Lusor

Lusor gives AI agents phones. A workspace holds phones: your own phone connected through the Lusor app, or a Lusor Phone, a cloud phone Lusor runs for you. You can send a task to a Lusor agent on a phone and follow the run until it returns an output, or drive a phone yourself one action at a time: read the screen, tap, type, swipe, launch apps. Both are available through a remote MCP server and a REST API.

Docs: https://docs.lusor.ai

## Install / connect

There is nothing to install. Lusor is a remote MCP server plus a REST API. Do not look for a Lusor CLI or package; the docs describe none.

1. Reuse a working Lusor MCP connection in the active harness if there is one.
2. Otherwise add the MCP server URL to the harness:

```
https://mcp.lusor.ai/mcp
```

Harness-specific commands (full guides: https://docs.lusor.ai/connect):

```bash
# Claude Code (--transport http is required)
claude mcp add --transport http lusor https://mcp.lusor.ai/mcp
# Codex CLI
codex mcp add lusor --url https://mcp.lusor.ai/mcp
# Pi
pi mcp add lusor --url https://mcp.lusor.ai/mcp
# Hermes Agent
hermes mcp add --url https://mcp.lusor.ai/mcp --auth oauth lusor
# Grok Build
grok mcp add --transport http lusor https://mcp.lusor.ai/mcp
```

Claude (web/desktop/mobile), ChatGPT (Business, Enterprise and Edu only) and Grok add it as a custom connector in their settings. Per-app steps: https://docs.lusor.ai/connect/claude, https://docs.lusor.ai/connect/chatgpt, https://docs.lusor.ai/connect/grok, https://docs.lusor.ai/connect/hermes, https://docs.lusor.ai/connect/pi, https://docs.lusor.ai/connect/codex.

The server exposes two tools:

- `search` reads the Lusor API reference to find an operation and its parameters.
- `execute` calls the Lusor API (list phones, start a run, read status and output, tap, type, screenshot).

An MCP connection can do what an API key can and nothing more. Billing, API keys, members, the vault, adding or removing phones, static IPs, workspace creation and routines answer `403 forbidden_for_mcp_oauth`; those are done in the Lusor app by the human.

## Get credentials

Pick one. Both give the same access.

- **Sign in with Lusor (OAuth), the default for MCP.** After you add the server, the harness opens a Lusor sign-in. The human signs in and chooses the organization to connect. You never see a key. Codex: `codex mcp login lusor`. Pi: `pi mcp login lusor`. Claude Code: run `/mcp`, select `lusor`, choose Authenticate. With OAuth, requests use the organization's default workspace; send the `X-Lusor-Workspace` header to choose another.
- **API key.** Needed for the REST API, and optional for MCP in apps that let you set headers. The human creates it in the Lusor app (https://app.lusor.ai) under **Settings → API Keys**. It is shown once and belongs to one workspace. Workspace admins and members can create keys; viewers cannot, and an API key cannot create other keys. Keep it in an environment variable, never in source control:

```bash
export LUSOR_API_KEY="<your API key>"
```

Send it as `X-Api-Key: $LUSOR_API_KEY` or `Authorization: Bearer $LUSOR_API_KEY`. To use a key with MCP: `codex mcp add lusor --url https://mcp.lusor.ai/mcp --bearer-token-env-var LUSOR_API_KEY`, the same flag on `pi mcp add`, or `claude mcp add --transport http lusor https://mcp.lusor.ai/mcp --header "Authorization: Bearer $LUSOR_API_KEY"`.

There is no keyless tier and no agent-signup flow: every `/v1` endpoint except `GET /v1/health` requires a key (or an OAuth sign-in over MCP). If you have no credentials, ask the human to do the sign-in or create the key, then continue.

Reference: https://docs.lusor.ai/authentication

## Choose your path

- Use Lusor from inside an AI app or coding harness -> Path A (MCP)
- Call Lusor from code or scripts -> Path B (REST API)
- Give a phone a task and get a result -> Path C (agent run)
- Operate a phone action by action -> Path D (direct control)
- Something needs a person -> Path E (what needs the human)

Paths C and D work through MCP (`execute`) or REST; the endpoints are the same.

## Path A: MCP

1. Add the server and authenticate as above.
2. Confirm the connection lists the `search` and `execute` tools (`pi mcp list`, `hermes mcp test lusor`, or `/mcp` in Claude Code).
3. Use `search` to find the operation you need, then `execute` to call it. The tools reach only documented `/v1` operations, and every call is checked by the API.

Guide: https://docs.lusor.ai/connect

## Path B: REST API

Base URL `https://api.lusor.ai`. Authenticate with an API key (see above).

```bash
curl https://api.lusor.ai/v1/devices -H "X-Api-Key: $LUSOR_API_KEY"
```

A key is bound to one workspace. Endpoints with an optional `workspaceId` use the key's workspace by default. Endpoints with `{workspaceId}` in the path need your workspace id, which is the `workspaceId` field of any agent (`GET /v1/agents`). Another workspace's id returns `404`. Errors: `401 unauthenticated` (no key), `401 invalid_api_key`, `404 not_found`, `429 rate_limit_exceeded` (wait for `Retry-After`).

Call the API from a server, never from a browser or shipped app. Phones: https://docs.lusor.ai/devices. Full reference: https://docs.lusor.ai/api-reference/introduction. Quickstart: https://docs.lusor.ai/quickstart.

## Path C: Run an agent and follow its status

An agent is a persistent assistant with one phone. Each task is a turn; each turn runs as a session.

1. Find a connected phone: `GET /v1/devices`, take the `id` of one with `"connected": true`. If there is none, the human must pair a phone or add a Lusor Phone in the Lusor app.
2. Reuse an agent from `GET /v1/agents`, or create one:

```bash
curl https://api.lusor.ai/v1/agents -H "X-Api-Key: $LUSOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "My agent", "devices": [{ "device_id": "<device id>" }] }'
```

3. Send a task (returns `202` with `sessionId`). The `Idempotency-Key` makes retries safe:

```bash
curl https://api.lusor.ai/v1/agents/<agent id>/turns -H "X-Api-Key: $LUSOR_API_KEY" \
  -H "Content-Type: application/json" -H "Idempotency-Key: task-1" \
  -d '{ "prompt": "Open Settings and tell me which Android version this phone runs." }'
```

`queued: true` means the phone is busy and the turn waits. `needsDevice: true` means the agent has no phone and the turn did not run.

4. Poll `GET /v1/sessions/<sessionId>/status` every few seconds. Final statuses: `completed` (or `complete`), `failed`, `cancelled`. `awaiting_human` means the agent needs an answer from the human in the Lusor app.
5. Read the result from `GET /v1/sessions/<sessionId>`: `output` holds the result, `error` explains a failure. `GET /v1/sessions/<sessionId>/events` lists each step. Stop a started run with `POST /v1/sessions/<sessionId>/stop`.

Runs use workspace credits; with none left a turn returns `402 credits_exhausted`.

Docs: https://docs.lusor.ai/agent-runs, https://docs.lusor.ai/quickstart

## Path D: Direct phone control

Each action runs once, as sent, with no Lusor agent involved. Endpoints live under `https://api.lusor.ai/v1/workspaces/{workspaceId}/devices/{deviceId}/`:

- Read the screen: `GET …/state` (UI element tree, each interactive element has an index like `[12]`) or `GET …/screenshot` (PNG).
- Act: `POST …/tap` (`{"index": 12}` or `{"x":540,"y":1200}`), `…/swipe`, `…/type` (`{"text":"hello"}`), `…/key`, `…/clear`, `…/back`, `…/home`, `…/recent`, `…/apps/start` (`{"package":"com.android.settings"}`), `…/apps/stop`.
- Add `"capture": true` to an action to get the screen right after it. `POST …/chain` runs up to 20 steps in one request.

Actions are not idempotent: read the screen before retrying a timed-out tap. On a Lusor Phone, direct control uses Lusor Phone minutes (a 60-second window per action burst). On an iPhone the element tree is not available yet; use screenshots and coordinates.

Docs: https://docs.lusor.ai/direct-control

## Path E: What needs the human

Do these yourself where you can; otherwise ask the human, then continue:

- Signing in to Lusor and approving OAuth access for the MCP connection (and creating an account if they have none).
- Creating the API key at https://app.lusor.ai under **Settings → API Keys**, and giving it to you through an environment variable or secret manager rather than chat.
- Pairing their own phone or adding a Lusor Phone, and choosing or paying for a plan or credits (https://lusor.ai/pricing). Billing, members, vault, and adding or removing phones are not available to API keys or MCP.
- Answering an agent run that is `awaiting_human`.

## Verify

Run these yourself and report the result.

MCP: list the connected tools and confirm `search` and `execute` are present, then ask Lusor to list the workspace's phones.

REST:

```bash
curl -s https://api.lusor.ai/v1/health
curl -s https://api.lusor.ai/v1/devices -H "X-Api-Key: $LUSOR_API_KEY"
```

`/v1/health` needs no key. `/v1/devices` returns `{"data": [...]}`; a `401` means the key is missing, wrong or revoked. Mark Lusor ready only when a phone with `"connected": true` is listed. Then run the Path C task above end to end and confirm the session reaches `completed` with an `output`.
