Skip to main content
Glama

Android MCP Server

import os import sys import yaml from mcp.server.fastmcp import FastMCP, Image from adbdevicemanager import AdbDeviceManager CONFIG_FILE = "config.yaml" CONFIG_FILE_EXAMPLE = "config.yaml.example" # Load config (make config file optional) config = {} device_name = None if os.path.exists(CONFIG_FILE): try: with open(CONFIG_FILE) as f: config = yaml.safe_load(f.read()) or {} device_config = config.get("device", {}) configured_device_name = device_config.get( "name") if device_config else None # Support multiple ways to specify auto-selection: # 1. name: null (None in Python) # 2. name: "" (empty string) # 3. name field completely missing if configured_device_name and configured_device_name.strip(): device_name = configured_device_name.strip() print(f"Loaded config from {CONFIG_FILE}") print(f"Configured device: {device_name}") else: print(f"Loaded config from {CONFIG_FILE}") print( "No device specified in config, will auto-select if only one device connected") except Exception as e: print(f"Error loading config file {CONFIG_FILE}: {e}", file=sys.stderr) print( f"Please check the format of your config file or recreate it from {CONFIG_FILE_EXAMPLE}", file=sys.stderr) sys.exit(1) else: print( f"Config file {CONFIG_FILE} not found, using auto-selection for device") # Initialize MCP and device manager # AdbDeviceManager will handle auto-selection if device_name is None mcp = FastMCP("android") deviceManager = AdbDeviceManager(device_name) @mcp.tool() def get_packages() -> str: """ Get all installed packages on the device Returns: str: A list of all installed packages on the device as a string """ result = deviceManager.get_packages() return result @mcp.tool() def execute_adb_shell_command(command: str) -> str: """Executes an ADB command and returns the output or an error. Args: command (str): The ADB shell command to execute Returns: str: The output of the ADB command """ result = deviceManager.execute_adb_shell_command(command) return result @mcp.tool() def get_uilayout() -> str: """ Retrieves information about clickable elements in the current UI. Returns a formatted string containing details about each clickable element, including its text, content description, bounds, and center coordinates. Returns: str: A formatted list of clickable elements with their properties """ result = deviceManager.get_uilayout() return result @mcp.tool() def get_screenshot() -> Image: """Takes a screenshot of the device and returns it. Returns: Image: the screenshot """ deviceManager.take_screenshot() return Image(path="compressed_screenshot.png") @mcp.tool() def get_package_action_intents(package_name: str) -> list[str]: """ Get all non-data actions from Activity Resolver Table for a package Args: package_name (str): The name of the package to get actions for Returns: list[str]: A list of all non-data actions from the Activity Resolver Table for the package """ result = deviceManager.get_package_action_intents(package_name) return result if __name__ == "__main__": mcp.run(transport="stdio")

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/minhalvp/android-mcp-server'

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