From 660e8ca124ebb778a316fc8edb84b27fdf497a1e Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Sun, 8 Jun 2025 19:25:09 +0800 Subject: [PATCH] feat: add mcp tool ToolGetForegroundApp --- internal/version/VERSION | 2 +- uixt/mcp_server.go | 13 ++++++----- uixt/mcp_tools_app.go | 47 ++++++++++++++++++++++++++++++++++++++++ uixt/option/action.go | 4 ++++ 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/internal/version/VERSION b/internal/version/VERSION index 802023e6..04dd715f 100644 --- a/internal/version/VERSION +++ b/internal/version/VERSION @@ -1 +1 @@ -v5.0.0-beta-2506081916 +v5.0.0-beta-2506081925 diff --git a/uixt/mcp_server.go b/uixt/mcp_server.go index b64d4e13..6b51bd88 100644 --- a/uixt/mcp_server.go +++ b/uixt/mcp_server.go @@ -96,12 +96,13 @@ func (s *MCPServer4XTDriver) registerTools() { s.registerTool(&ToolBack{}) // Back // App Tools - s.registerTool(&ToolListPackages{}) // ListPackages - s.registerTool(&ToolLaunchApp{}) // LaunchApp - s.registerTool(&ToolTerminateApp{}) // TerminateApp - s.registerTool(&ToolAppInstall{}) // AppInstall - s.registerTool(&ToolAppUninstall{}) // AppUninstall - s.registerTool(&ToolAppClear{}) // AppClear + s.registerTool(&ToolListPackages{}) // ListPackages + s.registerTool(&ToolLaunchApp{}) // LaunchApp + s.registerTool(&ToolTerminateApp{}) // TerminateApp + s.registerTool(&ToolAppInstall{}) // AppInstall + s.registerTool(&ToolAppUninstall{}) // AppUninstall + s.registerTool(&ToolAppClear{}) // AppClear + s.registerTool(&ToolGetForegroundApp{}) // GetForegroundApp // Screen Tools s.registerTool(&ToolScreenShot{}) diff --git a/uixt/mcp_tools_app.go b/uixt/mcp_tools_app.go index c917ea7f..dc20eea0 100644 --- a/uixt/mcp_tools_app.go +++ b/uixt/mcp_tools_app.go @@ -340,3 +340,50 @@ func (t *ToolAppClear) ConvertActionToCallToolRequest(action option.MobileAction } return mcp.CallToolRequest{}, fmt.Errorf("invalid app clear params: %v", action.Params) } + +// ToolGetForegroundApp implements the get_foreground_app tool call. +type ToolGetForegroundApp struct { + // Return data fields - these define the structure of data returned by this tool + PackageName string `json:"packageName" desc:"Package name of the foreground app"` + AppName string `json:"appName" desc:"Name of the foreground app"` +} + +func (t *ToolGetForegroundApp) Name() option.ActionName { + return option.ACTION_GetForegroundApp +} + +func (t *ToolGetForegroundApp) Description() string { + return "Get information about the currently running foreground app" +} + +func (t *ToolGetForegroundApp) Options() []mcp.ToolOption { + unifiedReq := &option.ActionOptions{} + return unifiedReq.GetMCPOptions(option.ACTION_GetForegroundApp) +} + +func (t *ToolGetForegroundApp) Implement() server.ToolHandlerFunc { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + if err != nil { + return nil, fmt.Errorf("setup driver failed: %w", err) + } + + // Get foreground app info + appInfo, err := driverExt.ForegroundInfo() + if err != nil { + return NewMCPErrorResponse(fmt.Sprintf("Get foreground app failed: %s", err.Error())), nil + } + + message := fmt.Sprintf("Current foreground app: %s (%s)", appInfo.AppName, appInfo.PackageName) + returnData := ToolGetForegroundApp{ + PackageName: appInfo.PackageName, + AppName: appInfo.AppName, + } + + return NewMCPSuccessResponse(message, &returnData), nil + } +} + +func (t *ToolGetForegroundApp) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) { + return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil +} diff --git a/uixt/option/action.go b/uixt/option/action.go index 65502028..56ebaa28 100644 --- a/uixt/option/action.go +++ b/uixt/option/action.go @@ -645,6 +645,9 @@ func (o *ActionOptions) validateActionSpecificFields(actionType ActionName) erro ACTION_AppInstall: func() error { return o.requireFields("appUrl", o.AppUrl != "") }, + ACTION_GetForegroundApp: func() error { + return nil + }, ACTION_TapByOCR: func() error { return o.requireFields("text", o.Text != "") }, @@ -752,6 +755,7 @@ func (o *ActionOptions) GetMCPOptions(actionType ActionName) []mcp.ToolOption { ACTION_AppInstall: {"platform", "serial", "appUrl", "packageName"}, ACTION_AppUninstall: {"platform", "serial", "packageName"}, ACTION_AppClear: {"platform", "serial", "packageName"}, + ACTION_GetForegroundApp: {"platform", "serial"}, ACTION_PressButton: {"platform", "serial", "button"}, ACTION_SwipeToTapApp: {"platform", "serial", "appName", "ignoreNotFoundError", "maxRetryTimes", "index"}, ACTION_SwipeToTapText: {"platform", "serial", "text", "ignoreNotFoundError", "maxRetryTimes", "index", "regex"},