Token导航 LogoToken导航TokenDH.com
mcpe2e (Jhona Codes) logo
开发工具未说明官方级别未说明来源级核验

mcpe2e (Jhona Codes)

MCP Server

mcpe2e是一个AI驱动的Flutter端到端测试工具,允许AI代理控制真实设备上的Flutter应用,执行点击、输入、滚动等操作,无需修改应用UI。

工具数

34

提示词数

0

GitHub Stars

2

资源数

0
Claude自动化测试开发工具Claude DesktopClaude

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

JhonaCodes

提供方

JhonaCodes

最后核验

2026/5/17 20:22

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

mcpe2e——人工智能驱动的Flutter E2E测试

](https://github.com/JhonaCodes/mcpe2e/releases/tag/v2.2.0) ![license](LICENSE)

mcpe2e允许AI代理(Claude、Codex、Gemini)控制在设备或模拟器上运行的真正Flutter应用程序。代理调用MCP工具——点击、键入、滚动、断言——这些命令作为真实的指针事件到达实时小部件树。

不需要修改UI。没有测试双打。应用程序按原样运行。

______________________________________________________________________

建筑

User → AI Agent (Claude / Codex / Gemini)
              |
              |  MCP  (JSON-RPC 2.0 / stdio)
              v
      mcpe2e_server  (Dart binary)           installed in ~/.local/bin/
      Translates MCP tool calls → HTTP
      Exposes workflow skill via MCP Prompts
              |
              |  HTTP  localhost:7778
              |  (ADB forward / iproxy / direct)
              v
      mcpe2e  (Flutter library)              dev_dependency in the app
      HTTP server embedded inside the app
      Executes real pointer events via GestureBinding
              |
              v
      Flutter app on device / simulator

两个独立的组件:

组件它是什么它在哪里运行
mcpe2eFlutter库——应用程序中嵌入的HTTP服务器设备内部
mcpe2e_serverMCP服务器二进制文件——将AI工具连接到HTTP开发人员的机器

mcpe2e MCP服务器。它是一个轻量级的HTTP服务器,位于正在运行的应用程序内部,并在实时小部件树上执行手势。

______________________________________________________________________

它是如何工作的——三种查找小部件的方法

代理按照以下优先级顺序解析小部件:

1.McpMetadataKey(推荐)

在小部件上注册密钥,以获得最可靠、最稳定的访问。这就是 默认和推荐方法 --它允许名为的代理访问小部件,启用断言,并在布局更改后幸存下来。

ElevatedButton(
  key: const McpMetadataKey(id: 'auth.login_button', widgetType: McpWidgetType.button),
  onPressed: _login,
  child: const Text('Log in'),
)
AI calls: tap_widget  key: auth.login_button
AI calls: assert_enabled  key: auth.login_button

2.现有Flutter键(自动)

如果你的应用程序已经使用 ValueKey 或者其他Flutter密钥,代理会自动从 inspect_ui --无需更改。这些元素以其键值出现在树中:

{ "type": "ElevatedButton", "key": "login_btn", "label": "Login", "x": 20, "y": 400 }
AI calls: tap_widget  key: login_btn

3.坐标(回退)

当小部件根本没有键时,代理会从以下位置回退到屏幕坐标 inspect_ui。这不需要更改应用程序代码,但在布局重建过程中稳定性较差。

{ "type": "ElevatedButton", "label": "Login", "x": 20, "y": 400, "w": 350, "h": 52 }
Center: cx = 20 + 350/2 = 195,  cy = 400 + 52/2 = 426

AI calls: tap_at  x: 195  y: 426
AI calls: input_text  x: 16  y: 220  text: "user@example.com"

这适用于 任何小部件 在树中——按钮、卡片、列表项、标签、下拉菜单——无需触摸应用程序源代码。

______________________________________________________________________

快速开始

步骤1--将mcpe2e添加到Flutter应用程序中

# pubspec.yaml
dev_dependencies:
  mcpe2e: ^2.2.0
flutter pub get

步骤2——安装MCP服务器并注册您的AI代理

dart run mcpe2e:setup

这个命令:

  1. 下载 mcpe2e_server 二进制为您的平台 ~/.local/bin/
  2. 打开一个交互式菜单,向您的AI代理注册(Claude Code、Claude Desktop、Codex CLI、Gemini CLI)

随时更改代理人注册:

mcpe2e_server setup

步骤3--在main.dart中启动服务器

import 'package:flutter/foundation.dart';
import 'package:mcpe2e/mcpe2e.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  if (kDebugMode) await McpEventServer.start();
  runApp(const MyApp());
}

