appium-mcp

by appium

Not rated
GitHub

About

MCP server for Mobile Development and Automation | iOS, Android, Simulator, Emulator, and Real Devices

Details

Author
appium
Categories
Productivity, Other, Developer Tools, Automation

Mobile Testing Setup for embedded local drivers

- Install Android Studio and the Android SDK. - Set theANDROID_HOMEenvironment variable. - Add the Android SDK tools to your system's PATH. - Enable USB debugging on your Android device. - Install the Android platform tools/build tools and keepadbavailable onPATH.

Standard config works in most of the tools::

{ "mcpServers": { "appium-mcp": { "disabled": false, "timeout": 100, "type": "stdio", "command": "npx", "args": ["appium-mcp@latest"], "env": { "ANDROID_HOME": "/path/to/android/sdk", "CAPABILITIES_CONFIG": "/path/to/your/capabilities.json" } } } }

The easiest way to install MCP Appium in Cursor IDE is using the one-click install button:

This will automatically configure the MCP server in your Cursor IDE settings. Make sure to update theANDROID_HOMEenvironment variable in the configuration to match your Android SDK path.

Go toCursor Settings → MCP → Add new MCP Server. Name it to your liking, use command type with the commandnpx -y appium-mcp@latest. You can also verify config or add command arguments via clickingEdit.

{ "appium-mcp": { "disabled": false, "timeout": 100, "type": "stdio", "command": "npx", "args": ["appium-mcp@latest"], "env": { "ANDROID_HOME": "/Users/xyz/Library/Android/sdk" } } }

Note:Make sure to update theANDROID_HOMEpath to match your Android SDK installation path.

Use the Gemini CLI to add the MCP Appium server:

gemini mcp add appium-mcp npx -y appium-mcp@latest

This will automatically configure the MCP server for use with Gemini. Make sure to update theANDROID_HOMEenvironment variable in the configuration to match your Android SDK path.

Use the Claude Code CLI to add the MCP Appium server:

claude mcp add appium-mcp -- npx -y appium-mcp@latest

This will automatically configure the MCP server for use with Claude Code. Make sure to update theANDROID_HOMEenvironment variable in the configuration to match your Android SDK path.

Note:For embedded local Android/iOS sessions, MCP Appium already includes the UiAutomator2 and XCUITest driver packages. The system-level requirements are the platform toolchains (ANDROID_HOME, Java, Android SDK tools, Xcode/iOS signing or simulator setup). For remote sessions, configure those requirements on the remote Appium/WebDriver server instead.

OpenTelemetry tracing is disabled by default. SetAPPIUM_MCP_OTEL_ENABLED=trueto initialize the Node.js OpenTelemetry SDK before the MCP server is constructed. The SDK uses standardOTEL_*environment variables, for example:

APPIUM_MCP_OTEL_ENABLED=true # Optional: include sanitized non-sensitive argument values in spans. # APPIUM_MCP_OTEL_INCLUDE_ARGUMENT_VALUES=true # Optional: attach custom key=value pairs to every span (e.g. test case ID, team name). # OTEL_RESOURCE_ATTRIBUTES=testcase.id=my-test-123,team=platform OTEL_SERVICE_NAME=appium-mcp OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://127.0.0.1:4318/v1/traces OTEL_TRACES_SAMPLER=parentbased_always_on

