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:
--projectif given, otherwise the Android project containing the client's working folder, otherwise the last project you opened in Keynobi.get_project_inforeports 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_taskandrun_testsfail 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 analysisfull-deploy— Build, find APK, install, and launch in one workflowbuild-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.xmlandroid://app-build-gradle— app/build.gradle.ktsandroid://build-gradle— root build.gradle.ktsandroid://gradle-settings— settings.gradle.ktsandroid://project-info— Project info report (same as get_project_info)
Workflow example
- Ask Claude Code to build and list errors.
- It calls
get_project_info, thenrun_gradle_task, thenget_build_errors. - For deploy:
list_devices,install_apk,launch_app. - For UI automation:
find_ui_elementsorlist_clickable_elements, thenui_tap_elementon returned tree paths; usescreenHash/expectScreenHashto 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 passesallow_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
.apkfiles 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.
| Tool | What it does |
|---|---|
run_gradle_task | Run a Gradle task (e.g. assembleDebug). Requires a trusted project; publish/upload/uninstall tasks are blocked by default |
get_build_status | Current build status (idle, running, success, failed, cancelled) |
get_build_errors | Structured compiler errors and warnings from the last build (JSON) |
get_build_log | Raw Gradle output lines (last N lines, capped) |
cancel_build | Cancel the running Gradle build |
list_build_variants | List variants and active variant (JSON) |
set_active_variant | Set the active build variant (persists in settings) |
find_apk_path | Output APK path for a variant after a build |
run_tests | Run unit tests (testDebug), connected tests, or a custom test task. Requires a trusted project |
get_build_config | Parse 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.
| Tool | What it does |
|---|---|
start_logcat | Start logcat streaming (required in headless before reads) |
stop_logcat | Stop the logcat stream |
get_logcat_entries | Recent logcat entries with filters (JSON) |
get_crash_logs | FATAL EXCEPTION, ANR, and native crash entries (JSON) |
get_crash_stack_trace | Parsed crash from logcat buffer; needs logcat streaming |
clear_logcat | Clear the in-memory logcat buffer |
get_logcat_stats | Logcat 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.
| Tool | What it does |
|---|---|
list_devices | Connected devices and running emulators (JSON) |
screenshot | Capture a screenshot (inline image) |
get_device_info | SDK level, model, screen, battery |
dump_app_info | App version, install path, activities |
get_memory_info | Memory breakdown (PSS, heap, native, graphics) |
install_apk | Install an APK (path-validated) |
launch_app | Launch an app (am start) |
stop_app | Force-stop the project's app |
restart_app | Force-stop and relaunch the project's app; data is kept unless clear_data is set |
get_app_runtime_state | Processes, threads, RSS for an app package |
list_avds | List AVDs (JSON) |
launch_avd | Start an emulator |
stop_avd | Stop 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.
| Tool | What it does |
|---|---|
get_ui_hierarchy | Focused window UI tree from UI Automator (JSON; interactive_only option) |
find_ui_elements | Fresh dump + search by text, content-desc, resource-id, class, or package |
list_clickable_elements | Fresh dump + list actionable UI elements with tree paths and centers |
find_ui_parent | Direct parent of a node from find_ui_elements / Layout tab treePath |
ui_tap | Tap device pixel coordinates; optional expectScreenHash |
ui_tap_element | Tap an element by treePath with optional screen-hash verification |
ui_type_text | adb shell input text (ASCII-oriented); optional screen hash |
ui_fill_input | Focus, clear, and type into an input by treePath or coordinates |
clear_focused_input | Clear the currently focused input field |
ui_type_text_unicode | Type Unicode text by pasting from the device clipboard (API 24+) |
send_ui_key | Allowlisted keyevent (Back, Home, Enter, …) |
hide_soft_keyboard | Hide the Android soft keyboard |
ui_swipe | Swipe or long-press in device pixels |
ui_scroll_until_element | Scroll until a matching element appears, returning the last screen hash on failure |
grant_runtime_permission | pm grant for android.permission.* on the project's app |
revoke_runtime_permission | pm revoke for android.permission.* on the project's app |
wait_for_element | Wait for a UI element matching text, content-desc, resource-id, class, or package filters |
ui_wait_for_idle | Wait until the UI appears stable before the next automation step |
ui_assert_element | Assert that a matching element is present for test-style checks |
open_deep_link | Open a deep link, optionally scoped to an app package |
open_app_settings | Open Android app info, permissions, or notifications settings |
set_device_orientation | Change device orientation for automation flows |
set_network_state | Toggle Wi-Fi, mobile data, or airplane mode; returns the previous state and never cuts off wireless ADB |
compare_ui_state | Compare 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.
| Tool | What it does |
|---|---|
get_project_info | Project path, Gradle root, how it was selected, trust state, and JDK |
run_health_check | Java/JDK, Android SDK, ADB, Gradle wrapper, and project (JSON) |