服务器在端口上启动 7777 在发布版本中是不允许的。

步骤4--运行应用程序

flutter run

mcpe2e_server 自动运行 adb forward 对于启动时连接的每台Android设备,无需手动端口转发。对于iOS,运行 iproxy 7778 7777 一次。

验证连接:

curl http://localhost:7778/ping
# {"status":"ok","port":7777}

步骤5——加载工作流技能(可选但推荐)

在开始任何任务之前,AI代理可以请求内置的工作流指南:

prompts/get { "name": "mcpe2e_workflow" }

这提供了一个完整的交互指南——核心循环、工具决策树、表单/对话框/导航模式、错误恢复和代理协议。任何兼容MCP的客户端(Claude、Gemini、Codex)都可以使用它。

第6步——进行第一次测试

在应用程序运行且代理已连接的情况下,典型的测试如下:

使用McpMetadataKey(推荐):

1. inspect_ui                                        → see all widgets
2. input_text  key: auth.email_field  text: "user@example.com"
3. input_text  key: auth.password_field  text: "secret123"
4. tap_widget  key: auth.login_button
5. wait  duration_ms: 1500
6. assert_text  key: dashboard.greeting  text: "Hello, user"

无按键(坐标回退):

1. inspect_ui
   → Agent sees: TextField "Email" at (16, 220), ElevatedButton "Login" at (20, 400, 350x52)
2. input_text  x: 16  y: 220  text: "user@example.com"
3. input_text  x: 16  y: 296  text: "secret123"
4. tap_at  x: 195  y: 426                           → center of Login button
5. wait  duration_ms: 1500
6. inspect_ui                                        → verify new screen content

这两种方法都有效。键提供稳定性并启用断言;坐标不需要更改应用程序。

______________________________________________________________________

可用工具(34)

大多数工具使用 keyMcpMetadataKey id或现有Flutter密钥。看 小部件键. 当没有键可用时,使用基于坐标的工具(tap_at, tap_by_label, input_text(x, y))作为退路。

多设备

工具参数说明
list_devices--发现所有连接的Android设备/模拟器、自动转发端口,ping每个端口
select_deviceserial通过串行方式切换活动设备。所有后续工具都针对所选设备
run_commandcommand, working_dir?, background?运行任何shell命令(flutter run, adb等等)

背景和检查

工具参数说明
get_app_context--已注册的具有元数据和功能的小部件
list_test_cases--别名 get_app_context
inspect_ui--包含值、状态和屏幕坐标的完整小部件树-- 无需注册
inspect_ui_compact--分组摘要(交互式/文本/其他/覆盖/加载)--在简单屏幕上保存令牌
capture_screenshot--当前屏幕为PNG图像--代理直接看到它

手势

工具参数说明
tap_widgetkey必填按键点击小部件-- 推荐
double_tap_widgetkey必填双击
long_press_widgetkey, duration_ms?必填长按
swipe_widgetkey, direction, distance?必填向某个方向滑动
scroll_widgetkey, direction必需滚动可滚动的小部件
scroll_until_visiblekey, target_key, max_attempts?必需滚动直到目标小部件可见
drag_widgetkey, dx, dy, duration_ms?必需从中心按像素偏移拖动
pinch_widgetkey, scale必需缩放
tap_atx, y--点击屏幕坐标(没有可用键时回退)
tap_by_labellabel--按可见文本内容点击(例如。 "Login", "Submit")

输入

工具参数说明
input_textkey, text, clear_first?必填按键在文本字段中键入-- 推荐
input_textx, y, text, clear_first?, skip_focus_tap?--按坐标键入文本字段(回退)
clear_textkey必填清除文本字段
select_dropdownkey, valueindex必填选择下拉选项
toggle_widgetkey必需切换复选框、开关或收音机
set_slider_valuekey, value (0.0–1.0)必填设置滑块位置

键盘和导航

工具参数说明
show_keyboardkey请求焦点并显示虚拟键盘
hide_keyboard--关闭虚拟键盘
press_back--返回导航--自动点击AppBar返回按钮(如果可见),返回系统返回事件
waitduration_ms暂停执行(在动画或网络调用后有用)

