feat: introduce MCP server, cross-platform runtime, and Showcase UI reorganization

- Showcase UI Reorganization:
  * Move web UI dashboard from root directory into apps/showcase_ui/ for cleaner project structure
  * Add 'artemis ui' CLI command (artemis/interfaces/cli/commands/ui.py) and launcher scripts for the interactive showcase console
- Standalone MCP Server & Notifiers (mcp_server/):
  * Implement dedicated MCP server package with mobile automation tools (device_state, inspect_trace, task_manager, task_runner)
  * Add multi-channel notifiers (AgentAPI, Desktop notifications, Webhooks, File output, and Composite routing)
  * Introduce background task runner and trace store for autonomous mobile execution monitoring
- Cross-Platform Runtime & Toolchain Support:
  * Add artemis/platform/ with OS-specific implementations for Linux, macOS (Darwin), and Windows
  * Add artemis/runtime/supervisor.py for resilient process and agent runtime supervision
  * Add artemis/toolchain/ with dependency resolution and SDK descriptors
  * Add cross-platform launcher scripts (start.sh, start.bat) and installer scripts (scripts/install_deps.*)
- Core Enhancements & Diagnostics:
  * Enhance coordinate normalization, OCR API fallback, and perception pipeline
  * Add credential validation (credentials_validator.py) and system diagnostics
  * Update bilingual documentation (README.md, README_CN.md) and architecture diagrams
- Test Suite Expansion:
  * Add integration tests for cloud gateway, remote ADB, and Artemis login
  * Add unit tests covering core diagnostics, platform detection, toolchain, credentials validator, optional OCR, and MCP tools
This commit is contained in:
somew1nd committed 2026-08-18 13:59:27 -07:00
1 parent 78e478f502
commit 9a5aaf99b7
249 files changed
+37226 -9339

No files matched your search

+20
View File
@@ -0,0 +1,20 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Internal MCP servers for ARTEMIS engine (ADB server, XML Fuzzy Search)."""
from artemis.mcp.adb_server import mcp as adb_mcp
from artemis.mcp.xml_search_server import mcp as xml_mcp
__all__ = ["adb_mcp", "xml_mcp"]
+9 -1
View File
@@ -29,9 +29,17 @@ if _REPO_ROOT not in sys.path:
from adbutils import AdbClient
from mcp.server.fastmcp import Context, FastMCP
try:
from mcp.server.fastmcp.server import Settings as FastMCPSettings
FastMCPSettings.model_rebuild()
except Exception:
pass
from artemis.clients.ui_automator_client import UIAutomatorClient
from artemis.context import ArtemisContext, DeviceContext, DevicePlatform
from artemis.controllers.unified_controller import UnifiedMobileController
from artemis.platform import platform
from artemis.utils.app_launch_utils import launch_app_with_retries
# Redirect stdio to prevent logs from breaking MCP JSON-RPC protocol and causing deadlocks.
@@ -130,7 +138,7 @@ def _get_controller():
ctx = ArtemisContext(
trace_id="mcp-session",
device=DeviceContext(
host_platform="LINUX",
host_platform=platform.os_type.name,
mobile_platform=DevicePlatform.ANDROID,
device_id=device_id,
device_width=width,
+10 -3
View File
@@ -25,6 +25,13 @@ if _REPO_ROOT not in sys.path:
# pylint: disable=wrong-import-position
from mcp.server.fastmcp import FastMCP
try:
from mcp.server.fastmcp.server import Settings as FastMCPSettings
FastMCPSettings.model_rebuild()
except Exception:
pass
from artemis.data_engine.storage import StorageManager
mcp = FastMCP("Android_XML_Fuzzy_Search")
@@ -83,7 +90,7 @@ def serialize_node(node, max_depth=1):
@mcp.tool()
def search_ui(image_hash: str, query: str, threshold: float = 0.6) -> dict:
"""Search for text in UI data (XML and OCR) retrieved from Data Engine by image hash.
"""Search for text in UI data retrieved from Data Engine by image hash.
Args:
image_hash: The SHA-256 hash of the image.
@@ -153,7 +160,7 @@ def parse_bounds(bounds_str):
@mcp.tool()
def search_by_coordinates(image_hash: str, x: int, y: int) -> str:
"""Search for elements in UI data (XML and OCR) retrieved from Data Engine by image hash that overlap with the given coordinates.
"""Search for elements in UI data retrieved from Data Engine by image hash that overlap with the given coordinates.
Args:
image_hash: The SHA-256 hash of the image.
@@ -161,7 +168,7 @@ def search_by_coordinates(image_hash: str, x: int, y: int) -> str:
y: The Y coordinate.
Returns:
A string containing the matching nodes and OCR results.
A string containing the matching nodes.
"""
db_path = os.getenv("DATA_ENGINE_DB_PATH")
if not db_path: