# Phonebox

> Cloud Android phones for AI agents: create a phone, read the screen, tap, type, install APKs, park.

- name: dev.phonebox/phonebox
- version: 0.1.0
- connection class: R1 (autonomous)
- trust: 96/100
- quality: 100/100 (strong)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/dev.phonebox%2Fphonebox
- tools: https://api.protogrid.dev/v1/servers/dev.phonebox%2Fphonebox/tools

**An agent can connect on its own if it already holds `PHONEBOX_TOKEN`.** Remote endpoint behind a static API key or header. The registry never sees the value; the agent fills the placeholder.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "phonebox": {
      "type": "http",
      "url": "https://phonebox.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${PHONEBOX_TOKEN}"
      }
    }
  }
}
```

Placeholders to fill: `${PHONEBOX_TOKEN}`.

## Trust

- hygiene: 100
- liveness: 100
- freshness: 100
- provenance: 85
- drivers: +repository +dns-namespace +website +reachable +uptime-100% +updated-13d-ago
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 100/100 (strong)

### protocol: n/a (weight 25)

- n/a `protocol.modern`, `protocol.stateless`, `protocol.transport`, `protocol.list_ttl`: no remote answered a protocol handshake (not probed yet, unreachable, or local-only)

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 100 (weight 30)

- pass `tools.descriptions`: every tool has a description
- pass `tools.description_length`: descriptions are concise
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 13 of 13 tools declare readOnlyHint or destructiveHint
- pass `tools.directory_hints`: every tool declares readOnlyHint, destructiveHint, idempotentHint and openWorldHint
- pass `tools.token_cost`: about 5,037 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 100 (weight 15)

- pass `stability.changes`: no tool changes in 30 days
- pass `stability.rug_pull`: no tool changed its meaning under the same name

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 13, about 5,037 tokens to load them all
- tool set hash: 9af64a7ec11a713c235aba88c4727cca
- badge: [![protogrid quality](https://protogrid.dev/badge/dev.phonebox/phonebox.svg)](https://protogrid.dev/servers/dev.phonebox/phonebox)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

_No tool definition changes recorded._

## Remotes

- https://phonebox.dev/mcp (streamable-http, auth api_key ${PHONEBOX_TOKEN}, reachable true, uptime30d 1)

## Packages

_none_

## Tools (13)

- `act`: Run up to 20 actions in order (tap, type, key, swipe, scroll, back, home, open_app, open_url, wait_for, …). The batch stops at the first failure, and the result shows the screen where it stopped, unless the screen couldn't be read, or not in time. Never repeat an action whose outcome is unknown; observe first.
- `complete_app_upload`: Finish an upload once its file has arrived, and wait while Phonebox reads and stores the APK. It answers with the upload: ready to install with install_app, or ended with an error saying why. If it is still processing when this returns, call it again with the same arguments: a repeat only waits.
- `create_app_upload`: Start an upload of your own APK, such as the debug build you just made, to install it on a phone. MCP can't carry a file, so this returns a one-off upload_url and the exact curl command to send the APK there from your shell; then call complete_app_upload with the storageId it answers. Send the URL one file of up to 500 MiB, within an hour.
- `create_phone`: Create a cloud Android phone and wait until it is ready (usually under two minutes). It costs $0.06 a minute while running. Always park it when you're done. If it is still creating or starting when this returns, call get_phone with its ID and wait "ready" to keep waiting: it only reads, while start_phone would renew the session.
- `get_phone`: Read one phone: its status, session and when it parks. With wait, wait until it is ready or parked. It never starts, renews or bills anything, so it is the way to wait for a phone that is still creating or starting.
- `install_app`: Install an app from Phonebox's app library by package name, in the background. It doesn't reach Google Play: to get a Play Store app, open the Play Store app on the phone with act and install it there. To check on an install later, open the app with act: open_app answers app_not_found until the install has finished. With upload instead of package, it installs your own APK (see create_app_upload) and waits until the phone lists the app, or says why it failed. While that upload is still installing on the phone, and for 10 minutes after that install succeeds, calling install_app again with it starts nothing: a repeat only waits for it, or reports it.
- `list_apps`: List the apps installed on a phone: package, label, version and whether it came with the phone. Open one with act and open_app.
- `list_phones`: List this project's phones, newest first, with their status and when each parks: up to 50 a page, and next_cursor for the next page. Parked phones keep their apps and sign-ins and cost nothing.
- `live_view_url`: Create a link a human can open to watch and control the phone, for example to sign in or solve a check. The link expires (default one hour). Anyone with the link controls the phone until it expires; share it only with your user and never paste it into logs or shared chats.
- `observe`: Read the screen: every visible element with a ref number, text and center, plus a screenshot when asked. Tap elements by ref with the act tool.
- `park_phone`: Park a phone to stop billing. Do this whenever you're done.
- `reboot_phone`: Restart a phone that is stuck, keeping everything on it, and wait until it is ready again. A phone can reboot once every 10 minutes; a reboot the phone service didn't confirm is never sent twice: wait for ready with get_phone instead. If it is still creating or starting when this returns, call get_phone with its ID and wait "ready" to keep waiting: it only reads, while start_phone would renew the session.
- `start_phone`: Start a parked phone and wait until it is ready. Its apps, files and sign-ins are kept. On a phone that is already running, it renews the session: a new deadline, with credit reserved for it. If it is still creating or starting when this returns, call get_phone with its ID and wait "ready" to keep waiting: it only reads, while start_phone would renew the session.