断言(需要注册密钥)

工具参数说明
assert_existskey小部件在树中
assert_textkey, text可见文本与预期值匹配
assert_visiblekey小部件在视口中可见
assert_enabledkey小部件已启用
assert_selectedkey复选框、开关或收音机处于活动状态
assert_valuekey, valueTextField控制器值匹配
assert_countkey, count列表或列恰好有N个子项
没有钥匙,代理仍然可以通过读取 inspect_ui 直接响应——每个文本小部件的内容、每个按钮的启用状态和每个复选框的选中状态都包含在树中。但是,对于正式的测试断言,请注册 McpMetadataKey 在widget上。

______________________________________________________________________

小部件键(McpMetadataKey)

McpMetadataKey推荐 识别小部件的方法。注册密钥可以获得:

  • 稳定的命名访问 --在布局更改和屏幕重建中幸存下来
  • 断言assert_text, assert_enabled, assert_selected等需要钥匙
  • 可靠的叠加交互 --对话框、底部纸张、抽屉在动画过程中会移动;钥匙绕过了那个
  • 更快的查找 --直接进入,而不是步行

如果你的应用程序已经使用 ValueKey,代理会自动从 inspect_ui --无需更改。

如果小部件根本没有键,则代理将退回到基于坐标的工具(tap_at, input_text(x, y)).这是有效的,但不太稳定。

如何添加密钥

分配一个 McpMetadataKey 作为小部件的 key:两者都有 idwidgetType 需要:

import 'package:mcpe2e/mcpe2e.dart';

// Button
ElevatedButton(
  key: const McpMetadataKey(
    id: 'auth.login_button',
    widgetType: McpWidgetType.button,
  ),
  onPressed: _login,
  child: const Text('Log in'),
)

// Text field
TextField(
  key: const McpMetadataKey(
    id: 'auth.email_field',
    widgetType: McpWidgetType.textField,
  ),
  controller: _emailController,
)

// Checkbox
Checkbox(
  key: const McpMetadataKey(
    id: 'settings.dark_mode',
    widgetType: McpWidgetType.checkbox,
  ),
  value: _darkMode,
  onChanged: _toggle,
)

// List (for assert_count)
ListView(
  key: const McpMetadataKey(
    id: 'order.list',
    widgetType: McpWidgetType.list,
  ),
  children: _items.map(_buildItem).toList(),
)

一旦分配了密钥,小部件就会出现在 inspect_ui 带着一个 "key" 现场。然后,代理可以使用基于密钥的工具:

tap_widget     key: auth.login_button
input_text     key: auth.email_field    text: "user@example.com"
assert_text    key: auth.email_field    text: "user@example.com"
assert_enabled key: auth.login_button
assert_count   key: order.list          count: 5

McpWidgetType值

widgetType 描述小部件类型并确定其可用功能:

button · textField · text · list · card · image · container · dropdown · checkbox · radio · switchWidget · slider · tab · custom

密钥命名约定

跟随 module.element[.variant] 图案:

auth.login_button          Login button on the auth screen
auth.email_field           Email input on the auth screen
profile.avatar             User avatar image
order.list                 The orders list
order.card.{id}            A dynamic card identified at runtime
settings.dark_mode         Dark mode toggle
modal.confirm.delete       Confirmation dialog
sheet.address.submit       Submit button inside a bottom sheet
nav.drawer                 Navigation drawer
snackbar.undo              Undo action in a snackbar

决议优先级

代理按以下顺序解析小部件:

优先级方法何时使用
第一名McpMetadataKey所有可测试小部件的默认值。支持断言,在重建过程中保持稳定
第二名现有Flutter密钥 (ValueKey,等等)应用程序已经有密钥,不需要更改
第三名坐标 (tap_at, input_text(x, y))不带任何键的小部件的回退——动态列表、第三方小部件、快速探索

当每种方法都适合时

场景方法
您控制的任何小部件McpMetadataKey --注册一次,随处使用
应用程序已具有 ValueKey on小部件按原样使用它们——代理会看到它们 inspect_ui
断言(assert_text, assert_enabled等)密钥 必需的 --断言仅适用于键
对话框/底板/抽屉/零食架按键 强烈推荐 --动画期间叠加坐标偏移
API的动态列表项order.card.{id} 使用运行时ID或坐标作为回退
您无法修改的第三方小部件通过 inspect_uitap_at
快速一次性探索坐标-快速,无需更改代码

