Simplify adb_input with string coordinates to fix MCP validation

- Changed all coordinate parameters to string type with empty defaults
- Simplified parameter validation using string checks
- Updated documentation to show string coordinates
- Removed complex optional parameter combinations causing MCP issues

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

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

View File

@ -41,28 +41,6 @@ class ADBCommand(BaseModel):
device_id: Optional[str] = None device_id: Optional[str] = None
class InputAction(BaseModel):
"""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 # Initialize FastMCP server
mcp = FastMCP("android-mcp-server") mcp = FastMCP("android-mcp-server")
@ -172,48 +150,60 @@ async def adb_screenshot(
@mcp.tool() @mcp.tool()
async def adb_input( async def adb_input(
action: InputAction = Field(description="Input action to perform on the device"), action_type: str,
device_id: Optional[str] = Field(None, description="Target device ID (if multiple devices connected)") x: str = "",
y: str = "",
x2: str = "",
y2: str = "",
key_code: str = "",
text: str = "",
device_id: Optional[str] = None
) -> Dict[str, Any]: ) -> Dict[str, Any]:
""" """
Send input events to Android device to simulate user interactions. Send input events to Android device to simulate user interactions.
Supports various input types: Supports various input types with simple parameter interface:
- tap: Single touch at coordinates (requires x, y) - tap: adb_input(action_type="tap", x="400", y="600")
- swipe: Drag gesture from one point to another (requires x, y, x2, y2) - swipe: adb_input(action_type="swipe", x="100", y="200", x2="300", y2="400")
- key: Hardware key press (requires key_code like KEYCODE_BACK) - key: adb_input(action_type="key", key_code="KEYCODE_BACK")
- text: Type text input (requires text string) - text: adb_input(action_type="text", text="Hello World")
Args: Args:
action: Input action configuration with type and parameters action_type: Type of input action ("tap", "swipe", "key", "text")
x: X coordinate for tap/swipe start (required for tap/swipe)
y: Y coordinate for tap/swipe start (required for tap/swipe)
x2: X coordinate for swipe end (required for swipe)
y2: Y coordinate for swipe end (required for swipe)
key_code: Android key code like KEYCODE_BACK (required for key)
text: Text to type (required for text)
device_id: Specific device to target (optional if only one device) device_id: Specific device to target (optional if only one device)
Returns: Returns:
Command execution result with success status Command execution result with success status
""" """
if action.action_type == "tap": if action_type == "tap":
if action.x is None or action.y is None: if not x or not y:
raise ValueError("tap action requires x and y coordinates") raise ValueError("tap action requires x and y coordinates")
cmd = ["shell", "input", "tap", str(action.x), str(action.y)] cmd = ["shell", "input", "tap", x, y]
elif action.action_type == "swipe": elif action_type == "swipe":
if any(coord is None for coord in [action.x, action.y, action.x2, action.y2]): if not x or not y or not x2 or not y2:
raise ValueError("swipe action requires x, y, x2, y2 coordinates") raise ValueError("swipe action requires x, y, x2, y2 coordinates")
cmd = ["shell", "input", "swipe", str(action.x), str(action.y), str(action.x2), str(action.y2)] cmd = ["shell", "input", "swipe", x, y, x2, y2]
elif action.action_type == "key": elif action_type == "key":
if action.key_code is None: if not key_code:
raise ValueError("key action requires key_code") raise ValueError("key action requires key_code")
cmd = ["shell", "input", "keyevent", action.key_code] cmd = ["shell", "input", "keyevent", key_code]
elif action.action_type == "text": elif action_type == "text":
if action.text is None: if not text:
raise ValueError("text action requires text") raise ValueError("text action requires text")
cmd = ["shell", "input", "text", action.text] cmd = ["shell", "input", "text", text]
else: else:
raise ValueError(f"Unknown action type: {action.action_type}") raise ValueError(f"Unknown action type: {action_type}. Must be one of: tap, swipe, key, text")
result = await run_adb_command(cmd, device_id) result = await run_adb_command(cmd, device_id)
return result return result