mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-31 13:29:35 +08:00
- Add detailed package-level documentation for mcp_server.go - Create MCP_SERVER_DOCUMENTATION.md with complete implementation guide - Create MCP_TOOLS_REFERENCE.md with quick reference for all tools - Add extensive code comments for key structures and functions - Document architecture, features, extension guide, and best practices - Include usage examples and troubleshooting information This provides complete documentation for developers to understand, use, and extend the HttpRunner MCP server functionality.
757 lines
19 KiB
Markdown
757 lines
19 KiB
Markdown
# HttpRunner MCP Server 完整说明文档
|
|
|
|
## 📖 概述
|
|
|
|
HttpRunner MCP Server 是基于 Model Context Protocol (MCP) 协议实现的 UI 自动化测试服务器,它将 HttpRunner 的强大 UI 自动化能力通过标准化的 MCP 接口暴露给 AI 模型和其他客户端。
|
|
|
|
## 🎯 核心功能特性
|
|
|
|
### 1. 设备管理
|
|
- **设备发现**: 自动发现 Android/iOS 设备和模拟器
|
|
- **设备选择**: 支持通过序列号/UDID 选择特定设备
|
|
- **多平台支持**: Android、iOS、Harmony、Browser 全平台覆盖
|
|
|
|
### 2. 交互操作
|
|
- **点击操作**: 支持坐标点击、OCR 文本点击、CV 图像识别点击
|
|
- **滑动操作**: 方向滑动、坐标滑动、智能滑动查找
|
|
- **拖拽操作**: 精确的拖拽控制,支持反作弊
|
|
- **输入操作**: 文本输入、按键操作
|
|
|
|
### 3. 应用管理
|
|
- **应用控制**: 启动、终止、安装、卸载、清除数据
|
|
- **包名查询**: 获取设备上所有应用包名
|
|
- **前台应用**: 获取当前前台应用信息
|
|
|
|
### 4. 屏幕操作
|
|
- **截图功能**: 高质量屏幕截图,支持 Base64 编码
|
|
- **屏幕信息**: 获取屏幕尺寸、方向等信息
|
|
- **UI 层次**: 获取界面元素层次结构
|
|
|
|
### 5. 高级功能
|
|
- **AI 驱动**: 支持 AI 模型驱动的智能操作
|
|
- **反作弊机制**: 内置反作弊检测和规避
|
|
- **Web 自动化**: 支持浏览器自动化操作
|
|
- **时间控制**: 精确的等待和延时控制
|
|
|
|
## 🏗️ 架构设计
|
|
|
|
### 整体架构
|
|
|
|
```
|
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
│ MCP Client │ │ MCP Server │ │ XTDriver Core │
|
|
│ (AI Model) │◄──►│ (mcp_server) │◄──►│ (UI Engine) │
|
|
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────┐
|
|
│ Device Layer │
|
|
│ Android/iOS/Web │
|
|
└─────────────────┘
|
|
```
|
|
|
|
### 核心组件
|
|
|
|
#### 1. MCPServer4XTDriver
|
|
```go
|
|
type MCPServer4XTDriver struct {
|
|
mcpServer *server.MCPServer // MCP 协议服务器
|
|
mcpTools []mcp.Tool // 注册的工具列表
|
|
actionToolMap map[option.ActionName]ActionTool // 动作到工具的映射
|
|
}
|
|
```
|
|
|
|
#### 2. ActionTool 接口
|
|
```go
|
|
type ActionTool interface {
|
|
Name() option.ActionName // 工具名称
|
|
Description() string // 工具描述
|
|
Options() []mcp.ToolOption // MCP 选项定义
|
|
Implement() server.ToolHandlerFunc // 工具实现逻辑
|
|
ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) // 动作转换
|
|
}
|
|
```
|
|
|
|
## 🛠️ 实现思路
|
|
|
|
### 1. 纯 ActionTool 架构
|
|
|
|
采用纯 ActionTool 风格架构,每个 MCP 工具都是独立的结构体:
|
|
|
|
```go
|
|
type ToolTapXY struct{}
|
|
|
|
func (t *ToolTapXY) Name() option.ActionName {
|
|
return option.ACTION_TapXY
|
|
}
|
|
|
|
func (t *ToolTapXY) Implement() server.ToolHandlerFunc {
|
|
return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
// 1. 设置驱动器
|
|
driverExt, err := setupXTDriver(ctx, request.Params.Arguments)
|
|
|
|
// 2. 解析参数
|
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
|
|
|
// 3. 执行操作
|
|
err = driverExt.TapXY(unifiedReq.X, unifiedReq.Y, opts...)
|
|
|
|
// 4. 返回结果
|
|
return mcp.NewToolResultText("操作成功"), nil
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2. 统一参数处理
|
|
|
|
使用 `parseActionOptions` 函数统一处理 MCP 请求参数:
|
|
|
|
```go
|
|
func parseActionOptions(arguments map[string]any) (*option.ActionOptions, error) {
|
|
b, err := json.Marshal(arguments)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("marshal arguments failed: %w", err)
|
|
}
|
|
|
|
var actionOptions option.ActionOptions
|
|
if err := json.Unmarshal(b, &actionOptions); err != nil {
|
|
return nil, fmt.Errorf("unmarshal to ActionOptions failed: %w", err)
|
|
}
|
|
|
|
return &actionOptions, nil
|
|
}
|
|
```
|
|
|
|
### 3. 设备管理策略
|
|
|
|
通过 `setupXTDriver` 函数实现设备的统一管理:
|
|
|
|
```go
|
|
func setupXTDriver(ctx context.Context, arguments map[string]any) (*XTDriver, error) {
|
|
// 1. 解析设备参数
|
|
platform := arguments["platform"].(string)
|
|
serial := arguments["serial"].(string)
|
|
|
|
// 2. 获取或创建驱动器
|
|
driverExt, err := GetOrCreateXTDriver(
|
|
option.WithPlatform(platform),
|
|
option.WithSerial(serial),
|
|
)
|
|
|
|
return driverExt, err
|
|
}
|
|
```
|
|
|
|
### 4. 错误处理机制
|
|
|
|
统一的错误处理和日志记录:
|
|
|
|
```go
|
|
if err != nil {
|
|
log.Error().Err(err).Str("tool", toolName).Msg("tool execution failed")
|
|
return mcp.NewToolResultError(fmt.Sprintf("操作失败: %s", err.Error())), nil
|
|
}
|
|
```
|
|
|
|
## 🔧 如何扩展接入新工具
|
|
|
|
### 步骤 1: 定义工具结构体
|
|
|
|
```go
|
|
// 新工具:长按操作
|
|
type ToolLongPress struct{}
|
|
|
|
func (t *ToolLongPress) Name() option.ActionName {
|
|
return option.ACTION_LongPress // 需要在 option 包中定义
|
|
}
|
|
|
|
func (t *ToolLongPress) Description() string {
|
|
return "在指定坐标执行长按操作"
|
|
}
|
|
```
|
|
|
|
### 步骤 2: 定义 MCP 选项
|
|
|
|
```go
|
|
func (t *ToolLongPress) Options() []mcp.ToolOption {
|
|
return []mcp.ToolOption{
|
|
mcp.WithString("platform", mcp.Enum("android", "ios"), mcp.Description("设备平台")),
|
|
mcp.WithString("serial", mcp.Description("设备序列号")),
|
|
mcp.WithNumber("x", mcp.Description("X 坐标")),
|
|
mcp.WithNumber("y", mcp.Description("Y 坐标")),
|
|
mcp.WithNumber("duration", mcp.Description("长按持续时间(秒)")),
|
|
mcp.WithBoolean("anti_risk", mcp.Description("是否启用反作弊")),
|
|
}
|
|
}
|
|
```
|
|
|
|
### 步骤 3: 实现工具逻辑
|
|
|
|
```go
|
|
func (t *ToolLongPress) Implement() server.ToolHandlerFunc {
|
|
return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
// 1. 设置驱动器
|
|
driverExt, err := setupXTDriver(ctx, request.Params.Arguments)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
|
}
|
|
|
|
// 2. 解析参数
|
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 3. 参数验证
|
|
if unifiedReq.X == 0 || unifiedReq.Y == 0 {
|
|
return nil, fmt.Errorf("x and y coordinates are required")
|
|
}
|
|
|
|
// 4. 构建选项
|
|
opts := []option.ActionOption{}
|
|
if unifiedReq.Duration > 0 {
|
|
opts = append(opts, option.WithDuration(unifiedReq.Duration))
|
|
}
|
|
if unifiedReq.AntiRisk {
|
|
opts = append(opts, option.WithAntiRisk(true))
|
|
}
|
|
|
|
// 5. 执行操作
|
|
log.Info().Float64("x", unifiedReq.X).Float64("y", unifiedReq.Y).
|
|
Float64("duration", unifiedReq.Duration).Msg("executing long press")
|
|
|
|
err = driverExt.LongPress(unifiedReq.X, unifiedReq.Y, opts...)
|
|
if err != nil {
|
|
return mcp.NewToolResultError(fmt.Sprintf("长按操作失败: %s", err.Error())), nil
|
|
}
|
|
|
|
// 6. 返回结果
|
|
return mcp.NewToolResultText(fmt.Sprintf("成功在坐标 (%.2f, %.2f) 执行长按操作",
|
|
unifiedReq.X, unifiedReq.Y)), nil
|
|
}
|
|
}
|
|
```
|
|
|
|
### 步骤 4: 实现动作转换
|
|
|
|
```go
|
|
func (t *ToolLongPress) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
|
|
if params, err := builtin.ConvertToFloat64Slice(action.Params); err == nil && len(params) >= 2 {
|
|
arguments := map[string]any{
|
|
"x": params[0],
|
|
"y": params[1],
|
|
}
|
|
|
|
// 添加持续时间
|
|
if len(params) > 2 {
|
|
arguments["duration"] = params[2]
|
|
}
|
|
|
|
// 提取动作选项
|
|
extractActionOptionsToArguments(action.GetOptions(), arguments)
|
|
|
|
return buildMCPCallToolRequest(t.Name(), arguments), nil
|
|
}
|
|
return mcp.CallToolRequest{}, fmt.Errorf("invalid long press params: %v", action.Params)
|
|
}
|
|
```
|
|
|
|
### 步骤 5: 注册工具
|
|
|
|
在 `registerTools()` 方法中添加新工具:
|
|
|
|
```go
|
|
func (s *MCPServer4XTDriver) registerTools() {
|
|
// ... 现有工具注册 ...
|
|
|
|
// 注册新工具
|
|
s.registerTool(&ToolLongPress{})
|
|
|
|
// ... 其他工具 ...
|
|
}
|
|
```
|
|
|
|
### 步骤 6: 添加单元测试
|
|
|
|
```go
|
|
func TestToolLongPress(t *testing.T) {
|
|
tool := &ToolLongPress{}
|
|
|
|
// 测试工具基本信息
|
|
assert.Equal(t, option.ACTION_LongPress, tool.Name())
|
|
assert.Contains(t, tool.Description(), "长按")
|
|
|
|
// 测试选项定义
|
|
options := tool.Options()
|
|
assert.NotEmpty(t, options)
|
|
|
|
// 测试动作转换
|
|
action := MobileAction{
|
|
Method: option.ACTION_LongPress,
|
|
Params: []float64{100, 200, 2.0}, // x, y, duration
|
|
ActionOptions: option.ActionOptions{
|
|
AntiRisk: true,
|
|
},
|
|
}
|
|
|
|
request, err := tool.ConvertActionToCallToolRequest(action)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, string(option.ACTION_LongPress), request.Params.Name)
|
|
assert.Equal(t, 100.0, request.Params.Arguments["x"])
|
|
assert.Equal(t, 200.0, request.Params.Arguments["y"])
|
|
assert.Equal(t, 2.0, request.Params.Arguments["duration"])
|
|
assert.Equal(t, true, request.Params.Arguments["anti_risk"])
|
|
}
|
|
```
|
|
|
|
## 📋 工具开发最佳实践
|
|
|
|
### 1. 命名规范
|
|
- 工具结构体: `Tool{ActionName}`
|
|
- 常量定义: `ACTION_{ActionName}`
|
|
- 参数名称: 使用下划线分隔 (`from_x`, `to_y`)
|
|
|
|
### 2. 参数验证
|
|
```go
|
|
// 必需参数验证
|
|
if unifiedReq.Text == "" {
|
|
return nil, fmt.Errorf("text parameter is required")
|
|
}
|
|
|
|
// 坐标参数验证
|
|
_, hasX := request.Params.Arguments["x"]
|
|
_, hasY := request.Params.Arguments["y"]
|
|
if !hasX || !hasY {
|
|
return nil, fmt.Errorf("x and y coordinates are required")
|
|
}
|
|
```
|
|
|
|
### 3. 错误处理
|
|
```go
|
|
// 统一错误格式
|
|
if err != nil {
|
|
return mcp.NewToolResultError(fmt.Sprintf("操作失败: %s", err.Error())), nil
|
|
}
|
|
|
|
// 成功结果
|
|
return mcp.NewToolResultText(fmt.Sprintf("操作成功: %s", details)), nil
|
|
```
|
|
|
|
### 4. 日志记录
|
|
```go
|
|
// 操作开始日志
|
|
log.Info().Str("action", "long_press").
|
|
Float64("x", x).Float64("y", y).
|
|
Msg("executing long press operation")
|
|
|
|
// 调试日志
|
|
log.Debug().Interface("arguments", arguments).
|
|
Msg("parsed tool arguments")
|
|
```
|
|
|
|
### 5. 选项处理
|
|
```go
|
|
// 使用 extractActionOptionsToArguments 统一处理
|
|
extractActionOptionsToArguments(action.GetOptions(), arguments)
|
|
|
|
// 或手动添加特定选项
|
|
if unifiedReq.AntiRisk {
|
|
opts = append(opts, option.WithAntiRisk(true))
|
|
}
|
|
```
|
|
|
|
## 🚀 高级特性
|
|
|
|
### 1. 反作弊支持
|
|
```go
|
|
// 在需要反作弊的操作中添加
|
|
if unifiedReq.AntiRisk {
|
|
arguments := getCommonMCPArguments(driver)
|
|
callMCPActionTool(driver, "evalpkgs", "set_touch_info", arguments)
|
|
}
|
|
```
|
|
|
|
### 2. 异步操作
|
|
```go
|
|
// 对于长时间运行的操作,使用 context 控制超时
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
```
|
|
|
|
### 3. 批量操作
|
|
```go
|
|
// 支持批量参数处理
|
|
for _, point := range unifiedReq.Points {
|
|
err := driverExt.TapXY(point.X, point.Y, opts...)
|
|
if err != nil {
|
|
return mcp.NewToolResultError(fmt.Sprintf("批量操作失败: %s", err.Error())), nil
|
|
}
|
|
}
|
|
```
|
|
|
|
## 📚 MCP Tools 快速参考
|
|
|
|
### 📱 设备管理工具
|
|
|
|
#### list_available_devices
|
|
**功能**: 发现所有可用的设备和模拟器
|
|
**参数**: 无
|
|
**返回**: JSON 格式的设备列表
|
|
```json
|
|
{
|
|
"androidDevices": ["emulator-5554", "device-serial"],
|
|
"iosDevices": ["iPhone-UDID", "simulator-UDID"]
|
|
}
|
|
```
|
|
|
|
#### select_device
|
|
**功能**: 选择要使用的设备
|
|
**参数**:
|
|
- `platform` (string): "android" | "ios" | "web" | "harmony"
|
|
- `serial` (string): 设备序列号或 UDID
|
|
|
|
---
|
|
|
|
### 👆 触摸操作工具
|
|
|
|
#### tap_xy
|
|
**功能**: 在相对坐标点击 (0-1 范围)
|
|
**参数**:
|
|
- `x` (number): X 坐标 (0.0-1.0)
|
|
- `y` (number): Y 坐标 (0.0-1.0)
|
|
- `duration` (number, 可选): 点击持续时间(秒)
|
|
- `anti_risk` (boolean, 可选): 启用反作弊
|
|
|
|
#### tap_abs_xy
|
|
**功能**: 在绝对像素坐标点击
|
|
**参数**:
|
|
- `x` (number): X 像素坐标
|
|
- `y` (number): Y 像素坐标
|
|
- `duration` (number, 可选): 点击持续时间(秒)
|
|
- `anti_risk` (boolean, 可选): 启用反作弊
|
|
|
|
#### tap_ocr
|
|
**功能**: 通过 OCR 识别文本并点击
|
|
**参数**:
|
|
- `text` (string): 要查找的文本
|
|
- `ignore_NotFoundError` (boolean, 可选): 忽略未找到错误
|
|
- `regex` (boolean, 可选): 使用正则表达式匹配
|
|
|
|
#### tap_cv
|
|
**功能**: 通过计算机视觉识别图像并点击
|
|
**参数**:
|
|
- `imagePath` (string): 模板图像路径
|
|
- `threshold` (number, 可选): 匹配阈值
|
|
|
|
#### double_tap_xy
|
|
**功能**: 在指定坐标双击
|
|
**参数**:
|
|
- `x` (number): X 坐标
|
|
- `y` (number): Y 坐标
|
|
|
|
---
|
|
|
|
### 🔄 手势操作工具
|
|
|
|
#### swipe
|
|
**功能**: 通用滑动 (自动检测方向或坐标)
|
|
**参数**: 支持方向滑动或坐标滑动两种模式
|
|
|
|
##### 方向滑动模式:
|
|
- `direction` (string): "up" | "down" | "left" | "right"
|
|
- `duration` (number, 可选): 滑动持续时间
|
|
- `press_duration` (number, 可选): 按压持续时间
|
|
|
|
##### 坐标滑动模式:
|
|
- `from_x` (number): 起始 X 坐标
|
|
- `from_y` (number): 起始 Y 坐标
|
|
- `to_x` (number): 结束 X 坐标
|
|
- `to_y` (number): 结束 Y 坐标
|
|
|
|
#### drag
|
|
**功能**: 拖拽操作
|
|
**参数**:
|
|
- `from_x` (number): 起始 X 坐标
|
|
- `from_y` (number): 起始 Y 坐标
|
|
- `to_x` (number): 结束 X 坐标
|
|
- `to_y` (number): 结束 Y 坐标
|
|
- `duration` (number, 可选): 拖拽持续时间(毫秒)
|
|
|
|
#### swipe_to_tap_app
|
|
**功能**: 滑动查找并点击应用
|
|
**参数**:
|
|
- `appName` (string): 应用名称
|
|
- `max_retry_times` (number, 可选): 最大重试次数
|
|
- `ignore_NotFoundError` (boolean, 可选): 忽略未找到错误
|
|
|
|
#### swipe_to_tap_text
|
|
**功能**: 滑动查找并点击文本
|
|
**参数**:
|
|
- `text` (string): 要查找的文本
|
|
- `max_retry_times` (number, 可选): 最大重试次数
|
|
- `regex` (boolean, 可选): 使用正则表达式
|
|
|
|
#### swipe_to_tap_texts
|
|
**功能**: 滑动查找并点击多个文本中的一个
|
|
**参数**:
|
|
- `texts` (array): 文本数组
|
|
- `max_retry_times` (number, 可选): 最大重试次数
|
|
|
|
---
|
|
|
|
### ⌨️ 输入操作工具
|
|
|
|
#### input
|
|
**功能**: 在当前焦点元素输入文本
|
|
**参数**:
|
|
- `text` (string): 要输入的文本
|
|
|
|
#### press_button
|
|
**功能**: 按设备按键
|
|
**参数**:
|
|
- `button` (string): 按键名称
|
|
- Android: "BACK", "HOME", "VOLUME_UP", "VOLUME_DOWN", "ENTER"
|
|
- iOS: "HOME", "VOLUME_UP", "VOLUME_DOWN"
|
|
|
|
#### home
|
|
**功能**: 按 Home 键
|
|
**参数**: 无
|
|
|
|
#### back
|
|
**功能**: 按返回键 (仅 Android)
|
|
**参数**: 无
|
|
|
|
---
|
|
|
|
### 📱 应用管理工具
|
|
|
|
#### list_packages
|
|
**功能**: 列出设备上所有应用包名
|
|
**参数**: 无
|
|
|
|
#### app_launch
|
|
**功能**: 启动应用
|
|
**参数**:
|
|
- `packageName` (string): 应用包名
|
|
|
|
#### app_terminate
|
|
**功能**: 终止应用
|
|
**参数**:
|
|
- `packageName` (string): 应用包名
|
|
|
|
#### app_install
|
|
**功能**: 安装应用
|
|
**参数**:
|
|
- `appUrl` (string): APK/IPA 文件路径或 URL
|
|
|
|
#### app_uninstall
|
|
**功能**: 卸载应用
|
|
**参数**:
|
|
- `packageName` (string): 应用包名
|
|
|
|
#### app_clear
|
|
**功能**: 清除应用数据
|
|
**参数**:
|
|
- `packageName` (string): 应用包名
|
|
|
|
---
|
|
|
|
### 📸 屏幕操作工具
|
|
|
|
#### screenshot
|
|
**功能**: 截取屏幕截图
|
|
**参数**: 无
|
|
**返回**: Base64 编码的图像数据
|
|
|
|
#### get_screen_size
|
|
**功能**: 获取屏幕尺寸
|
|
**参数**: 无
|
|
**返回**: 屏幕宽度和高度 (像素)
|
|
|
|
#### get_source
|
|
**功能**: 获取 UI 层次结构
|
|
**参数**:
|
|
- `packageName` (string, 可选): 指定应用包名
|
|
|
|
---
|
|
|
|
### ⏱️ 时间控制工具
|
|
|
|
#### sleep
|
|
**功能**: 等待指定秒数
|
|
**参数**:
|
|
- `seconds` (number): 等待秒数
|
|
|
|
#### sleep_ms
|
|
**功能**: 等待指定毫秒数
|
|
**参数**:
|
|
- `milliseconds` (number): 等待毫秒数
|
|
|
|
#### sleep_random
|
|
**功能**: 随机等待
|
|
**参数**:
|
|
- `params` (array): 随机参数数组
|
|
|
|
---
|
|
|
|
### 🛠️ 实用工具
|
|
|
|
#### set_ime
|
|
**功能**: 设置输入法
|
|
**参数**:
|
|
- `ime` (string): 输入法包名
|
|
|
|
#### close_popups
|
|
**功能**: 关闭弹窗
|
|
**参数**: 无
|
|
|
|
---
|
|
|
|
### 🌐 Web 操作工具
|
|
|
|
#### web_login_none_ui
|
|
**功能**: 无 UI 登录
|
|
**参数**:
|
|
- `packageName` (string): 应用包名
|
|
- `phoneNumber` (string, 可选): 手机号
|
|
- `captcha` (string, 可选): 验证码
|
|
- `password` (string, 可选): 密码
|
|
|
|
#### secondary_click
|
|
**功能**: 右键点击
|
|
**参数**:
|
|
- `x` (number): X 坐标
|
|
- `y` (number): Y 坐标
|
|
|
|
#### hover_by_selector
|
|
**功能**: 悬停在选择器元素上
|
|
**参数**:
|
|
- `selector` (string): CSS 选择器或 XPath
|
|
|
|
#### tap_by_selector
|
|
**功能**: 点击选择器元素
|
|
**参数**:
|
|
- `selector` (string): CSS 选择器或 XPath
|
|
|
|
#### secondary_click_by_selector
|
|
**功能**: 右键点击选择器元素
|
|
**参数**:
|
|
- `selector` (string): CSS 选择器或 XPath
|
|
|
|
#### web_close_tab
|
|
**功能**: 关闭浏览器标签页
|
|
**参数**:
|
|
- `tabIndex` (number): 标签页索引
|
|
|
|
---
|
|
|
|
### 🤖 AI 操作工具
|
|
|
|
#### ai_action
|
|
**功能**: AI 驱动的智能操作
|
|
**参数**:
|
|
- `prompt` (string): 自然语言指令
|
|
|
|
#### finished
|
|
**功能**: 标记任务完成
|
|
**参数**:
|
|
- `content` (string): 完成信息
|
|
|
|
---
|
|
|
|
### 📋 通用参数说明
|
|
|
|
#### 设备参数 (所有工具通用)
|
|
- `platform` (string): 设备平台
|
|
- "android": Android 设备
|
|
- "ios": iOS 设备
|
|
- "web": Web 浏览器
|
|
- "harmony": 鸿蒙设备
|
|
- `serial` (string): 设备标识符
|
|
- Android: 设备序列号 (如 "emulator-5554")
|
|
- iOS: 设备 UDID
|
|
- Web: 浏览器会话 ID
|
|
|
|
#### 坐标参数
|
|
- **相对坐标**: 0.0-1.0 范围,相对于屏幕尺寸
|
|
- **绝对坐标**: 像素值,基于实际屏幕分辨率
|
|
|
|
#### 时间参数
|
|
- `duration`: 操作持续时间 (秒)
|
|
- `press_duration`: 按压持续时间 (秒)
|
|
- `milliseconds`: 毫秒数
|
|
|
|
#### 行为参数
|
|
- `anti_risk`: 启用反作弊检测
|
|
- `ignore_NotFoundError`: 忽略元素未找到错误
|
|
- `regex`: 使用正则表达式匹配
|
|
- `pre_mark_operation`: 启用操作前标记 (用于调试和可视化)
|
|
- `max_retry_times`: 最大重试次数
|
|
- `index`: 元素索引 (多个匹配时)
|
|
|
|
---
|
|
|
|
### 🔧 使用示例
|
|
|
|
#### 基本点击操作
|
|
```json
|
|
{
|
|
"name": "tap_xy",
|
|
"arguments": {
|
|
"platform": "android",
|
|
"serial": "emulator-5554",
|
|
"x": 0.5,
|
|
"y": 0.3
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 滑动操作
|
|
```json
|
|
{
|
|
"name": "swipe",
|
|
"arguments": {
|
|
"platform": "android",
|
|
"serial": "emulator-5554",
|
|
"direction": "up",
|
|
"duration": 0.5
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 应用启动
|
|
```json
|
|
{
|
|
"name": "app_launch",
|
|
"arguments": {
|
|
"platform": "android",
|
|
"serial": "emulator-5554",
|
|
"packageName": "com.example.app"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### OCR 文本点击
|
|
```json
|
|
{
|
|
"name": "tap_ocr",
|
|
"arguments": {
|
|
"platform": "android",
|
|
"serial": "emulator-5554",
|
|
"text": "登录",
|
|
"ignore_NotFoundError": false
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### ⚠️ 注意事项
|
|
|
|
1. **设备连接**: 确保设备已连接并可访问
|
|
2. **权限要求**: 某些操作需要设备 root 或开发者权限
|
|
3. **坐标系统**: 注意相对坐标 (0-1) 和绝对坐标 (像素) 的区别
|
|
4. **平台差异**: 不同平台支持的功能可能有差异
|
|
5. **错误处理**: 建议启用适当的错误忽略选项
|
|
6. **性能考虑**: 避免过于频繁的操作,适当添加等待时间
|