Droid-Lab-MCP (cirkasssian/Droid-Lab-MCP) is an MCP server listed on the M8ven Trust Index. It scores 41 out of 100, grade D. It declares 44 tools. No publisher has claimed this listing.
Android emulator control for AI agents: an MCP server with 42 tools (env lifecycle, AVD/SDK management, UI automation with multitouch, adb shell, emu console, diagnostics) plus a self-hosted bridge with live H.264/Opus streaming and a token-protected browser viewer.
Caution. Specific findings reduced this grade. They are listed on the page. Grades reflect the full trust pyramid: code, verification depth, and reputation. New projects cap at C until adoption is earned.
How we verified
Verified is a snapshot. Live keeps it current, and builds your track record.
⚡ Connect GitHub → continuous verification on every pushwhy connect →Who stands behind it
cirkasssian
Source: github_repo_search
Claim it to get a verified publisher badge, a free copy of our full audit findings, and direct contact for any high-priority issues we find. Or connect your repo for our deepest verification, Live Monitored: read-only, revoke anytime. What we access →
Install from
The grade above is for the source repository. Registries can serve a different version, so we mark the ones we were not able to read.
These names and descriptions are the publisher's own, read from the source code. We print them as written. Our assessment is the findings above, not this list.
env_startStart emulator (cold boot, state lost on env_stop) + bridge on loopback. Idempotent; for a different AVD run env_stop first. Browser input disabled until set_dev_input(true). Self-bootstraps missing AVD, cmdline-tools, java, scrcpy (network required). First start ~30-60s.
env_stopStop bridge + emulator (adb emu kill, then forced). External emulators (not via env_start) are left alone.
env_statusStatus: processes, device (boot, Android version, screen, foreground app), input mode, bridge address.
env_listEntries of the emulator registry + all AVDs discovered in the SDK (emulator -list-avds).
system_images_listSystem images: installed + available for download (sdkmanager --list).
system_image_installDownload system image (sdkmanager --install). Package from system_images_list. Licenses auto-accepted. 30-min cap, cancellable, progress.
avd_createCreate an AVD from a system image + add entry to the emulator registry. Tag/ABI from the package. Device profile defaults to pixel_7; use list_devices to see options (pixel_tablet, nexus_7, …).
list_devicesDevice profiles usable with avd_create (pixel_7, pixel_tablet, nexus_7, …). Run avdmanager list device.
screenshotFull-res screenshot (PNG → shots/, downscaled JPEG inline). Multiply image coords by 1.5 for tap/swipe (native px). ui_dump is faster for exact coordinates.
tapTap on the device screen in NATIVE pixels (screen 1080x2400).
swipeSwipe from point to point in native pixels. Long press = swipe(x,y,x,y,ms=800).
scrollScroll at a point: dy > 0 — down, dy < 0 — up (number of "clicks").
keytextType text into focused field (Unicode/Cyrillic via ADBKeyBoard). Long strings auto-split.
clipboard_getRead the device clipboard. Scrcpy suppresses unchanged text — no response within 5s if buffer is unchanged. Parallel calls serialized.
clipboard_setWrite text to clipboard; paste=true also pastes into focused field (repeat with paste duplicates — not idempotent).
install_apkInstall APK (adb install -r -t). Path is on the emulator machine. Cancellable, may take minutes.
push_fileCopy file to device (adb push). Cancellable.
open_appLaunch app by package (monkey → LAUNCHER intent), e.g. com.android.settings.
deep_linkOpen URI (VIEW intent): https, app links, custom schemes. Optional package force-selects handler.
app_listInstalled packages (default: third-party; system=true includes system). filter = case-insensitive substring. Package names for open_app/close_app.
close_appForce-stop app (am force-stop), works even for hung apps. Package from app_list.
app_permissionGrant/revoke runtime permission (pm grant/revoke). Only dangerous permissions declared in the manifest.
pull_fileDownload file from device (adb pull). Default dst: pulled/<basename> in project root. Cancellable.
logcatDevice log snapshot (logcat -d, not a stream). Last N lines, optional filter-spec and substring filter (case-insensitive).
ui_dumpUI element tree (uiautomator dump): class, text, desc, resource-id, clickable/scrollable, center(x,y) in native px for tap. Full XML saved to shots/.
wait_forPoll the UI tree server-side until an element appears. Criteria: text/rid/desc substrings (case-insensitive, AND). Returns center(x,y) ready for tap. Replaces dozens of ui_dump+sleep calls.
device_stateFull state: processes, boot, Android/API version, screen, resolution, foreground app, input mode.
access_startBridge → 0.0.0.0; returns a tokenized LAN URL for live video + input. Input mode resets to observation; enable with set_dev_input(true).
access_stopBridge → loopback; LAN access cut off. MCP continues to operate the device.
bridge_restartRestart the bridge (web/server.js) without touching the emulator. Applies code changes, recovers a hung/dead bridge. Preserves host binding and input mode; access token regenerates (new URL in reply).
set_resolutionChange stream resolution (324x720, 486x1080, 1004x2231). 1004x2231 is manual-only (ABR may downgrade). list=true shows options.
reboot_emulatorReboot device (adb reboot). App state preserved. Waits ~120s for boot. Stream auto-restores.
adb_restartRestart the adb server (kill-server + start-server). For wedged adb: device gone, offline/unauthorized, stale port 5037. Streams auto-recover. NOT a device reboot — see reboot_emulator.
set_dev_inputAllow (true) or disallow (false) browser input. Requires MCP-controlled bridge (token). "Let me poke" → true; "give it back" → false.
shellRaw adb shell (dumpsys, getprop, settings, pm, ps, netstat, screenrecord). Prefer dedicated tools when they cover the task.
emuEmulator console (adb emu): battery, network throttle, GSM call/SMS, GPS, rotate. Requires running emulator.
bugreportFull Android bugreport → zip in shots/ (1-3 min). For deep diagnostics when logcat/shell are not enough.
app_uninstallUninstall a third-party app (adb uninstall). System apps cannot be removed.
app_clear_dataReset app to first-launch state (pm clear): wipes data, cache, logins, runtime permissions.
bridge_logsTail host-side logs: file="bridge" (relay/stream), "emulator" (qemu), "mcp" (this server). For on-device logs use logcat.
pinchTwo-finger pinch at a point (native px). dist = final finger separation: >200 zoom in, <200 zoom out. Scrcpy control channel only, no adb fallback.
set_orientationLock portrait/landscape or restore auto-rotation (lock=false). Affects whole device.
mcp_configRead/update persisted config (state dir/config.json). Options: port, requireToken, defaultAvd, lastAvd, extraArgs, bootTimeoutMs, scrcpyVersion, inputEnabled. {show:true} reads; pass keys to update; {reset:true} restores defaults; {defaults:true} confirms defaults. Changes apply on next bridge resta…
ABR_CHECK_MSBacklog check periodABR_COOLDOWN_SECSMinimum interval between switchesABR_DOWN_BYTESWS backlog safety net for a downgradeABR_RTT_MSRTT-probe downgrade thresholdABR_UP_SECSCongestion-free seconds before an upgradeADBadb binaryANDROID_HOMEemulator, platform-tools (adb); ANDROID_HOME or default pathsANDROID_SDK_ROOTBOOT_TIMEOUT_MSBoot wait limitBRIDGE_PORTBridge port controlled by the MCPEMU_AUTO_RESTART_MAXEMU_AUTO_RESTART_WINDOW_MSEMU_AVDDefault AVDEMU_BINEmulator binaryEMU_EXTRA_ARGSExtra emulator argumentsFFMPEGHOSTBridge interfaceJAVA_HOMEProgramFilesSCRCPYSCRCPY_SERVERServer jar for the raw hostSCRCPY_VERSIONWEB_ACCESS_TOKENBridge HTTP/WS token; without it access is openWEB_CONTROL_TOKENInput-control token; browser input disabled until set_dev_inputWEB_INPUT_ENABLEDManual start: 0 = observation modeXDG_STATE_HOMEPORTTool annotations match behaviour
10 read-only tools perform write/delete/exec — env_list (line 65: execFile(bin, args, { timeout, maxBuffer, encoding, windowsHide: true, signal, ...(env ? { env: { ..…); system_images_list (line 1077: fs.mkdirSync(def, { recursive: true })); list_devices (line 65: execFile(bin, args, { timeout, maxBuffer, encoding, windowsHide: true, signal, ...(env ? { env: { ..…)
Either remove the readOnlyHint:true annotation, or remove the write/delete call from the tool handler.
Destructive tools are labelled
7 tools perform destructive updates without destructiveHint — env_start deletes at line 561 (fs.rmSync(dest, { force: true })); screenshot deletes at line 984 (fs.rmSync(path.join(CAPTURES_DIR, f), { force: true })); ui_dump deletes at line 984 (fs.rmSync(path.join(CAPTURES_DIR, f), { force: true }))
Add destructiveHint:true to any tool whose handler calls .delete(), .upsert(), .update(), unlink, rm, DELETE, DROP, REPLACE INTO, or any operation that overwrites existing data.
openWorldHint matches behaviour
1 tool claims openWorldHint=false but make outbound HTTP — set_resolution → dynamic (line 2156)
Either flip openWorldHint to true (acknowledging external reach) or refactor the handler to avoid outbound HTTP. If the only network calls are to a known fixed endpoint that you consider part of the tool itself, document that and keep openWorldHint=false; otherwise true is honest.
Descriptions match behaviour
2 tools describe read intent but their handlers mutate — env_list (line 65: execFile(bin, args, { timeout, maxBuffer, encoding, windowsHide: true, signal, ...(env ? { env: { ..…); system_images_list (line 1077: fs.mkdirSync(def, { recursive: true }))
Rename the tool, rewrite the description, or move the side-effect into a separate clearly-named tool.
Tests exist
No test files found
Add tests that exercise each declared tool.
Shell command execution
9 calls in production code run through a shell (web/server.js:115, web/server.js:217, web/server.js:230)
Prefer library functions over shell-outs. If you must shell out, ensure all inputs are properly escaped.
Tool description accuracy
env_list: description implies read-only but handler writes/deletes/executes; system_images_list: description implies read-only but handler writes/deletes/executes
Update tool descriptions to accurately reflect all capabilities — especially write, delete, or execute operations.
Claim the listing to review these findings one by one and send us a correction where you disagree, straight to the team. Claiming also means we tell you when the grade moves, and reach you first if we find anything urgent.
[](https://m8ven.ai/mcp/cirkasssian/droid-lab-mcp)?variant=verified from the URL.Vetting this one by hand? Tool Check is an MCP that scores other MCPs. Add it once and ask Claude, ChatGPT, or any MCP client to grade a server, surface CVEs, check the publisher, and suggest safer alternatives — before you install.
https://m8ven.ai/api/mcp/tool-check