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:
parent
db6998510c
commit
9b1ba05695
174
src/server.py
174
src/server.py
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user