(Please check the[official documentas well)

When enabled, appium-mcp creates spans for MCP tool calls, prompt loads, resource reads, and resource template reads. Error status is recorded for thrown operation errors and MCP tool results marked withisError. Span attributes intentionally avoid raw screenshots, XML page source, prompts, credentials, and other high-cardinality or sensitive payloads.

Tool spans include payload-free result-size attributes:mcp.tool.result.content_count,content_types,text_chars,resource_count,resource_text_chars,image_count,audio_count,base64_chars, andbase64_bytes_estimate(all prefixed withmcp.tool.result.).content_typescontains only known MCP types orother; payload values, resource URIs, MIME types, and unknown type strings are never recorded. Sizes are counted directly from known result fields without serializing or copying the complete result.

For local trace inspection, use the Jaeger setup intools/telemetry:

Then openhttp://127.0.0.1:16686and run appium-mcp with the environment values intools/telemetry/jaeger.env.

Create acapabilities.jsonfile to define your device capabilities:

{ "android": { "appium:app": "/path/to/your/android/app.apk", "appium:deviceName": "Android Device", "appium:platformVersion": "11.0", "appium:automationName": "UiAutomator2", "appium:udid": "your-device-udid" }, "ios": { "appium:app": "/path/to/your/ios/app.ipa", "appium:deviceName": "iPhone 15 Pro", "appium:platformVersion": "17.0", "appium:automationName": "XCUITest", "appium:udid": "your-device-udid" }, "general": { "platformName": "mac", "appium:automationName": "mac2", "appium:bundleId": "com.apple.Safari" } }

Set theCAPABILITIES_CONFIGenvironment variable to point to your configuration file.

MCP Appium - MCP server for Mobile Development and Automation | iOS, Android, Simulator, Emulator, and Real Devices

MCP Appium is an intelligent MCP (Model Context Protocol) server designed to empower AI assistants with a robust suite of tools for mobile automation. It streamlines mobile app testing by enabling natural language interactions, intelligent locator generation, and automated test creation for both Android and iOS platforms.

- Cross-Platform Support: Automate tests for both Android (UiAutomator2) and iOS (XCUITest).
- AI-Powered Element Finding: Locate UI elements using natural language descriptions powered by vision models - no need for complex XPath or selectors.
- Intelligent Locator Generation: AI-powered element identification using priority-based strategies.
- Interactive Session Management: Easily create and manage sessions on local mobile devices.
- Smart Element Interactions: Perform actions like clicks, text input, screenshots, and element finding.
- Automated Test Generation: Generate Java/TestNG test code from natural language descriptions.
- Page Object Model Support: Utilize built-in templates that follow industry best practices.
- Flexible Configuration: Customize capabilities and settings for different environments.
- Multilingual Support: Use your native language - AI handles all interactions naturally in any language (English, Spanish, Chinese, Japanese, Korean, etc.).

Before you begin, ensure you have the following installed:

- Node.js(v22 or higher)
- npmoryarn
- Java Development Kit (JDK)(8 or higher)
- Android SDK(for Android testing)
- Xcode(for iOS testing on macOS)

- Embedded local drivers: whenappium_session_managementcreates anandroidoriossession withoutremoteServerUrl, MCP Appium uses the bundledappium-uiautomator2-driverorappium-xcuitest-driverdependency directly. You still need the platform toolchains below, but you do not need to install a global Appium server or runappium driver install uiautomator2/appium driver install xcuitestfor this mode.
- Remote WebDriver/Appium server: whenremoteServerUrlis provided toaction=createoraction=attach, MCP Appium uses thewebdriverclient to talk to that existing server. In this mode the remote server is responsible for its installed drivers, plugins, device access, and capability handling. Use this mode forplatform=general; embedded local creation is available only for Android and iOS.

Mobile Testing Setup for embedded local drivers

- Install Android Studio and the Android SDK. - Set theANDROID_HOMEenvironment variable. - Add the Android SDK tools to your system's PATH. - Enable USB debugging on your Android device. - Install the Android platform tools/build tools and keepadbavailable onPATH.

Standard config works in most of the tools::

{ "mcpServers": { "appium-mcp": { "disabled": false, "timeout": 100, "type": "stdio", "command": "npx", "args": ["appium-mcp@latest"], "env": { "ANDROID_HOME": "/path/to/android/sdk", "CAPABILITIES_CONFIG": "/path/to/your/capabilities.json" } } } }

The easiest way to install MCP Appium in Cursor IDE is using the one-click install button:

This will automatically configure the MCP server in your Cursor IDE settings. Make sure to update theANDROID_HOMEenvironment variable in the configuration to match your Android SDK path.

Go toCursor Settings → MCP → Add new MCP Server. Name it to your liking, use command type with the commandnpx -y appium-mcp@latest. You can also verify config or add command arguments via clickingEdit.

{ "appium-mcp": { "disabled": false, "timeout": 100, "type": "stdio", "command": "npx", "args": ["appium-mcp@latest"], "env": { "ANDROID_HOME": "/Users/xyz/Library/Android/sdk" } } }

Note:Make sure to update theANDROID_HOMEpath to match your Android SDK installation path.

Use the Gemini CLI to add the MCP Appium server:

gemini mcp add appium-mcp npx -y appium-mcp@latest

This will automatically configure the MCP server for use with Gemini. Make sure to update theANDROID_HOMEenvironment variable in the configuration to match your Android SDK path.

Use the Claude Code CLI to add the MCP Appium server:

claude mcp add appium-mcp -- npx -y appium-mcp@latest

This will automatically configure the MCP server for use with Claude Code. Make sure to update theANDROID_HOMEenvironment variable in the configuration to match your Android SDK path.

Note:For embedded local Android/iOS sessions, MCP Appium already includes the UiAutomator2 and XCUITest driver packages. The system-level requirements are the platform toolchains (ANDROID_HOME, Java, Android SDK tools, Xcode/iOS signing or simulator setup). For remote sessions, configure those requirements on the remote Appium/WebDriver server instead.

OpenTelemetry tracing is disabled by default. SetAPPIUM_MCP_OTEL_ENABLED=trueto initialize the Node.js OpenTelemetry SDK before the MCP server is constructed. The SDK uses standardOTEL_environment variables, for example:

APPIUM_MCP_OTEL_ENABLED=true # Optional: include sanitized non-sensitive argument values in spans. # APPIUM_MCP_OTEL_INCLUDE_ARGUMENT_VALUES=true # Optional: attach custom key=value pairs to every span (e.g. test case ID, team name). # OTEL_RESOURCE_ATTRIBUTES=testcase.id=my-test-123,team=platform OTEL_SERVICE_NAME=appium-mcp OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://127.0.0.1:4318/v1/traces OTEL_TRACES_SAMPLER=parentbased_always_on

(Please check theofficial documentas well)

When enabled, appium-mcp creates spans for MCP tool calls, prompt loads, resource reads, and resource template reads. Error status is recorded for thrown operation errors and MCP tool results marked withisError. Span attributes intentionally avoid raw screenshots, XML page source, prompts, credentials, and other high-cardinality or sensitive payloads.

Tool spans include payload-free result-size attributes:mcp.tool.result.content_count,content_types,text_chars,resource_count,resource_text_chars,image_count,audio_count,base64_chars, andbase64_bytes_estimate(all prefixed withmcp.tool.result.).content_typescontains only known MCP types orother; payload values, resource URIs, MIME types, and unknown type strings are never recorded. Sizes are counted directly from known result fields without serializing or copying the complete result.

For local trace inspection, use the Jaeger setup intools/telemetry:

Then openhttp://127.0.0.1:16686and run appium-mcp with the environment values intools/telemetry/jaeger.env.

Create acapabilities.jsonfile to define your device capabilities:

{ "android": { "appium:app": "/path/to/your/android/app.apk", "appium:deviceName": "Android Device", "appium:platformVersion": "11.0", "appium:automationName": "UiAutomator2", "appium:udid": "your-device-udid" }, "ios": { "appium:app": "/path/to/your/ios/app.ipa", "appium:deviceName": "iPhone 15 Pro", "appium:platformVersion": "17.0", "appium:automationName": "XCUITest", "appium:udid": "your-device-udid" }, "general": { "platformName": "mac", "appium:automationName": "mac2", "appium:bundleId": "com.apple.Safari" } }

Set theCAPABILITIES_CONFIGenvironment variable to point to your configuration file.

Platform names and "general" mode

- You can pass any platform name toappium_session_management(action=create).
- If the platform isiosorandroid, the server builds capabilities for that platform (including selected device info when local).
- If the platform is any other value, it is treated internally asgeneral:

- The session will use the providedcapabilitiesexactly as given, or

- IfCAPABILITIES_CONFIGis set, it will merge with thegeneralsection from your capabilities file.

Integrator notes (sessions, transport, logging)

ForCI,device farms, ormulti-sessionsetups:

The process keeps oneactiveAppium session; tools use it whensessionIdis omitted. If a tool call does not include asessionId, it will target the active session instead of a specific one. If more than one session exists (seeappium_session_managementwithaction=list), passsessionIdon every tool callthat must target a specific session. Do not assume the active session is stable if other clients or flows can create, select, or delete sessions.

IfAPPIUM_MCP_PERSIST_REMOTE_SESSIONS_PATHis set, MCP Appium persistsattached remote sessionsto that directory as JSON files. The path may be absolute or relative to the current working directory. Each session is stored under a canonical filename derived from a hash of thesessionId; older legacy filenames are migrated, and duplicate files for the same session are removed when the directory is read. When a persisted attached session is used again, the server tries to reattach to the remote Appium session; unreachable entries are pruned automatically.

When the MCPclient disconnects, the serverdeletes only MCP-owned sessionsit is tracking (AppiumdeleteSessionfor each, viasafeDeleteAllSessions).Attachedsessions (ownership=attached) are intentionally left on the remote Appium server. Transports that drop often—httpStreambehind proxies, idle timeouts, or flaky clients—canwipe owned automationin one go under the default policy.stdiois usually safer for a single long-lived operator; if you usehttpStream, expect reconnects to requirenew owned sessionswhere applicable.

Forgrids, cloud labs, or CI, preferremoteServerUrlplus explicitcapabilitiesonappium_session_management(action=create)—for exampleappium:udid, app path or id, platform version—rather than depending on local discovery.select_deviceis geared towardlocalADB / simulator picking; use it as adev convenience, not the main path for allocated remote devices.

Tool calls are logged with argumentredactionimplemented viaJSON.stringify. Oversized payloads (especially longbase64 strings, e.g., screenshot/image payloads, and also very largecapabilitiesobjects) costCPUandlog volume. PreferCAPABILITIES_CONFIGand avoid passing large inline blobs in tool arguments when possible.

Set theSCREENSHOTS_DIRenvironment variable to specify where screenshots are saved. If not set, screenshots are saved to the current working directory. Supports both absolute and relative paths (relative paths are resolved from the current working directory). The directory is created automatically if it doesn't exist.

Screen recordings are saved as MP4 files to the same directory as screenshots (SCREENSHOTS_DIR, oros.tmpdir()if not set).

- iOS: Requiresffmpegto be installed and available onPATH. The default codec islibx264withyuv420ppixel format for QuickTime compatibility.
- Android: Uses the built-inscreenrecordcommand via UiAutomator2. No additional dependencies required.

To start recording, callappium_screen_recordingwithaction="start". You may providetimeLimitin seconds to limit the maximum recording duration, but the start call still returns immediately. To finalize the recording, save the video, and receive the file path, callappium_screen_recordingagain withaction="stop".

Configure AI-powered element finding using vision models. When enabled, a separate tool —appium_ai— is registered alongsideappium_find_element. It exposesaction=find_element, which locates UI elements from natural-language descriptions and returns a coordinate UUID (ai-element:x,y:bbox) that can be passed toappium_gesture(tap/double_tap/long_press).

This feature is opt-in.WhenAI_VISION_ENABLEDis unset orfalse, theappium_aitool isnot registeredand the LLM has no way to invoke vision-based finding — keepingappium_find_elementpurely traditional. This deliberate gating prevents the model from defaulting to a slow, paid vision call when a stable locator (accessibility id, resource-id, etc.) would do the job.

{ "appium-mcp": { "env": { "ANDROID_HOME": "/path/to/android/sdk", "AI_VISION_ENABLED": "true", "AI_VISION_API_BASE_URL": "https://dashscope.aliyuncs.com/compatible-mode/v1", "AI_VISION_API_KEY": "your_api_key_here" } } }

IfAI_VISION_ENABLED=trueis set without both API vars, the server fails to start with a clear error message — misconfiguration is surfaced immediately rather than mid-test.

See theEnvironment Variablestable above for the full list ofAI_VISION_options and their defaults.

Based on benchmark testing, the following models are recommended:
- Qwen3-VL-235B-A22B-Instruct

- Provider: Alibaba Cloud DashScope

- Accuracy: 100%
- Speed: 12649ms
- API:https://dashscope.aliyuncs.com/compatible-mode/v1

- Provider: Google AI

- Accuracy: 100%
- Speed: 17353
- API:https://generativelanguage.googleapis.com/v1beta

More models benchmarked can be foundhere.

- Image Compression: Automatically compresses screenshots to reduce API latency and token costs (50-80% size reduction)
- Result Caching: Caches results for 5 minutes using a module-level LRU cache (max 50 entries) that persists across tool calls, avoiding redundant API calls for identical screenshot + instruction pairs
- Coordinate Handling: Innormalizedmode (default), the model returns 0–1000 range coordinates that are automatically scaled to absolute pixel coordinates using the original image dimensions — independent of any image compression. Inabsolutemode, image resizing is disabled so the model's returned pixel coordinates always map directly to the original screen dimensions.

appium_get_page_source,appium_screenshot, andgenerate_locatorsuse static MCP App viewers by default when the client advertises MCP Apps support.

- Page source XML and generated locator JSON remain in their normal text results for the LLM. Their viewers read those existing results instead of receiving duplicated copies inside generated HTML.
- Saved screenshot base64 is delivered to the viewer throughstructuredContent, which MCP Apps keeps out of model context. The LLM still receives the saved file path. ExplicitreturnRawBase64=truecalls keep their existing raw image result.

For clients with unreliable MCP Apps rendering, setAPPIUM_MCP_APPS_ENABLEDtofalseor0:

{ "appium-mcp": { "env": { "APPIUM_MCP_APPS_ENABLED": "false" } } }

This keeps interactive UI enabled but forces the previous embedded viewers. The compatibility mode places viewer data inside inline HTML and therefore uses more result tokens and bandwidth. With a synthetic 95,000-character page source, the static mode reduced the result from approximately 267 KB to 95 KB (about 64%).

NO_UI=trueorNO_UI=1takes precedence over this setting and disables both static and embedded UI.

Set theNO_UIenvironment variable totrueor1to disable UI components and improve performance:

{ "appium-mcp": { "env": { "NO_UI": "true", "ANDROID_HOME": "/path/to/android/sdk" } } }

- Significantly Faster Response Times: UI rendering and data processing are completely skipped, resulting in 50-80% faster tool responses depending on the operation.
- Major Token Savings: Eliminates 500-5000+ tokens per request by removing HTML UI components from responses, dramatically reducing LLM API costs.
- Massive Bandwidth Reduction:

- Screenshots: Saves 1-5MB of base64-encoded image data per screenshot

- Page source: Saves 50-200KB+ of duplicated XML data in HTML UI
- Locators: Saves 10-100KB+ of element data in interactive UI
- Device/App lists: Saves 5-50KB of HTML UI per selection

The following tools return lightweight text-only responses when NO_UI is enabled:

- appium_screenshot- Screenshot files are still saved to disk, but base64 data is not embedded in responses
- appium_get_page_source- Returns XML as text without interactive inspector UI
- generate_locators- Returns locator data as JSON without interactive UI
- select_device- Returns device list as text without picker UI
- appium_session_management(action=create) - Returns session info as text without dashboard UI
- appium_context- Returns context list as text withaction=listwithout switcher UI
- appium_app_lifecycle(action=list) - Returns app list as JSON without interactive UI

- ✅ Automated test execution in CI/CD pipelines
- ✅ Batch processing multiple devices/sessions
- ✅ Cost-sensitive LLM API usage (reduces token consumption by 60-90%)
- ✅ Network-constrained environments
- ✅ Scripted automation where human interaction is not needed
- ❌ Interactive debugging and exploration (keep UI enabled for better experience)

The documentation tools —appium_documentation_query(RAG search over the Appium docs) andappium_skills— live in a separate package,@appium/mcp-documentation, that carries a multi-megabyte embeddings cache and pulls in a heavy ML stack (@xenova/transformers,@langchain/). To keep the default install lean,this package is not a runtime dependency of appium-mcp and is never downloaded unless you opt in.It is declared as anoptional peer dependency*.

Enabling the tools is a two-step opt-in:

1. Install the optional package(in the same project/environment as appium-mcp):

Installing it with your own package manager dedupes against appium-mcp's existing dependencies, so only the genuinely new code is added.

2. SetAPPIUM_MCP_DOCS_ENABLEDin your MCP server config:

{ "appium-mcp": { "env": { "APPIUM_MCP_DOCS_ENABLED": "true", "ANDROID_HOME": "/path/to/android/sdk" } } }

- Unset / not truthy (default):the documentation tools arenot registered, and nothing related to them (cache, embeddings, ML dependencies) is loaded.
- Truthy (true/1/yes/on):the server registers the documentation tools if@appium/mcp-documentationis installed. If the flag is set but the package isnotinstalled, the server starts normallywithoutthe documentation tools and logs a hint to runnpm install @appium/mcp-documentation.

The gate is governed by the env var, not by mere presence of the package: withAPPIUM_MCP_DOCS_ENABLEDunset, the tools stay hidden even if the package happens to be installed.

Pre-installing it that way also avoids the first-run download delay.

By default (APPIUM_MCP_ON_CLIENT_DISCONNECTunset ordelete_all), when theMCP client disconnects, this serverdeletes every MCP-owned Appium session(the same sessionssafeDeleteAllSessionstargets) so embedded drivers are not left running after a short-lived assistant run.Attachedsessions (ownership=attached) are unchanged by this teardown.

HTTP and streamable MCP clients maydisconnect briefly(reconnect, reload, proxy). If that tears down drivers you still need, setAPPIUM_MCP_ON_CLIENT_DISCONNECTtoskipin your MCP serverenv(same pattern asNO_UIabove). Withskip, sessionssurvivedisconnect until you callappium_session_managementwithaction=delete, or you stop the Appium server / process.

Tradeoff:skipcan leaveorphaned sessionson your Appium server if nothing cleans up — use it when disconnect is not the same as “automation finished.”

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.