Enhance tool descriptions and parameter annotations

- Added comprehensive docstrings for all MCP tools
- Enhanced Pydantic Field descriptions with examples
- Added detailed parameter validation and constraints
- Improved type hints for better IDE support
- Added usage examples in parameter descriptions

Tools improved:
- adb_devices: Better device status documentation
- adb_screenshot: Clear file handling explanation
- adb_input: Detailed action type documentation with examples
- adb_launch_app: Package name examples and usage
- adb_launch_url: URL scheme support documentation
- adb_list_packages: Filtering capabilities explained
- adb_shell_command: Security warnings and examples

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ryan Malloy 2025-08-12 12:20:38 -06:00
parent db6998510c
commit 9b1ba05695

View File

@ -18,16 +18,21 @@ from pydantic import BaseModel, Field
class DeviceInfo(BaseModel):
"""Android device information"""
device_id: str
status: str
"""Android device information returned by ADB"""
device_id: str = Field(description="Unique device identifier/serial number")
status: str = Field(
description="Device connection status",
json_schema_extra={
"examples": ["device", "offline", "unauthorized", "no permissions"]
}
)
class ScreenshotResult(BaseModel):
"""Screenshot capture result"""
success: bool
local_path: Optional[str] = None
error: Optional[str] = None
"""Screenshot capture operation result"""
success: bool = Field(description="Whether the screenshot was captured successfully")
local_path: Optional[str] = Field(None, description="Absolute path to the saved screenshot file")
error: Optional[str] = Field(None, description="Error message if operation failed")
class ADBCommand(BaseModel):
@ -37,14 +42,26 @@ class ADBCommand(BaseModel):
class InputAction(BaseModel):
"""Input action parameters"""
action_type: str = Field(description="Type of input: tap, swipe, key")
x: Optional[int] = None
y: Optional[int] = None
x2: Optional[int] = None
y2: Optional[int] = None
key_code: Optional[str] = None
text: Optional[str] = None
"""Input action parameters for simulating user interactions"""
action_type: str = Field(
description="Type of input action to perform",
json_schema_extra={
"enum": ["tap", "swipe", "key", "text"],
"examples": ["tap", "swipe", "key", "text"]
}
)
x: Optional[int] = Field(None, description="X coordinate for tap/swipe start (pixels)", ge=0)
y: Optional[int] = Field(None, description="Y coordinate for tap/swipe start (pixels)", ge=0)
x2: Optional[int] = Field(None, description="X coordinate for swipe end (pixels)", ge=0)
y2: Optional[int] = Field(None, description="Y coordinate for swipe end (pixels)", ge=0)
key_code: Optional[str] = Field(
None,
description="Android key code (e.g., KEYCODE_BACK, KEYCODE_HOME, KEYCODE_CAMERA)",
json_schema_extra={
"examples": ["KEYCODE_BACK", "KEYCODE_HOME", "KEYCODE_CAMERA", "KEYCODE_VOLUME_DOWN"]
}
)
text: Optional[str] = Field(None, description="Text to type (for text action type)")
# Initialize FastMCP server
@ -86,7 +103,15 @@ async def run_adb_command(cmd: List[str], device_id: Optional[str] = None) -> Di
@mcp.tool()
async def adb_devices() -> List[DeviceInfo]:
"""List all connected Android devices"""
"""
List all Android devices connected via USB or network.
Returns device information including unique identifiers and connection status.
Use this to identify available devices before performing other operations.
Returns:
List of connected devices with their IDs and status
"""
result = await run_adb_command(["devices"])
if not result["success"]:
@ -108,8 +133,23 @@ async def adb_devices() -> List[DeviceInfo]:
@mcp.tool()
async def adb_screenshot(device_id: Optional[str] = None, local_filename: str = "screenshot.png") -> ScreenshotResult:
"""Take screenshot from Android device and save locally"""
async def adb_screenshot(
device_id: Optional[str] = Field(None, description="Target device ID (if multiple devices connected)"),
local_filename: str = Field("screenshot.png", description="Local filename to save screenshot to")
) -> ScreenshotResult:
"""
Capture a screenshot from Android device and save it locally.
Takes a screenshot of the current screen content and saves it as a PNG file.
Automatically handles device communication and file transfer.
Args:
device_id: Specific device to target (optional if only one device)
local_filename: Name for the saved screenshot file
Returns:
Result object with success status and file path
"""
# Take screenshot on device
result = await run_adb_command(["shell", "screencap", "-p", "/sdcard/temp_screenshot.png"], device_id)
@ -131,8 +171,26 @@ async def adb_screenshot(device_id: Optional[str] = None, local_filename: str =
@mcp.tool()
async def adb_input(action: InputAction, device_id: Optional[str] = None) -> Dict[str, Any]:
"""Send input events to Android device"""
async def adb_input(
action: InputAction = Field(description="Input action to perform on the device"),
device_id: Optional[str] = Field(None, description="Target device ID (if multiple devices connected)")
) -> Dict[str, Any]:
"""
Send input events to Android device to simulate user interactions.
Supports various input types:
- tap: Single touch at coordinates (requires x, y)
- swipe: Drag gesture from one point to another (requires x, y, x2, y2)
- key: Hardware key press (requires key_code like KEYCODE_BACK)
- text: Type text input (requires text string)
Args:
action: Input action configuration with type and parameters
device_id: Specific device to target (optional if only one device)
Returns:
Command execution result with success status
"""
if action.action_type == "tap":
if action.x is None or action.y is None:
@ -162,24 +220,69 @@ async def adb_input(action: InputAction, device_id: Optional[str] = None) -> Dic
@mcp.tool()
async def adb_launch_app(package_name: str, device_id: Optional[str] = None) -> Dict[str, Any]:
"""Launch Android app by package name"""
async def adb_launch_app(
package_name: str = Field(description="Android package name (e.g., com.android.chrome)"),
device_id: Optional[str] = Field(None, description="Target device ID (if multiple devices connected)")
) -> Dict[str, Any]:
"""
Launch an Android application by its package name.
Starts the main activity of the specified app. Use adb_list_packages to find
available package names on the device.
Args:
package_name: Full package identifier (e.g., com.android.chrome, com.whatsapp)
device_id: Specific device to target (optional if only one device)
Returns:
Command execution result with success status and output
"""
cmd = ["shell", "monkey", "-p", package_name, "-c", "android.intent.category.LAUNCHER", "1"]
result = await run_adb_command(cmd, device_id)
return result
@mcp.tool()
async def adb_launch_url(url: str, device_id: Optional[str] = None) -> Dict[str, Any]:
"""Open URL in default browser"""
async def adb_launch_url(
url: str = Field(description="URL to open (e.g., https://example.com)"),
device_id: Optional[str] = Field(None, description="Target device ID (if multiple devices connected)")
) -> Dict[str, Any]:
"""
Open a URL in the device's default browser application.
Launches the default browser and navigates to the specified URL.
Supports HTTP, HTTPS, and other URL schemes supported by Android.
Args:
url: Web address to navigate to
device_id: Specific device to target (optional if only one device)
Returns:
Command execution result with success status
"""
cmd = ["shell", "am", "start", "-a", "android.intent.action.VIEW", "-d", url]
result = await run_adb_command(cmd, device_id)
return result
@mcp.tool()
async def adb_list_packages(device_id: Optional[str] = None, filter_text: Optional[str] = None) -> Dict[str, Any]:
"""List installed packages on device"""
async def adb_list_packages(
device_id: Optional[str] = Field(None, description="Target device ID (if multiple devices connected)"),
filter_text: Optional[str] = Field(None, description="Filter packages containing this text (e.g., 'chrome', 'google')")
) -> Dict[str, Any]:
"""
List all installed applications on the Android device.
Retrieves package names of all installed apps, optionally filtered by text.
Useful for finding package names to use with adb_launch_app.
Args:
device_id: Specific device to target (optional if only one device)
filter_text: Only return packages containing this text
Returns:
Dictionary with success status, package list, and count
"""
cmd = ["shell", "pm", "list", "packages"]
if filter_text:
cmd.extend(["|", "grep", filter_text])
@ -202,8 +305,23 @@ async def adb_list_packages(device_id: Optional[str] = None, filter_text: Option
@mcp.tool()
async def adb_shell_command(command: str, device_id: Optional[str] = None) -> Dict[str, Any]:
"""Execute shell command on Android device"""
async def adb_shell_command(
command: str = Field(description="Shell command to execute (e.g., 'ls /sdcard', 'getprop ro.build.version.release')"),
device_id: Optional[str] = Field(None, description="Target device ID (if multiple devices connected)")
) -> Dict[str, Any]:
"""
Execute arbitrary shell commands on the Android device.
Runs commands in the Android shell environment. Use with caution as this
provides direct access to the device's command line interface.
Args:
command: Shell command string to execute
device_id: Specific device to target (optional if only one device)
Returns:
Command execution result with stdout, stderr, and return code
"""
cmd = ["shell"] + command.split()
result = await run_adb_command(cmd, device_id)
return result