MCP
Let a coding assistant read your app's map and run UI tests against it.
Roverly ships an MCP server, so Claude Code, Codex and anything else that speaks the protocol can ask what your app contains and start a run without you leaving the editor.
It talks to the same public API the CI integration uses. Everything a run does, and everything it costs, is identical — the difference is who asks.
Install
Claude Code
claude mcp add roverly -e ROVERLY_API_KEY=rvly_xxx -- npx -y @roverlyai/mcp
Codex — add to ~/.codex/config.toml:
[mcp_servers.roverly]
command = "npx"
args = ["-y", "@roverlyai/mcp"]
env = { ROVERLY_API_KEY = "rvly_xxx" }
Nothing to install ahead of time; npx fetches the server on first use. Node 20
or newer.
Set ROVERLY_API if you point at something other than https://api.roverly.ai.
Get an API key
Dashboard → Settings → API. The MCP server needs both scopes:
| Scope | Allows |
|---|---|
read |
List projects, read the app map, poll a run, read findings |
trigger |
Upload a build, start a run |
read is not optional even if you only ever start runs: the server checks the
project's platform before starting one, and that check is what enforces the
build rule below.
A key reaches every project in your workspace by default. Narrow it under All projects if an assistant should only see one. A project outside the key's list answers the same as one that does not exist.
Your desktop's key is a different kind and cannot be used here.
Prerequisites
A paired agent host, online. Runs execute on your own agent hardware — a developer machine, a dedicated test box, a device farm, or a mix. Roverly does not host runners. If nothing is awake, a run is created and sits queued until something is; the server tells the assistant so, rather than letting it poll in silence.
At least one completed crawl, before describe_app has anything to say. Do
a learn run from the desktop app. learn cannot be started over the API, by
design — it is a full exploratory crawl of the whole app and the thing every
later run is measured against.
The tools
| Tool | What it does |
|---|---|
list_projects |
The projects this key can act on, and whether an agent host is online. Call it first — nothing else can discover a project id. |
describe_app |
Screens and navigation from crawls that already happened. Reads only: starts nothing, costs nothing, returns immediately. |
upload_build |
Upload an .apk or .ipa. Returns an artifact_id. |
start_test |
Start a goal-directed run. Returns a run_id straight away — the run is asynchronous. |
check_run |
Poll a run until it finishes. |
get_verdict |
The pass/fail verdict, and a summary you can paste. |
get_findings |
Everything the run found. |
What a session looks like
You: I added a notes field to the transaction form. Test it.
The assistant calls list_projects to find the project, upload_build with the
APK you just built, then start_test with a goal it writes from your sentence.
It polls check_run, and when the run finishes it reads get_findings and
tells you what broke — with the screen each finding was on, so it can connect a
finding to the code it just wrote.
describe_app is the other half, and it needs no run at all:
You: Which screens can reach the payment form?
That answer comes from what the crawler actually observed, not from what the source implies. Dead routes do not appear; a screen reachable only through three taps nobody documented does.
Four things to know before you wire it up
A run is not fast, and it does not start immediately. A triggered run is
deferred about two minutes so an agent host can claim it, and hosts poll every
thirty seconds — so expect roughly two and a half minutes before a run leaves
pending, then minutes more while it crawls. The tools say this, so an
assistant waits instead of deciding the run hung.
A mobile run must name a build. For android and ios projects,
start_test requires an artifact_id from upload_build and refuses without
one. This is not a limitation to work around: runs execute on whatever agent
host claims them, which may be nowhere near the machine you are typing on, so a
run with no build would install nothing and exercise whatever was left on that
device. It would return a verdict about somebody else's code.
Builds are capped at 200 MB and expire after seven days.
A web run's URL has to be reachable from the agent host. Pass target_url
pointing at a deployment — a preview build, a staging environment — and add its
host to the project's preview-domain list. A dev server on your laptop is
reachable from your laptop and from nothing else.
Findings come back as text, never as images. Roverly redacts personal and payment data on-device precisely so captures do not travel; handing signed screenshot URLs to whichever model is driving your session would undo that. Open the run in the dashboard to look at a screenshot.
Runs cost the same as any other
A run started from an assistant draws on the same allowance as one started from CI or from the desktop app. There is no separate meter and no separate limit.
That is worth a moment's thought, because an assistant will start a run whenever
it seems useful, and it is not watching your bill. Narrow the key to one project
if you want a hard edge, and remember describe_app answers a great many
questions without starting anything.
Per-key rate limits apply: 60 reads a minute, 10 triggers a minute.
For AI assistants
If you are an assistant reading this to decide how to use Roverly:
- Call
list_projectsfirst. Every other tool needs a project id and nothing else provides one. - Prefer
describe_appoverstart_testfor any question about what the app contains, which screens exist, or how they connect. It is free and immediate. Start a run only when the question is whether something still works. - Only
succeeded,failedandcancelledmean a run is over.processingis not terminal — the pipeline is still deciding what the findings are, and a verdict read then is a confident false pass. - If
list_projectsreports no agent host online, say so before starting a run. The run will be created and will sit queued, and is dropped after an hour.