Skip to main content
Glama

android-device

Manage Android devices by listing, connecting, disconnecting, rebooting, and retrieving properties through the DroidMind MCP server.

Instructions

Perform various device management operations on Android devices.

This single tool consolidates various device-related actions. The 'action' parameter determines the operation.

Args: action: The specific device operation to perform. ctx: MCP Context for logging and interaction. serial (Optional[str]): Device serial number. Required by most actions except connect/list. ip_address (Optional[str]): IP address for 'connect_device' action. port (Optional[int]): Port for 'connect_device' action (default: 5555). mode (Optional[str]): Reboot mode for 'reboot_device' action (default: "normal").

Returns: A string message indicating the result or status of the operation.


Available Actions and their specific argument usage:

  1. action="list_devices"

    • No specific arguments required beyond ctx.

  2. action="connect_device"

    • Requires: ip_address

    • Optional: port

  3. action="disconnect_device"

    • Requires: serial

  4. action="reboot_device"

    • Requires: serial

    • Optional: mode (e.g., "normal", "recovery", "bootloader")

  5. action="device_properties"

    • Requires: serial


Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYes
serialNo
ip_addressNo
portNo
modeNonormal

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler function for the 'android-device' MCP tool. Decorated with @mcp.tool(name='android-device'). It validates inputs based on action and dispatches to specific helper implementations (_list_devices_impl, _connect_device_impl, etc.) for list_devices, connect_device, disconnect_device, reboot_device, and device_properties actions.
    @mcp.tool(name="android-device")
    async def android_device(
        action: DeviceAction,
        ctx: Context,
        serial: str | None = None,
        ip_address: str | None = None,
        port: int = 5555,
        mode: str = "normal",
    ) -> str:
        """
        Perform various device management operations on Android devices.
    
        This single tool consolidates various device-related actions.
        The 'action' parameter determines the operation.
    
        Args:
            action: The specific device operation to perform.
            ctx: MCP Context for logging and interaction.
            serial (Optional[str]): Device serial number. Required by most actions except connect/list.
            ip_address (Optional[str]): IP address for 'connect_device' action.
            port (Optional[int]): Port for 'connect_device' action (default: 5555).
            mode (Optional[str]): Reboot mode for 'reboot_device' action (default: "normal").
    
        Returns:
            A string message indicating the result or status of the operation.
    
        ---
        Available Actions and their specific argument usage:
    
        1.  `action="list_devices"`
            - No specific arguments required beyond `ctx`.
        2.  `action="connect_device"`
            - Requires: `ip_address`
            - Optional: `port`
        3.  `action="disconnect_device"`
            - Requires: `serial`
        4.  `action="reboot_device"`
            - Requires: `serial`
            - Optional: `mode` (e.g., "normal", "recovery", "bootloader")
        5.  `action="device_properties"`
            - Requires: `serial`
        ---
        """
        try:
            # Argument checks based on action
            if (
                action
                in [
                    DeviceAction.DISCONNECT_DEVICE,
                    DeviceAction.REBOOT_DEVICE,
                    DeviceAction.DEVICE_PROPERTIES,
                ]
                and serial is None
            ):
                return f"❌ Error: 'serial' is required for action '{action.value}'."
    
            if action == DeviceAction.CONNECT_DEVICE and ip_address is None:
                return "❌ Error: 'ip_address' is required for action 'connect_device'."
    
            # Dispatch to implementations
            if action == DeviceAction.LIST_DEVICES:
                return await _list_devices_impl(ctx)
            if action == DeviceAction.CONNECT_DEVICE:
                # ip_address is checked not None above
                return await _connect_device_impl(ctx, ip_address, port)  # type: ignore
            if action == DeviceAction.DISCONNECT_DEVICE:
                return await _disconnect_device_impl(serial, ctx)  # type: ignore
            if action == DeviceAction.REBOOT_DEVICE:
                return await _reboot_device_impl(serial, ctx, mode)  # type: ignore
            if action == DeviceAction.DEVICE_PROPERTIES:
                return await _device_properties_impl(serial, ctx)  # type: ignore
    
            # Should not be reached if DeviceAction enum is comprehensive
            valid_actions = ", ".join([act.value for act in DeviceAction])
            logger.error("Invalid device action '%s' received. Valid actions are: %s", action, valid_actions)
            return f"❌ Error: Unknown device action '{action}'. Valid actions are: {valid_actions}."
    
        except Exception as e:
            logger.exception("Unexpected error during device operation %s for serial '%s': %s", action, serial, e)
            return f"❌ Error: An unexpected error occurred during '{action.value}': {e!s}"
  • Enum class DeviceAction defining the possible actions (sub-commands) for the android-device tool, used as the 'action' parameter in the handler.
    class DeviceAction(str, Enum):
        """Defines the available sub-actions for the 'android-device' tool."""
    
        LIST_DEVICES = "list_devices"
        CONNECT_DEVICE = "connect_device"
        DISCONNECT_DEVICE = "disconnect_device"
        REBOOT_DEVICE = "reboot_device"
        DEVICE_PROPERTIES = "device_properties"
  • Helper function implementing the 'list_devices' action: lists connected devices using get_device_manager().
    async def _list_devices_impl(ctx: Context) -> str:
        """
        List all connected Android devices.
    
        Returns:
            A formatted list of connected devices with their basic information.
        """
        try:
            devices = await get_device_manager().list_devices()
    
            if not devices:
                return "No devices connected. Use the connect_device tool to connect to a device."
    
            # Format the device information
            result = f"# Connected Android Devices ({len(devices)})\n\n"
    
            for i, device in enumerate(devices, 1):
                model = await device.model
                android_version = await device.android_version
                result += f"""## Device {i}: {model}
    - **Serial**: `{device.serial}`
    - **Android Version**: {android_version}
    """
    
            return result
        except Exception as e:
            logger.exception("Error in list_devices_impl: %s", e)
            return f"❌ Error listing devices: {e}\n\nCheck logs for detailed traceback."
  • Helper function implementing the 'connect_device' action: validates IP/port and connects using get_device_manager().connect().
    async def _connect_device_impl(ctx: Context, ip_address: str, port: int = 5555) -> str:
        """
        Connect to an Android device over TCP/IP.
    
        Args:
            ip_address: The IP address of the device to connect to
            port: The port to connect to (default: 5555)
    
        Returns:
            A message indicating success or failure
        """
        # Validate IP address format
        ip_pattern = r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$"
        if not re.match(ip_pattern, ip_address):
            return "❌ Invalid IP address format. Please use the format: xxx.xxx.xxx.xxx"
    
        # Validate port range
        if port < 1 or port > 65535:
            return "❌ Invalid port number. Port must be between 1 and 65535."
    
        try:
            # Attempt to connect to the device
            device = await get_device_manager().connect(ip_address, port)
    
            if device:
                model = await device.model
                android_version = await device.android_version
    
                return f"""
    # ✨ Device Connected Successfully! ✨
    
    - **Device**: {model}
    - **Connection**: {ip_address}:{port}
    - **Android Version**: {android_version}
    
    The device is now available for commands and operations.
                """
    
            return f"❌ Failed to connect to device at {ip_address}:{port}"
        except Exception as e:
            logger.exception("Error connecting to device in _connect_device_impl: %s", e)
            return f"❌ Error connecting to device: {e!s}"
  • MCP tool registration decorator specifying the tool name as 'android-device'.
    @mcp.tool(name="android-device")
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It does well by documenting the return type ('string message indicating result or status') and default values for port and mode. However, it lacks information about error conditions, side effects (e.g., whether reboot_device is destructive), authentication requirements, or rate limits that would be important for a device management tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections: general purpose, parameter overview, and detailed action documentation. It's appropriately sized for a multi-action tool. However, the 'Returns' section could be integrated more smoothly, and some redundancy exists between the Args section and the detailed action list.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex multi-action tool with 5 parameters and 0% schema coverage, the description provides excellent coverage of parameter usage and action-specific requirements. The presence of an output schema means the description doesn't need to detail return values. The main gap is lack of behavioral context about side effects, errors, and prerequisites that would be important for device operations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Given 0% schema description coverage, the description fully compensates by providing comprehensive parameter documentation. It explains the purpose of the 'action' parameter as determining the operation, documents all 5 parameters with their relationships to specific actions, distinguishes required vs optional parameters, provides default values, and gives examples for the 'mode' parameter. This adds substantial value beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool performs 'various device management operations on Android devices' and consolidates multiple actions. It distinguishes itself from siblings by focusing on device-level operations rather than app, file, or UI interactions. However, it could be more specific about the exact scope of 'device management' beyond the listed actions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear guidance through the 'Available Actions' section, showing when each action is appropriate and what parameters they require. It distinguishes between required and optional parameters for each action. However, it doesn't explicitly state when to choose this tool over sibling tools like android-shell or android-diag for related operations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hyperb1iss/droidmind'

If you have feedback or need assistance with the MCP directory API, please join our Discord server