MCP Appium
OfficialThis server provides an MCP toolset for automating and testing mobile apps on iOS and Android (local or remote Appium servers), including device/session management, UI interaction, AI-assisted element finding, test generation, and extensibility via plugins.
Discover and prepare devices: list/select Android or iOS devices, boot iOS/tvOS simulators, install/launch WebDriverAgent, and prepare real iOS devices with provisioning profiles.
Manage Appium sessions: create, attach, detach, delete, list, and switch active sessions for local/embedded drivers or remote Appium/WebDriver servers.
Interact with UI elements: find elements by accessibility id, id, predicates, class chains, uiautomator, or xpath; tap, long press, double tap, scroll, swipe, pinch, drag-and-drop, and perform custom W3C multi-touch actions.
Use AI vision finding: when enabled, locate elements from natural-language descriptions and use returned coordinates for gestures.
Read and manipulate app state: get page source, screenshots, element text/attributes, window size, orientation, geolocation, device info, battery status, and screen recordings.
Control device behavior: lock/unlock, shake, open notifications, press hardware/navigation keys, manage clipboard, keyboard, and alerts.
Manage apps and permissions: activate, terminate, install, uninstall, list, query state, background, clear data, open deep links, and get/update/reset app permissions.
Handle web/hybrid contexts: list and switch between native and webview contexts.
Generate tests and locators: create Java/TestNG test code from natural-language steps and generate locators for interactable elements.
Query Appium documentation (optional opt-in): RAG-based documentation search and skills guidance.
Extend via plugins: register custom tools/prompts/resources, wrap tool calls with lifecycle hooks, apply tool/resource policies, and verify plugin/tool names.
Enables mobile test automation for Android apps using UiAutomator2, supporting element discovery, interactions, screen navigation, session management, and automated test generation for both emulators and real devices.
Integrates with Android SDK for Android device testing setup and configuration.
Provides comprehensive mobile automation capabilities through Appium, including cross-platform test creation, intelligent element locator generation, context switching for webviews, and Java/TestNG test code generation following Page Object Model best practices.
Enables mobile test automation for iOS apps using XCUITest, supporting simulator boot, WebDriverAgent setup, element interactions, screen navigation, session management, and automated test generation for both simulators and real devices.
Integrates with Xcode and iOS simulators for iOS device testing, including WebDriverAgent installation and configuration for real device testing with provisioning profiles.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Appiumtake a screenshot of the login screen on my Android device"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.
Table of Contents
Related MCP server: MCP Appium
🚀 Features
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.).
📋 Prerequisites
Before you begin, ensure you have the following installed:
System Requirements
Node.js (v22 or higher)
npm or yarn
Java Development Kit (JDK) (8 or higher)
Android SDK (for Android testing)
Xcode (for iOS testing on macOS)
MCP Appium supports two driver modes:
Embedded local drivers: when
appium_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: when
remoteServerUrlis 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
Android
Install Android Studio and the Android SDK.
Set the
ANDROID_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 keep
adbavailable onPATH.
iOS (macOS only)
Install Xcode from the App Store.
Install the Xcode Command Line Tools:
xcode-select --install.Install iOS simulators through Xcode.
For real device testing, enable Developer Mode on the device and sign in to your Apple ID in Xcode (Settings → Accounts). Use
appium_prepare_ios_real_deviceto download and sign WebDriverAgent in a single call - it will guide you through provisioning profile selection and return capabilities for session startup.
🛠️ Installation
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"
}
}
}
}In Cursor IDE
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 the ANDROID_HOME environment variable in the configuration to match your Android SDK path.
Or install manually:
Go to Cursor Settings → MCP → Add new MCP Server. Name it to your liking, use command type with the command npx -y appium-mcp@latest. You can also verify config or add command arguments via clicking Edit.
Here is the recommended configuration:
{
"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 the ANDROID_HOME path to match your Android SDK installation path.
With Gemini CLI
Use the Gemini CLI to add the MCP Appium server:
gemini mcp add appium-mcp npx -y appium-mcp@latestThis will automatically configure the MCP server for use with Gemini. Make sure to update the ANDROID_HOME environment variable in the configuration to match your Android SDK path.
With Claude Code CLI
Use the Claude Code CLI to add the MCP Appium server:
claude mcp add appium-mcp -- npx -y appium-mcp@latestThis will automatically configure the MCP server for use with Claude Code. Make sure to update the ANDROID_HOME environment variable in the configuration to match your Android SDK path.
⚙️ Configuration
Environment Variables
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.
Variable | Required | Description |
| Optional | Absolute path to a |
| Optional | Directory where screenshots and screen recordings are saved. Defaults to the current working directory |
| Optional | Set to |
| Optional | MCP Apps static UI mode. Enabled by default. Set to |
| Optional | Session cleanup when the MCP client disconnects: |
| Optional | Absolute path to a pre-extracted |
REMOTE_SERVER_URL_ALLOW_REGEX | Optional | Regular expression applied to the complete remoteServerUrl value before MCP Appium connects to a remote Appium/WebDriver server. When unset, any HTTP(S) destination is accepted. Set this in shared infrastructure or CI environments that require an explicit destination policy. See Remote server security and trust model. |
| Optional | Set to |
| Required when | Base URL of the OpenAI-compatible vision model API |
| Required when | API key for the vision model provider |
| Optional | Vision model name (default: |
| Optional | Coordinate type: |
| Optional | Max image width in pixels before compression (default: |
| Optional | JPEG quality 1–100 for compressed screenshots sent to the vision API (default: |
| Optional | Set to |
| Optional | Hugging Face model used for semantic search in Appium documentation queries (default: |
| Optional | Directory path for persisted attached remote session info. When set, attached remote sessions are stored as JSON files in that directory and can be rehydrated after restart. |
| Optional | Set to |
| Optional | Set to |
| Optional | Set to |
| Optional | Service name reported to the OpenTelemetry collector (example: |
| Optional | OTLP/HTTP traces endpoint (example: |
| Optional | Trace sampling strategy; |
| Optional | Comma-separated |
OpenTelemetry tracing
OpenTelemetry tracing is disabled by default. Set APPIUM_MCP_OTEL_ENABLED=true to initialize the Node.js OpenTelemetry SDK before the MCP server is constructed. The SDK uses standard OTEL_* 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 document as 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 with isError. 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, and base64_bytes_estimate (all prefixed with mcp.tool.result.). content_types contains only known MCP types or other; 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 in tools/telemetry:
npm run telemetry:jaeger:startThen open http://127.0.0.1:16686 and run appium-mcp with the environment values in tools/telemetry/jaeger.env.
Capabilities
Create a capabilities.json file 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 the CAPABILITIES_CONFIG environment variable to point to your configuration file.
Platform names and "general" mode
You can pass any platform name to
appium_session_management(action=create).If the platform is
iosorandroid, the server builds capabilities for that platform (including selected device info when local).If the platform is any other value, it is treated internally as
general:The session will use the provided
capabilitiesexactly as given, orIf
CAPABILITIES_CONFIGis set, it will merge with thegeneralsection from your capabilities file.
This allows custom setups and non-standard platforms to work without changing server logic.
Integrator notes (sessions, transport, logging)
For CI, device farms, or multi-session setups:
Multi-session and sessionId
The process keeps one active Appium session; tools use it when sessionId is omitted. If a tool call does not include a sessionId, it will target the active session instead of a specific one. If more than one session exists (see appium_session_management with action=list), pass sessionId on every tool call that must target a specific session. Do not assume the active session is stable if other clients or flows can create, select, or delete sessions.
Session persistence
If APPIUM_MCP_PERSIST_REMOTE_SESSIONS_PATH is set, MCP Appium persists attached remote sessions to 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 the sessionId; 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.
Client disconnect
When the MCP client disconnects, the server deletes only MCP-owned sessions it is tracking (Appium deleteSession for each, via safeDeleteAllSessions). Attached sessions (ownership=attached) are intentionally left on the remote Appium server. Transports that drop often—httpStream behind proxies, idle timeouts, or flaky clients—can wipe owned automation in one go under the default policy. stdio is usually safer for a single long-lived operator; if you use httpStream, expect reconnects to require new owned sessions where applicable.
Remote Appium, CI, and device farms
For grids, cloud labs, or CI, prefer remoteServerUrl plus explicit capabilities on appium_session_management (action=create)—for example appium:udid, app path or id, platform version—rather than depending on local discovery. select_device is geared toward local ADB / simulator picking; use it as a dev convenience, not the main path for allocated remote devices.
Tool logging and argument size
Tool calls are logged with argument redaction implemented via JSON.stringify. Oversized payloads (especially long base64 strings, e.g., screenshot/image payloads, and also very large capabilities objects) cost CPU and log volume. Prefer CAPABILITIES_CONFIG and avoid passing large inline blobs in tool arguments when possible.
Screenshots
Set the SCREENSHOTS_DIR environment 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 Recording
Screen recordings are saved as MP4 files to the same directory as screenshots (SCREENSHOTS_DIR, or os.tmpdir() if not set).
iOS: Requires ffmpeg to be installed and available on
PATH. The default codec islibx264withyuv420ppixel format for QuickTime compatibility.Android: Uses the built-in
screenrecordcommand via UiAutomator2. No additional dependencies required.
To start recording, call appium_screen_recording with action="start". You may provide timeLimit in 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, call appium_screen_recording again with action="stop".
AI Vision Element Finding
Configure AI-powered element finding using vision models. When enabled, a separate tool — appium_ai — is registered alongside appium_find_element. It exposes action=find_element, which locates UI elements from natural-language descriptions and returns a coordinate UUID (ai-element:x,y:bbox) that can be passed to appium_gesture (tap / double_tap / long_press).
This feature is opt-in. When AI_VISION_ENABLED is unset or false, the appium_ai tool is not registered and the LLM has no way to invoke vision-based finding — keeping appium_find_element purely 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.
Required Environment Variables:
{
"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"
}
}
}If AI_VISION_ENABLED=true is set without both API vars, the server fails to start with a clear error message — misconfiguration is surfaced immediately rather than mid-test.
Optional Environment Variables:
See the Environment Variables table above for the full list of AI_VISION_* options and their defaults.
Supported Vision Model Providers:
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
gemini-3-flash-preview
Provider: Google AI
Accuracy: 100%
Speed: 17353
API:
https://generativelanguage.googleapis.com/v1beta
More models benchmarked can be found here.
Performance Features:
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: In
normalizedmode (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.
Performance Optimization
MCP Apps Mode
appium_get_page_source, appium_screenshot, and generate_locators use 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 through
structuredContent, 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, set APPIUM_MCP_APPS_ENABLED to false or 0:
{
"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=true or NO_UI=1 takes precedence over this setting and disables both static and embedded UI.
NO_UI Mode
Set the NO_UI environment variable to true or 1 to disable UI components and improve performance:
{
"appium-mcp": {
"env": {
"NO_UI": "true",
"ANDROID_HOME": "/path/to/android/sdk"
}
}
}Benefits:
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
Lower Memory Usage: Client applications consume less memory without HTML rendering and embedded data.
Perfect for Headless Environments: Ideal for CI/CD pipelines, automated testing scripts, batch operations, or any scenario where visual UI feedback is not required.
Better Scalability: Reduced resource consumption allows handling more concurrent sessions.
Affected Tools:
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 responsesappium_get_page_source- Returns XML as text without interactive inspector UIgenerate_locators- Returns locator data as JSON without interactive UIselect_device- Returns device list as text without picker UIappium_session_management(action=create) - Returns session info as text without dashboard UIappium_context- Returns context list as text withaction=listwithout switcher UIappium_app_lifecycle(action=list) - Returns app list as JSON without interactive UI
When to Enable NO_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)
Documentation Tools (opt-in)
The documentation tools — appium_documentation_query (RAG search over the Appium docs) and appium_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 an optional peer dependency.
Enabling the tools is a two-step opt-in:
1. Install the optional package (in the same project/environment as appium-mcp):
npm install @appium/mcp-documentationInstalling it with your own package manager dedupes against appium-mcp's existing dependencies, so only the genuinely new code is added.
2. Set APPIUM_MCP_DOCS_ENABLED in your MCP server config:
{
"appium-mcp": {
"env": {
"APPIUM_MCP_DOCS_ENABLED": "true",
"ANDROID_HOME": "/path/to/android/sdk"
}
}
}Behavior:
Unset / not truthy (default): the documentation tools are not 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 is not installed, the server starts normally without the 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: with APPIUM_MCP_DOCS_ENABLED unset, the tools stay hidden even if the package happens to be installed.
Pre-installing it that way also avoids the first-run download delay.
MCP disconnect behavior
By default (APPIUM_MCP_ON_CLIENT_DISCONNECT unset or delete_all), when the MCP client disconnects, this server deletes every MCP-owned Appium session (the same sessions safeDeleteAllSessions targets) so embedded drivers are not left running after a short-lived assistant run. Attached sessions (ownership=attached) are unchanged by this teardown.
HTTP and streamable MCP clients may disconnect briefly (reconnect, reload, proxy). If that tears down drivers you still need, set APPIUM_MCP_ON_CLIENT_DISCONNECT to skip in your MCP server env (same pattern as NO_UI above). With skip, sessions survive disconnect until you call appium_session_management with action=delete, or you stop the Appium server / process.
Tradeoff: skip can leave orphaned sessions on your Appium server if nothing cleans up — use it when disconnect is not the same as “automation finished.”
Remote server security and trust model
MCP Appium is designed to run as a local, single-user MCP server or as part of a trusted CI job. It is not intended to be exposed as a shared service to untrusted MCP clients.
The remoteServerUrl argument is intentionally configurable because MCP Appium acts as an Appium/WebDriver client and may need to connect to local, remote, private-network, or CI-hosted Appium servers.
Only allow trusted users and trusted workflow configuration to control remoteServerUrl. In particular:
Do not expose the MCP tool surface directly to untrusted users.
In CI, do not construct
remoteServerUrlfrom untrusted pull request content, repository data, prompts, or other externally controlled input.Keep remote server URLs in trusted MCP or CI configuration where possible.
Use
REMOTE_SERVER_URL_ALLOW_REGEXto restrict the permitted Appium server URLs when the execution environment requires an explicit destination policy.
When REMOTE_SERVER_URL_ALLOW_REGEX is not set, MCP Appium accepts any syntactically valid HTTP or HTTPS destination. Remote server URLs must not contain a query string or fragment. The variable is a regular-expression check against the complete remoteServerUrl value and can only narrow the HTTP(S) destinations accepted by the built-in validation.
Capability discovery for attached sessions does not follow HTTP redirects. This keeps a permitted endpoint from redirecting the initial metadata request to a destination outside the configured URL policy.
If a remote URL contains credentials, MCP Appium redacts its userinfo from logs and error responses. Opt-in persisted-session files may still contain credentials and sensitive capabilities because they are needed for reattachment; those files are created with owner-only (0600) permissions, and permissions on existing regular session files are repaired when read. Use a dedicated persistence directory owned by the MCP process.
For example, to permit only a specific Appium server:
REMOTE_SERVER_URL_ALLOW_REGEX='^https://appium\.example\.com:4723(?:/wd/hub)?/?$'To permit Appium servers under a controlled internal domain:
REMOTE_SERVER_URL_ALLOW_REGEX='^https://[a-z0-9-]+\.appium\.example\.internal(?::[0-9]+)?(?:/.*)?$'Treat this setting as an additional deployment safeguard. Network-level controls, CI isolation, and trusted MCP client configuration should remain the primary security boundaries.
🔌 Plugin API
Use appium-mcp/core to compose the default Appium MCP server with custom business logic without maintaining a fork. Plugins can register MCP tools, prompts, resources, and resource templates, and can wrap tool execution with lifecycle hooks. Call hooks are tool-only: prompts, resources, and resource templates are registered with FastMCP but are not wrapped by beforeCall or afterCall.
createAppiumMcpServer({ policy }) can also hide nonmatching tools and resources from MCP discovery. The factory is async, so await it before starting the returned server. Policy rules are regular expressions matched against tool and resource names exactly as registered. The policy is applied at registration time to both single and batch registration methods. Resource policy matches the resource name only; resources or resource templates without a string name cannot match a non-empty allowResources list.
import { createAppiumMcpServer } from 'appium-mcp/core';
import type {
AppiumMcpPlugin,
McpRegistry,
ToolCallContext,
} from 'appium-mcp/core';
import { z } from 'zod';
class CheckoutPlugin implements AppiumMcpPlugin {
readonly name = 'checkout-plugin';
readonly version = '1.0.0';
register(registry: McpRegistry): void {
const parameters = z.object({ orderId: z.string() });
registry.addTool({
name: 'assert_checkout_summary',
description:
'Assert that the checkout summary screen shows an expected order ID.',
parameters,
execute: async (args) => {
const { orderId } = parameters.parse(args);
return {
content: [
{ type: 'text', text: `Assert checkout order ${orderId}` },
],
};
},
});
}
async beforeCall(ctx: ToolCallContext): Promise<void> {
if (ctx.toolName === 'appium_gesture') {
console.error(`[checkout-plugin] about to call ${ctx.toolName}`);
}
}
}
const server = await createAppiumMcpServer({
plugins: [new CheckoutPlugin()],
additionalInstructions: 'Custom checkout policies are active.',
policy: {
allowTools: [/^appium_session_management$/, /^assert_checkout_summary$/],
allowResources: [/^Generate Code With Locators$/],
},
});
await server.start({ transportType: 'stdio' });Stdio logging
start({ transportType: 'stdio' }) automatically configures Appium and WebDriver logging before the stdio transport starts, keeping stdout reserved for JSON-RPC. You normally do not need to configure logging separately.
In stdio mode, WDIO_LOG_LEVEL values that would write verbose output to stdout (trace, debug, and info) are clamped to warn. Quieter error and silent values are preserved. This behavior only applies to stdio; httpStream logging is unchanged.
For advanced integrations that need to configure logging explicitly, configureStdioTransportLogging() is exported from appium-mcp/core. Call it before starting stdio work; calling server.start({ transportType: 'stdio' }) already invokes it automatically.
Plugin lifecycle:
register(registry, core): called during server construction. Register custom tools, prompts, resources, and resource templates here.initialize(ctx): called lazily on the first MCP client connection. Use it for async setup such as artifact storage or internal service clients.beforeCall(ctx): called before a registered MCP tool executes. Return aToolCallResultto short-circuit the tool. This hook only applies to tools, not prompts, resources, or resource templates.afterCall(ctx, result): called after a registered MCP tool executes. Return a modifiedToolCallResultto decorate or replace the response. This hook only applies to tools, not prompts, resources, or resource templates.destroy(): called after the last MCP client disconnects.
Safe plugin surface
The supported plugin API is intentionally small:
Surface | Safe methods |
|
|
|
|
|
|
|
|
McpRegistry methods delegate to the matching FastMCP registration APIs, so their object shapes follow FastMCP's documented tool, prompt, resource, and resource-template definitions. Appium MCP wraps registered tools with plugin call hooks, but prompts and resources are registered directly with FastMCP.
Each plugin name should be unique within the server. If two plugins use the same name, Appium MCP keeps the first plugin registered for that name and skips later plugins with a warning. Use a stable, package-style or organization-prefixed name, such as acme-checkout-plugin, to avoid collisions when composing plugins from multiple teams.
Each tool name should also be unique across all plugins and the core server. Tool names follow FastMCP behavior, not plugin-name behavior: when a tool is registered with the same name as an existing tool, FastMCP replaces the earlier tool definition with the later one. Appium MCP registers built-in tools before plugin tools, which means a plugin tool that uses the same name as a built-in tool replaces the built-in tool. Appium MCP tools usually have an appium_ prefix, so plugin tool names should use that pattern only when they intentionally override a core tool.
Verify plugin and tool names
Use verifyAppiumMcpNames before publishing or deploying a custom plugin setup. It registers your plugin capabilities into a lightweight collector, registers the Appium MCP core tools, and reports duplicate plugin names, duplicate tool names, and registration errors without starting the MCP server.
The recommended approach is to verify the same plugin array you pass to createAppiumMcpServer({ plugins }). This preserves your real plugin instances and order:
import {
formatVerificationReport,
verifyAppiumMcpNames,
} from 'appium-mcp/core';
import { plugins } from './plugins.js';
const report = verifyAppiumMcpNames({ plugins });
console.log(formatVerificationReport(report));
process.exit(report.ok ? 0 : 1);When you provide multiple plugins, order is preserved. Plugins are verified in array order after the appium-mcp core tools. This matters because Appium MCP keeps the first plugin for a duplicate plugin name and skips later plugins with the same name, while duplicate tool names follow FastMCP's later-registration-wins behavior. Tool names still need to be unique across all loaded plugins and appium-mcp core; the verifier reports any collisions it finds.
The report labels this package's own shipped tools as appium-mcp core. Plugin sources are labeled as plugin:<name> with the plugin version.
Treat anything outside appium-mcp/core as internal. In particular, plugins should not rely on private server internals, internal session-store modules, tool implementation files, or the raw FastMCP server instance. If a plugin needs another stable primitive, open an issue so it can be added to AppiumMcpCore or McpRegistry deliberately.
See examples/plugin-example.ts for a fuller cookbook with tools, prompts, resources, resource templates, call hooks, and lifecycle setup.
🎯 Available Tools
MCP Appium provides a comprehensive set of tools organized into the following categories:
Platform & Device Setup
Tool | Description |
| REQUIRED FIRST: Discover available devices and select one. Auto-selects if only one device found |
| Boot an iOS/tvOS simulator, download WDA (if not cached), and install/launch WDA in a single call. Each step is skipped if already satisfied (iOS/tvOS only). Set |
| Prepare a real iOS device for Appium testing. Two-step flow: (1) call without |
Session Management
Tool | Description |
| Unified session management. |
| Control device behavior: lock/unlock the screen, shake the device, or open the notifications panel ( |
| Read or update Appium driver session settings in one tool. |
The remote server URL in appium_session_management (action=create or action=attach) can be set via the remoteServerUrl parameter.
When remoteServerUrl is omitted, action=create starts an embedded local UiAutomator2 or XCUITest driver for platform=android or platform=ios. platform=general requires remoteServerUrl. When remoteServerUrl is present, action=create calls WebDriver newSession on the remote server, and action=attach connects MCP Appium to an existing remote session without owning its lifecycle.
If REMOTE_SERVER_URL_ALLOW_REGEX is set, the URL must match the provided regex pattern for security reasons.
This allows you to restrict which remote servers can be used with your MCP Appium instance, preventing unauthorized connections.
Without an allow regex, any syntactically valid HTTP(S) URL without a query string or fragment is accepted.
Context Management
Tool | Description |
| Manage contexts in one tool. |
Element Discovery & Interaction
Tool | Description |
| Find a specific element using traditional locator strategies. Strategy priority: |
| Opt-in (gated by |
| Perform a touch gesture. |
| Perform a drag and drop gesture from a source location to a target location (supports element-to-element, element-to-coordinates, coordinates-to-element, and coordinates-to-coordinates) |
| Execute raw W3C Actions API sequences for custom multi-touch gestures (rotate, three-finger swipe, edge swipes, precise timing). Prefer |
| Enter text into an input field |
| Hide the on-screen keyboard or query visibility. |
| Get text content from an element |
| Read or set device clipboard plain text. |
| Handle alerts with |
Screen & Navigation
Tool | Description |
| Take a screenshot and save as PNG. Optionally provide |
| Get the width and height of the device screen in pixels |
| Get the page source (XML) from the current screen |
| Get or set device/screen orientation with |
| Get, set, or reset the device GPS coordinates with |
| Start or stop screen recording with |
| Get device information, battery status, or current device time. Use |
App Management
Tool | Action | Description |
|
| Activate (launch/bring to foreground) a specified app by bundle ID or name |
|
| Terminate (close) a specified app |
|
| Install an app on the device from a file path |
|
| Uninstall an app from the device by bundle ID or name |
|
| List all installed apps on the device (Android and iOS) |
|
| Check whether an app is installed. Package name for Android, bundle ID for iOS. |
|
| Query the current state of an app: 0=not installed, 1=not running, 2=background suspended, 3=background, 4=foreground |
|
| Background the current app for a duration (optional; defaults to 5 seconds) |
|
| Clear app data and cache without uninstalling ( |
|
| Open a deep link URL with the default or a specified app |
| Get, update, or reset app permissions in one tool ( | Android: list or change runtime permissions. iOS Simulator: get/set privacy via bundle id; reset ( |
Test Generation & Documentation
Tool | Description |
| Generate intelligent locators for all interactive elements on the current screen |
| Generate automated test code from natural language scenarios |
| Opt-in (gated by |
| Opt-in (gated by |
🤖 Client Support
MCP Appium is designed to be compatible with any MCP-compliant client.
📚 Usage Examples
Amazon Mobile App Checkout Flow
Here's an example prompt to test the Amazon mobile app checkout process:
Open Amazon mobile app, search for "iPhone 15 Pro", select the first search result, add the item to cart, proceed to checkout, sign in with email "test@example.com" and password "testpassword123", select shipping address, choose payment method, review order details, and place the order. Use JAVA + TestNG for test generation.This example demonstrates a complete e-commerce checkout flow that can be automated using MCP Appium's intelligent locator generation and test creation capabilities.
AI-Powered Element Finding Examples
Traditional Mode — prefer stable identifiers:
Try strategies in priority order: accessibility id first, then id, then platform-native predicates (-ios predicate string / -ios class chain on iOS, -android uiautomator on Android). Reach for xpath only when nothing more stable exists.
{
"tool": "appium_find_element",
"arguments": {
"strategy": "accessibility id",
"selector": "search-button"
}
}xpath fallback (when no accessibility id, resource-id, or platform-native predicate works):
{
"tool": "appium_find_element",
"arguments": {
"strategy": "xpath",
"selector": "//android.widget.Button[@text='Search']"
}
}Scroll until element is on screen (appium_gesture / scroll_to_element):
{
"tool": "appium_gesture",
"arguments": {
"action": "scroll_to_element",
"strategy": "xpath",
"selector": "//*[contains(@text,'My header')]",
"direction": "down",
"maxScrollAttempts": 40,
"scrollDistancePreset": "medium"
}
}Use scrollDistance (0.05–1) instead of scrollDistancePreset when you want an exact fraction. Then call appium_find_element with the same strategy / selector to obtain the element id.
AI Mode (Natural Language) — requires AI_VISION_ENABLED=true:
When the AI tool is enabled, use appium_ai (not appium_find_element) for vision-based finding:
{
"tool": "appium_ai",
"arguments": {
"action": "find_element",
"instruction": "yellow search button at the bottom of the screen"
}
}The returned UUID (ai-element:x,y:bbox) flows directly into appium_gesture:
{
"tool": "appium_gesture",
"arguments": {
"action": "tap",
"elementUUID": "ai-element:540,2280:480,2240,600,2320"
}
}More instruction examples:
"username input field at top""settings icon in top-right corner""red delete button next to the item""blue submit button at bottom""profile picture in navigation bar"
When to reach for appium_ai vs appium_find_element:
Prefer
appium_find_elementwhenever a stable accessibility id, resource-id, or unique text exists — faster, free, deterministic.Use
appium_aionly when the element has no stable identifier, the page source is unavailable, or you must locate by visual cues (color, position, icon).See AI Vision Element Finding for setup and configuration.
Working in Your Native Language
MCP Appium works seamlessly in any language - you don't need to know English! The AI assistant understands and responds in your native language. Simply describe what you want to do in your preferred language:
Examples in different languages:
🇪🇸 Spanish: "Abre la aplicación de Amazon, busca 'iPhone 15 Pro' y agrégalo al carrito"
🇨🇳 Chinese: "打开Amazon应用,搜索'iPhone 15 Pro'并添加到购物车"
🇯🇵 Japanese: "Amazonアプリを開いて、'iPhone 15 Pro'を検索してカートに追加する"
🇰🇷 Korean: "Amazon 앱을 열고 'iPhone 15 Pro'를 검색한 후 장바구니에 추가"
🇫🇷 French: "Ouvre l'application Amazon, recherche 'iPhone 15 Pro' et ajoute-le au panier"
🇩🇪 German: "Öffne die Amazon App, suche nach 'iPhone 15 Pro' und füge es zum Warenkorb hinzu"
The AI will handle your requests naturally and generate the appropriate test code, regardless of the language you use.
🙌 Contributing
Contributions are welcome! Please feel free to submit a pull request or open an issue to discuss any changes.
📄 License
This project is licensed under the Apache-2.0. See the LICENSE file for details.
Available Tools
31 toolsappium_alertA
Handle system alerts with action=accept|dismiss, or read alert text with action=get_text.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform on alert: accept, dismiss, or get_text | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| buttonLabel | No | Optional label of the button to click for accept/dismiss. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the behavioral split between mutating actions (accept/dismiss) and a read action (get_text), which adds meaningful context beyond the readOnlyHint=false annotation. It does not contradict the annotations and gives a clear idea of the tool's side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that immediately conveys the purpose and the key action syntax. Every element earns its place with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a relatively simple tool with one required enum parameter, the description plus schema covers the main invocation patterns. It does not mention error cases like what happens if no alert is present, but that is arguably beyond the core need for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides full descriptions for all three parameters (100% coverage), so the baseline applies. The description reinforces the meaning of the action values by noting that get_text reads alert text, but it does not add details about sessionId or buttonLabel beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific operation ('Handle system alerts') and enumerates the exact actions available: accept, dismiss, and get_text. It distinguishes itself from sibling tools like appium_get_text by scoping the operation to system alerts rather than generic element text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool: whenever a system alert needs to be accepted, dismissed, or its text read. However, it does not explicitly contrast with alternatives or state when not to use it, leaving some inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_app_lifecycleC
Manage app lifecycle, installation, state, data, and deep links.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Android package or iOS bundle ID; takes precedence over name. | |
| url | No | URL for deep_link (e.g. https://example.com or myapp://path). | |
| name | No | Human-readable app name resolved to an ID; alternative to id. | |
| path | No | App file path; required for install. | |
| action | Yes | activate: foreground app; terminate: stop app; is_installed: check installation; clear: clear app data without uninstalling (all require id or name). install: requires path. uninstall: requires id/name; Android keepData is optional. list: optional iOS applicationType. query_state: get state 0=not installed,1=not running,2=background suspended,3=background,4=foreground (requires id or name). background: send foreground app to background; optional seconds (default 5). deep_link: requires url; id/name is optional. | |
| seconds | No | Background duration; default 5. Use -1 to remain in background. | |
| keepData | No | Android uninstall: preserve app data and cache. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| waitForLaunch | No | Android deep_link: wait for the activity to return; default true. | |
| applicationType | No | iOS list filter: User (default) or System. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already indicate readOnlyHint=false and openWorldHint=false, so the description adds little behavioral context. It merely restates broad categories like installation and data without disclosing potentially destructive behaviors (e.g., uninstall, clear data) or side effects beyond what the schema already states.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short sentence, front-loaded with the main domain categories. It is compact and easy to parse, though its brevity sacrifices usefulness for a complex multi-action tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given ten parameters, ten possible actions, and no output schema, this one-line description is too thin. It does not explain that the action parameter determines which optional parameters are required, nor does it provide any high-level workflow or caution about destructive actions. The rich schema compensates partially, but the description itself is not contextually complete for real agent use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already describes every parameter in detail, including per-action requirements and semantics. The description adds no parameter-level meaning, which matches the baseline for full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description lists broad domains (lifecycle, installation, state, data, deep links) so an agent can roughly tell it is an app-management tool, but the verb 'Manage' is vague and does not specify what actual operations are performed. It does not clearly distinguish itself from sibling tools such as appium_mobile_device_control or appium_mobile_permissions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives. The description does not name any sibling tools, conditions, exclusions, or prerequisites, leaving the agent to infer usage from the name and schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_contextA
Manage Appium contexts with one tool. action=list returns all contexts and current context. action=switch changes to a target context.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Use list to fetch contexts or switch to change context. | |
| context | No | Required when action is switch. Common values: NATIVE_APP or WEBVIEW_<id>/WEBVIEW_<package>. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false, and the description aligns by stating that switch changes the context. It also discloses that list returns both all contexts and the current context. Deeper behavioral details such as switch failure modes or side effects are not covered, but the basic mutation behavior is transparent enough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. It front-loads the tool's purpose and immediately explains both enum actions, making it quick for an agent to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema covers all parameters, and the description covers the primary behavioral outcomes for both actions. Minor missing details like switch failure behavior or return format are not essential given the schema and annotations present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with every parameter already documented including enum values, the context requirement for switch, and the sessionId default. The description adds little beyond restating the action outcomes, which is acceptable given the schema carries the semantic load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool manages Appium contexts and specifies two concrete actions: list returns all contexts plus the current context, and switch changes to a target context. It distinguishes itself from sibling tools by targeting the context resource, though it does not name an alternative explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides internal routing guidance by explaining what each action does, so an agent knows whether to use list or switch. It does not, however, discuss when to prefer this tool over sibling tools or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_drag_and_dropA
Perform a drag-and-drop gesture from a source location to a target location. The gesture: long press the source (default 600ms), drag to the target (default 1200ms), then release. Source and target can each be specified as either an element UUID or coordinates. Useful for reordering lists, moving items, drag-to-delete.
| Name | Required | Description | Default |
|---|---|---|---|
| sourceX | No | Source X coordinate. Required if sourceElementUUID is not provided. | |
| sourceY | No | Source Y coordinate. Required if sourceElementUUID is not provided. | |
| targetX | No | Target X coordinate. Required if targetElementUUID is not provided. | |
| targetY | No | Target Y coordinate. Required if targetElementUUID is not provided. | |
| duration | No | Duration of the drag movement in milliseconds. Default 1200. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| longPressDuration | No | Duration of the long press before dragging in milliseconds. Default 600. | |
| sourceElementUUID | No | UUID of source element to drag from. Either sourceElementUUID or sourceX+sourceY must be provided. | |
| targetElementUUID | No | UUID of target element to drop on. Either targetElementUUID or targetX+targetY must be provided. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag mutation via readOnlyHint=false, and the description adds the full gesture sequence (long press, drag, release) plus default timings of 600ms and 1200ms. It does not cover failure modes or stale-element behavior, but the core interaction model is clearly disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact, front-loaded sentences cover the action, gesture mechanics, source/target options, and use cases with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a gesture tool with a 100%-covered schema, the description supplies the action sequence, timing defaults, coordinate/element alternatives, and practical use cases. The absence of an output schema leaves return behavior unspecified, but this is a minor gap for a UI gesture.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema documents all 9 parameters with constraints and defaults, so the coverage baseline of 3 applies. The description mostly restates the timing defaults and the element-vs-coordinate option already present in the schema, adding no significant new parameter-level meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('drag-and-drop gesture from source to target') and gives distinctive mechanics. It is clearly distinct from generic siblings like appium_gesture and appium_perform_actions, though it does not explicitly name or contrast them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides concrete use cases ('reordering lists, moving items, drag-to-delete') that imply when to choose this tool over generic alternatives. It stops short of explicit when/when-not guidance or naming sibling alternatives, so routing is left partly to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_driver_settingsA
Read or update Appium driver session settings (e.g. idle timeouts, selector waits). Use action=get to return JSON settings; action=update merges a map into the session. Works for embedded UiAutomator2/XCUITest sessions and remote WebDriver clients that support Appium settings.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | get: read current Appium driver session settings (timeouts, selector waits, flags). update: merge a settings map into the session (requires settings). | |
| settings | No | Required when action is update. Driver-specific keys (e.g. Android UiAutomator2: waitForIdleTimeout, waitForSelectorTimeout, ignoreUnimportantViews; iOS XCUITest has its own set). Use action=get first to inspect current values. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds meaningful behavior beyond the annotations: it explains that get returns JSON, that update performs a merge rather than a full overwrite, and that only sessions supporting Appium settings are applicable. Annotations only provide readOnlyHint=false and openWorldHint=false, so the description carries the behavioral burden and does so reasonably well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three focused sentences, with the core operation first, action details second, and applicability third. There is no filler or redundant elaboration; every sentence contributes useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's purpose, action modes, supported session types, and the output shape for get. It is slightly less complete for the update path because the return value is not specified, but the schema covers parameter requirements and the overall guidance is sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents action, settings, and sessionId. The description adds value by giving examples and confirming the merge behavior, but it mostly restates what the schema already says. This matches the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the operation: "Read or update Appium driver session settings" and provides concrete examples like "idle timeouts, selector waits." It is more specific than a bare tool name, though it does not explicitly contrast with sibling tools such as appium_session_management.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear action-level guidance: "Use action=get to return JSON settings; action=update merges a map into the session." It also scopes applicability to embedded UiAutomator2/XCUITest sessions and compatible remote WebDriver clients, but it does not explicitly say when not to use this tool or when to prefer a sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_find_elementARead-only
Find a specific element by strategy and selector which will return a uuid that can be used for interactions.
[PRIORITY 2: Use this to search for a target element.]
Strategy priority: accessibility id > id > platform-native (-ios predicate string / -ios class chain on iOS, -android uiautomator on Android) > xpath (last resort — slow & brittle). See the strategy parameter for the full ranking.
Scrolling until an element appears: use appium_gesture with action=scroll_to_element (same strategy + selector), not this tool.
Vision / natural-language find: use appium_ai with action=find_element, not this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | Selector string for the chosen strategy. Do not pass natural-language descriptions of the target here; use appium_ai (action=find_element) for that. | |
| strategy | Yes | Locator strategy. Try in priority order: (1) accessibility id [cross-platform, fastest, most stable], (2) id [Android resource-id; iOS aliases accessibility id], (3) -ios predicate string [iOS native, fast], (4) -ios class chain [iOS native, hierarchy queries], (5) -android uiautomator [Android native, expressive UiSelector], (6) xpath [LAST RESORT — slow on iOS XCUITest, brittle to layout changes], (7) name [legacy; often aliased on iOS], (8) class name [too generic, usually multi-match], (9) css selector [webview/hybrid contexts only]. Platform tips: iOS prefer (1)→(3)→(4); Android prefer (1)→(2)→(5); xpath last on both. For natural-language / vision-based find, use the appium_ai tool (action=find_element), not this one. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only, and the description adds behavioral context beyond that: it returns a UUID for later interactions, provides a strategy priority ranking, and warns that xpath is slow and brittle. It does not describe not-found behavior or waiting semantics, but the annotations carry the safety profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded, with the core purpose stated first and clear routing notes following. It is somewhat long and repeats ranking information that also exists in the schema, but every section serves a practical purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only lookup tool with full schema coverage and annotations, the description is largely complete: it defines the return value, strategy selection, and important sibling-tool exclusions. It omits edge-case behavior like 'element not found' or multiple matches, but the core invocation context is covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents strategy, selector, and sessionId. The description reinforces the strategy priority and exclusions, but adds little meaning beyond what the parameter descriptions already provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Find a specific element by strategy and selector' and adds the key outcome — returning a UUID for interactions. It also distinguishes itself from related tools by naming the scrolling and vision-based alternatives it is not.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use guidance is provided via a strategy priority ordering, and the description clearly says when NOT to use this tool: scrolling should use appium_gesture with scroll_to_element, and natural-language finding should use appium_ai. This is strong routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_generate_testsA
Generate tests for a mobile app: follow the returned instructions to drive the real session with MCP tools (select_device, appium_session_management, appium_find_element, appium_gesture, appium_set_value, etc.), then emit code. Use generate_locators only when you need a full locator snapshot; prefer appium_find_element for normal steps.
| Name | Required | Description | Default |
|---|---|---|---|
| steps | Yes | The steps of the test |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already set readOnlyHint=false, so the non-read-only nature is known; description adds that it drives a real session via MCP tools, implying side effects, and clarifies that actual interactions are delegated to sibling tools. It doesn't fully disclose test execution risks, but with annotations that's acceptable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose and action workflow; the second sentence earns its place by preventing misuse of generate_locators. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex meta-orchestration tool with no output schema, it names the relevant sibling tools and gives an end-to-end flow. Lacks details on the returned instruction format, but that is likely unnecessary for correct invocation, and the one input is fully specified by the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the only parameter, steps, has a clear schema description. The tool description adds no extra parameter detail, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Generate tests for a mobile app'), then differentiates from generate_locators explicitly and names typical sibling tools for the workflow. An agent can tell what it does and how it relates to adjacent tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives direct workflow: follow returned instructions, drive session with listed MCP tools, then emit code; also explicitly says when to use generate_locators vs appium_find_element. This is stronger than most – names alternatives and conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_geolocationA
Get, set, or reset the device geolocation (GPS coordinates). Works on both iOS (simulators and real devices) and Android (emulators and real devices with mock location enabled). Use action=get to read current coordinates, action=set with latitude/longitude (and optional altitude for Android) to simulate a location, or action=reset to restore the system default. Note: On Android emulators, reset is not supported — use action=set to manually restore coordinates instead. On Android real devices, the mocked location may persist until the GPS cache refreshes.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform. get: read the current device geolocation. set: set the device geolocation (requires latitude and longitude; optional altitude for Android). reset: reset the geolocation to the default/system value. Not supported on Android emulators — use action=set instead. | |
| altitude | No | Altitude value in meters. Android only, defaults to 0. Ignored on iOS. Used with: set. | |
| latitude | No | Latitude value (-90 to 90). Measurement of distance north or south of the Equator. Required for: set. | |
| longitude | No | Longitude value (-180 to 180). Measurement of distance east or west of the prime meridian. Required for: set. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
While the annotations only declare readOnlyHint=false and openWorldHint=false, the description adds useful behavior: platform support differences, reset unsupported on Android emulators, the suggestion to use set instead, and the note about mocked location persistence on Android real devices. This goes beyond what the annotations or schema communicate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is informative without padding; each sentence earns its place. The main action modes are front-loaded, followed by platform caveats. The structure flows logically from overview to usage to edge cases.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of an output schema, the description could have briefly stated the return shape for action=get, but 'read current coordinates' is reasonably indicative. It covers platform-specific behavior, action semantics, and limitations. The only minor gap is the exact output format for get operations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description repeats the action modes and mentions optional altitude, but it does not add substantial meaning beyond the schema's parameter descriptions. The schema already documents required-for-set, ranges, platform applicability, and defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-plus-resource statement: 'Get, set, or reset the device geolocation (GPS coordinates).' It clearly distinguishes this from other Appium control siblings by naming a unique resource and the three supported operations. The platform coverage statement further disambiguates the tool's scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit conditional guidance: use action=get to read, action=set to simulate, action=reset to restore, and explains when reset is not supported. It does not explicitly name alternative sibling tools, but the geolocation scope is distinctive enough that the intended usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_gestureA
Perform a touch gesture. Use 'action' to choose: tap, double_tap, long_press, scroll, swipe, pinch_zoom, scroll_to_element, back. Choose scroll vs swipe by intent: scroll to browse content in a list or feed; swipe to dismiss, switch screens, navigate carousels, or pull-to-refresh (speed=fast). For drag-and-drop use appium_drag_and_drop. For custom multi-touch use appium_perform_actions.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | X coordinate. For tap/double_tap/long_press: tap location (alternative to elementUUID). For scroll/swipe: starting X for custom-coordinate mode (requires y, endX, endY). For pinch_zoom: center X of the pinch. Requires y. Ignored if elementUUID is set. | |
| y | No | Y coordinate. For tap/double_tap/long_press: tap location. For scroll/swipe: starting Y for custom-coordinate mode. For pinch_zoom: center Y of the pinch. Requires x. Ignored if elementUUID is set. | |
| endX | No | Ending X coordinate. Used by: scroll, swipe (custom-coordinate mode). | |
| endY | No | Ending Y coordinate. Used by: scroll, swipe (custom-coordinate mode). | |
| scale | No | Pinch scale factor. < 1 = zoom out (pinch close), > 1 = zoom in (pinch open). Example: 0.5 = zoom out 50%, 2.0 = zoom in 2x. Required for: pinch_zoom. | |
| speed | No | Swipe speed. slow = deliberate drag; normal = default navigation speed; fast = flick with no hold, use for pull-to-refresh and other velocity-sensitive UIs. Used by: swipe. | |
| action | Yes | Gesture to perform. tap: tap an element or a coordinate. double_tap: trigger a double-tap action (e.g. zoom in on an image, favorite a post). long_press: press and hold to open a context menu or initiate drag. scroll: browse a list, feed, or page to reveal content. swipe: dismiss a card, switch screens or tabs, navigate a carousel, or pull-to-refresh (use speed=fast). pinch_zoom: zoom in (scale > 1) or out (scale < 1) on maps, images, or any zoomable view. scroll_to_element: scroll until a specific element is on screen (strategy + selector + direction up|down). Stops when the element is found, page source is unchanged after a scroll (end of scrollable content), or maxScrollAttempts is reached. Optional scrollDistance (0.05–1) or scrollDistancePreset (small|medium|large). back: triggers the system back navigation (e.g., Android back button or iOS navigation controller pop). | |
| duration | No | Duration in milliseconds. long_press default 2000 (range 500-10000). scroll default 800. For swipe, prefer the speed parameter; duration overrides it if both are provided. | |
| selector | No | Locator selector value. Required for: scroll_to_element. | |
| strategy | No | Locator strategy. Required for: scroll_to_element. Priority: accessibility id > id > platform-native (-ios predicate string / -ios class chain on iOS, -android uiautomator on Android) > xpath (LAST RESORT — slow on iOS XCUITest, brittle) > name > class name > css selector (webview only). Same ranking as appium_find_element. | |
| velocity | No | Pinch velocity in scale factor per second. Default 2.2. Used by: pinch_zoom. | |
| direction | No | Direction for scroll or swipe. Coordinates are auto-calculated from screen or element bounds. Either direction OR custom coordinates (x, y, endX, endY) must be provided for these actions. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| elementUUID | No | UUID of the element to act on. Used by: tap, double_tap, long_press, pinch_zoom. For scroll/swipe, when provided with direction, the gesture is calculated relative to this element instead of the whole screen. | |
| scrollDistance | No | scroll_to_element only: vertical swipe length as a fraction 0.05–1 (same scale as legacy scroll). Ignored when scrollDistancePreset is set. Default 0.45 if neither preset nor scrollDistance is set. | |
| maxScrollAttempts | No | scroll_to_element only: maximum scroll attempts after the element is not yet visible (default 10). | |
| scrollDistancePreset | No | scroll_to_element only: convenience preset — small ≈ light nudge (0.25), medium ≈ 0.45, large = full default swipe (1). When set, overrides scrollDistance. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only carry readOnlyHint=false and openWorldHint=false, so the description carries much of the disclosure burden. It adds useful context about scroll vs swipe intent and delegates drag-and-drop/multi-touch to siblings, but it does not describe side effects, return values, errors, or prerequisites such as session/element requirements. Most behavioral details live only in the schema parameter descriptions, not in the tool description itself.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tight sentences: purpose and action list first, then the scroll-vs-swipe decision rule, then sibling routing. No filler or repetition; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the high complexity of 17 parameters and no output schema, the definition is nearly complete because the schema descriptions are exhaustive and the tool description handles sibling discrimination. The only gap is that the description does not state what the tool returns or how failures are signaled, which would matter for an agent deciding how to handle the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 17 parameters in detail. The tool description adds selection guidance but no extra parameter semantics; it does not need to, since the schema fully covers this. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Perform') and resource ('touch gesture') and immediately lists the supported action variants. It also distinguishes itself from the sibling tools appium_drag_and_drop and appium_perform_actions, making its scope unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: 'Choose scroll vs swipe by intent' and gives concrete use cases for each. It also names alternatives directly: 'For drag-and-drop use appium_drag_and_drop. For custom multi-touch use appium_perform_actions.' This is exactly the routing an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_get_active_elementARead-only
Get the currently active/focused element and return its UUID for follow-up interactions. [PRIORITY 1: Use this first when you need to find what element currently has focus]
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already signals a safe read operation, and the description is consistent with it. Since there is no output schema, the explicit statement that it returns a UUID for follow-up interactions adds genuinely useful behavioral context beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences: the first states the core action and return value, the second adds a decision rule. No redundant wording or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-parameter read-on ly getter, the description covers what it returns and whe to use it. The only missing context is edge-case behavior when no element is active/focused, but this is a minor gap given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema fully describes the only parameter (sessionId, optional, with its own description), so the description does not need to add parameter-level detail. Baseline of 3 applies because schema coverage is 100%.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Get') with a clear resource ('currently active/focused element') and states the output ('its UUID for follow-up interactions'). This clearly distinguishes it from siblings like appium_find_element, which locates elements by criteria rather than returning the focused one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The PRIORITY 1 note gives an explicit condition for when to use this tool ('when you need to find what element currently has focus'). It does not name alternatives or state when not to use it, so it stops short of a full when/when-not guide.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_get_element_attributeARead-only
Get the value of an element attribute. Use this to check element state (enabled, selected, checked, focused, displayed, clickable) or read properties (name, value, label, content-desc, resource-id, class).
| Name | Required | Description | Default |
|---|---|---|---|
| attribute | Yes | The attribute name to retrieve. Common attributes: "enabled", "selected", "displayed", "checked", "focused", "clickable", "scrollable", "focusable", "name", "value", "label", "text", "content-desc", "resource-id", "class", "package". | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| elementUUID | Yes | Element ID from appium_find_element. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, so the read-only nature is covered. The description adds usage context but does not disclose behavioral details such as whether an invalid attribute returns null, empty string, or an error, nor any platform-specific quirks. This is acceptable but not richly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with no filler. The core operation is front-loaded, and the usage examples are immediately useful without unnecessary elaboration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only getter with fully described parameters and a clear annotation, the description and schema together provide sufficient context to call the tool. The main gap is the lack of explicit return/error behavior, but 'Get the value' conveys the core return semantic, making this near-complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by grouping attributes into state checks versus property reads, which helps the agent choose meaningful attribute names. It does not add meaningful new information about sessionId or elementUUID beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the operation as retrieving an element attribute value and provides concrete examples (enabled, selected, checked, content-desc, resource-id). This makes the purpose understandable and distinct from generic page-source or screenshot tools, though it does not explicitly distinguish it from the sibling appium_get_text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Use this to check element state... or read properties' gives explicit guidance on when to apply the tool. However, it does not mention alternatives or conditions when another tool like appium_get_text should be preferred, so it stops short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_get_page_sourceBRead-only
Get the page source (XML) from the current screen
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already signals safety, and the description adds that the result is XML and tied to the current screen. However, it does not disclose contextual behaviors such as whether the source can be large, whether accessibility data is included, or what happens when no session exists. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no filler: verb, object, format, and scope are all present. Given the simple schema, this is appropriately concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only operation with one optional parameter, the description and schema cover the essential call information. It identifies the return format as XML and the schema handles session targeting; no critical detail needed to invoke the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single optional sessionId parameter, and the schema already explains the active-session fallback. The description adds no parameter-specific meaning, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: 'Get the page source (XML) from the current screen.' It is unambiguous and easy for an agent to act on, though it does not explicitly differentiate itself from sibling tools that inspect UI content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to prefer this over alternatives like appium_get_text, appium_find_element, or appium_screenshot. There is also no mention of prerequisites such as an active session or when the full XML source is the appropriate choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_get_textCRead-only
Get text from an element
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| elementUUID | Yes | Element ID from appium_find_element. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true in annotations, the safety profile is already known. The description adds no behavioral context beyond the annotation - it doesn't explain return format, behavior on missing elements, or whether hidden text is included. Since the description adds nothing beyond the structured fields, it falls short of the baseline.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single clear sentence with no wasted words. It is efficient and front-loads the core action, though it could be expanded with useful context without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple getter with two parameters and readOnlyHint annotation, the description is minimally adequate. However, with no output schema, it fails to mention the return type (string) or any edge-case behavior, and it doesn't differentiate from get_element_attribute, leaving some ambiguity for an agent deciding how to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both sessionId and elementUUID documented. The description itself doesn't add parameter-level meaning, but the schema already explains that elementUUID comes from appium_find_element. Baseline 3 is appropriate because the schema carries the semantic weight.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Get text from an element' uses a specific verb and resource, clearly indicating the tool retrieves the text content of a UI element. It is distinguishable from siblings like appium_get_element_attribute and appium_get_active_element, though it doesn't explicitly state those distinctions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided about when to use this tool versus alternatives such as appium_get_element_attribute. The only implied usage is through the elementUUID parameter description referencing appium_find_element, but the tool description itself lacks any when-to-use or exclusion context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_get_window_sizeARead-only
Get the width and height of the device screen in pixels. Useful for calculating coordinates for swipes, taps, and scrolls.
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds the unit and use-case context but does not disclose return shape or orientation-dependent behavior; this is acceptable but not especially rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with the core action and result, followed by a practical use case. Every word earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has a single optional parameter documented in the schema, and the description explains what it returns (width and height in pixels) and why it is useful. It is nearly complete, though a note about orientation or return field names would make it fully self-contained without an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with the only parameter (sessionId) already explained as optional and falling back to the active session. The description adds no parameter-specific meaning, matching the baseline for fully documented schema parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves screen width and height in pixels, naming a specific resource ('device screen') and unit. It is readily distinguishable from gesture/coordinate tools, though it does not explicitly contrast with appium_mobile_device_info, which could also expose screen-related info.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: this is for calculating coordinates for swipes, taps, and scrolls. It does not mention exclusions or alternative tools, but for a simple read tool the intended use is easy to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_mobile_clipboardA
Read or set the device clipboard as plain text (Android UiAutomator2 / iOS XCUITest). action=get returns current text; action=set requires content.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | get: read device clipboard as plain text. set: write plain text to the clipboard. | |
| content | No | Required when action is set. Plain text to put on the clipboard. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the minimal annotations (readOnlyHint false, openWorldHint false), the description discloses the two operational modes and the dependency between action and content. It could add side-effect or error context, such as overwriting existing clipboard contents, but it still provides meaningful behavioral clarity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One compact sentence delivers the verb, resource, scope, platform support, and action-specific behavior without any filler. It is front-loaded and every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description plus the fully documented schema is enough for an agent to correctly invoke get or set. Some details are missing, such as return behavior nuances or failure conditions, but the tool is simple and the description covers the essential invocation logic.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters and the action/content dependency. The description reinforces these semantics but does not add new parameter-level meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Read or set') on a specific resource ('device clipboard as plain text') and names the supported platforms. This clearly differentiates it from sibling tools focused on elements, gestures, or device control.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear action-level guidance: use 'get' to read and 'set' to write, with content required for 'set'. It does not explicitly mention alternatives or exclusions, but no sibling tool appears to compete with clipboard functionality, so the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_mobile_device_controlB
Control device behavior: lock/unlock the screen, shake the device, or open the notifications panel. Use the action parameter to choose what to do.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform. lock: lock the device (optional seconds for timed lock). unlock: unlock the device. shake: perform shake gesture (iOS only). open_notifications: open notifications panel (Android only). | |
| seconds | No | Only for action=lock: lock duration in seconds before auto-unlock. Omit to remain locked until unlock. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate a mutating operation (readOnlyHint=false), and the description aligns by naming state-changing actions. It adds modest context by specifying screen lock/unlock and device shake, but it does not disclose platform restrictions, side effects, or session targeting behavior beyond what the schema already states.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler; the core action list is front-loaded and the action parameter guidance is relevant. It is appropriately compact, though 'Control device behavior' is slightly redundant with the listed actions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter action selector with no output schema, the description plus schema is adequate. Still, the description alone omits the lock-duration parameter and session targeting, and there is no behavioral detail about return values or effects, so it is not fully self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameter baseline is 3. The description's 'Use the action parameter to choose what to do' adds little beyond the schema's already detailed enum, and it does not mention the optional seconds or sessionId parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description enumerates four concrete device actions—lock/unlock the screen, shake, open notifications—which clarifies what the tool does. 'Control device behavior' is somewhat general, but the explicit list disambiguates it from most sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The action list implies when to use the tool: whenever the needed operation is lock, unlock, shake, or open_notifications. However, it does not explicitly contrast this with siblings like appium_gesture or appium_orientation, nor does it state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_mobile_device_infoARead-only
Get device information, battery status, or current device time in a single call. Use the "action" parameter to select which data to retrieve. Works on both iOS and Android.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform: "info" returns device model/OS/locale/etc., "battery" returns battery level and charging state, "time" returns the current device time. | |
| format | No | Only used when action is "time". moment.js format string for the returned time. Defaults to ISO 8601 (YYYY-MM-DDTHH:mm:ssZ). | |
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry the readOnlyHint=true safety profile, so the description only needs to add behavioral context, and it does add some: the 'single call' efficiency trait and the cross-platform scope ('Works on both iOS and Android'). However, it does not disclose edge behaviors like session requirements, error cases, or permission needs; these are not critical given the read-only profile but prevent a higher score.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with the core purpose front-loaded. The platform note ('Works on both iOS and Android') adds genuine value, while the action-parameter sentence is mildly redundant with the schema but still concise. No wasted words overall.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity read-only tool (one required param, no output schema), the package is complete: the description covers the purpose and platform scope, and the schema fully documents parameter semantics including return-value descriptions via the action enum. The only notable gap is the absence of sibling-selection guidance, which is already counted under usage guidelines.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents each parameter in detail, including the enum meanings for action ('info' returns device model/OS/locale/etc., 'battery' returns battery level and charging state, 'time' returns current device time) and the sessionId fallback behavior. The description's 'Use the action parameter' line merely restates the schema, adding no semantic value beyond the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Get') and resource ('device information, battery status, or current device time'), and explicitly enumerates the three retrievable data types. This clearly distinguishes it from siblings like appium_mobile_device_control and select_device, which cover control and selection rather than info retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than explicit: an agent can infer to use this when device info, battery, or time is needed, but there is no when-not-to-use guidance or alternative routing. The sentence 'Use the action parameter to select which data to retrieve' explains in-tool parameter behavior, not tool selection. With 30+ siblings, explicit exclusion guidance would have helped.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_mobile_fileA
Push or pull a file using Appium mobile extensions. action=push uses payloadBase64, action=pull returns contentBase64.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | push uploads a file to device; pull downloads from device. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| remotePath | Yes | Path to the file on the device. Android (UiAutomator2): use an absolute path (e.g. /data/local/tmp/foo.txt or /sdcard/Download/foo.txt). iOS (XCUITest): use the formats described in the Appium XCUITest file transfer guide (e.g. @com.example.app:documents/file.txt or simulator-relative paths). | |
| payloadBase64 | No | Required when action=push. Ignored when action=pull. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate the tool is not read-only (readOnlyHint=false) and has no open-world hint, so the description carries the burden of behavioral detail. It adds action-specific behavior: 'action=push uses payloadBase64, action=pull returns contentBase64.' This is useful but still does not describe side effects, failure modes, or limitations. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no filler. The core purpose is front-loaded, and the action-specific input/output behavior is summarized efficiently. Every clause carries useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the full parameter schema, including platform-specific remotePath guidance, the description is nearly complete for invoking correctly. It additionally supplies the missing output clue for pull ('returns contentBase64'). A minor gap is the lack of any note about push response/errors, but this does not seriously impair correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds no real parameter semantics beyond mentioning payloadBase64's role, which the schema already documents. remotePath and sessionId semantics are fully handled by the schema, not enhanced by the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair: 'Push or pull a file using Appium mobile extensions.' It then explicitly names the two actions ('push' and 'pull') and their data flow, making it easy to distinguish from sibling tools that handle gestures, clipboard, screenshots, or device controls.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied: if an agent needs to transfer a file to or from a device, this is the tool. However, the description does not explicitly state when to use it versus alternatives, nor does it mention prerequisites like having an active session or selecting a device, leaving some inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_mobile_keyboardA
Hide the software keyboard or check if it is visible (Android UiAutomator2 / iOS XCUITest). action=hide uses mobile: hideKeyboard; action=is_shown uses mobile: isKeyboardShown.
| Name | Required | Description | Default |
|---|---|---|---|
| keys | No | hide only: optional key names to dismiss the keyboard (e.g. "done"). Forwarded to mobile: hideKeyboard when non-empty. Ignored for is_shown. | |
| action | Yes | hide: dismiss the software keyboard (mobile: hideKeyboard). is_shown: whether the keyboard is visible (mobile: isKeyboardShown). | |
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the underlying protocol commands (mobile: hideKeyboard and mobile: isKeyboardShown), platform support, and the fact that keys are only honored for hide. This adds meaningful behavioral detail beyond the sparse annotations, though it does not mention error cases or return values.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. It front-loads the primary purpose and then compactly explains the two action modes, making it quick for an agent to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-action utility, the description plus the 100% schema coverage provides enough information to invoke the tool correctly. It lacks an explicit return type for is_shown, but the overall context is still sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents action, keys, and sessionId. The description mostly reinforces the schema rather than adding new semantic detail, which fits the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear, specific purpose: hide the software keyboard or check whether it is visible. It also names the two supported platforms and the underlying mobile commands, making it easy to distinguish from siblings like appium_mobile_press_key.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly maps each action value to its behavior and mobile command, giving the agent clear guidance on how to choose between hide and is_shown. It does not explicitly discuss when to prefer sibling tools, but the tool's purpose is distinct enough that the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_mobile_permissionsA
Get/update Android app permissions or iOS Simulator privacy services; reset iOS privacy prompts. See action-specific parameters.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | App ID; overrides name. Android defaults to the app under test; required for iOS get/update. | |
| name | No | App name resolved to an ID. Android defaults to the app under test; alternative to id for iOS get/update. | |
| access | No | iOS update only: map of access rule → yes|no|unset|limited (Simulator + AppleSimulatorUtils). Required for iOS update. | |
| action | Yes | get: list (Android) or read one privacy state (iOS Simulator). update: grant/revoke (Android) or set privacy map (iOS Simulator). reset: restore a privacy prompt for the app under test (iOS only). | |
| target | No | Android update: pm (default) or appops. | |
| service | No | iOS get: privacy service name (e.g. camera, microphone, photos). iOS reset: service name or numeric XCUIProtectedResource id. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| permissions | No | Android update only: permission name(s), `all` (with pm target), or appops names. Required for Android update. | |
| permissionFilter | No | Android get only: which bucket to return. Defaults to requested per UiAutomator2. | |
| permissionChangeAction | No | Android update: for pm target grant (default) or revoke; for appops allow, deny, ignore, default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide readOnlyHint=false, so the description carries the burden of behavioral disclosure. It discloses that 'reset' affects iOS privacy prompts and that 'update' modifies permissions, but it does not specify side effects, requirements (e.g., simulator must be booted), whether changes persist, or what happens to existing settings. The description adds some context beyond the annotations but omits important behavioral details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one efficient sentence that front-loads the core verbs and resources, then points to the schema for details. Every clause carries meaning; there is no filler or redundancy. The structure is ideal for a tool with a rich schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (10 parameters, nested objects) and the absence of an output schema, the description alone is not enough to fully understand invocation. However, the schema descriptions fill most gaps. The main missing context is return values and side effects, neither of which is covered by the description or an output schema. The 'See action-specific parameters' hint guides the agent to the schema, but the description does not stand alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already explained in the input schema. The description adds only a pointer ('See action-specific parameters'), which is useful but does not enhance the parameters' meaning beyond what the schema provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific verbs 'Get/update' and 'reset' against concrete resources ('Android app permissions', 'iOS Simulator privacy services', 'iOS privacy prompts'), and scopes the platform split. This is a clear verb+resource statement that differentiates the tool from sibling tools like appium_mobile_device_control or appium_driver_settings, which do not mention permissions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use cases by stating the platforms and actions but does not explicitly route to an alternative or state when not to use it. It only points to 'action-specific parameters' in the schema. There are no exclusionary clauses or named alternatives among the siblings, so usage is inferred rather than directly guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_mobile_press_keyB
Press navigation keys (BACK, HOME, APP_SWITCH) on Android or physical buttons (HOME, volume, etc.) on iOS/tvOS.
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | Logical key/button to press. On Android: BACK, HOME, APP_SWITCH. On iOS/tvOS: HOME, VOLUME_UP, VOLUME_DOWN, UP, DOWN, LEFT, RIGHT, MENU, PLAY_PAUSE, SELECT. | |
| keyCode | No | Android keycode to press. If provided, takes precedence over key for Android. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| isLongPress | No | Android only. Whether to perform a long press. Defaults to false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral context beyond the readOnlyHint=false annotation by specifying platform-specific key support (Android vs iOS/tvOS). However, it does not disclose side effects, error behavior, or precedence rules (e.g., keyCode overrides key), though some of those are present in the schema. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence with no filler. It front-loads the core action and immediately gives useful platform distinctions, making efficient use of every word.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a relatively simple action tool with full schema coverage of parameters and no output schema, the description sufficiently states the purpose and platform behavior. It lacks explicit alternative routing, but the core information an agent needs to invoke the tool is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already explains all four parameters. The description adds no parameter-specific meaning beyond the platform mapping already present in the key field's enum description, so a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Press') and names the resource ('navigation keys', 'physical buttons'), and it clarifies platform differences. It distinguishes itself from likely siblings like appium_gesture or appium_mobile_keyboard by focusing on hardware/navigation keys, though it does not explicitly name an alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance about when to use this tool versus alternatives such as appium_mobile_keyboard or appium_gesture. The description states what the tool does but gives no explicit when/when-not context or comparison with sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_orientationA
Get or set the device/screen orientation. Supports action=get and action=set (LANDSCAPE or PORTRAIT).
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Use get to read current orientation, set to change orientation. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| orientation | No | Required when action is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description openly indicates both a read operation (get) and a mutating operation (set), which aligns with readOnlyHint=false. It also communicates the allowed orientation values. While it does not go deep into side effects or failure modes, the behavior is clear enough for this simple tool and the annotations already signal mutability.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with the primary action front-loaded. It conveys the tool's purpose and supported values with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple three-parameter tool with a complete schema, the description covers the essential behavior and valid actions. The only minor gap is that no return value format is described, but the absence of an output schema and the straightforward nature of orientation get/set reduce the importance of that omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters (action, sessionId, orientation) are already documented in the schema. The description adds no significant parameter meaning beyond restating the action values, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb (get or set) and the resource (device/screen orientation), and explicitly lists the supported action values. It is immediately distinguishable from sibling tools like appium_get_window_size or appium_mobile_device_control because the resource is named precisely.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: use this tool when you need to read or change the device/screen orientation. It does not explicitly name alternatives or exclusion cases, but the narrow scope and explicit action values make the intended usage unmistakable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_perform_actionsA
Execute raw W3C Actions API sequences for advanced multi-touch gestures not covered by appium_gesture. Use this for custom multi-finger gestures (rotate, three-finger swipe, edge swipes), complex timing sequences, or any gesture requiring precise control over individual touch points. Prefer appium_gesture for standard gestures (tap, scroll, swipe, pinch) — it handles platform differences automatically.
| Name | Required | Description | Default |
|---|---|---|---|
| actions | Yes | W3C Actions API input source array. Each entry is one input source (pointer/key/none) with its action sequence. Multiple pointer sources enable multi-touch gestures (e.g. two-finger rotate, three-finger swipe). All sources execute in parallel, synchronized tick-by-tick. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate the tool is not read-only, and the description conveys that it executes raw action sequences with side effects. It does not add much behavioral context beyond that, such as potential device-state changes or return behavior, though the raw API framing makes the mutating nature clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, zero filler, with the core purpose front-loaded and the routing instruction placed clearly at the end. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a raw API tool, the description plus a fully documented schema gives an agent enough to invoke it correctly. The main gap is that it does not describe what kind of result or acknowledgement the raw API returns, but the absence of an output schema makes that a minor omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with thorough documentation for input sources, action types, coordinates, durations, and origin. The description contributes gesture-level context but does not need to explain individual parameters because the schema already carries the full semantic load; baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause states a specific verb and resource ('Execute raw W3C Actions API sequences') and immediately differentiates it from appium_gesture. Concrete use cases are listed, so an agent can clearly tell this is for advanced, custom multi-touch gestures rather than standard ones.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: custom multi-finger gestures, complex timing sequences, or precise control over touch points. It also explicitly tells the agent to prefer appium_gesture for standard gestures because it handles platform differences automatically.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_prepare_ios_real_deviceA
Prepare an iOS real device for Appium testing in a single call. Two-mode flow: (1) Call without provisioningProfileUuid to receive the list of available .mobileprovision profiles — present them to the user (highlight any with recommendedForWda=true) and ask them to pick one. (2) Call again with the chosen UUID to download the matching WebDriverAgent release, package it as an IPA, and resign it with the chosen profile (wildcard "*" profiles are supported — a concrete WDA bundle ID is substituted at sign time). WDA download and unsigned IPA are cached per WDA version; the signed IPA is rebuilt every call. Pass the returned capabilitiesHint to appium_session_management (action=create) so Appium installs and launches the signed prebuilt WDA instead of rebuilding. Requires macOS, Xcode 16+, and a paired developer-mode device.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | UDID of the connected iOS real device. Use select_device to discover it. | |
| forceRebuild | No | If true, ignore the cached WDA download and unsigned IPA and start clean. The signed IPA is always rebuilt regardless. Default: false. | |
| provisioningProfileUuid | No | UUID of the .mobileprovision profile to sign WDA with. If omitted, the tool returns the list of available profiles so you can ask the user to pick one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are minimal (readOnlyHint=false, openWorldHint=false), leaving the description to carry the burden — and it delivers. It discloses cache semantics (WDA download and unsigned IPA cached per version, signed IPA rebuilt every call), mode-dependent side effects (list-only vs download/package/resign), wildcard profile handling with bundle ID substitution at sign time, and the external toolchain requirements. Nothing here contradicts readOnlyHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Longer than a typical tool description, but the tool genuinely warrants it — a two-mode flow, caching behavior, signing mechanics, and a cross-tool handoff all need explaining. The purpose is front-loaded, the modes are numbered for easy parsing, and every sentence (prerequisites, cache rules, capabilitiesHint routing) carries information without repeating the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and sparse annotations, the description compensates well: it states what mode 1 returns (profile list with recommendedForWda flags), what mode 2 returns (capabilitiesHint), the prerequisites, and the downstream call. The residual gaps are the full response envelope shape and failure cases (e.g., no profiles found, device not paired), which an output schema would normally cover.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, which sets a baseline of 3, but the description adds meaning above the schema: it explains the two-mode flow keyed to provisioningProfileUuid presence, the wildcard ('*') profile substitution detail, and how forceRebuild interacts with the per-version cache of the WDA download and unsigned IPA. It also clarifies the capabilitiesHint output contract that connects to session creation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource statement — 'Prepare an iOS real device for Appium testing in a single call' — then details a concrete two-mode mechanism, so there is no ambiguity about what the tool accomplishes. It is clearly distinguished from siblings: appium_session_management is positioned as the downstream consumer of capabilitiesHint, select_device is referenced for UDID discovery, and the real-device provisioning focus sets it apart from prepare_ios_simulator.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit usage sequence: first call without provisioningProfileUuid to obtain the profile list, present it to the user, then call again with the chosen UUID. It also states hard prerequisites (macOS, Xcode 16+, paired developer-mode device) and routes the output to appium_session_management with action=create. It does not explicitly name when-not cases or alternatives, so it misses the top of the scale.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_screen_recordingA
Start or stop screen recording. action=start begins recording; action=stop stops and saves to MP4.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | start begins recording; stop ends, retrieves, and saves it. | |
| bitRate | No | Android only. Video bit rate in bits per second. | |
| videoFps | No | iOS only. Frames per second. Default: 10. | |
| bugReport | No | Android only. Display timestamp overlay. Requires API level 27+. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| timeLimit | No | Recorder limit in seconds; it does not retrieve/save automatically, so call stop. iOS default 180/max 4200; Android default 180/max 1800. | |
| videoSize | No | Android only. Frame size in WIDTHxHEIGHT format (e.g. 1280x720). | |
| videoType | No | iOS only. Video codec to use (e.g. libx264). | |
| videoScale | No | iOS only. Scaling value (e.g. 1280:720). | |
| pixelFormat | No | iOS only. Output pixel format (e.g. yuv420p). | |
| forceRestart | No | Restart and discard any active recording; default false. | |
| videoFilters | No | iOS only. FFMPEG video filters. Takes precedence over videoScale. | |
| videoQuality | No | iOS only. Video quality preset. Default: medium. | |
| hardwareAcceleration | No | iOS only. FFMPEG hardware acceleration backend. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate non-read-only, so the description carries the burden of explaining the mutation. It adds meaningful behavioral detail: 'action=start begins recording; action=stop stops and saves to MP4.' This goes beyond the annotation by specifying the two-phase lifecycle and the save-on-stop behavior, which is essential for correct invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The purpose is front-loaded and the action mapping is immediately clear. Every word contributes to understanding the tool's core function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (14 parameters) and rich per-parameter schema descriptions, the concise description is largely sufficient. It captures the key start/stop workflow and MP4 output. Minor missing high-level context, such as the need to call stop even after timeLimit, is already explained in the schema parameter description, so the description does not need to duplicate it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The main description merely repeats the action enum and its meaning already present in the schema; it does not add semantics for the other 13 parameters. No extra value beyond the detailed property descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Start or stop screen recording.' It clearly identifies the two supported actions (start/stop) and the output format (MP4). This distinguishes it from siblings like appium_screenshot, since screen recording is a distinct video-capture operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool: when you need to begin or end a screen recording. However, it gives no explicit guidance about when not to use it or which sibling alternative to choose (e.g., appium_screenshot for still images). The usage context is clear but not oriented against other tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_screenshotB
Take a screenshot and save as PNG. Optionally provide elementUUID to capture only that element.
| Name | Required | Description | Default |
|---|---|---|---|
| maxWidth | No | Optional maximum width in pixels to resize the screenshot. The aspect ratio is preserved. Useful for reducing token usage when sending screenshots to LLMs. | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| elementUUID | No | Optional element UUID. If provided, captures only this element. If omitted, captures full screen. | |
| returnRawBase64 | No | When true, returns the raw base64-encoded PNG image instead of saving it to disk. This should only be enabled when a human explicitly invokes the tool manually, typically to view the screenshot on a different machine (e.g. when the server runs on a remote machine and the saved file is not accessible). An LLM must always keep this false and rely on the saved file path. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses a meaningful side effect: the screenshot is saved as a PNG file, which is useful given readOnlyHint=false. However, it does not say where the file is saved, what response shape to expect, or how returnRawBase64 changes the behavior beyond what the schema already states. Some behavioral context is present but incomplete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded: the main action and output format appear first, followed by a single optional-behavior sentence. There is no redundant wording or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple zero-required-parameter tool, and the input schema richly documents all parameters including the LLM-specific returnRawBase64 guidance. The description could have stated the returned file path contract explicitly, but the schema's reference to 'saved file path' plus the 'save as PNG' side effect make it sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters are already documented. The description adds only a simple restatement of elementUUID's optional capture behavior, which provides marginal value beyond the schema but does not introduce any new parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Take a screenshot') and the output format ('save as PNG'), and it mentions the optional element-scoped capture mode. It does not explicitly differentiate from sibling appium_screen_recording or other capture tools, but the core purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to prefer this tool over alternatives such as appium_screen_recording, nor does it mention exclusions or prerequisites. The only usage hint is the optional elementUUID behavior, which is more of a parameter detail than a tool-selection guideline.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_session_managementBDestructive
Manage Appium sessions. Use action=create to start a session, attach to connect to an existing one, detach to forget an attached session, delete to stop one, list to see all active sessions, or select to switch the active session.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform. create: Create a new Appium session with Android, iOS or any device/driver Appium supports. DEFAULT MODE (no remoteServerUrl) — USE THIS UNLESS THE USER EXPLICITLY PROVIDES A SERVER URL: - Drivers run embedded inside this MCP server; no separate Appium process is needed - Use select_device tool FIRST to discover devices and let the user choose platform and device - Then call action=create with the selected platform (do NOT pass remoteServerUrl) - For iOS simulators, call prepare_ios_simulator before action=create - DO NOT assume or default to any platform - NEVER invent a localhost URL (e.g. http://localhost:4723) — omitting remoteServerUrl IS the local/embedded mode REMOTE SERVER MODE (only when user explicitly provides a URL like http://localhost:4723): - SKIP select_device tool entirely - Infer the platform from the user's request (e.g., 'ios', 'android', or 'general') - If platform is 'general', treat the provided capabilities as a pass-through W3C/Appium capability set (useful for non-Android/iOS drivers like Windows, macOS, or custom drivers) - Infer device type from context when possible (e.g., 'simulator', 'real device') - Call session with action=create directly with platform, remoteServerUrl, and any other capabilities from the user's request - Example: User says 'start session with http://localhost:4723 for ios with iphone 17' → infer platform='ios' and call session(action=create) with remoteServerUrl and platform parametersattach: Attach MCP Appium to an existing remote Appium session without taking ownership of its lifecycle. Requires remoteServerUrl and sessionId. Always pass capabilities with at least platformName (e.g. '{"platformName":"iOS"}' or '{"platformName":"Android"}') so the client is configured with the correct protocol commands.detach: Remove an attached Appium session from MCP Appium without deleting the real remote session. Defaults to the active session.delete: Delete a mobile session and clean up resources. If sessionId is omitted, deletes the active session.list: List all active Appium sessions managed by this MCP server, including active flag, ownership, and current context.select: Set an existing Appium session as the active session for subsequent tool calls (requires sessionId). | |
| platform | No | Required for create. For local servers, must match the platform selected via select_device. Use "general" for non-Android/iOS drivers (Windows, macOS, custom). For remote servers, infer from context. | |
| sessionId | No | For attach: existing session to connect to. For delete: session to remove (defaults to active). For detach: attached session to remove from MCP (defaults to active). For select: session to activate. Required for attach and select. | |
| capabilities | No | Optional W3C capabilities for create. Provide as a JSON string (e.g. '{"appium:app":"/path/to/app","appium:platformVersion":"17.0"}'). For create: applied on top of defaults for ios/android, or used as-is for general. Common: appium:app, appium:deviceName, appium:platformVersion, appium:bundleId. When passing from a capabilitiesHint result, serialize the full object to JSON — do NOT drop boolean or numeric values. For attach: always include platformName ("iOS" or "Android") so the WebDriver client loads the correct Appium protocol commands (e.g. '{"platformName":"iOS"}'). | |
| remoteServerUrl | No | Remote Appium server URL for create or attach (e.g. http://localhost:4723). Omit to use local server for create. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=false and destructiveHint=true, so the agent knows this tool can mutate state. The description adds a small behavioral distinction between detach ('forget') and delete ('stop'), which is useful. However, it does not disclose important traits such as attach not taking ownership of the remote session lifecycle or detach leaving the real remote session intact—details that would prevent misuse and are only found in the parameter schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the general purpose and enumerates all actions without filler. It is compact and easily scannable. It is slightly run-on, but every clause earns its place, so the efficiency is strong.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a multi-action tool with five parameters, the full definition is quite complete: the action parameter description covers local vs remote modes, prerequisites (select_device, prepare_ios_simulator), explicit prohibitions ('NEVER invent a localhost URL'), and examples. The tool description alone is thin, but the schema richness compensates. The absence of an output schema is partially mitigated by the list action describing its returned fields, though create/select return shapes are not described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The complete parameter descriptions in the schema (modes, examples, JSON serialization, required capabilities for attach) already carry the full semantic load. The tool description itself does not add parameter meaning, but given the high coverage, no further description contribution is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (Appium sessions) and lists six concrete actions (create, attach, detach, delete, list, select), so the tool's scope is clear and visibly distinct from device-control, element, and file siblings. The verb 'Manage' is generic, but the action enumeration compensates and gives the agent a precise idea of what the tool does. It does not explicitly name an alternative sibling, so a 5 is not warranted.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus siblings like select_device, prepare_ios_simulator, or the appium_* device-control tools. It only implies that session management is its job. Although the action=create parameter description later provides rich workflow rules (e.g., 'Use select_device tool FIRST', 'SKIP select_device tool entirely'), that guidance is not in the tool description itself, and the description carries no exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_set_valueC
Enter text into an element
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The text to enter | |
| sessionId | No | Session ID to target. If omitted, uses the active session. | |
| w3cActions | No | When true, type text via the W3C Actions API (performActions) instead of the driver-specific setValue. No elementUUID needed — key events are sent to whatever element currently has focus. Works on both Android and iOS. | |
| elementUUID | No | Element ID from appium_find_element. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate a non-read-only action, and the description adds little behavioral detail. It does not disclose whether text replaces existing content, whether the element must have focus, whether automation must wait for visibility, or how failures behave. Some useful behavior appears in the w3cActions parameter description, but not in the tool description itself.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with a clear verb and object. There is no filler or redundant information, making it highly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although the schema documents parameters well, the tool lacks usage context, preconditions, and sibling differentiation. Given the large set of related Appium input and action tools, an agent could easily call the wrong one without additional guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage with descriptive entries for all four parameters, including the detailed w3cActions flag. The description itself adds no parameter-level meaning, but this is acceptable because the schema already carries that burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Enter text') and the resource ('an element'), so an agent can tell that this is a text-input operation. However, it does not differentiate it from sibling input tools like appium_mobile_keyboard or appium_perform_actions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance about when to use this tool instead of related tools such as appium_mobile_keyboard, appium_mobile_press_key, or appium_perform_actions. The description implies text entry but provides no conditions, prerequisites, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_locatorsARead-only
Generate locators for all interactable elements on the current page. [PRIORITY 3: Use this for debugging/inspection or when you need comprehensive element info with locator suggestions]
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | No | Session ID to target. If omitted, uses the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and not open-world. The description adds useful scoping context ('current page', 'all interactable elements') but does not disclose details like output structure, failure behavior, or performance characteristics. There is no contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the core purpose comes first, followed by a concise usage hint. Every part contributes actionable information without unnecessary filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is low-complexity: one optional, fully documented parameter, read-only annotations, and no nested schema. The description covers purpose and when to use it. It could describe the exact return format more explicitly, but for a debugging/inspection tool this is largely sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one parameter, sessionId, and the schema description fully explains it: 'Session ID to target. If omitted, uses the active session.' With 100% schema coverage, the description does not need to add parameter-level meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Generate locators for all interactable elements on the current page.' It clearly conveys what the tool does and the output type (locators + element info). It does not explicitly distinguish itself from sibling tools like appium_find_element, but the 'all interactable elements' scope is reasonably distinctive.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The bracketed note explicitly gives usage context: 'Use this for debugging/inspection or when you need comprehensive element info with locator suggestions.' This is clear and actionable, though it does not mention when not to use the tool or name alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepare_ios_simulatorA
Prepare an iOS/tvOS simulator for Appium testing in a single call. Automatically boots the simulator, downloads prebuilt WDA (if not cached), and installs/launches WDA on a free per-simulator port (so multiple simulators can run in parallel without colliding on the default 8100). Pass the returned capabilitiesHint (appium:webDriverAgentUrl) to appium_session_management (action=create) so the session reuses this running WDA instead of trying to start its own. Use skipWda=true to only boot without WDA. Set APPIUM_MCP_WDA_APP_PATH to an absolute path to a pre-extracted WebDriverAgentRunner-Runner.app to skip download entirely (useful in environments where external downloads are blocked).
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | The UDID of the iOS simulator to prepare. Use select_device to get this. | |
| skipWda | No | If true, only boot the simulator without downloading or installing WDA. Default: false. | |
| platform | No | The simulator platform to download WDA for. Default is "ios". Use "tvos" for Apple TV simulators. | ios |
| forceRefreshWda | No | If true, re-download WDA even if already cached. Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the sparse annotations, the description reveals that the tool boots simulators, downloads prebuilt WDA when not cached, installs/launches it on a per-simulator free port to avoid 8100 collisions, and can skip WDA via flags or env var. The side-effecting nature is consistent with readOnlyHint=false, and no statement contradicts openWorldHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence delivers distinct information: the one-line purpose, the behavioral/parallelism detail, the downstream session hand-off, the skip-WDA switch, and the env-var fallback. It is dense but not bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description still tells the agent what the tool returns (capabilitiesHint containing appium:webDriverAgentUrl) and how to consume it. It also covers the boot/no-WDA/offline-download cases an agent is likely to need, making the description sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all four parameters (100% coverage), so the description's job is additive. It adds practical context for skipWda=true (boot-only mode) and introduces the APPIUM_MCP_WDA_APP_PATH environment variable, which is absent from the schema but materially affects download behavior. Platform and forceRefreshWda are not expanded beyond schema, so a 4 rather than 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Prepare') and resource ('iOS/tvOS simulator'), and states the intended outcome ('for Appium testing in a single call'). It also names concrete actions (boots, downloads, installs/launches WDA) that distinguish it from session management and real-device preparation siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly provides workflow guidance: the returned capabilitiesHint should be passed to appium_session_management(action=create) to reuse WDA rather than start a new one. It also gives conditional usage for skipWda=true and APPIUM_MCP_WDA_APP_PATH, including the environment where downloads are blocked.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
select_deviceA
Discover and select a device for LOCAL Appium servers ONLY. DO NOT use this tool for REMOTE Appium servers - remoteServerUrl indicates a remote server. WORKFLOW FOR LOCAL SERVERS: 1. ASK THE USER which platform they want (Android or iOS) - do not assume 2. Call this tool with the chosen platform (and iosDeviceType for iOS) 3. If only one device is found, it is auto-selected - proceed to appium_session_management (action=create) (or prepare_ios_simulator for iOS simulators) 4. If multiple devices are found, ask the user which one they want, then call this tool again with deviceUdid 5. After selection, proceed to appium_session_management (action=create) (or prepare_ios_simulator for iOS simulators, then appium_session_management with action=create) WORKFLOW FOR REMOTE SERVERS: - SKIP this tool entirely - Device selection should be handled via capabilities on appium_session_management (action=create) (e.g., appium:deviceName, appium:udid) - The remote Appium server is already configured for specific device(s)
| Name | Required | Description | Default |
|---|---|---|---|
| platform | Yes | The platform to list devices for (must match previously selected platform) | |
| deviceUdid | No | The UDID of the device selected by the user. If not provided, this tool will list available devices for the user to choose from. | |
| iosDeviceType | No | For iOS only: Specify whether to use 'simulator' or 'real' device. REQUIRED when platform is 'ios'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are minimal (readOnlyHint false, openWorldHint false), so the description carries the behavioral burden. It discloses key traits: the tool auto-selects when only one device is found, requires a second call with deviceUdid when multiple are found, and must not be used for remote servers. It does not explicitly describe the return format or what happens if no devices are found, but the workflow is otherwise transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average, but highly structured with clear workflow numbering and front-loaded local/remote distinction. Minor redundancy exists in repeated references to appium_session_management (action=create) and prepare_ios_simulator, but these repetitions reinforce the handoff rather than adding noise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema, the description covers nearly everything an agent needs: local vs remote handling, user-asking requirements, auto-selection behavior, re-call semantics, and follow-up steps. It is slightly incomplete in not describing the tool's response shape or fallback behavior when zero devices are found, but those are secondary given the explicit workflow.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents each parameter. The description adds meaningful usage sequencing: call first with just platform (and iosDeviceType for iOS), then call again with deviceUdid if multiple devices are found. It also reinforces that iosDeviceType is required for iOS, going slightly beyond the static schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's specific purpose: 'Discover and select a device for LOCAL Appium servers ONLY.' It explicitly distinguishes the tool from remote-server workflows and names sibling tools like appium_session_management and prepare_ios_simulator, so an agent can reliably tell when to use it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is exceptionally well specified. It says 'DO NOT use this tool for REMOTE Appium servers' and gives the exact alternative ('handled via capabilities on appium_session_management'). The numbered local workflow tells the agent when to call, when to ask the user, when to re-call with deviceUdid, and what to do next.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
31 tool updates
v1.92.11- First observed
appium_alert - First observed
appium_app_lifecycle - First observed
appium_context - First observed
appium_drag_and_drop - First observed
appium_driver_settings - First observed
appium_find_element - First observed
appium_generate_tests - First observed
appium_geolocation - First observed
appium_gesture - First observed
appium_get_active_element - First observed
appium_get_element_attribute - First observed
appium_get_page_source - First observed
appium_get_text - First observed
appium_get_window_size - First observed
appium_mobile_clipboard - First observed
appium_mobile_device_control - First observed
appium_mobile_device_info - First observed
appium_mobile_file - First observed
appium_mobile_keyboard - First observed
appium_mobile_permissions - First observed
appium_mobile_press_key - First observed
appium_orientation - First observed
appium_perform_actions - First observed
appium_prepare_ios_real_device - First observed
appium_screen_recording - First observed
appium_screenshot - First observed
appium_session_management - First observed
appium_set_value - First observed
generate_locators - First observed
prepare_ios_simulator - First observed
select_device
TDQS
Most tools map cleanly to distinct Appium capabilities, and potentially overlapping gesture tools are explicitly differentiated. The main ambiguity comes from broad action-param tools like appium_session_management and appium_app_lifecycle, plus appium_find_element's reference to an appium_ai tool that isn't in the exposed set.
The appium_ prefix and snake_case convention are consistent, and verb-first names like get_*, set_*, and perform_actions are recognizable. However, many names are noun-phrases such as appium_geolocation, appium_mobile_device_info, and appium_app_lifecycle, mixed with imperative verbs like select_device and prepare_ios_simulator, so no single verb_noun pattern dominates.
At 31 tools, this is larger than the ideal 3-15 range and heavier than most focused MCP servers. The broad Appium mobile automation domain justifies much of the surface, but some consolidation or culling would tighten the set.
The tool set covers session management, device preparation, element interaction, gestures, app lifecycle, permissions, context, recording, and app lifecycle, so core workflows are thoroughly supported. It isn't perfect: appium_find_element points users to an appium_ai tool that isn't actually exposed, and a few niche Appium extensions are missing.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Control real Android and iOS devices with LLM agents — tap, swipe, type, automate flows.
Drive real Android & iOS devices and web browsers from natural language for mobile + web QA. 290+ tools across device control, app management, automation sessions, browser automation, and flow recording / replay. Bearer-auth — get a token at robotactions.com → Profile → API Tokens.
Cloud iOS simulators and Android emulators your agent can create, drive, and throw away.
Give your AI agents the tools to build, manage, and run automation workflows.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceEnables AI-powered mobile app testing and automation through Appium, using Azure OpenAI to intelligently navigate mobile applications and generate test cases.-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to automate Android mobile device testing through Appium, with automatic device detection, screen element inspection, and natural language test scenario execution.3MIT
- AlicenseNot gradedqualityDmaintenanceEnables comprehensive control of iOS simulators and real devices through AI assistants, supporting app management, UI automation, screenshots, media operations, and location simulation for iOS development and testing workflows.6MIT
- AlicenseAqualityBmaintenanceEnables AI assistants to control mobile and desktop devices with natural language, including running automation tasks, taking screenshots, and managing devices.65MIT
Appeared in Searches
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/appium/appium-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server