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
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
mcp = FastMCP("android-mcp-server")
@ -172,48 +150,60 @@ async def adb_screenshot(
@mcp.tool()
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)")
action_type: str,
x: str = "",
y: str = "",
x2: str = "",
y2: str = "",
key_code: str = "",
text: str = "",
device_id: Optional[str] = None
) -> 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)
Supports various input types with simple parameter interface:
- tap: adb_input(action_type="tap", x="400", y="600")
- swipe: adb_input(action_type="swipe", x="100", y="200", x2="300", y2="400")
- key: adb_input(action_type="key", key_code="KEYCODE_BACK")
- text: adb_input(action_type="text", text="Hello World")
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)
Returns:
Command execution result with success status
"""
if action.action_type == "tap":
if action.x is None or action.y is None:
if action_type == "tap":
if not x or not y:
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":
if any(coord is None for coord in [action.x, action.y, action.x2, action.y2]):
elif action_type == "swipe":
if not x or not y or not x2 or not y2:
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":
if action.key_code is None:
elif action_type == "key":
if not 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":
if action.text is None:
elif action_type == "text":
if not text:
raise ValueError("text action requires text")
cmd = ["shell", "input", "text", action.text]
cmd = ["shell", "input", "text", text]
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)
return result