推荐:为覆盖的小部件添加按键

对话框、底图、抽屉和任务栏在单独的覆盖层中渲染。在打开动画的过程中,它们的坐标可能会发生偏移 tap_at 可靠性较低。添加a McpMetadataKey 让代理使用这些表面 tap_widget 而不是追逐坐标。

// Confirmation dialog actions
AlertDialog(
  title: const Text('Delete item?'),
  actions: [
    TextButton(
      key: const McpMetadataKey(
        id: 'modal.confirm.cancel',
        widgetType: McpWidgetType.button,
      ),
      onPressed: () => Navigator.pop(context),
      child: const Text('Cancel'),
    ),
    ElevatedButton(
      key: const McpMetadataKey(
        id: 'modal.confirm.ok',
        widgetType: McpWidgetType.button,
      ),
      onPressed: _delete,
      child: const Text('Delete'),
    ),
  ],
)

// Bottom sheet action button
showModalBottomSheet(
  context: context,
  builder: (_) => ElevatedButton(
    key: const McpMetadataKey(
      id: 'sheet.checkout.submit',
      widgetType: McpWidgetType.button,
    ),
    onPressed: _submit,
    child: const Text('Confirm'),
  ),
);

没有密钥,代理仍然可以使用以下命令与覆盖小部件交互 tap_at 呼叫之后 inspect_ui --但可能需要 wait 为了让动画完成,坐标可能会在运行之间移动。

______________________________________________________________________

路线跟踪(McpNavigatorObserver)

get_app_context 报告当前路线。为了获得准确的路线名称,请注册观察者:

// With MaterialApp
MaterialApp(
  navigatorObservers: [McpNavigatorObserver.instance],
  ...
)

// With GoRouter
GoRouter(
  observers: [McpNavigatorObserver.instance],
  ...
)

如果没有它,路由将回退到从屏幕名称导出的值。

______________________________________________________________________

对话框中的文本输入

当对话框或覆盖层阻止焦点点击时,使用ADB回退:

// 1. Focus the field
tap_at x:  y: 

// 2. Type via ADB (run_command)
run_command: adb -s  shell input text "your_text"

// Get the serial from:
run_command: adb devices

这适用于身份验证码、PIN码和任何 TextField 内部A AlertDialogBottomSheet.

______________________________________________________________________

管理代理

mcpe2e_server setup

交互式菜单,无需重新安装即可启用或禁用单个代理(Claude Code、Claude Desktop、Codex CLI、Gemini CLI)。

______________________________________________________________________

平台连接性

平台机制设置
AndroidADB转发(自动)无-- mcpe2e_server 启动时处理它
iOSiproxyiproxy 7778 7777
macOS/Linux/Windows桌面直接本地主机设置 TESTBRIDGE_URL=http://localhost:7777
Web不支持Flutter Web无法打开TCP套接字

TESTBRIDGE_URL 告诉 mcpe2e_server 在哪里访问应用程序。违约: http://localhost:7778.

______________________________________________________________________

存储库结构

mcpe2e/              Flutter library — add to your app as dev_dependency
mcpe2e_server/       MCP server binary — install once on your machine
docs/                Integration guides and examples
CLAUDE.md            Architecture reference for Claude Code context

______________________________________________________________________

文档

文件描述
mcpe2e/README.mdFlutter库参考(端点、API、生产安全)
mcpe2e_server/README.mdMCP服务器设置、配置和工具参考
docs/integration-guide.md任何Flutter应用程序的逐步集成
docs/test-flow-example.md完成测试演练
docs/writing-tests.md脚本模式和目标模式测试格式、模板
CLAUDE.mdClaude代码上下文的架构参考

______________________________________________________________________

从源头构建

git clone https://github.com/JhonaCodes/mcpe2e
cd mcpe2e/mcpe2e_server
dart pub get
dart compile exe bin/mcp_server.dart -o mcpe2e_server

需要Dart SDK>=3.5.0。macOS(arm64、x86_64)、Linux(x86_24)和Windows(x86_14)的预编译二进制文件可在每个平台上使用 .

目录标签

目录标签

Claude自动化测试开发工具Dart本地部署Flutter测试AI测试端到端测试移动应用测试

支持客户端

Claude DesktopClaude

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

session

工具数量(toolCount,工具数)

34

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明session部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP