uiautomator2-mcp-server 0.1.1__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- uiautomator2_mcp_server-0.1.2/CHANGELOG.md +21 -0
- {uiautomator2_mcp_server-0.1.1/src/uiautomator2_mcp_server.egg-info → uiautomator2_mcp_server-0.1.2}/PKG-INFO +17 -10
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/README.md +6 -6
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/pyproject.toml +18 -3
- uiautomator2_mcp_server-0.1.2/src/u2mcp/__main__.py +82 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/u2mcp/_version.py +3 -3
- uiautomator2_mcp_server-0.1.2/src/u2mcp/mcp.py +61 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/u2mcp/tools/device.py +4 -3
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2/src/uiautomator2_mcp_server.egg-info}/PKG-INFO +17 -10
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/uiautomator2_mcp_server.egg-info/requires.txt +1 -1
- uiautomator2_mcp_server-0.1.1/CHANGELOG.md +0 -7
- uiautomator2_mcp_server-0.1.1/src/u2mcp/__main__.py +0 -60
- uiautomator2_mcp_server-0.1.1/src/u2mcp/mcp.py +0 -18
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/LICENSE +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/MANIFEST.in +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/setup.cfg +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/u2mcp/.gitignore +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/u2mcp/__init__.py +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/u2mcp/py.typed +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/u2mcp/tools/__init__.py +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/u2mcp/tools/action.py +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/u2mcp/tools/app.py +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/uiautomator2_mcp_server.egg-info/SOURCES.txt +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/uiautomator2_mcp_server.egg-info/dependency_links.txt +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/uiautomator2_mcp_server.egg-info/entry_points.txt +0 -0
- {uiautomator2_mcp_server-0.1.1 → uiautomator2_mcp_server-0.1.2}/src/uiautomator2_mcp_server.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# CHANGELOG
|
|
2
|
+
|
|
3
|
+
## 0.1.2
|
|
4
|
+
|
|
5
|
+
> 📅 2026-01-09
|
|
6
|
+
|
|
7
|
+
- ⛓️💥 Breaking:
|
|
8
|
+
- http/stdio transport is now a required command line argument, user should choose either `http` or `stdio`, `stdio` is the default.
|
|
9
|
+
|
|
10
|
+
- 🆕 New:
|
|
11
|
+
- Added Authorization bearer token verification
|
|
12
|
+
- Added `--log-level` command line argument
|
|
13
|
+
|
|
14
|
+
- 🗑️ Removed:
|
|
15
|
+
- Removed the feature that http/stdio transports run at the same
|
|
16
|
+
|
|
17
|
+
## 0.1.1
|
|
18
|
+
|
|
19
|
+
> 📅 2026-01-06
|
|
20
|
+
|
|
21
|
+
An early release.
|
|
@@ -1,25 +1,32 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: uiautomator2-mcp-server
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: uiautomator2 mcp server
|
|
5
|
-
Author: tanbro
|
|
6
|
-
License: GPL-3.0-or-later
|
|
5
|
+
Author-email: tanbro <tanbro@163.com>
|
|
6
|
+
License-Expression: GPL-3.0-or-later
|
|
7
7
|
Project-URL: homepage, https://github.com/tanbro/uiautomator2-mcp-server
|
|
8
8
|
Project-URL: documentation, https://github.com/tanbro/uiautomator2-mcp-server/blob/main/README.md
|
|
9
9
|
Project-URL: repository, https://github.com/tanbro/uiautomator2-mcp-server.git
|
|
10
10
|
Project-URL: issues, https://github.com/tanbro/uiautomator2-mcp-server/issues
|
|
11
11
|
Project-URL: changelog, https://github.com/tanbro/uiautomator2-mcp-server/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: uiautomator2,mcp,fastmcp,adb,android,adbutils
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
12
19
|
Requires-Python: >=3.11
|
|
13
20
|
Description-Content-Type: text/markdown
|
|
14
21
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: fastmcp<3.0,>=2.
|
|
22
|
+
Requires-Dist: fastmcp<3.0,>=2.11.0
|
|
16
23
|
Requires-Dist: uiautomator2<4.0,>=3.5
|
|
17
24
|
Dynamic: license-file
|
|
18
25
|
|
|
19
26
|
# uiautomator2-mcp-server
|
|
20
27
|
|
|
21
|
-

