Guide

MCP for Claude Code & Codex

Keynobi includes an MCP server so Claude Code, Codex, and other stdio MCP clients can run builds, read logcat and crashes, inspect the UI, drive guarded UI automation, and manage devices using your real project and device state instead of guessing. It exposes 56 tools. Transport is local stdio to the Keynobi binary—not a Keynobi-hosted proxy.

Android tools
56
local transport
stdio
cloud proxies
0

Setup

Install Keynobi in /Applications first—the command records the app's path, and a path inside a mounted DMG stops working after you eject it. Then register it once. The easiest way is to copy the command from Health Center or Copy MCP Setup Commands in the command palette, which fills in the correct path.

Claude Code

claude mcp add --scope user --transport stdio keynobi -- '/Applications/Keynobi.app/Contents/MacOS/keynobi' --mcp

--scope user makes Keynobi available in every folder. Without it, Claude Code registers the server only for the folder where you ran the command. The copied command does not include it yet, so add it yourself.

Codex

codex mcp add keynobi -- '/Applications/Keynobi.app/Contents/MacOS/keynobi' --mcp

To bind MCP to a specific Android project, append --project /path/to/MyAndroidProject to either command. After updating Keynobi, restart your AI clients so they use the new binary.

How MCP relates to the app

Your AI client starts its own Keynobi MCP process in the background. It does not connect to the Keynobi window you have open, and the window does not need to be running.

  • Project — chosen once when the client starts the server: --project if given, otherwise the Android project containing the client's working folder, otherwise the last project you opened in Keynobi. get_project_info reports which rule was used. If you switch projects in Keynobi, restart the MCP server in your AI client.
  • Trust — an AI client can build only a project you trusted in Keynobi. For any other project, run_gradle_task and run_tests fail with a message asking you to open the project in Keynobi and choose Trust. The MCP server never asks for or grants trust itself; other tools keep working, and trusting applies without restarting the server.
  • Builds and logcat started by an AI client do not appear live in the Build and Logcat tabs. They can show up in build history the next time Keynobi starts.
  • Activity — the MCP Activity panel (Cmd+Shift+M) and the status bar MCP pill show setup status, whether a server is running, and recent tool calls.

Built-in prompts

  • diagnose-crash — Crash logs, memory, and app info for root-cause analysis
  • full-deploy — Build, find APK, install, and launch in one workflow
  • build-and-fix — Run build and explain each error with suggested fixes

Resources

Read-only reports and project files exposed to the client. The build file resources are listed only when the matching .kts file exists in the app module or project root.

  • android://health — Health report (same as run_health_check)
  • android://manifest — AndroidManifest.xml
  • android://app-build-gradle — app/build.gradle.kts
  • android://build-gradle — root build.gradle.kts
  • android://gradle-settings — settings.gradle.kts
  • android://project-info — Project info report (same as get_project_info)

Workflow example

  1. Ask Claude Code to build and list errors.
  2. It calls get_project_info, then run_gradle_task, then get_build_errors.
  3. For deploy: list_devices, install_apk, launch_app.
  4. For UI automation: find_ui_elements or list_clickable_elements, then ui_tap_element on returned tree paths; use screenHash / expectScreenHash to avoid stale screens.

Safety model

Log lines, UI text, and project files an agent reads can try to steer it, so every tool argument is treated as untrusted.

  • Validated input. Gradle tasks, package names, device serials, deep links, runtime permissions, UI key names, coordinates, and tree paths are checked before anything runs. Device shell arguments are quoted.
  • Project trust. Gradle runs only for projects you trusted in the app.
  • Restricted Gradle tasks. publish*, upload*, uninstall*, Play Store and Maven Central release tasks (including abbreviations) and Gradle options are refused unless you turn on Allow unrestricted Gradle tasks in Settings. Builds time out after 600 seconds by default.
  • Scoped app actions. stop_app, restart_app, and granting or revoking permissions act only on your project's app unless the call passes allow_foreign_package: true.
  • No lost connections. Commands that would drop a wireless-ADB connection are refused, and adb calls time out instead of hanging.
  • No general file access. MCP takes no arbitrary paths. APK installs are limited to .apk files in the project's build outputs, and resources read fixed project files.
  • Annotated tools. Every tool declares read-only, destructive, and open-world hints so your client can ask before destructive calls.

Tools reference

All 56 tools, grouped the same way as on the features page.

Build · 10

Run Gradle, inspect live build state, pull structured errors, switch variants, find APKs, and run tests.

