MCP Appium
Enables automation and testing of Android applications and devices using UiAutomator2, including creating sessions, interacting with UI elements, capturing screenshots, and generating test code.
Provides mobile automation capabilities through Appium, including session management, AI-powered element finding, UI interactions, screenshots, locator generation, and automated test creation for mobile apps.
Enables automation and testing of iOS applications, simulators, and real devices using XCUITest, including managing sessions, interacting with UI elements, capturing screenshots, and generating test code.
Click on "Deploy 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 AppiumLaunch the Android app and tap the login button"
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.
HTTP transport security
The --httpStream transport rejects MCP requests containing an Origin header
by default and disables CORS. To allow a trusted browser client, set a
comma-separated list of exact origins before starting the server:
APPIUM_MCP_ALLOWED_ORIGINS='https://inspector.example.com,http://localhost:3000' appium-mcp --httpStreamOrigins must use http or https and contain only scheme://host[:port].
Paths (including a trailing slash), credentials, wildcards and null are not
accepted; invalid configuration fails startup. Matching is exact, including
scheme and port. Unlisted, empty and opaque (null) origins receive HTTP 403
on MCP requests, even with an existing session. Preflight responses only grant
CORS access to listed origins. Browser cookies are not enabled by this setting.
The allowlist is captured when the server is constructed. It applies to both
the CLI and createAppiumMcpServer; the raw httpStream.cors option cannot
override it. Unset or empty configuration grants no browser access.
Clients that omit Origin, and stdio clients, continue to work. Origin validation
is not client authentication: non-browser clients can omit or forge this header.
Keep the HTTP listener on loopback; deployments exposed to other machines need
authentication and network access controls.
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 system temp directory ( |
| Optional | Directory for fresh XML snapshots when |
| 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 |
| Optional | Comma-separated list of exact HTTP(S) origins allowed to access the HTTP transport from browser clients (e.g. |
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 valid HTTP(S) server URL is accepted. This checks the supplied URL only, not destinations selected by the WebDriver client from server responses. See Remote server security and trust model. |
REMOTE_SERVER_ENABLE_DIRECT_CONNECT | Optional |
|
ALLOW_REMOTE_APP_URLS | Optional |
|
| 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 | Trace export protocol: |
| Optional | Trace-specific protocol; overrides |
| Optional | Traces endpoint. HTTP/JSON: |
| Optional | Trace sampling strategy; |
| Optional | Comma-separated |
REMOTE_SERVER_ENABLE_DIRECT_CONNECT and ALLOW_REMOTE_APP_URLS preserve existing behavior
when unset. Values are case-insensitive and may contain surrounding whitespace; other values
(including an empty string) fail server startup. They are operator-controlled environment
settings, not MCP tool arguments.
URL-based app installation is an intentional Appium feature. For embedded sessions it downloads
on the MCP host; for remote sessions it downloads on the remote Appium server. Disabling
ALLOW_REMOTE_APP_URLS limits these app inputs, not all host network access or all driver
capabilities that may use the network. When URL installation is enabled, redirect handling,
download size limits, and cache management remain the responsibility of the Appium downloader
and deployment controls. The app lifecycle tool uses openWorldHint: true because its operations
can interact with external services.
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_onThe default remains OTLP HTTP/JSON. To use OTLP/gRPC with TLS:
APPIUM_MCP_OTEL_ENABLED=true \
OTEL_SERVICE_NAME=appium-mcp \
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=grpc \
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://collector.example.com:443 \
npm run start:stdioFor a local gRPC collector without TLS, use http://127.0.0.1:4317. gRPC endpoints must not include
/v1/traces; HTTP/JSON trace endpoints should include that path (or the receiver's configured path).
Both exporters accept https:// for TLS. The receiver must support the selected protocol and encoding.
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL takes precedence over OTEL_EXPORTER_OTLP_PROTOCOL; empty values
are treated as unset. Unsupported protocols, including http/protobuf, produce an initialization error
when tracing is enabled. Endpoint, headers, timeout, and TLS configuration are handled by the selected
OpenTelemetry exporter. For example, use OTEL_EXPORTER_OTLP_TRACES_HEADERS for authentication metadata,
and OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE for a custom gRPC CA certificate file.
See the OpenTelemetry environment variable documentation and gRPC exporter documentation.
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 system temp directory (os.tmpdir()). 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".
For iOS, videoScale accepts width:height with dimensions from 1 to 16384 (for example, 1280:720). One dimension may be -1 or -2 to preserve the aspect ratio; -2 also makes that dimension divisible by two. Scaling expressions and custom videoFilters are no longer supported by this MCP tool.
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.
In the Page Source Inspector, Search highlights matching text in the displayed XML. Press Enter to jump to the next match or Shift+Enter for the previous match; navigation wraps and keeps the full XML visible. The match counter shows your current position.
Enter text in Search and click Find locators to generate candidates for
matching elements. Search uses a case-insensitive literal substring of element types and attribute values
(such as name, label, text, and resource ID), including hidden elements and types such as iOS icons.
Generation fetches fresh XML from the device; the XML already displayed remains unchanged. An empty search
keeps the default driver-specific filter. UiAutomator2 and XCUITest native sessions use their mobile
control filters; Web contexts use HTML control filters. Other native drivers include XML elements
without requiring mobile tag names or clickable/focusable attributes (the hierarchy wrapper remains
excluded). The same search is available directly with
generate_locators({query: "Calendar"}).
Use Preferred XPath attributes in Locator Candidates to enter additional attribute names, separated
by commas (for example AutomationId, data-testid). XPath generation tries them in the specified order
before the built-in attributes, retaining the existing uniqueness checks and fallbacks. This changes
XPath candidate generation, not which elements are included. Leave it empty to keep the defaults.
The same option is available as generate_locators({xpathAttributes: ["AutomationId", "data-testid"]}).
Up to 20 names are accepted; XPath expressions and namespace prefixes are not supported.
The MCP Apps Page Source Inspector also offers Take screenshot. It refreshes XML, reads screen
size, and captures an image. Select an XML element in the preview to overlay its screen bounds;
Search narrows that element list. Bounds use x, y, width, height or Android's
bounds="[left,top][right,bottom]". Hidden elements, missing or empty bounds, and offscreen elements
are reported without an overlay. Captures are sequential, not atomic: keep the device still and
recapture after navigation or rotation. Other coordinate formats and Web DOM layout are not inferred.
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 UI by default. WithsaveToFile: true, returns the saved XML path and byte size instead;NO_UIdoes not enable file saving.generate_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 supplied Appium server URLs. Trust the permitted servers and their responses as described below.
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.
REMOTE_SERVER_URL_ALLOW_REGEX validates the supplied server URL only. Subsequent
destinations selected by HTTP redirects, Appium direct-connect metadata, or a
WebDriver BiDi webSocketUrl are handled by the WebDriver client library and are
not checked against this regex. Intercepting or modifying the client library's
internal transport is outside appium-mcp's scope. Operators must therefore trust
the permitted Appium servers and their responses. Set
REMOTE_SERVER_ENABLE_DIRECT_CONNECT=false to disable direct connect through the
client's public option; this does not disable HTTP redirects or BiDi connections.
Deployments that need to restrict all outbound destinations should enforce that
policy through network egress controls.
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
Load plugins from the command line
Pass --plugin to start the standard server with a plugin, without writing a server bootstrap module. Repeat the option to load multiple plugins in order; both --plugin <module> and --plugin=<module> work with stdio and --httpStream:
appium-mcp --plugin ./checkout-plugin.mjs --plugin=@acme/appium-mcp-pluginEach module must default-export either an AppiumMcpPlugin object or a plugin class whose constructor takes no arguments. For example, save this as checkout-plugin.mjs:
export default class CheckoutPlugin {
name = 'checkout-plugin';
version = '1.0.0';
register(registry) {
registry.addTool({
name: 'checkout_status',
description: 'Return the checkout integration status.',
execute: async () => ({content: [{type: 'text', text: 'Checkout plugin ready'}]}),
});
}
}Use an exported object (for example, export default new CheckoutPlugin(options)) when a plugin needs constructor options. TypeScript plugins must be compiled to JavaScript before loading.
Relative paths and installed package names resolve from the working directory where appium-mcp is launched. Package names use Node's CommonJS resolution (createRequire(...).resolve()), including require or default export conditions and legacy main entries. Packages exposing only an import export must be loaded through an explicit file path (for example, --plugin ./node_modules/my-plugin/plugin.mjs) or a file: URL. Loading still uses dynamic import(), so ESM plugin files, including those with top-level await, remain supported.
Absolute paths and file: URLs are also accepted; absolute paths are recommended in MCP client configurations because the client's working directory can vary. The CLI does not install packages: install package plugins in that working directory first.
Plugins execute in the server process, so load only trusted files and packages and keep plugin logs on stderr when using stdio. A missing module or invalid plugin export stops startup with an error instead of silently omitting the plugin. The optional documentation plugin, when enabled, is registered before CLI plugins. The existing duplicate-name and lifecycle rules below apply.
Compose a server programmatically
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: |
| Find all matching elements using the same locator strategies. Returns JSON |
| 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 |
| Return full XML inline by default. Set |
| 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 |
QA Intelligence & Token-Efficient Tools (added in this fork)
Full details, parameters and limits: TOOL_CATALOG.md. Status of every capability: IMPLEMENTATION_STATUS.md. Tests: npm test runs unit tests only; npm run test:integration:android runs the device suite (src/tests/integration/README.md); npm run bench:tokens measures token cost against the upstream baseline.
Tool | Description |
| Compact one-line-per-element view of the screen; |
| Up to 25 tap/type/wait/read/back/pause steps in one call, with a screen diff |
| Wait on a locator, check uniqueness, clear popups, scroll to a target |
| Classify the screen; build validated, scored locator candidates |
| Structural diff, pixel/layout checks, static accessibility audit |
| Evidence-based failure diagnosis; session diagnosis with bounded, safe recovery; connectivity (the last is opt-in group |
| Scenario generation, record/replay/export workflows, bounded safety-gated exploration (opt-in group |
Safety (on by default): destructive operations (appium_app_lifecycle uninstall and clear, a fullReset capability in appium_session_management create, appium_mobile_file push, appium_provider_upload_app) need a single-use confirmToken that is bound to the operation, target and session and expires after two minutes. The first call changes nothing. For controlled environments such as a CI job on a throwaway emulator there is an opt-in trusted automation mode that skips the confirmation only for the operations and apps you list explicitly (APPIUM_MCP_TRUSTED_MODE, _OPS, _APPS, _REASON); it is never enabled automatically, and a configuration mistake leaves confirmation on. The old APPIUM_MCP_ALLOW_DESTRUCTIVE switch is not supported. Details and risks: TOOL_CATALOG.md.
Fewer tokens: the default registers 40 tools. The qa and providers groups are opt-in: set APPIUM_MCP_TOOL_GROUPS=default,qa, default,providers, default,qa,providers, or all. An exact list such as core,observe,interact registers only those groups. Groups: core, observe, interact, locators, device, advanced, ios (default) and qa, providers (opt-in). appium_get_page_source accepts mode=compact, generate_locators accepts limit, appium_app_lifecycle list accepts filter and limit, appium_mobile_permissions get accepts grep, and appium_mobile_device_info accepts verbosity=minimal.
Device providers (local and cloud): appium_provider_list, appium_provider_devices, appium_provider_check, appium_provider_upload_app, appium_provider_session, appium_provider_finish and appium_session_overview. Local Android is live-verified. LambdaTest, BrowserStack, Sauce Labs and Kobiton are implemented but not live-verified (no accounts were available), and Kobiton is only partial. See DEVICE_CONNECTIVITY_GUIDE.md and .env.example. Local iOS needs macOS and Xcode and cannot run on Windows.
🤖 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"
}
}appium_find_element preserves its existing element ID and success message. When the driver returns additional fields, a JSON text block includes {elementId, attributes} with the original attribute names and values. MCP does not fetch extra attributes or change driver settings automatically.
For drivers that support elementResponseAttributes, enable richer responses for both appium_find_element and appium_find_elements with the existing Settings API. First call appium_driver_settings with action=get to record the current values, then update the settings. Choose attribute names supported by your driver; the following example uses XCUITest attributes:
{
"tool": "appium_driver_settings",
"arguments": {
"action": "update",
"settings": {
"shouldUseCompactResponses": false,
"elementResponseAttributes": "attribute/name,label,enabled,attribute/visible"
}
}
}These settings apply to the session. attribute/name requests the element's name attribute; the name response field can represent its element type. Attribute keys such as attribute/visible are preserved in the MCP response. Supported fields depend on the driver.
Find all matching elements after applying these settings:
{
"tool": "appium_find_elements",
"arguments": {
"strategy": "-ios predicate string",
"selector": "type == 'XCUIElementTypeButton'"
}
}Example response (actual values depend on the app):
{
"elements": [
{
"elementId": "<webdriver-element-id>",
"attributes": {
"attribute/name": "menu",
"label": "Menu",
"enabled": true,
"attribute/visible": true
}
}
]
}Pass the chosen elementId as elementUUID to interaction tools. Each match keeps its own ID and attributes; compact responses omit attributes, and no matches returns {"elements":[]} successfully. Driver failures remain errors. Neither search tool makes additional attribute requests. Restore the recorded settings with action=update when richer responses are no longer needed (shouldUseCompactResponses: true disables the additional fields for drivers supporting this setting).
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.
Behavioral evals
Model-dependent MCP tool-selection and argument evals are available separately from
npm test. See evals/README.md for setup and npm run eval:mcp.
For local evaluation using Codex with ChatGPT login, use npm run eval:codex.
Page source file output and filtered summaries
Argument | Default | Behavior |
|
|
|
| Omitted | XPath selecting elements; requires |
| Omitted | Case-sensitive literal substring of tag names or attribute values; requires |
| Active session | Selects the Appium session. |
appium_get_page_source keeps its existing behavior by default: full XML is returned inline, with the existing inspector behavior. Omit saveToFile or pass saveToFile: false to use this mode; it does not write a file.
To opt into file output, pass saveToFile: true. Each call retrieves a fresh page source and saves a new snapshot; it does not reuse previously saved XML. XML is saved on the MCP server's filesystem and the response is JSON {filepath, bytes}. Set PAGE_SOURCES_DIR to choose a directory (relative paths resolve from the server working directory); otherwise the OS temporary directory is used. Files have unique names and owner-only permissions. Remove saved files when no longer needed.
With NO_UI=true, the default response still contains full XML and omits the additional HTML UI, as before. File output requires saveToFile: true regardless of NO_UI; it does not embed XML or HTML. Use the default inline mode when the client cannot access server files.
Save the full XML without returning its contents:
{
"tool": "appium_get_page_source",
"arguments": {"saveToFile": true}
}Example response (the path and byte count vary):
{"filepath": "/tmp/page-source-<uuid>.xml", "bytes": 41312}To inspect only part of the tree, pass saveToFile: true together with selector (an XPath selecting elements), pattern (a case-sensitive literal substring of tag names or attribute values), or both. Matching nodes include identifying attributes, visibility and bounds when present, plus explicitly visible siblings. Summaries are capped at 100 nodes including siblings and report truncated; the saved XML always contains the full tree. No matches returns matches: []. Filters cannot be combined with saveToFile: false.
{
"tool": "appium_get_page_source",
"arguments": {"saveToFile": true, "selector": "//*[@name='View All']"}
}{
"tool": "appium_get_page_source",
"arguments": {"saveToFile": false}
}Available Tools
40 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; defaults to 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 annotations indicate only that the tool is not read-only; the description adds that get_text is a read operation while accept/dismiss mutate the alert. However, it does not disclose behavior such as what happens when no alert is present, whether accept/dismiss consume the alert, or edge cases involving buttonLabel.
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?
A single front-loaded sentence with no filler. It conveys the resource and the three action modes without wasting words, making it easy to scan and 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 three-parameter tool with no output schema, the description plus schema is nearly sufficient; 'read alert text' reasonably implies the return value. Still, it does not specify return details or no-alert/error behavior, so it stops just short of fully 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 documents all parameters including the action enum and buttonLabel. The description mostly restates those values, adding only the semantic framing of get_text as reading alert text, which provides marginal extra value.
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 target resource (system alerts) and enumerates the exact operations: accept, dismiss, or get alert text. This makes it clearly distinguishable from generic text tools such as appium_get_text, despite 'handle' being a generic verb.
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 establishes a clear trigger condition: use this tool when a system alert must be accepted, dismissed, or its text read. It does not explicitly name alternative tools or state when not to use it, but the alert-specific scope makes routing an agent straightforward.
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 or HTTP(S) URL; required for install. Embedded URL downloads require ALLOW_REMOTE_APP_URLS=true (default). Remote sessions resolve app inputs on the remote Appium server. | |
| limit | No | list: return at most this many apps. | |
| 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. | |
| filter | No | list: only apps whose id or name contains this text (case-insensitive). | |
| 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; defaults to the active session. | |
| confirmToken | No | Required to repeat uninstall/clear after the first call returns CONFIRMATION REQUIRED. Single use. | |
| 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?
Annotations only declare readOnlyHint=false and openWorldHint=true. The description does not disclose that several actions are destructive (uninstall, clear), that a confirmToken workflow gates repeats, that some actions require id/name, or that inputs resolve on a remote Appium server. For a mutation-heavy tool, this leaves most behavioral burden undocumented in the description text.
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?
It is a single, front-loaded sentence with no filler, which is structurally clean. But the brevity comes from under-specification rather than efficient communication; the sentence reads as a topic list rather than an actionable definition.
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 13-parameter, 10-action mutation tool with no output schema and minimal annotations. The description omits confirmation requirements, destructive-action warnings, required-parameter distinctions per action, and session scoping, leaving it far from complete for the complexity involved.
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 id, path, action semantics, seconds, confirmToken, and other parameters in detail. The description adds no parameter meaning beyond the generic topics "state, data, and deep links," so it sits at the baseline for fully documented schemas.
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?
"Manage app lifecycle, installation, state, data, and deep links" correctly signals a multi-action app-management tool and enumerates the domains covered. However, "Manage" is a vague umbrella verb, and the description never differentiates this tool from siblings such as appium_session_management or appium_mobile_device_control, so the agent must inspect the action enum to know what it actually does.
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 when-to-use guidance, no alternatives, and no exclusions. All routing information (which action to pick, when confirmation is required, when to use this versus session tools) lives in the schema's action description, not in the tool description itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_batchA
Run up to 25 steps (tap, type, wait, read, back, pause) in ONE call and return per-step results plus a compact screen summary. Locators: id=, desc=, text=, xpath=, uia=, pred=. Taps/types wait up to 10s for the element by default.
| Name | Required | Description | Default |
|---|---|---|---|
| steps | Yes | ||
| sessionId | No | Session ID; defaults to the active session. | |
| stopOnError | No | Default true. | |
| observeAfter | No | Screen summary after the batch. Default diff. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false; the description adds real context beyond that, disclosing the 25-step cap, the returned payload shape, and the default 10s element wait for taps/types. It does not explain what happens when a step fails mid-batch or whether partial mutation persists, which matters for a non-read-only tool.
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, front-loaded with the core capability, then locator syntax, then timing behavior. No filler and nothing buried.
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?
No output schema exists, yet the description states the return shape (per-step results plus screen summary), which covers the main gap. The step-variant semantics (e.g. what 'read' returns, 'until'/'timeoutSec' interaction) and failure behavior remain unspecified for a fairly complex nested 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 75% and the nested oneOf step variants carry no per-property descriptions, so the description compensates with genuinely additive detail: the locator prefix grammar (id=, desc=, text=, xpath=, uia=, pred=) appears nowhere in the schema. The wait-default and stopOnError/observeAfter defaults it mentions are already documented in the schema, so not every sentence adds 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?
Specific verb and resource: 'Run up to 25 steps (tap, type, wait, read, back, pause) in ONE call', plus what it returns ('per-step results plus a compact screen summary'). The batching scope makes it distinguishable from single-action siblings like appium_perform_actions or appium_find_element, though no sibling is named 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 'in ONE call' framing implies this is for multi-step sequences rather than single interactions, but the description never states when to prefer it over appium_perform_actions or when a single-step tool is the better choice. Usage is inferable rather than stated.
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; defaults to the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations carry no behavioral hints (readOnlyHint=false, openWorldHint=false), so the description itself must disclose side effects. It states that list returns all contexts and the current context, and that switch changes to a target context, which covers the basic effects. However, it does not disclose what happens on invalid context, whether the switch persists, or any session-level implications, leaving significant behavioral gaps.
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 wasted words. The first sentence states the tool's overall purpose, and the second precisely defines the two actions, front-loading the essential information immediately.
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 3 parameters and no output schema, the description covers the core functionality but omits details an agent might need, such as what the switch action returns, error behavior for invalid contexts, and the effect on the active session. It is adequate for a knowledgeable user but not fully complete for autonomous selection and 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 input schema already documents all three parameters. The description adds marginal value by explaining the distinct outcomes of list versus switch, but it does not enrich the context or sessionId parameters beyond the schema's existing descriptions, so the 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 a specific verb and resource, 'Manage Appium contexts', and enumerates the two supported actions (list and switch) with distinct effects. It clearly differentiates this tool from the many sibling Appium tools by focusing solely on context management, which is unique among the listed 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?
The description implies that the tool is for managing Appium contexts but does not explicitly state when to use this tool versus alternatives or when not to use it. It provides no prerequisites or conditions beyond the actions themselves, so an agent must infer usage context from the tool name and description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_diagnoseARead-only
Failure intelligence: after a step fails, checks session liveness, app state, current screen (dialog, keyboard, hidden/ambiguous/disabled target) and logcat crash/ANR/network signals, then returns evidence, likely causes with confidence, next steps and safe recovery. Read-only; never retries or changes state.
| Name | Required | Description | Default |
|---|---|---|---|
| appId | No | Package / bundle id, enables crash correlation and app-state check. | |
| error | No | The error message from the failed step. | |
| locator | No | Locator that failed (id=..., text=...). | |
| sessionId | No | Session ID; defaults to the active session. | |
| includeLogs | No | Read logcat (Android) for crashes/ANR/network errors. Default true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint; the description adds real behavioral context by stating it never retries and never changes state, and by enumerating what evidence it collects and that causes come with confidence scores. The main omission is the cost/latency profile, since reading logcat can be slow and is on by default.
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 dense but well-ordered sentence: purpose first, then the checks performed, then the outputs, then the read-only guarantee. Nothing is redundant, though the mid-sentence parenthetical list of screen conditions makes it slightly heavy 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 five-parameter, all-optional diagnostic tool with no output schema, the description adequately covers what the tool inspects and roughly what it returns (evidence, likely causes, next steps). It stops short of describing the shape of that evidence or how to act on confidence values, but the essentials for correct invocation are 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 coverage is 100%, so every parameter is already documented, including the includeLogs default and the sessionId fallback to the active session. The description adds only indirect hints (it mentions logcat signals and screen/app state) and no new syntax or selection guidance, 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?
Names a specific verb-and-resource: it diagnoses a failure by checking session liveness, app state, screen state (dialog, keyboard, hidden/ambiguous/disabled target) and logcat crash/ANR/network signals, then returns evidence plus ranked causes and next steps. That is far more specific than the sibling tools (appium_screen_intel, appium_session_health, appium_observe), which each cover only one facet.
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 trigger is explicit and front-loaded: 'after a step fails'. An agent knows exactly when to reach for it. It does not, however, name how it relates to overlapping siblings such as appium_session_health or appium_screen_intel, so an agent cannot tell from this text whether diagnose subsumes them or should be paired with them.
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; defaults to 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?
The description goes beyond the sparse annotations by disclosing the exact gesture sequence (long press, drag, release) and default durations (600ms and 1200ms). It also explains that source and target can be an element UUID or coordinates, adding practical behavioral context beyond what annotations provide.
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, with the core action stated first, followed by the gesture mechanics and then representative use cases. Every sentence contributes useful 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?
For a tool with 9 parameters and no output schema, the description covers the essential behavioral contract: what gesture is performed, the timing defaults, and the two ways to specify source and target. It does not exhaustively explain every edge case, but it is sufficiently complete for an agent to select and invoke 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?
Schema description coverage is 100%, so the baseline is 3. The description repeats default timings and the element/coordinate alternative that are already present in the parameter schemas, but it does not add significant new meaning beyond what the structured schema already documents.
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 and resource ('Perform a drag-and-drop gesture from a source location to a target location') and details the gesture mechanics, making it clearly distinct from gesture-related siblings like appium_gesture and appium_perform_actions. It also clarifies the two acceptable input forms (element UUID or coordinates).
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 clear usage context with concrete examples ('Useful for reordering lists, moving items, drag-to-delete'), which helps an agent decide when to use this tool. However, it does not explicitly name alternative tools or state when not to use this tool.
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; defaults to the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide no real behavioral cover beyond readOnlyHint=false, so the description carries the burden. It usefully reveals that get returns JSON settings and update merges a map into the session, but it does not describe update response behavior, side effects, or failure cases. This is adequate but not 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 sentences with no filler: the first front-loads the tool's purpose and action modes, and the second scopes supported client types. 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 moderately simple settings tool, the description covers the main operational distinctions: reading vs. updating, merge semantics, and supported session types. Since there is no output schema, it could have specified what update returns, but the core usage is complete enough for an agent to invoke 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?
Schema description coverage is 100%, so the schema already documents all parameters. The description adds some useful context by naming typical settings keys and explaining the get/update split, but it does not significantly compensate beyond the schema's own detailed parameter 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 uses a specific verb-resource pair ('Read or update Appium driver session settings') with concrete examples like idle timeouts and selector waits. It is clearly distinct from the sibling tools by targeting driver session settings, though it does not explicitly name or differentiate itself from a sibling.
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 action-level guidance: use action=get to read settings and action=update to merge a settings map. It also clarifies supported session types (embedded UiAutomator2/XCUITest and remote WebDriver clients), which helps an agent decide when this tool applies.
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 an element by strategy and selector. Pass its ID as elementUUID to interaction tools. Returns driver attributes as JSON. For drivers supporting elementResponseAttributes, use appium_driver_settings to configure it with shouldUseCompactResponses=false. Prefer accessibility id > id > platform-native > xpath (last resort: slow/brittle). See strategy for platform-specific guidance. To scroll until a target is found, use appium_gesture action=scroll_to_element with the same strategy and selector, rather than repeatedly calling this tool. Vision fallback: appium_ai action=find_element (if enabled).
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | Selector for the strategy. Do not pass natural-language descriptions; use appium_ai action=find_element for vision. | |
| strategy | Yes | accessibility id: cross-platform, fast and stable. id: Android resource-id; iOS accessibility-id alias. iOS prefer accessibility id > -ios predicate string > -ios class chain; Android prefer accessibility id > id > -android uiautomator. Use xpath last (slow/brittle). name: legacy; class name: broad matches; css selector: webview only. | |
| sessionId | No | Session ID; defaults to the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnlyHint, openWorldHint), so the description's job is supplementary. It does add real value: the return shape ('Returns driver attributes as JSON'), the elementResponseAttributes dependency on appium_driver_settings with shouldUseCompactResponses=false, and the caveat against natural-language selectors. It stops short of describing failure behavior when an element is not found.
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?
Front-loads the core purpose and the returned-UUID contract in the first two sentences, with preference ordering and cross-tool routing after. Dense and mostly waste-free, though the driver-settings aside could be trimmed.
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, the description carries the return-format burden and does so ('driver attributes as JSON'). Combined with strategy guidance, the scroll alternative, and the vision fallback, an agent has everything needed to select and call this 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?
Schema description coverage is 100% and the strategy enum is thoroughly documented in the schema itself (per-platform guidance is already in the enum/param descriptions). The description's strategy preference ordering largely repeats the schema, so it adds direction but little 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?
States a specific verb and resource ('Find an element by strategy and selector') and immediately clarifies the downstream contract: the returned element UUID is passed to interaction tools. It is cleanly distinguishable from the sibling appium_find_elements (plural).
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?
Explicitly routes the agent to alternatives: appium_gesture action=scroll_to_element for scrolling-until-found, and appium_ai action=find_element for the vision fallback. It also gives a concrete preference ordering (accessibility id > id > platform-native > xpath) with the reason xpath is last resort.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_find_elementsARead-only
Find all elements matching a strategy and selector. Returns JSON {elements: [{elementId, attributes?}]}; no matches returns {elements: []}. Pass an elementId as elementUUID to interaction tools. Additional driver attributes are preserved. For drivers supporting elementResponseAttributes, use appium_driver_settings to configure it with shouldUseCompactResponses=false. Use appium_find_element when only one match is needed.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | Selector for the strategy. Do not pass natural-language descriptions; use appium_ai action=find_element for vision. | |
| strategy | Yes | accessibility id: cross-platform, fast and stable. id: Android resource-id; iOS accessibility-id alias. iOS prefer accessibility id > -ios predicate string > -ios class chain; Android prefer accessibility id > id > -android uiautomator. Use xpath last (slow/brittle). name: legacy; class name: broad matches; css selector: webview only. | |
| sessionId | No | Session ID; defaults to 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, and the description goes well beyond them: it specifies the exact return payload, the empty-match contract, that elementId must be reused as elementUUID by interaction tools, and the shouldUseCompactResponses=false prerequisite for elementResponseAttributes drivers.
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 tight sentences, front-loaded with the core behavior and return shape, then interaction hand-off and configuration caveat. No filler or repetition.
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, the description compensates by describing the returned JSON structure and the empty-result case, plus how to configure compact responses. Nothing needed to call or consume the result 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%, with rich per-strategy guidance and an enum, so the schema carries the parameter burden and baseline is 3. The description adds only an output-side note about passing elementId as elementUUID, not new input 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?
States a specific verb and resource ('Find all elements matching a strategy and selector') and explicitly distinguishes itself from appium_find_element by match-count semantics. An agent can select it without opening the schema.
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?
Names the alternative (appium_find_element) with the selecting condition ('when only one match is needed'), and the selector schema routes vision/natural-language lookups to appium_ai action=find_element. Explicit when-not guidance is present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_generate_testsA
Return a workflow to execute the scenario with MCP tools, then generate test code from observed interactions. Prefer appium_find_element; generate_locators is for broad inspection.
| 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?
The description discloses that the tool executes a scenario via MCP tools, observes interactions, and then produces test code, which is meaningful behavioral context. However, with sparse annotations it omits side-effect details, session or device prerequisites, and whether the generated code is returned inline or written elsewhere.
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, both information-dense: the first explains the workflow and output, and the second provides actionable locator-selection guidance. There is no filler or redundant repetition of 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?
For a one-parameter tool with a documented schema, the description is mostly adequate: an agent can infer the expected input and output. The main gaps are missing prerequisites such as an active Appium session or device, and the expected granularity of the steps input.
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 fully documents the single steps parameter as the steps of the test, and the description only alludes to it via the word scenario. No additional formatting, granularity, or example guidance is provided, so this stays at the schema-coverage 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 first sentence states a specific outcome: return a workflow to execute a scenario and then generate test code from observed interactions. The second sentence differentiates the tool from appium_find_element and generate_locators, making the purpose largely 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 explicit routing guidance: prefer appium_find_element for targeted element location and reserve generate_locators for broad inspection. It does not enumerate all exclusion cases or alternative tools, but the context is clear enough for an agent to decide when to use this tool.
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; defaults to the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the minimal annotations, the description discloses meaningful behavioral caveats: Android emulator reset is unsupported, mocked locations may persist until GPS cache refresh on Android real devices, and altitude is Android-only. These details help an agent anticipate platform-specific outcomes. The readOnlyHint=false annotation is consistent with the mutating set/reset actions.
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, starting with the core function and platform scope before detailing action modes and edge cases. Every sentence contributes operational information, and there is no filler or redundant restatement.
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 fully covers action selection, platform constraints, required parameters, and important caveats. There is no output schema, and the description does not specify the exact return shape of action=get, but the invocation path is otherwise complete and unambiguous.
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 explaining action semantics and platform dependencies, such as action=set requiring latitude/longitude, altitude being Android-only, and reset having an Android emulator limitation. This supplements the schema rather than merely repeating it.
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 'Get, set, or reset the device geolocation (GPS coordinates)', providing specific verbs and the resource being operated on. It clearly distinguishes this tool from sibling Appium tools by naming the exact geolocation capability and supported platforms.
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 action-based guidance: use action=get to read, action=set with latitude/longitude to simulate, and action=reset to restore defaults. It also notes that reset is unsupported on Android emulators and directs users to action=set instead. It does not mention alternative sibling tools, but it clearly scopes its own usage context.
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 pixel coordinate, paired with y: tap location, pinch center, or scroll/swipe start (requires endX/endY). elementUUID overrides x/y for tap/double_tap/long_press/pinch_zoom. | |
| y | No | Y pixel coordinate, paired with x; same action meanings and elementUUID precedence as x. | |
| endX | No | Ending X coordinate in pixels for scroll/swipe; requires x, y, endY. | |
| endY | No | Ending Y coordinate in pixels for scroll/swipe; requires x, y, endX. | |
| scale | No | Required for pinch_zoom: <1 zooms out, >1 zooms in (e.g. 0.5 or 2 for 2x). | |
| speed | No | Swipe only. slow: deliberate drag; normal: default navigation speed; fast: flick without an initial hold. Use fast for pull-to-refresh and other velocity-sensitive interfaces. | |
| action | Yes | tap/double_tap/long_press: requires elementUUID or both x/y. scroll/swipe: requires direction or x/y/endX/endY. pinch_zoom: requires scale (<1 out, >1 in). scroll_to_element: requires strategy/selector; direction up/down (default down). Stops on a match, unchanged page source, or maxScrollAttempts. Adjust distance with scrollDistance or scrollDistancePreset. back: system back navigation. | |
| duration | No | Duration in milliseconds. long_press defaults to 2000 (range 500–10000); scroll defaults to 800. For swipe, prefer speed unless a custom movement duration is needed. For W3C swipe, overrides movement time; speed still sets the initial hold. Ignored by iOS native mobile: swipe (direction, no elementUUID, speed != fast). | |
| selector | No | Locator selector value. Required for: scroll_to_element. | |
| strategy | No | Required for scroll_to_element. Prefer accessibility id > id > platform-native (iOS: -ios predicate string / -ios class chain; Android: -android uiautomator) > xpath (last resort: slow/brittle). name is legacy; class name may match multiple elements; css selector is webview-only. Same priorities 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/swipe. Coordinates are calculated from the screen or element bounds. Provide either direction or custom coordinates (x, y, endX, endY); direction takes precedence if both are given. For scroll_to_element, use up/down; default down. | |
| sessionId | No | Session ID; defaults to the active session. | |
| elementUUID | No | Element UUID for tap, double_tap, long_press, or pinch_zoom; overrides x/y for these actions. For scroll/swipe with direction, coordinates are calculated relative to this element instead of the whole screen. | |
| scrollDistance | No | scroll_to_element only: vertical swipe distance fraction (0.05–1). Ignored when scrollDistancePreset is set. Default 0.45 when neither option is supplied. | |
| maxScrollAttempts | No | scroll_to_element only: maximum scroll attempts after the initial lookup fails. Default 10. | |
| scrollDistancePreset | No | scroll_to_element only: small is a light nudge (0.25), medium is 0.45, large is the full default swipe (1). Overrides scrollDistance when set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and openWorldHint=false, so the safety profile is clear. The description adds action-level intent such as browse versus dismiss versus pull-to-refresh, but it does not describe side effects, waits, or failure behavior beyond what the schema already covers.
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, front-loaded with the core action and followed by action selection and sibling routing guidance. It contains no filler and does not redundantly restate the long 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?
For a 17-parameter gesture tool, the description provides the high-level action model and sibling routing while the schema carries the detailed mechanics. It is nearly complete, though a complex eight-action tool could briefly mention session or element-precedence behavior at a high level.
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 every parameter is documented in detail, so the description does not need to repeat coordinate, duration, or locator mechanics. It does add useful action-selection semantics that the schema does not fully capture, especially scroll versus swipe intent.
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, then enumerates the supported touch actions. It also distinguishes this tool from appium_drag_and_drop and appium_perform_actions, so an agent can route correctly without opening the schema.
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 explains when to use scroll versus swipe by intent and names the two sibling alternatives for drag-and-drop and custom multi-touch. The pull-to-refresh speed hint further reduces ambiguity.
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; defaults to the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The read-only behavior is already covered by annotations, so the description doesn't need to restate that. It adds useful context by specifying that the tool returns a UUID intended for follow-up interactions. It does not mention edge cases like what happens when no element is focused, but that is a minor omission for such a simple read-only tool.
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, efficient components: the purpose first, then the priority usage note. There is no filler, and the key information is front-loaded.
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-parameter, read-only tool with safety annotations, the description is nearly complete: it states what is returned (UUID) and why it matters. The only real gap is the lack of guidance on the no-focused-element case, especially given the absence of 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 coverage is 100%: the only parameter, sessionId, is already documented as defaulting to the active session. The description adds no parameter-level detail, so the schema carries the semantic load and the 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 and resource ('Get the currently active/focused element') and states a concrete output ('return its UUID for follow-up interactions'). This clearly distinguishes it from siblings like appium_find_element, which search for elements rather than report the current focus.
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 provides explicit usage context: 'Use this first when you need to find what element currently has focus.' This is clear and actionable, but it does not name alternatives or state when not to use it, so it stops short of a 5.
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; defaults to 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, and the description is consistent with that non-destructive getter. The description adds no further behavioral detail beyond the annotation, such as what happens if the attribute does not exist or the exact return format.
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 with no filler. The core action is front-loaded, followed by the practical use cases, making it easy to parse quickly.
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 3-parameter tool with full schema coverage, the description is largely sufficient for selection and invocation. The main omission is the exact return type or null behavior for missing attributes, but that is minor given the tool name and examples.
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?
With 100% schema description coverage, the baseline is 3, but the description adds meaningful semantic grouping by separating state attributes from property attributes. This helps the agent choose appropriate values for the attribute parameter beyond what the schema lists.
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 ('Get the value of an element attribute') and concrete use examples, so an agent can tell what the tool does. It does not explicitly differentiate it from the overlapping sibling appium_get_text, which can also retrieve text or value attributes.
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 says 'Use this to check element state... or read properties', giving clear contexts for when the tool is appropriate. However, it does not mention when not to use it or when to prefer a sibling tool, so it stops short of a 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_sourceB
Get current-screen XML. saveToFile=true returns server-local path/bytes and enables selector/pattern summaries.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | full (default): raw XML. compact: one line per actionable/readable element (about 90% smaller); use when you only need to act. | |
| pattern | No | Literal tag/attribute substring. | |
| selector | No | XPath selecting elements. | |
| sessionId | No | Session ID; defaults to the active session. | |
| saveToFile | No | Save fresh XML to a file; return path/bytes instead of XML. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description usefully explains that saveToFile=true returns a server-local path/bytes rather than XML, which explains why readOnlyHint=false despite this being a read-style operation (it writes a file server-side). However, 'enables selector/pattern summaries' is ambiguous — it does not say whether selector/pattern are ignored or rejected without saveToFile=true, and there is no note on output size or cost of full-mode XML.
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 with the core action front-loaded and no filler. The second sentence is dense but slightly cryptic ('enables selector/pattern summaries'), costing a bit of clarity for its brevity.
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 five-parameter tool with zero required params and no output schema, the description is thin: it omits any indication of what the XML/compact output looks like, how large it can get, and how it relates to the many competing observation tools. The saveToFile behavior is well covered, but the default full-mode path is not.
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, but the description adds real meaning beyond the schema: it clarifies the returned path is server-local (not client-fetchable) and ties saveToFile to the selector/pattern behavior. The linkage between saveToFile and the filtering parameters is the kind of cross-parameter interaction the schema alone does not convey.
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: 'Get current-screen XML', which is unambiguous about what is returned. It does not differentiate itself from nearby siblings such as appium_screenshot, appium_screen_intel, or appium_find_element, so an agent must infer when raw page source beats those options.
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 when-to-use or when-not-to-use guidance in the description; it never mentions the sibling tools that overlap (screenshot, screen_intel, find_element). The only usage hint ('use when you only need to act') lives in the mode enum in the schema, not in the description.
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; defaults to 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 description aligns with readOnlyHint=true and does not contradict the annotations, but it adds no behavioral detail beyond them. There is no mention of return format, stale-element behavior, or side effects, so the description contributes little transparency that the annotation doesn't already supply.
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 or redundancy. It is appropriately compact for a simple getter tool, though it sacrifices explanatory richness for brevity.
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 two-parameter read-only getter with a well-documented schema and readOnly annotation, the tool is minimally callable. However, there is no output schema, and the description could usefully state that the return value is the element's text content; it also fails to route agents away from nearby siblings.
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?
Both parameters are already described in the JSON schema: sessionId defaults to the active session and elementUUID comes from appium_find_element. With 100% schema coverage, the description adds no extra parameter 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 states a specific operation ('Get text') and target ('from an element'), making the core purpose immediately clear. However, it doesn't contrast with related siblings such as appium_get_element_attribute or clarify whether 'text' means visible text vs. an attribute value.
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 on when to use this tool versus alternatives like appium_get_element_attribute or appium_get_active_element. The only implied trigger is needing text from an element, but no prerequisites, exclusions, or contextual cues are provided.
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; defaults to the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No contradiction with annotations: readOnlyHint=true matches the read-only 'Get' wording. The description adds useful context beyond the annotation by specifying the result is the device screen dimensions in pixels rather than element-level or abstract coordinates.
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 with no redundancy: the first states the return value and unit, the second states the practical use case. 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?
The tool is simple: one optional parameter, read-only, and the return semantics are clear from 'width and height in pixels.' The description plus schema fully equip an agent to decide to call it and interpret 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% and the only parameter, sessionId, is already documented as 'Session ID; defaults to the active session.' The description adds nothing needed about parameters, so the schema carries the 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 names a specific verb and resource: 'Get the width and height of the device screen in pixels.' This clearly distinguishes the tool from sibling getters like appium_get_text, appium_get_element_attribute, appium_get_page_source, and appium_get_active_element.
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 gives a concrete intended use: 'calculating coordinates for swipes, taps, and scrolls,' which tells an agent when to call it. It does not explicitly name exclusions or alternative tools, but for a simple screen-size query the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_locator_intelARead-only
Find target element(s) by description and return validated locator candidates, each with live match count (1 = unique), a 0-100 stability score and warnings (value-dependent ids, positional xpath, hidden target). Recommended locator is first. Counts come from the current screen, so re-verify after navigation.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Resource-id fragment. | |
| text | No | Text, content-desc or id fragment of the target (case-insensitive). | |
| input | No | Only input fields. | |
| limit | No | Max targets (default 3). | |
| clickable | No | ||
| sessionId | No | Session ID; defaults to the active session. | |
| verbosity | No | Output size. Default standard. | |
| includeHidden | No | Also consider off-screen/hidden nodes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true and openWorldHint=false, so the description carries real weight here and does so well: it explains match-count semantics (1 = unique), the 0-100 stability score, the three warning classes (value-dependent ids, positional xpath, hidden target), and that results are ordered with the recommended locator first. The staleness caveat about re-verifying after navigation is exactly the kind of behavioral context annotations cannot express.
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, purpose first and caveat last, with no filler; each clause (match count, stability score, warnings, ordering) conveys a distinct fact. The sentences are densely packed with parenthetical clauses, which costs a little readability but not substance.
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, the description must explain the return value and largely does: a ranked list of locator candidates with match counts, stability scores and warnings. The remaining gap is that it never says which locator strategies are emitted (id, accessibility id, xpath, etc.), which an agent needs to know to use the candidates.
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 88%, so the schema already documents id, text, input, limit, clickable, sessionId, verbosity and includeHidden in detail. The description adds only indirect meaning, e.g. the 'hidden target' warning implicitly ties to includeHidden and 'by description' maps loosely to text/id. Baseline 3 is appropriate since the schema does the heavy lifting.
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 ('find target element(s) by description') plus the distinctive output ('validated locator candidates'), which separates it from plain find tools like appium_find_element/appium_find_elements and from generate_locators. It never names a sibling explicitly, so the differentiation is inferred rather than stated.
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 prescribed: the tool is for discovering stable locators before authoring a test, and the closing note gives a concrete rule ('counts come from the current screen, so re-verify after navigation'). There is no explicit when-not guidance and no named alternative for cases where the agent already knows the locator or just wants to interact with an element.
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; defaults to the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint=false, so the description's confirmation of a set/write mode adds modest value. It does contribute platform scope, plain-text semantics, and the behavior that action=get returns current text. However, it does not disclose side effects such as replacing the existing clipboard contents or any platform-specific failure behavior; these would be useful but are not severe omissions.
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 operation is front-loaded, followed by the mode-specific behavior and the prerequisite condition for set. 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 simple two-action clipboard tool, the description plus the input schema is sufficient to invoke it correctly: action is required and enum-limited, content is required when setting, and sessionId defaults to the active session. The return for get is described as current text, and no output schema exists. Minor caveats such as clipboard persistence or platform restrictions are not covered, but the tool is simple enough that the current description feels 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 all three parameters are already documented. The description adds a little extra meaning by linking action=get to returning text and action=set to requiring content, but this mostly restates the schema's enum descriptions rather than providing substantial new semantic information. 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 states a precise verb+resource pair: 'Read or set the device clipboard as plain text.' It also narrows the scope by naming the supported platforms (Android UiAutomator2 / iOS XCUITest) and enumerating the two modes via action=get and action=set, which clearly distinguishes it from sibling tools that target elements, keyboards, or sessions.
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 mode-level guidance: 'action=get returns current text; action=set requires content.' This tells the agent exactly when each action branch is appropriate and which parameter is needed. It does not name alternative sibling tools for exclusion, but there is no obvious clipboard-specific sibling among the listed tools, so the guidance is sufficiently clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_mobile_device_controlA
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; defaults to the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, so the agent knows this mutates state. The description adds no further behavioral context beyond what the schema already provides (platform-specific actions). It does not disclose side effects like disrupting the app under test or requiring an active session. Since annotations cover the mutation aspect and the schema covers platform limitations, a 3 is appropriate – the description adds minimal but non-contradictory context.
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 immediately states the tool's purpose and points to the key parameter. It is concise, avoids repetition, and contains no 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?
For a tool with three parameters fully described in the schema and no output schema, the description is adequate. It explains what the tool does and directs the agent to the action parameter. It does not mention preconditions like device availability or potential interference with the test, but these are not strictly required for correct invocation. The description is complete enough for an agent 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%, so all parameters are documented in the schema. The description only says 'Use the action parameter to choose what to do,' which adds no additional meaning beyond the schema's detailed enum and per-parameter descriptions. Baseline 3 is correct when the schema fully documents 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 resource (device behavior) and lists specific actions: lock/unlock the screen, shake, open notifications. This is distinct from sibling tools like appium_gesture (screen gestures) or appium_orientation (screen rotation), making the purpose immediately clear.
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 usage: if you need to perform these device-level actions, use this tool. However, it does not mention alternatives or when not to use it, such as 'use appium_gesture for screen-level interactions' or platform-specific exclusions (though the schema does note iOS-only for shake and Android-only for open_notifications). No explicit when/when-not guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_mobile_device_infoBRead-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; defaults to the active session. | |
| verbosity | No | info only. minimal: model, brand, OS, locale, display, time zone and connectivity state without per-network detail. Default standard (unchanged). |
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 cross-platform applicability and that all three data points come back in one call, but says nothing about session fallback behavior or whether failures raise or return partial data. With annotations present, a 3 fits.
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, front-loaded with what the tool retrieves and then how to select it. No filler; the platform note earns its place as scoping 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?
There is no output schema, yet the description does not characterize return shape beyond the action labels, and the schema's own descriptions carry most of that burden. For a simple read-only tool this is close to adequate, but it does not fully cover what an agent gets back.
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 itself spells out the action enum, the moment.js format string, the sessionId default, and the verbosity modes. The description only restates that 'action' selects the data, adding nothing beyond structured fields, so the 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?
The description names a concrete verb plus three specific resources (device info, battery status, device time), so an agent knows exactly what the tool returns without opening the schema. It is clear enough to distinguish from siblings like appium_orientation or appium_geolocation, though it never explicitly says so.
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 tells the agent to use the 'action' parameter to pick which datum to fetch and that it works on iOS and Android, which is useful routing context. It gives no explicit when-to-use vs alternatives guidance (e.g., vs appium_session_health for status, or appium_observe for broader state).
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; defaults to 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). | |
| confirmToken | No | push only: required on the repeat call after CONFIRMATION REQUIRED. | |
| 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 declare readOnlyHint=false and openWorldHint=false, so the safety profile is partly covered. The description adds that pull returns contentBase64 (useful return-shape context), but omits the two-step CONFIRMATION REQUIRED flow documented only in the schema and says nothing about overwriting existing device files or permission needs.
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, zero filler, and the primary capability is front-loaded before the per-action data requirements.
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, noting the contentBase64 return is valuable, but the definition stays silent on the confirmation-token workflow and on overwrite/destructive semantics for push — meaningful gaps for a file-write tool with five parameters.
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 every parameter is already documented, including action, remotePath formats, and the confirmToken requirement. The description's 'action=push uses payloadBase64' restates exactly what the schema says, adding no new syntax or format 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 ('Push or pull') and resource ('a file') scoped to Appium mobile extensions, and names both modes. No sibling tool performs file transfer, so differentiation is de facto clear, though it never explicitly says it is the only/right tool for this job.
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 push/pull split implies when each mode applies (upload vs. download), but there is no explicit 'use this when' guidance, no prerequisites, and no mention of the confirmation handshake that governs push.
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; defaults to the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false, so the tool is expected to mutate state. The description confirms the hide action is mutating and the is_shown action is a query, but does not add deeper behavioral details such as side effects when the keyboard is already hidden, platform-specific quirks, or error conditions. It adds the platform scope (Android/iOS), which is useful context beyond 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 concise sentences with the core purpose front-loaded, followed by the action mappings. Every word earns its place; there is no fluff or redundancy, making it efficient and easily scannable.
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 tool with three parameters and no output schema, the description covers the actions but fails to specify the return value for is_shown (expected boolean). It also does not mention error handling or platform-specific behaviors. While the core functionality is clear, the missing return-type detail leaves a gap for an agent relying on the description 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%, and the description duplicates the parameter information already present in the schema (e.g., keys are only for hide, action enum). It adds no new semantic value beyond what the schema provides, 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 states a clear verb-resource pairing: hide the software keyboard or check its visibility, scoped to Android/iOS. It names the two specific actions (hide, is_shown) and maps them to Appium commands, making the purpose unambiguous and distinct from sibling tools 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 clearly states what the tool does and the two action variants, but does not explicitly say when to use it versus alternatives or when not to use it. The context is implied (keyboard control), but no exclusions or sibling routing is provided, leaving the agent to infer appropriateness.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_mobile_permissionsB
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. | |
| grep | No | Android get: keep only permission names containing this text (case-insensitive). | |
| 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; defaults to 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 declare a non-read-only, closed-world tool, and the description correctly reflects that mixed read/write nature plus the platform boundary (iOS reset is Simulator-only, reset is iOS-only). It does not disclose prerequisites such as AppleSimulatorUtils for iOS, permission/entitlement requirements, or what state is lost on reset, so it adds only moderate context beyond 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?
A single front-loaded sentence pairs the action scope with the platform scope, and the trailing pointer to action-specific parameters is short. The only weakness is that 'See action-specific parameters' spends words without conveying 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?
For an 11-parameter, nested-object tool with no output schema, the description conveys the operation surface but leaves platform prerequisites and the relationship between action and required parameters to the schema. It is adequate given the rich schema, but not self-sufficient for an agent choosing between the three actions.
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 documented in the schema, including action, target, service, access, and permissionChangeAction. The description adds nothing parameter-specific beyond pointing at the schema, which matches the baseline for fully covered schemas.
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 specific verbs and a named resource: read/update Android app permissions, read/update iOS Simulator privacy services, and reset iOS privacy prompts. It clearly separates the two platforms, which no sibling tool covers, though it does not explicitly name a sibling it is distinct from.
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?
Platform scoping (Android vs iOS Simulator) implies when each path applies, but there is no explicit when-to-use guidance and no routing away from adjacent tools such as appium_driver_settings or appium_app_lifecycle. 'See action-specific parameters' defers the decision to the schema rather than explaining it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_mobile_press_keyA
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; defaults to 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?
Annotations already signal a non-read-only operation, so the description only needs to add behavioral context. It adds platform-specific key behavior and implies navigation side effects via key names, but it does not explicitly state effects like leaving the current screen (HOME/APP_SWITCH) or changing volume, nor does it mention long-press behavior.
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?
A single sentence delivers the core action and platform scope with no filler or repetition. It is front-loaded and every phrase 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 input schema fully documents all four parameters, including platform restrictions and keyCode precedence, so the brief description plus the schema gives an agent what it needs for a simple key press. The main missing piece is relationship guidance to sibling input tools, which is already captured 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%, so the baseline is 3 and the schema already documents key, keyCode precedence, sessionId, and isLongPress. The description only echoes a subset of key-to-platform mappings and adds no new meaning 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 opens with the specific action 'Press' and identifies the exact resources: navigation keys (BACK, HOME, APP_SWITCH) on Android and physical buttons on iOS/tvOS. This clearly distinguishes the tool from sibling input tools like appium_mobile_keyboard and appium_gesture without needing to open the schema.
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 choose this tool over alternatives or when not to use it. The only context is platform coverage ('on Android' vs 'on iOS/tvOS'), but the description never names a sibling like appium_mobile_keyboard or appium_perform_actions or gives a selection condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_observeARead-only
Compact one-line-per-element view of the current screen (class, id, desc, text, flags, center). Far cheaper than page source or generate_locators. Use diff=true after an action.
| Name | Required | Description | Default |
|---|---|---|---|
| diff | No | Return only changes since the last observe (default false). | |
| limit | No | Max nodes (default 80). | |
| sessionId | No | Session ID; defaults to the active session. | |
| includeText | No | Include text of non-clickable nodes (default true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety and scope are covered. The description adds cost/relative-expense context and the contents of each output line, which is genuinely useful, but says nothing about pagination/truncation behavior at limit=300 or about what 'diff' compares against beyond the schema's wording.
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, both front-loaded with the most decision-relevant facts: what the output looks like, its relative cost, and the one usage rule. No 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?
With no output schema, the description takes on the job of describing return contents and does so via the field list (class, id, desc, text, flags, center). Defaults for diff, limit, and includeText are left to the schema, which is reasonable given full coverage.
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 earns an extra point by giving the diff parameter situational meaning ('after an action') that the schema's 'since the last observe' does not convey.
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 (current screen) and the exact shape of the result (one line per element with class, id, desc, text, flags, center), which clearly distinguishes it from bulkier siblings like get_page_source. It lacks an explicit verb ('return'/'observe'), presenting itself as a noun phrase, but an agent can still tell precisely what it gets.
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 names two alternatives (page source, generate_locators) and frames this as the cheaper option, and it gives a concrete trigger for the diff parameter: 'Use diff=true after an action.' It stops short of stating when NOT to use it, such as when full hierarchy or attributes are required.
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; defaults to the active session. | |
| orientation | No | Required when action is set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false; the description adds that the tool can set orientation to LANDSCAPE or PORTRAIT. However, it does not mention side effects, persistence, or what the get action returns, leaving some behavioral detail undisclosed.
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, well-structured sentence that front-loads the core purpose and then lists supported actions and values. There is no filler or redundant content.
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 parameters and required fields, and the description conveys the get/set semantics. However, since there is no output schema, the description does not explain what the get action returns, which is a small but relevant completeness gap.
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 fully documents all three parameters and enums. The description mostly restates what the schema already provides (action=get/set, LANDSCAPE/PORTRAIT) without adding new semantic detail.
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-resource pair: 'Get or set the device/screen orientation.' It is specific enough to identify the tool's purpose, though it does not explicitly contrast it with sibling tools, so it misses the top score.
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 usage is implied: use this tool when you need to read or change the device orientation. It does not explicitly state when to prefer this over related siblings like appium_get_window_size or appium_context, nor 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_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; defaults to the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark readOnlyHint=false and openWorldHint=false, so the description must carry the interaction model — and it does, noting that multiple pointer sources run in parallel and are synchronized tick-by-tick, and that it is raw/low-level compared to the platform-normalizing sibling. It stops short of covering failure behavior (invalid action chains, element-level vs viewport coordinates, timeouts), which matters for a raw-action tool.
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, each earning its place: capability, concrete use cases, then the routing rule to the alternative. Nothing is repeated from the schema and the highest-value guidance is front-loaded.
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, highly-nested tool with no output schema, the description plus the fully documented schema give an agent what it needs to construct a valid call and choose the right tool. The remaining gap is expected failure/error semantics for malformed action chains, which is secondary given the schema quality.
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 nested action structure (pointerType, origin, duration, button) is fully documented in the schema, so the baseline is 3. The description adds only the conceptual framing that individual sources correspond to fingers in multi-touch, not syntax or format detail 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?
States a specific verb and resource — 'Execute raw W3C Actions API sequences' — and immediately scopes it against the sibling appium_gesture. An agent can distinguish this from the sibling without opening either schema, because the description names which gestures belong here (rotate, three-finger swipe, edge swipes) and which do 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?
It gives both directions explicitly: use this for custom multi-finger gestures, complex timing, or precise per-touch-point control; prefer appium_gesture for standard gestures (tap, scroll, swipe, pinch). The alternative and the condition selecting it are named, plus a concrete reason (automatic platform handling).
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 signed WDA for a real iOS device. Omit provisioningProfileUuid to list profiles; ask the user to choose, highlighting recommendedForWda. Pass the chosen UUID to download, package, and sign WDA; wildcard profiles use a concrete WDA bundle ID. Downloads/unsigned IPA are cached per version; signing always reruns. Pass capabilitiesHint to appium_session_management action=create to install/launch the signed WDA. 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?
Description discloses substantial behavior beyond annotations: omitting provisioningProfileUuid lists profiles, wildcard profiles use a concrete WDA bundle ID, downloads/unsigned IPA are cached per version while signing always reruns, and the tool hands off to appium_session_management. It also states prerequisites and the need to ask the user, which the readOnlyHint=false annotation alone does not convey.
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?
Dense but efficient: purpose, user-interaction flow, cache behavior, handoff, and requirements each earn their place. The most important operational detail (omit UUID to list profiles) appears immediately after the 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 complex, mutating tool with no output schema, the description covers prerequisites, two modes of operation, the exact next step (capabilitiesHint to appium_session_management), and cache semantics. However, it leaves the concrete shape of the returned profile list unspecified beyond 'list of available profiles' and 'recommendedForWda', so an agent lacks full return-value transparency.
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 already documents all three parameters (100% coverage), so baseline is 3. The description adds workflow-level meaning: the omission semantics of provisioningProfileUuid, the recommendedForWda highlighting, the cache/forceRebuild interaction ('signing always reruns'), and wildcard-profile behavior. This is meaningful but not exhaustive enough to warrant 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?
States a specific verb and resource: 'Prepare signed WDA for a real iOS device.' This clearly distinguishes from the sibling prepare_ios_simulator by targeting real devices, and the rest of the description narrows the exact deliverable (signed WDA).
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 clear context: real iOS device, requires macOS, Xcode 16+, paired developer-mode device, and a two-step flow depending on provisioningProfileUuid. It does not explicitly name an alternative like prepare_ios_simulator or state when not to use this tool, so it falls short of the 5-level 'explicit when-not/alternatives' bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_screen_intelARead-only
Classify the current screen (form, list, dialog, login...) and summarise inputs, buttons, navigation, keyboard/dialog state, below-the-fold content and suggested next actions. One call replaces page source + several finds.
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No | Also save this screen under a name for appium_ui_diff. | |
| sessionId | No | Session ID; defaults to the active session. | |
| verbosity | No | Output size. Default standard. |
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 that output is a summarisation rather than raw source, that it includes below-the-fold content beyond the visible viewport, and that it returns suggested next actions. It does not discuss size/latency characteristics or how verbosity affects the payload (the schema handles the parameter, not the behavior).
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, zero filler, with the primary capability front-loaded and the competitive positioning (replaces page source + finds) as the closing justification. Every clause corresponds to a concrete output element.
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 a non-trivial aggregation tool, the description usefully enumerates the shape of the result and mentions below-the-fold and suggested actions, which an agent could not otherwise infer. Minor gap: it does not clarify that the call is viewport-scoped versus full-tree, nor how verbosity changes the summary depth.
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 all three optional parameters documented, including the snapshot linkage to appium_ui_diff and the verbosity default, so the schema carries parameter meaning. The description adds no additional syntax, defaults, or interaction guidance for these parameters, placing it at 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?
Names a specific verb pair (classify, summarise) against a precise resource (the current screen) and enumerates exactly what is produced: type, inputs, buttons, navigation, keyboard/dialog state, below-the-fold content, suggested actions. It also positions itself against siblings by stating it replaces page source plus several finds, which maps to appium_get_page_source and appium_find_element(s).
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?
"One call replaces page source + several finds" gives clear context for preferring this tool over the low-level inspection siblings. It stops short of explicit exclusions or sequencing advice (e.g., when to prefer appium_locator_intel or appium_observe instead), so it is clear guidance without full when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_screen_recordingB
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; defaults to 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. Width:height, each 1–16384 (e.g. 1280:720); one may be -1 or -2 to preserve aspect ratio. | |
| pixelFormat | No | iOS only. Output pixel format (e.g. yuv420p). | |
| forceRestart | No | Restart and discard any active recording; default false. | |
| 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 declare readOnlyHint=false and openWorldHint=false, which is minimal context. The description adds that stop produces an MP4 file, but omits where that file lands, whether the path is returned, how forceRestart interacts with an in-flight recording, and that the recorder is stateful per session.
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 with the core capability front-loaded and zero filler. Nothing is repeated or padded.
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 stateful 13-parameter recorder with no output schema and thin annotations, the agent still lacks the outcome of the call — where the MP4 is saved or whether a path is returned — and any note that recording must be stopped explicitly. The description is far too thin for this tool's complexity.
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 action semantics, platform scoping, defaults, and the timeLimit caveat. The description's 'action=start/stop' restates what the schema already says, so baseline 3 applies with no added 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 pair and resource ('Start or stop screen recording') and clarifies both action values, so an agent knows exactly what the tool does. It never contrasts itself with the nearby appium_screenshot sibling or other capture tools, so differentiation is left implicit.
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 start/stop pairing implies a workflow (begin capture, then terminate to persist), but there is no explicit guidance on when to choose recording over screenshot, when a session must already exist, or whether recording should be stopped before session teardown.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_screenshotA
Take a screenshot and save as PNG. Optionally provide elementUUID to capture only that element.
| Name | Required | Description | Default |
|---|---|---|---|
| maxWidth | No | Resize to at most this width in pixels, preserving aspect ratio. | |
| sessionId | No | Session ID; defaults to the active session. | |
| elementUUID | No | Capture this element; omit for the full screen. | |
| returnRawBase64 | No | Return inline PNG instead of saving, for explicit manual use when the server file is inaccessible. LLMs must keep false and use the saved path. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the core behavior: capturing a screenshot and saving it as PNG. It does not contradict the annotations, but with readOnlyHint false and openWorldHint false, the annotations add little context, and the description does not mention output paths, return semantics, or limitations such as element visibility.
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 concise sentence that front-loads the main action and then introduces the optional element capture. Every word contributes to understanding, with no filler or repetition.
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 screenshot tool with fully documented parameters, the description plus schema is largely sufficient. It lacks an explicit statement of the return value, such as the saved file path, but the returnRawBase64 parameter description partially covers that expectation.
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 parameters are already well documented. The description mostly restates the elementUUID behavior found in the schema without adding significant new meaning, 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 uses a specific verb and resource: 'Take a screenshot and save as PNG.' It also distinguishes the element-capture mode from full-screen capture, making the tool's purpose clear and distinct from siblings like appium_screen_recording or appium_get_page_source.
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 purpose implies the tool should be used for still visual capture, and the optional elementUUID note adds a usage mode. However, it does not explicitly mention alternatives, such as screen recording or page source, or state when one should be preferred over the other.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_session_healthA
Diagnose a session: device state (adb), Appium server (remote), session liveness, app state and foreground, ANR dialog. Returns the failure kind with signals and whether replacing the session would help. With recover=true and only for a recoverable failure (dead session or driver), replaces the session once, bounded to 2 attempts per 10 minutes, never touches other sessions, never resets app data, relaunches the app and verifies the new session. Cloud and attached sessions are not replaced.
| Name | Required | Description | Default |
|---|---|---|---|
| appId | No | App to check and restore (defaults to the session capability appPackage/bundleId). | |
| detail | No | Return the full report even when healthy. | |
| recover | No | If the session is dead, delete it and create a new one with the same platform and capabilities. Default false (report only). | |
| sessionId | No | Session ID; defaults to the active session. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, so the mutating nature is already signalled; the description nonetheless adds real value with a rate bound (2 attempts per 10 minutes), scope guarantees (never touches other sessions, never resets app data), and the post-replacement verify step. It does not describe the shape of the returned signals or what the response looks like when recovery is attempted and fails.
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 the diagnostic scope before the recovery caveats, and essentially no filler. The second sentence is dense and runs long with stacked caveats, which slightly hurts scanability.
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 zero-required-parameter diagnostic with no output schema, it covers what is checked, what is returned (failure kind plus signals plus a replacement verdict), and the exact guardrails on the one mutating path. Remaining gap is the response shape on a report-only call, which the description only summarizes.
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 baseline is 3; the description still adds meaning for recover by narrowing it to specific failure kinds and by disclosing the retry ceiling, which the schema property text does not contain. It says nothing extra about detail or appId, and the default-to-active-session behavior it mentions is already in 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?
States a specific verb (Diagnose) and resource (a session), then enumerates exactly what is inspected: device state via adb, Appium server reachability, session liveness, app state/foreground, ANR dialog. That is far more specific than a title restatement, though it never names how it differs from siblings like appium_diagnose or 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?
Gives a clear condition for the mutating path: recover=true applies only to a recoverable failure (dead session or driver), and it states exclusions — cloud and attached sessions are not replaced. What's missing is routing guidance against the obvious alternatives (appium_diagnose, appium_session_management) for the non-recovery case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_session_managementADestructive
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 | create: Create a new Appium session. DEFAULT MODE (no remoteServerUrl): use 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. Ask for platform/device if unknown; do not assume a platform. - For iOS simulators, run prepare_ios_simulator before creating the session. - Call appium_session_management action=create with the selected platform and any returned capabilitiesHint serialized as capabilities. - Do NOT pass remoteServerUrl for local/embedded mode. NEVER invent a localhost URL. REMOTE SERVER MODE (only when user explicitly provides a URL): - Skip local device selection and preparation; do not call select_device. - Infer platform and device type from the request when possible; ask if unclear. - Use platform=general for non-Android/iOS drivers (Windows, macOS, custom); capabilities pass through without platform defaults. - Call appium_session_management action=create with platform, remoteServerUrl, and the requested capabilities. - Example: "create an iOS session at http://localhost:4723" means platform=ios and remoteServerUrl=http://localhost:4723; do not discover local devices. attach: connect to an existing remote Appium session without taking ownership of its lifecycle. Requires remoteServerUrl and sessionId; capabilities are fetched from the remote server. detach: remove an attached session from MCP without deleting the real remote session. Defaults to the active session. delete: delete a session and clean up resources. Defaults to the active session. list: list managed sessions with active flag, ownership, and current context. select: set sessionId as the active session for subsequent calls; requires sessionId. | |
| platform | No | Required for create. For local sessions, match the platform selected via select_device. For remote sessions, infer from the request; general supports non-Android/iOS drivers (Windows, macOS, custom) and requires remoteServerUrl. | |
| sessionId | No | Required for attach and select: the existing session to connect to or activate. For delete: session to delete. For detach: attached session to forget without stopping it. Delete/detach default to the active session when omitted. | |
| capabilities | No | Optional W3C capabilities as a JSON string, e.g. '{"appium:app":"/path/to/app","appium:platformVersion":"17.0"}'. Create: overrides defaults for ios/android; passed through as-is for general. Common keys: appium:app, appium:deviceName, appium:udid, appium:platformVersion, appium:bundleId. When using capabilitiesHint from a preparation tool, serialize the full object to JSON; preserve boolean and numeric values. Attach: optional fallback values (e.g. '{"platformName":"iOS"}'); capabilities fetched from the server take precedence. | |
| confirmToken | No | create only: required on the repeat call when capabilities request fullReset (CONFIRMATION REQUIRED). | |
| 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?
The description adds meaningful lifecycle distinctions beyond the annotations, especially that attach does not take ownership and detach removes a session from MCP without deleting the real remote session. This complements destructiveHint=true by clarifying which actions actually destroy resources.
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 front-loaded with the general purpose and then compactly maps each action to its effect. Every clause contributes to selecting the correct action, with no redundant wording.
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 six-parameter, destructive, multi-action session tool, the description provides adequate high-level action semantics, while the very rich schema carries the detailed create/attach/capability behavior. The top-level description itself does not surface the local-versus-remote create nuance, but that is well covered in structured schema descriptions.
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 parameter meanings are already documented in detail, including remote/local create behavior and confirmation requirements. The description only restates the action values and does not add parameter-level meaning 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 identifies session lifecycle management and enumerates all six actions, so the resource and operations are unambiguous. It does not explicitly contrast itself with sibling tools, keeping it below a 5.
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 gives direct action-selection guidance: create to start, attach for existing sessions, detach to forget without deleting, delete to stop, list to inspect, and select to activate. It lacks explicit when-not-use conditions or alternatives outside this tool, but the internal action routing is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_set_valueB
Enter text into an element
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The text to enter | |
| sessionId | No | Session ID; defaults to 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 already indicate readOnlyHint=false, so the mutation behavior is known. The description adds no further behavioral context such as whether existing text is replaced, whether the element must be editable, or how w3cActions changes focus behavior.
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 or redundant wording. It is appropriately concise for the simple operation it names.
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 annotations cover the mutation profile, but the description alone is thin for a tool with two distinct input modes (elementUUID vs w3cActions). Missing usage guidance and behavioral details prevent it from being 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 parameters are fully documented in the schema. The description itself adds no parameter-level meaning, but the baseline of 3 applies because the schema carries the 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 uses a specific verb and resource: 'Enter text into an element'. It clearly identifies the operation and target, and is distinguishable from sibling read tools like appium_get_text, though it does not explicitly name or contrast 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?
There is no guidance on when to use this tool versus alternatives such as appium_mobile_keyboard, appium_mobile_press_key, or appium_perform_actions. No exclusions, prerequisites, or selection criteria are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_verify_locatorARead-only
Count matches for each locator on the live screen. Only a count of exactly 1 is safe to put in test code; >1 is ambiguous, 0 is absent.
| Name | Required | Description | Default |
|---|---|---|---|
| locators | Yes | Locators to check, same grammar as wait_for. | |
| sessionId | No | Session ID; defaults to 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 safety is covered. The description adds real context beyond that: it operates against the live/current screen state rather than a cached snapshot, and it defines the interpretation thresholds for the returned counts. It says nothing about cost, timing, or whether the screen is re-queried per locator.
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, zero filler, with the action front-loaded and the interpretation rule immediately after. Nothing redundant or out of order.
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 two-parameter read-only tool with no output schema, the description conveys the essential shape of the result (a count per locator) and how to read it. The only gap is that it does not state the literal return structure or whether mismatched locators are reported together, but that is a minor omission here.
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%, including the note that locators use the same grammar as wait_for and that sessionId defaults to the active session, so the schema already carries the parameter meaning. The description adds only that counts are produced per locator, without elaborating on the array or the session override. 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?
The description opens with a specific verb and resource: "Count matches for each locator on the live screen." That clearly separates it from the element-returning siblings (appium_find_element, appium_find_elements) and from appium_wait_for. It stops short of naming any sibling explicitly, so it lands at a clear-but-undifferentiated 4.
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 gives the decision rule for acting on the result: only a count of exactly 1 is safe for test code, >1 is ambiguous, 0 is absent. That tells the agent the situation this tool is for (validating a locator before committing it to a test). It does not mention when to skip this tool in favor of appium_wait_for or appium_locator_intel, so no explicit alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
appium_wait_forARead-only
Poll until a locator is present (or gone). Use instead of retrying find_element after navigation.
| Name | Required | Description | Default |
|---|---|---|---|
| until | No | Default present. | |
| locator | Yes | id=..., desc=..., text=..., xpath=..., uia=... or pred=... | |
| sessionId | No | Session ID; defaults to the active session. | |
| timeoutSec | No | Default 15. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds that the tool polls, which is useful behavioral context. However, it omits critical wait semantics: polling interval, what happens on timeout (throw vs. return null/false), and whether the matched element is returned — none of which is recoverable from an output schema, since none exists.
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, zero filler, with the core action stated first and the routing guidance second. Nothing could be trimmed without losing 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?
With four fully documented params and no output schema, the definition is close to sufficient, but a wait tool's most important contract — timeout behavior and what is returned on success versus failure — is left entirely unstated. An agent cannot tell whether it must follow this with a find call or whether the element comes back directly.
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 locator syntax, the until enum, sessionId defaulting, and the 1-120s timeout range. The description only echoes the present/gone duality; it adds no additional meaning, so the 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 (poll/wait) and resource (a locator) plus the two conditions it supports (present or gone). It also implicitly distinguishes itself from appium_find_element by naming 'retrying find_element' as the thing it replaces.
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 an explicit usage rule: use this instead of retrying find_element after navigation. That names both the context and the alternative. It stops short of stating when NOT to use it (e.g., when you need the element handle itself, which presumably requires appium_find_element).
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 current-page locator candidates for inspection. Defaults: controls for UiAutomator2/XCUITest/Web; all elements except hierarchy for other native drivers.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Return at most this many elements (default: all). | |
| query | No | Case-insensitive literal substring of an element tag or attribute value (name, label, text, ID, etc.). Searches all element types, including hidden elements. Blank or omitted keeps the default driver-specific filter. | |
| sessionId | No | Session ID; defaults to the active session. | |
| xpathAttributes | No | Additional XPath attribute names in priority order, e.g. AutomationId or data-testid. Tried before built-in attributes; defaults remain as fallback. No namespace prefixes or XPath expressions. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description earns credit for disclosing the driver-dependent default filtering (controls for UiAutomator2/XCUITest/Web, all elements except hierarchy for other native drivers), which is real behavioral context not derivable from structured fields. It stops short of explaining what a 'locator candidate' actually is, whether results are ranked, or why hierarchy is excluded.
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, front-loaded with the action and scope, followed by the defaults. Nothing is wasted, though terms like 'controls' and 'hierarchy' are used without unpacking, which leaves the second sentence denser than it needs to be.
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?
There is no output schema, so the description carries the burden of explaining the return value, and it does not: it never says what a candidate looks like (XPath, accessibility ID, UiSelector), how many are returned by default, or whether they are ordered. For a read-only, zero-required-param tool the risk is low, but the deliverable is underspecified.
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 baseline is 3; the description exceeds that by defining what the 'default driver-specific filter' referenced in the query parameter actually resolves to per driver, which the schema leaves opaque. It adds no new detail on limit, sessionId, or xpathAttributes, but those are already well documented in 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 gives a specific verb and resource: 'Generate current-page locator candidates for inspection.' An agent immediately knows this produces candidate selectors for the currently loaded screen. It does not, however, distinguish itself from nearby siblings such as appium_locator_intel, appium_verify_locator, or appium_find_elements, so the differentiation job is left undone.
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?
'For inspection' implies the exploratory/debugging use case, but there is no explicit when-to-use statement, no when-not-to-use exclusion, and no pointer to alternatives like appium_verify_locator (to validate a chosen locator) or appium_find_element (to act on one). The usage is inferable but not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepare_ios_simulatorA
Boot an iOS/tvOS simulator, download/cache WDA, and launch it on a free per-simulator port. Pass capabilitiesHint (appium:webDriverAgentUrl) to appium_session_management action=create to reuse WDA. skipWda=true only boots. APPIUM_MCP_WDA_APP_PATH can point to an extracted WebDriverAgentRunner-Runner.app (absolute path) to skip download.
| 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?
Annotations only mark this as not read-only, so the description carries the burden. It adds valuable behavioral context: WDA is cached, launched on a free per-simulator port, and can be skipped via an environment variable pointing to an already-extracted app. It doesn't describe failure modes or cleanup, but the main side effects are visible.
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 carry all necessary information, with the core action front-loaded and optional usage details following. It is appropriately concise, though the second and third sentences are dense and mix integration guidance with environment configuration.
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, the description still explains the full setup flow: boot, WDA download/cache/launch, reuse via capabilities, and the skip-download path via environment variable. It implies the returned WDA URL without explicitly stating it, leaving a minor gap for an agent that needs to rely solely on this text.
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 references skipWda and the environment variable override, which supplements the schema slightly, but it does not add significant new meaning to the parameters beyond what the property 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+resource: boot an iOS/tvOS simulator, download/cache WebDriverAgent, and launch it on a per-simulator port. This clearly distinguishes it from the sibling appium_prepare_ios_real_device by targeting simulators and explicitly mentions Apple TV support.
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 provides concrete usage direction: pass capabilitiesHint (appium:webDriverAgentUrl) to appium_session_management to reuse WDA, and use skipWda=true when only booting is needed. It stops short of explicitly stating when not to use this tool or comparing it to the real-device sibling, so it isn't a perfect 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
select_deviceA
Discover/select a LOCAL device. Ask for platform if unknown; one device is auto-selected. For multiple devices, ask the user to choose, then pass deviceUdid. Next: prepare_ios_simulator for iOS simulators, then appium_session_management action=create. Skip for REMOTE servers: pass device capabilities (appium:deviceName/appium:udid) and the user-provided remoteServerUrl to session creation.
| Name | Required | Description | Default |
|---|---|---|---|
| platform | Yes | Platform chosen by the user. | |
| deviceUdid | No | User-selected UDID. Omit to discover devices. | |
| iosDeviceType | No | Required for ios: simulator or real device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide little signal (both hints false), so the description carries the behavioral burden. It discloses interactive behavior: asking the user, auto-selecting one device, or requesting a choice among multiple. It also explains what to do in the remote case, giving the agent a clear behavioral contract, though it does not address no-device or failure scenarios.
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 with the core purpose, then proceeds through decision branches and exceptions. It uses semicolons and colons to pack workflow into three sentences with minimal waste. A bulleted structure might improve scannability, but 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 simple parameter surface and lack of an output schema, the description covers purpose, decision rules, the remote exception, and next steps for iOS simulators. It is missing a real-iOS device route and any behavior for zero devices found, but the overall flow is clear enough for an agent to invoke the tool correctly in common cases.
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 each parameter already has a meaningful description. The tool description adds only slight reinforcement, such as 'ask the user to choose, then pass deviceUdid,' which is already implied by the schema. There is no substantial semantic value beyond the schema, so 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 opens with a specific verb and resource: 'Discover/select a LOCAL device.' It clearly delineates local versus remote use, which distinguishes it from sibling Appium session/device tools. The phrase 'Skip for REMOTE servers' further separates this tool's scope from session-creation 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 description gives explicit decision guidance: ask for platform if unknown, auto-select when one device, ask the user when multiple, and skip for remote servers by passing capabilities to session creation. However, it only names prepare_ios_simulator for iOS simulators and omits the real-iOS preparation path, leaving a sibling-adjacent gap.
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.
40 tool updates
v1.99.3- First observed
appium_alert - First observed
appium_app_lifecycle - First observed
appium_batch - First observed
appium_context - First observed
appium_diagnose - First observed
appium_drag_and_drop - First observed
appium_driver_settings - First observed
appium_find_element - First observed
appium_find_elements - 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_locator_intel - 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_observe - First observed
appium_orientation - First observed
appium_perform_actions - First observed
appium_prepare_ios_real_device - First observed
appium_screen_intel - First observed
appium_screen_recording - First observed
appium_screenshot - First observed
appium_session_health - First observed
appium_session_management - First observed
appium_set_value - First observed
appium_verify_locator - First observed
appium_wait_for - First observed
generate_locators - First observed
prepare_ios_simulator - First observed
select_device
TDQS
Scored across 40 tools
Many tools have distinct purposes, but there are notable overlapping clusters: screen inspection (appium_observe, appium_screen_intel, appium_get_page_source, generate_locators), element finding (appium_find_element, appium_find_elements, appium_wait_for, appium_verify_locator), and diagnostics/recovery (appium_diagnose, appium_session_health, appium_session_management). Descriptions often clarify intended use, but the volume and overlap still create meaningful misselection risk.
Most names are snake_case and readable, but the appium_ prefix is inconsistent: select_device, prepare_ios_simulator, and generate_locators lack it while most others include it. Verb style also varies between action-oriented names and noun-like names such as appium_screen_intel, appium_alert, and appium_context.
With 40 tools, the surface is well beyond a typical focused tool set for mobile automation and includes several overlapping inspection, locator, and diagnostic tools. While the domain is broad, many tools could be consolidated, making the count excessive for practical selection.
The set covers a wide Appium lifecycle: device selection/preparation, session management, gestures, element interaction, app lifecycle, files, permissions, geolocation, diagnostics, and test generation. Minor gaps remain around explicit log/network/performance retrieval, but the core mobile automation surface is largely complete.
Maintenance
Related MCP Connectors
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.
Let AI agents control Android and iOS devices on Mobilerun Cloud: screen, input, apps, workflows.
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
Give your AI agent a real cloud Android phone: push APKs, drive it, get screenshots and logs.
Related MCP Servers
- 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

MCP Appiumofficial
AlicenseAqualityBmaintenanceEnables AI assistants to automate mobile app testing and development for iOS and Android through natural language interactions. Supports intelligent element identification, session management, automated test generation, and comprehensive device interactions including clicks, swipes, screenshots, and app management.3216,435 npm518Apache 2.0- AlicenseAqualityBmaintenanceEnables AI assistants to control mobile and desktop devices with natural language, including running automation tasks, taking screenshots, and managing devices.65 npmMIT

MobAI MCP Serverofficial
AlicenseAqualityCmaintenanceEnables AI assistants to automate mobile devices (Android and iOS) through a single DSL interface, supporting actions like tap, type, swipe, and assertions.20147 npm254Apache 2.0