Androir Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Androir Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<a id="readme-top"></a>
<div align="center">
<img src="assets/logo.svg" width="96" height="96" alt="androir-mcp logo">
Drive real Android devices from any AI agent — see the screen, tap, swipe, type, over `adb`.
An independent, standalone Model Context Protocol server that gives an AI agent a clean, safe automation surface for physical Android devices and emulators: capture the screen, read the live UI tree, and drive input — backed entirely by adb + uiautomator, no native code and no device-side app.
</div>
[!NOTE] Requiresadb(Android platform-tools) and an Android device with USB debugging enabled (or an emulator). The server runs locally, holds no credentials, and talks only to the device(s)adbalready sees.
androir-mcp is a standalone MCP server for automating Android over adb. It is its own project — not a copy or port of anything — exposing a small, conventional screen-read + input tool set that drops into any MCP-based agent loop.
Everything is backed by adb and uiautomator: there is no native code and nothing to install on the device. The agent shells out to adb (always as an argv array — never a shell string) to capture screenshots, dump the UI hierarchy, and send input events.
The key advantage on Android is that describe_screen returns the real UI tree — exact element bounds and text straight from uiautomator — rather than guessing from OCR. Tap coordinates come back as element centers and feed straight into tap, so an agent can read a screen and act on it deterministically.
<p align="right"><a href="#readme-top">back to top ↑</a></p>
uiautomator UI tree into a flat list oflabels with center tap coordinates (text / content-desc / class, entity-decoded).
unicode all type verbatim).
the installed package list, cached per device).
http(s) URL in the default browser.device state, properties, and battery.
Safety by construction:
string, and any value handed to the device shell is single-quoted for it, so there is no shell-injection surface.
[A-Za-z0-9.:_-] (≤ 128 chars) before reaching any subprocess.
adb stderr (which canleak serials/paths) and no host stack traces reach the model.
<p align="right"><a href="#readme-top">back to top ↑</a></p>
| Tool | adb implementation | Returns |
|---|---|---|
list_targets | adb devices -l | serials + model + state |
status | adb -s S get-state (+ props, battery) | device/offline/unauthorized + info |
screenshot | adb -s S exec-out screencap -p | PNG image content |
describe_screen | adb -s S exec-out uiautomator dump /dev/tty (fallback: dump to /sdcard then exec-out cat) → parse XML | element list: label / center tap (x,y) |
tap (x,y) | adb -s S shell input tap X Y | confirmation |
swipe (x1,y1,x2,y2,dur_ms?) | adb -s S shell input swipe X1 Y1 X2 Y2 DUR | confirmation |
long_press (x,y,dur_ms?) | input swipe X Y X Y DUR (same point) | confirmation |
type_text (text) | adb -s S shell input text '<quoted>' (space→%s, single-quoted for the device shell) | confirmation |
press_key (key) | adb -s S shell input keyevent <KEYCODE> — names: home→3, back→4, enter→66, recents→187 | confirmation |
press_home | input keyevent 3 | confirmation |
press_back | input keyevent 4 | confirmation |
launch_app (name or pkg) | resolve name→package (from pm list packages), then monkey -p PKG -c android.intent.category.LAUNCHER 1 | confirmation |
open_url (url) | am start -a android.intent.action.VIEW -d '<url>' (http/https only) | confirmation |
All tools take an optional serial; it defaults to the single connected device and errors if the choice is ambiguous. Coordinates are in device pixels, so describe_screen tap points feed straight into tap with no translation.
<p align="right"><a href="#readme-top">back to top ↑</a></p>
PATH.Confirm it's visible:
adb devicesnpm install
npm run buildAdd the built server to your MCP client config:
{
"mcpServers": {
"androir": {
"command": "node",
"args": ["/path/to/androir-mcp/dist/index.js"]
}
}
}With a device connected, run the self-check (it lists targets, takes a screenshot, and dumps the UI tree):
npm run selfcheckIt prints PASS when the three core tools work end-to-end against a real device.
<p align="right"><a href="#readme-top">back to top ↑</a></p>
Once androir is attached to your MCP client, give the agent a goal and let it read the screen and act:
You: Open the Settings app, go to Wi-Fi, and tell me which network is connected.
>
Agent: callslaunch_app("settings")→describe_screen()(reads the labels + tap coordinates) →tap(x, y)on "Wi-Fi" →describe_screen()again → reports the connected network.
Because describe_screen returns exact element bounds and text, the agent taps real coordinates rather than guessing from a screenshot.
<p align="right"><a href="#readme-top">back to top ↑</a></p>
screenshot, describe_screen, tap, swipe,long_press, type_text, press_key/home/back, launch_app, open_url, list_targets, status
uiautomator XML parsing → labels + center tap coordinates (entity-decoded, malformed-XML tolerant)npx binThis README and roadmap fill in as the project progresses.
<p align="right"><a href="#readme-top">back to top ↑</a></p>
<p align="right"><a href="#readme-top">back to top ↑</a></p>
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.