|
|
22
|
-

|
|
28
|
+
[](https://github.com/tanbro/uiautomator2-mcp-server)
|
|
29
|
+
[](https://pypi.org/project/uiautomator2-mcp-server/)
|
|
23
30
|
|
|
24
31
|
A MCP (Model Context Protocol) server that provides tools for controlling and interacting with Android devices using uiautomator2. This server allows you to perform various operations on Android devices such as connecting to devices, taking screenshots, getting device information, accessing UI hierarchy, tap on screens, and more.
|
|
25
32
|
|
|
@@ -36,8 +43,8 @@ A MCP (Model Context Protocol) server that provides tools for controlling and in
|
|
|
36
43
|
## Requirements
|
|
37
44
|
|
|
38
45
|
- Python >= 3.11
|
|
39
|
-
-
|
|
40
|
-
- Android device
|
|
46
|
+
- adb executable in your PATH
|
|
47
|
+
- Android device connected in debug mode
|
|
41
48
|
|
|
42
49
|
## Installation
|
|
43
50
|
|
|
@@ -54,10 +61,10 @@ The server can be run in different transport modes:
|
|
|
54
61
|
|
|
55
62
|
```bash
|
|
56
63
|
# Run in streamable HTTP mode
|
|
57
|
-
u2mcp --
|
|
64
|
+
u2mcp --host 0.0.0.0 --port 8000 --no-token http
|
|
58
65
|
|
|
59
66
|
# Run in stdio mode
|
|
60
|
-
u2mcp
|
|
67
|
+
u2mcp stdio
|
|
61
68
|
```
|
|
62
69
|
|
|
63
70
|
### Using the Tools
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# uiautomator2-mcp-server
|
|
2
2
|
|
|
3
|
-

|
|
4
|
-

|
|
3
|
+
[](https://github.com/tanbro/uiautomator2-mcp-server)
|
|
4
|
+
[](https://pypi.org/project/uiautomator2-mcp-server/)
|
|
5
5
|
|
|
6
6
|
A MCP (Model Context Protocol) server that provides tools for controlling and interacting with Android devices using uiautomator2. This server allows you to perform various operations on Android devices such as connecting to devices, taking screenshots, getting device information, accessing UI hierarchy, tap on screens, and more.
|
|
7
7
|
|
|
@@ -18,8 +18,8 @@ A MCP (Model Context Protocol) server that provides tools for controlling and in
|
|
|
18
18
|
## Requirements
|
|
19
19
|
|
|
20
20
|
- Python >= 3.11
|
|
21
|
-
-
|
|
22
|
-
- Android device
|
|
21
|
+
- adb executable in your PATH
|
|
22
|
+
- Android device connected in debug mode
|
|
23
23
|
|
|
24
24
|
## Installation
|
|
25
25
|
|
|
@@ -36,10 +36,10 @@ The server can be run in different transport modes:
|
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
# Run in streamable HTTP mode
|
|
39
|
-
u2mcp --
|
|
39
|
+
u2mcp --host 0.0.0.0 --port 8000 --no-token http
|
|
40
40
|
|
|
41
41
|
# Run in stdio mode
|
|
42
|
-
u2mcp
|
|
42
|
+
u2mcp stdio
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
### Using the Tools
|
|
@@ -3,10 +3,25 @@ name = "uiautomator2-mcp-server"
|
|
|
3
3
|
dynamic = ["version"]
|
|
4
4
|
description = "uiautomator2 mcp server"
|
|
5
5
|
readme = "README.md"
|
|
6
|
-
authors = [{ name = "tanbro" }]
|
|
6
|
+
authors = [{ name = "tanbro", email = "tanbro@163.com" }]
|
|
7
7
|
requires-python = ">=3.11"
|
|
8
|
-
dependencies = ["fastmcp>=2.
|
|
9
|
-
license =
|
|
8
|
+
dependencies = ["fastmcp>=2.11.0,<3.0", "uiautomator2>=3.5,<4.0"]
|
|
9
|
+
license = "GPL-3.0-or-later"
|
|
10
|
+
keywords = ["uiautomator2", "mcp", "fastmcp", "adb", "android", "adbutils"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
# How mature is this project? Common values are
|
|
13
|
+
# 3 - Alpha
|
|
14
|
+
# 4 - Beta
|
|
15
|
+
# 5 - Production/Stable
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
|
|
18
|
+
# Specify the Python versions you support here.
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Programming Language :: Python :: 3.14",
|
|
24
|
+
]
|
|
10
25
|
|
|
11
26
|
[build-system]
|
|
12
27
|
requires = ["setuptools>=80", "setuptools-scm>=8"]
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import re
|
|
5
|
+
import secrets
|
|
6
|
+
from typing import Annotated, Any, Literal
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def run(
|
|
12
|
+
transport: Annotated[
|
|
13
|
+
Literal["http", "stdio"], typer.Argument(help="Run mcp server on streamable-http http or stdio transport")
|
|
14
|
+
] = "stdio",
|
|
15
|
+
host: Annotated[
|
|
16
|
+
str, typer.Option("--host", "-H", show_default=False, help="Host address of streamable-http transport")
|
|
17
|
+
] = "127.0.0.1",
|
|
18
|
+
port: Annotated[
|
|
19
|
+
int, typer.Option("--port", "-p", show_default=False, help="Port number of streamable-http transport")
|
|
20
|
+
] = 8000,
|
|
21
|
+
json_response: Annotated[bool, typer.Option("--json-response", "-j", help="Whether to use JSON response format")] = True,
|
|
22
|
+
log_level: Annotated[
|
|
23
|
+
Literal["debug", "info", "warning", "error", "critical"], typer.Option("--log-level", "-l", help="Log level")
|
|
24
|
+
] = "info",
|
|
25
|
+
no_token: Annotated[
|
|
26
|
+
bool,
|
|
27
|
+
typer.Option(
|
|
28
|
+
"--no-token",
|
|
29
|
+
help="Disable authentication bearer token verification of streamable-http transport. If not set, a token will be generated randomly.",
|
|
30
|
+
),
|
|
31
|
+
] = False,
|
|
32
|
+
token: Annotated[
|
|
33
|
+
str | None,
|
|
34
|
+
typer.Option("--token", "-t", help="Explicit set token of streamable-http authentication"),
|
|
35
|
+
] = None,
|
|
36
|
+
):
|
|
37
|
+
"""Run uiautomator2 mcp server"""
|
|
38
|
+
logging.basicConfig(
|
|
39
|
+
level=log_level.upper(),
|
|
40
|
+
format="[%(asctime)s] %(levelname)s %(name)s - %(message)s",
|
|
41
|
+
handlers=[logging.StreamHandler()],
|
|
42
|
+
force=True,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
logging.getLogger("mcp.server").setLevel(logging.WARNING)
|
|
46
|
+
logging.getLogger("sse_starlette").setLevel(logging.WARNING)
|
|
47
|
+
logging.getLogger("docket").setLevel(logging.WARNING)
|
|
48
|
+
logging.getLogger("fakeredis").setLevel(logging.WARNING)
|
|
49
|
+
|
|
50
|
+
from . import tools as _
|
|
51
|
+
from .mcp import mcp, update_params
|
|
52
|
+
|
|
53
|
+
transport_kwargs: dict[str, Any] = {"json_response": json_response}
|
|
54
|
+
|
|
55
|
+
update_params(transport=transport)
|
|
56
|
+
|
|
57
|
+
if transport == "http":
|
|
58
|
+
if token:
|
|
59
|
+
token = token.strip()
|
|
60
|
+
if not re.match(r"^[a-zA-Z0-9\-_.~!$&'()*+,;=:@]{8,64}$", token):
|
|
61
|
+
raise typer.BadParameter("Token must be 8-64 characters long and can only contain URL-safe characters")
|
|
62
|
+
elif not no_token:
|
|
63
|
+
token = secrets.token_urlsafe()
|
|
64
|
+
if token:
|
|
65
|
+
update_params(token=token, host=host, port=port)
|
|
66
|
+
|
|
67
|
+
if host:
|
|
68
|
+
transport_kwargs["host"] = host
|
|
69
|
+
if port:
|
|
70
|
+
transport_kwargs["port"] = port
|
|
71
|
+
|
|
72
|
+
mcp.run(transport="streamable-http", **transport_kwargs, log_level=log_level)
|
|
73
|
+
else:
|
|
74
|
+
mcp.run(log_level=log_level)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def main():
|
|
78
|
+
typer.run(run)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
if __name__ == "__main__":
|
|
82
|
+
main()
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
31
|
+
__version__ = version = '0.1.2'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 2)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g5defce9f7'
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This MCP server provides tools for controlling and interacting with Android devices using uiautomator2.
|
|
3
|
+
|
|
4
|
+
It allows you to perform various operations on Android devices such as connecting to devices, taking screenshots,
|
|
5
|
+
getting device information, accessing UI hierarchy, tap on screens, and more...
|
|
6
|
+
|
|
7
|
+
It also provides tools for managing Android applications, such as installing, uninstalling, starting, stopping, and clearing applications.
|
|
8
|
+
|
|
9
|
+
Before performing operations on a device, you need to initialize it using the init tool.
|
|
10
|
+
|
|
11
|
+
All operations require a device serial number to identify the target device.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from contextlib import asynccontextmanager
|
|
15
|
+
from textwrap import dedent
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
from fastmcp import FastMCP
|
|
19
|
+
from fastmcp.server.auth import AccessToken, AuthProvider
|
|
20
|
+
from rich.console import Console
|
|
21
|
+
from rich.markdown import Markdown
|
|
22
|
+
|
|
23
|
+
__all__ = ["mcp"]
|
|
24
|
+
|
|
25
|
+
_params: dict[str, Any] = {}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def update_params(**kwargs):
|
|
29
|
+
global _params
|
|
30
|
+
_params.update(kwargs)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@asynccontextmanager
|
|
34
|
+
async def _lifespan(instance: FastMCP):
|
|
35
|
+
if _params.get("transport") == "http" and (token := _params.get("token")):
|
|
36
|
+
content = dedent(f"""
|
|
37
|
+
------
|
|
38
|
+
|
|
39
|
+
**Server configured with authentication token. Connect using this token in the Authorization header:**
|
|
40
|
+
|
|
41
|
+
`Authorization: Bearer {token}`
|
|
42
|
+
|
|
43
|
+
------
|
|
44
|
+
""").strip()
|
|
45
|
+
Console().print(Markdown(content))
|
|
46
|
+
|
|
47
|
+
yield
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class _SimpleTokenAuthProvider(AuthProvider):
|
|
51
|
+
_scopes = ["mcp:tools"]
|
|
52
|
+
|
|
53
|
+
async def verify_token(self, token: str) -> AccessToken | None:
|
|
54
|
+
if server_token := _params.get("token"):
|
|
55
|
+
if token == server_token:
|
|
56
|
+
return AccessToken(token=token, client_id="user", scopes=self._scopes)
|
|
57
|
+
return None
|
|
58
|
+
return AccessToken(token=token, client_id="user", scopes=self._scopes)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
mcp = FastMCP(name="uiautomator2", instructions=__doc__, lifespan=_lifespan, auth=_SimpleTokenAuthProvider())
|
|
@@ -10,8 +10,7 @@ from typing import Any, Literal
|
|
|
10
10
|
|
|
11
11
|
import uiautomator2 as u2
|
|
12
12
|
from adbutils import adb
|
|
13
|
-
from fastmcp.dependencies import
|
|
14
|
-
from fastmcp.server.context import Context
|
|
13
|
+
from fastmcp.server.dependencies import get_context
|
|
15
14
|
from fastmcp.utilities.logging import get_logger
|
|
16
15
|
from PIL.Image import Image
|
|
17
16
|
|
|
@@ -62,7 +61,7 @@ async def device_list() -> list[dict[str, Any]]:
|
|
|
62
61
|
|
|
63
62
|
|
|
64
63
|
@mcp.tool("init")
|
|
65
|
-
async def init(serial: str = ""
|
|
64
|
+
async def init(serial: str = ""):
|
|
66
65
|
"""Install essential resources to device.
|
|
67
66
|
|
|
68
67
|
Important:
|
|
@@ -111,6 +110,8 @@ async def init(serial: str = "", ctx: Context = CurrentContext()):
|
|
|
111
110
|
|
|
112
111
|
logger.info("read uiautomator2 init command stdio")
|
|
113
112
|
|
|
113
|
+
ctx = get_context()
|
|
114
|
+
|
|
114
115
|
while True:
|
|
115
116
|
tag, line = await output_queue.get()
|
|
116
117
|
|
|
@@ -1,25 +1,32 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: uiautomator2-mcp-server
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: uiautomator2 mcp server
|
|
5
|
-
Author: tanbro
|
|
6
|
-
License: GPL-3.0-or-later
|
|
5
|
+
Author-email: tanbro <tanbro@163.com>
|
|
6
|
+
License-Expression: GPL-3.0-or-later
|
|
7
7
|
Project-URL: homepage, https://github.com/tanbro/uiautomator2-mcp-server
|
|
8
8
|
Project-URL: documentation, https://github.com/tanbro/uiautomator2-mcp-server/blob/main/README.md
|
|
9
9
|
Project-URL: repository, https://github.com/tanbro/uiautomator2-mcp-server.git
|
|
10
10
|
Project-URL: issues, https://github.com/tanbro/uiautomator2-mcp-server/issues
|
|
11
11
|
Project-URL: changelog, https://github.com/tanbro/uiautomator2-mcp-server/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: uiautomator2,mcp,fastmcp,adb,android,adbutils
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
12
19
|
Requires-Python: >=3.11
|
|
13
20
|
Description-Content-Type: text/markdown
|
|
14
21
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: fastmcp<3.0,>=2.
|
|
22
|
+
Requires-Dist: fastmcp<3.0,>=2.11.0
|
|
16
23
|
Requires-Dist: uiautomator2<4.0,>=3.5
|
|
17
24
|
Dynamic: license-file
|
|
18
25
|
|
|
19
26
|
# uiautomator2-mcp-server
|
|
20
27
|
|
|
21
|
-

|
|
22
|
-

|
|
28
|
+
[](https://github.com/tanbro/uiautomator2-mcp-server)
|
|
29
|
+
[](https://pypi.org/project/uiautomator2-mcp-server/)
|
|
23
30
|
|
|
24
31
|
A MCP (Model Context Protocol) server that provides tools for controlling and interacting with Android devices using uiautomator2. This server allows you to perform various operations on Android devices such as connecting to devices, taking screenshots, getting device information, accessing UI hierarchy, tap on screens, and more.
|
|
25
32
|
|
|
@@ -36,8 +43,8 @@ A MCP (Model Context Protocol) server that provides tools for controlling and in
|
|
|
36
43
|
## Requirements
|
|
37
44
|
|
|
38
45
|
- Python >= 3.11
|
|
39
|
-
-
|
|
40
|
-
- Android device
|
|
46
|
+
- adb executable in your PATH
|
|
47
|
+
- Android device connected in debug mode
|
|
41
48
|
|
|
42
49
|
## Installation
|
|
43
50
|
|
|
@@ -54,10 +61,10 @@ The server can be run in different transport modes:
|
|
|
54
61
|
|
|
55
62
|
```bash
|
|
56
63
|
# Run in streamable HTTP mode
|
|
57
|
-
u2mcp --
|
|
64
|
+
u2mcp --host 0.0.0.0 --port 8000 --no-token http
|
|
58
65
|
|
|
59
66
|
# Run in stdio mode
|
|
60
|
-
u2mcp
|
|
67
|
+
u2mcp stdio
|
|
61
68
|
```
|
|
62
69
|
|
|
63
70
|
### Using the Tools
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
fastmcp<3.0,>=2.
|
|
1
|
+
fastmcp<3.0,>=2.11.0
|
|
2
2
|
uiautomator2<4.0,>=3.5
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
import logging
|
|
5
|
-
from typing import Annotated, Any, Awaitable
|
|
6
|
-
|
|
7
|
-
import typer
|
|
8
|
-
|
|
9
|
-
logging.basicConfig(
|
|
10
|
-
level=logging.INFO,
|
|
11
|
-
format="[%(asctime)s] %(levelname)s %(name)s - %(message)s",
|
|
12
|
-
handlers=[logging.StreamHandler()],
|
|
13
|
-
force=True,
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
logging.getLogger("mcp.server").setLevel(logging.WARNING)
|
|
17
|
-
logging.getLogger("sse_starlette").setLevel(logging.WARNING)
|
|
18
|
-
logging.getLogger("docket").setLevel(logging.WARNING)
|
|
19
|
-
logging.getLogger("fakeredis").setLevel(logging.WARNING)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def run(
|
|
23
|
-
http: Annotated[bool, typer.Option("--http", "-h", help="Run mcp server in streamable http mode")] = False,
|
|
24
|
-
stdio: Annotated[bool, typer.Option("--stdio", "-s", help="Run mcp server in stdio mode")] = False,
|
|
25
|
-
host: Annotated[str | None, typer.Option("--host", "-H", show_default=False, help="Host address for http mode")] = None,
|
|
26
|
-
port: Annotated[int | None, typer.Option("--port", "-p", show_default=False, help="Port number for http mode")] = None,
|
|
27
|
-
log_level: Annotated[str | None, typer.Option("--log-level", "-l", help="Log level")] = None,
|
|
28
|
-
):
|
|
29
|
-
"""Run uiautomator2 mcp server"""
|
|
30
|
-
if not http and not stdio:
|
|
31
|
-
typer.Abort("Please specify one of ‘--http’ or ‘--stdio’")
|
|
32
|
-
|
|
33
|
-
from . import tools as _
|
|
34
|
-
from .mcp import mcp
|
|
35
|
-
|
|
36
|
-
awaitables: list[Awaitable] = []
|
|
37
|
-
|
|
38
|
-
if http:
|
|
39
|
-
transport_kwargs: dict[str, Any] = {}
|
|
40
|
-
if host:
|
|
41
|
-
transport_kwargs["host"] = host
|
|
42
|
-
if port:
|
|
43
|
-
transport_kwargs["port"] = port
|
|
44
|
-
awaitables.append(mcp.run_http_async(transport="streamable-http", **transport_kwargs, log_level=log_level))
|
|
45
|
-
|
|
46
|
-
if stdio:
|
|
47
|
-
awaitables.append(mcp.run_stdio_async(log_level=log_level))
|
|
48
|
-
|
|
49
|
-
async def _run():
|
|
50
|
-
await asyncio.gather(*awaitables)
|
|
51
|
-
|
|
52
|
-
asyncio.run(_run())
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def main():
|
|
56
|
-
typer.run(run)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if __name__ == "__main__":
|
|
60
|
-
main()
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This MCP server provides tools for controlling and interacting with Android devices using uiautomator2.
|
|
3
|
-
|
|
4
|
-
It allows you to perform various operations on Android devices such as connecting to devices, taking screenshots,
|
|
5
|
-
getting device information, accessing UI hierarchy, tap on screens, and more...
|
|
6
|
-
|
|
7
|
-
It also provides tools for managing Android applications, such as installing, uninstalling, starting, stopping, and clearing applications.
|
|
8
|
-
|
|
9
|
-
Before performing operations on a device, you need to initialize it using the init tool.
|
|
10
|
-
|
|
11
|
-
All operations require a device serial number to identify the target device.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
from fastmcp import FastMCP
|
|
15
|
-
|
|
16
|
-
__all__ = ["mcp"]
|
|
17
|
-
|
|
18
|
-
mcp = FastMCP(name="uiautomator2", instructions=__doc__)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|