ToolWhat it does
run_gradle_taskRun a Gradle task (e.g. assembleDebug). Requires a trusted project; publish/upload/uninstall tasks are blocked by default
get_build_statusCurrent build status (idle, running, success, failed, cancelled)
get_build_errorsStructured compiler errors and warnings from the last build (JSON)
get_build_logRaw Gradle output lines (last N lines, capped)
cancel_buildCancel the running Gradle build
list_build_variantsList variants and active variant (JSON)
set_active_variantSet the active build variant (persists in settings)
find_apk_pathOutput APK path for a variant after a build
run_testsRun unit tests (testDebug), connected tests, or a custom test task. Requires a trusted project
get_build_configParse build.gradle(.kts) for SDK levels, applicationId, types, flavors (no Gradle run)

Logcat and crashes · 7

Start streams, read filtered entries, pull crash logs and stack traces, clear buffers, and summarize log stats.

ToolWhat it does
start_logcatStart logcat streaming (required in headless before reads)
stop_logcatStop the logcat stream
get_logcat_entriesRecent logcat entries with filters (JSON)
get_crash_logsFATAL EXCEPTION, ANR, and native crash entries (JSON)
get_crash_stack_traceParsed crash from logcat buffer; needs logcat streaming
clear_logcatClear the in-memory logcat buffer
get_logcat_statsLogcat statistics (counts by level, crashes, packages)

Devices and apps · 13

List devices and AVDs, capture screenshots, inspect packages and memory, install, launch, stop, and restart apps.

ToolWhat it does
list_devicesConnected devices and running emulators (JSON)
screenshotCapture a screenshot (inline image)
get_device_infoSDK level, model, screen, battery
dump_app_infoApp version, install path, activities
get_memory_infoMemory breakdown (PSS, heap, native, graphics)
install_apkInstall an APK (path-validated)
launch_appLaunch an app (am start)
stop_appForce-stop the project's app
restart_appForce-stop and relaunch the project's app; data is kept unless clear_data is set
get_app_runtime_stateProcesses, threads, RSS for an app package
list_avdsList AVDs (JSON)
launch_avdStart an emulator
stop_avdStop a running emulator

UI hierarchy and automation · 24

Read UI Automator trees, find elements, tap/type/swipe safely, wait/assert UI state, open links/settings, and change test conditions.

ToolWhat it does
get_ui_hierarchyFocused window UI tree from UI Automator (JSON; interactive_only option)
find_ui_elementsFresh dump + search by text, content-desc, resource-id, class, or package
list_clickable_elementsFresh dump + list actionable UI elements with tree paths and centers
find_ui_parentDirect parent of a node from find_ui_elements / Layout tab treePath
ui_tapTap device pixel coordinates; optional expectScreenHash
ui_tap_elementTap an element by treePath with optional screen-hash verification
ui_type_textadb shell input text (ASCII-oriented); optional screen hash
ui_fill_inputFocus, clear, and type into an input by treePath or coordinates
clear_focused_inputClear the currently focused input field
ui_type_text_unicodeType Unicode text by pasting from the device clipboard (API 24+)
send_ui_keyAllowlisted keyevent (Back, Home, Enter, …)
hide_soft_keyboardHide the Android soft keyboard
ui_swipeSwipe or long-press in device pixels
ui_scroll_until_elementScroll until a matching element appears, returning the last screen hash on failure
grant_runtime_permissionpm grant for android.permission.* on the project's app
revoke_runtime_permissionpm revoke for android.permission.* on the project's app
wait_for_elementWait for a UI element matching text, content-desc, resource-id, class, or package filters
ui_wait_for_idleWait until the UI appears stable before the next automation step
ui_assert_elementAssert that a matching element is present for test-style checks
open_deep_linkOpen a deep link, optionally scoped to an app package
open_app_settingsOpen Android app info, permissions, or notifications settings
set_device_orientationChange device orientation for automation flows
set_network_stateToggle Wi-Fi, mobile data, or airplane mode; returns the previous state and never cuts off wireless ADB
compare_ui_stateCompare captured UI state to detect screen changes

Project and health · 2

Report the active project, how it was chosen, its trust state and JDK, and health checks for Java, SDK, ADB, and the Gradle wrapper.

ToolWhat it does
get_project_infoProject path, Gradle root, how it was selected, trust state, and JDK
run_health_checkJava/JDK, Android SDK, ADB, Gradle wrapper, and project (JSON)