This server provides 10 tools with explicit Zod schemas and descriptions. All tools are properly registered via server.tool() with type-safe input validation. However, there are significant gaps in definition quality: (1) output schemas are not documented, responses return generic text content without structured field definitions; (2) parameter descriptions are functional but minimal, averaging ~60 chars and lacking actionable guidance on valid ranges, formats, or dependencies; (3) error messages are generic catch-all blocks that don't classify errors as retryable, user-fixable, or fatal; (4) no tool composition guidance, related tools (install-apk, uninstall-apk, clear-app-data) don't document how they chain; (5) destructive operations (kill-server, uninstall-apk, clear-app-data) lack confirmation/dry-run patterns. Tool names are clear action verbs (get-, list-, install-, etc.), which is a strength. Schemas use Zod with basic type safety (boolean, string), but do not enforce ranges, enums, or format constraints, e.g. deviceId accepts any string without validation. Most tools (6 of 10) return plain text results in isError/content structure with no structured output schema, forcing LLMs to parse unstructured output.
No documented output schemas. All tools return generic {content: [{type: 'text', text: string}]} or {isError: true, content: [...]} without specifying what fields or structured data the LLM should expect. This forces LLMs to parse free-form text rather than extract typed fields, increasing error rates and token waste.
Destructive operations (kill-server, uninstall-apk, clear-app-data) lack confirmation or dry-run patterns. An agent can irreversibly kill the ADB server or delete app data without a confirmation step, inviting catastrophic errors.
Generic error handling. All tools wrap errors in catch-all blocks that return 'Failed to X: [error message]' without classifying errors as retryable, user-fixable, or fatal. LLMs cannot decide whether to retry, ask the user, or give up.
Recommendations
Add structured output schemas to all tools. Instead of returning plain text, parse ADB output and return typed objects. E.g., get-devices should return {devices: [{id: string, status: string, model?: string}]} and list-packages should return {packages: [{name: string, path?: string, installer?: string}], total: number} for pagination support.
Add input validation and constraints. Enforce deviceId format (serial number validation), apkPath existence check, and packageName non-empty constraint. Return actionable errors: 'Invalid deviceId: got "xyz", expected a 12-16 character serial number or 'emulator-5554'.'
Implement confirmation flow for destructive operations. Add a dry-run parameter or split kill-server into check-server + kill-server-confirmed. Document in descriptions: 'This operation is irreversible. Call confirm_kill_server() first.'
Classify errors into recovery categories. Parse stderr to detect 'device offline', 'permission denied', 'file not found' and return: {status: 'error', errorType: 'user_fixable'|'retryable'|'fatal', message: '...', nextSteps: ['...'], recoveryGuide: '...'}. This lets LLMs know whether to retry, ask the user, or abort.
Add tool composition guidance in descriptions. E.g., install-apk should note: 'First call get-devices() to list available devices, then install-apk() to install. After installation, call list-packages() to verify.' Uninstall should warn: 'Use list-packages() to find the packageName before calling this.'
Document parameter formats and constraints in descriptions. E.g., deviceId: 'Target device serial number (e.g., "192.168.1.100:5555" for wireless, "emulator-5554" for emulator, or device serial from get-devices).' apkPath: 'Absolute or relative path to a valid .apk file (will be validated on execution).'
Score history
Overall score trend
↑ 33 points across a rubric change (v1 → v2)
53/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-21
D
53
2026-07-28+
v2
2026-03-09
F
20
-
v1
Pull a file from the Android device to the local machine
Parameter descriptions lack actionable format guidance. E.g., deviceId accepts any string without explaining the expected format (e.g., 'serial number, typically 12-16 hex chars'). apkPath accepts any string without validation that it's a valid file path. Missing constraints invite invalid inputs.
No tool composition hints. Related tools (install-apk, uninstall-apk, list-packages, clear-app-data) do not document how they chain. E.g., list-packages should hint 'Call this first to identify the target package before uninstalling.' Missing dependencies force extra agent reasoning.
Boolean flags with unclear side effects. allowDowngrade (default true) in install-apk and allowReinstall (default true), it's unclear whether defaults are safe or risky. Defaults that allow dangerous actions invite agent errors.
install-apk
Add batch variants for tools agents call in loops. E.g., batch_uninstall_apk([{deviceId, packageNames: []}]) instead of n separate uninstall calls, reducing latency and token waste.
Simplify complex parameter sets using defaults. E.g., install-apk should default allowReinstall=false (safer), grantPermissions=true (common intent). Document: 'Use allowReinstall=true only if you intend to upgrade an existing app.'
Return pagination hints for large result sets. list-packages could return {packages: [...], count: number, note: 'Showing 50 results; call list-packages with a filter to narrow results'} so agents know they can request subsets.
Add error recovery suggestions. E.g., if install-apk fails with 'device offline', return: 'Device is not responding. Try: 1) Reconnect USB cable, 2) call start-server(), 3) call get-devices() to verify connection, then retry.'