Flutter应用调试工具

Flutter Copilot是一个连接AI工具与Flutter运行时的MCP方案,支持页面验证、交互调试、日志排查和运行时诊断。

  • by dust365
  • Dart
  • 本地部署
  • 8 星标
  • 更新于
在 GitHub 查看 dust365/flutter_copilot

使用说明

Flutter Copilot

Flutter Copilot 是一个面向运行中 Flutter 应用的 MCP 方案,让 Claude Code、Cursor 等 AI Agent 能够直接连接、观察、操作和诊断 App。

它通过 MCP + VM Service 把 AI 工具和 Flutter 运行时连接起来,让 Agent 不只停留在代码层面,还能进入真实应用状态完成页面验证、交互调试、日志排查和运行时诊断。

Demo

Flutter Copilot 包含三个已发布的包:

  • flutter_copilot_mcp:MCP Server,负责让 Claude Code、Cursor 等 AI Client 连接并调用 Flutter 能力
  • flutter_copilot_claw:Flutter 侧挂载插件,负责在 App 内注册运行时能力
  • flutter_copilot_cli:面向终端用户与 CI 的命令行工具,不依赖 MCP 协议即可直接驱动 Flutter App

更多演示功能请查看演示视频。

项目概述

Flutter Copilot 由三部分组成:

  • flutter_copilot_mcp:运行在 App 外部的 MCP Server,对 AI Client 暴露标准工具能力(已发布到 pub.dev)
  • flutter_copilot_claw:集成在 Flutter App 内的运行时挂载插件,负责注册 VM Service 扩展(已发布到 pub.dev)
  • flutter_copilot_cli:基于 Node.js 的命令行工具,直连 VM Service 执行交互、截图、脚本化测试,适用于终端调试与 CI 流水线(已发布到 npm)

一句话理解:

flutter_copilot_claw 在 App 内提供能力,flutter_copilot_mcp 在 App 外桥接 AI Agent,flutter_copilot_cli 则在终端/CI 中直接驱动 App,最终让人类与 AI 都能操作运行中的 Flutter 应用。

适用场景

Flutter Copilot 适合这些典型场景:

  • 页面交互验证
  • 冒烟测试与流程回归
  • UI 问题复现与调试
  • 运行时日志采集
  • 热重载后的快速确认
  • Widget 重建热点排查

核心能力

连接与观察

  • 连接 Flutter App 的 VM Service
  • 获取当前页面可交互元素
  • 截图与日志获取

交互与导航

  • 点击、输入、滚动
  • 拖拽、滑动、长按、双击
  • 页面导航控制
  • Hot Reload

诊断能力

  • Rebuild Snapshot / 重建热点分析

元素定位方式

  • ValueKey<String>
  • 文本内容
  • Widget 类型
  • 坐标

其中 ValueKey<String> 是最稳定、最推荐的方式。

工作原理

Flutter Copilot 的调用链路可以概括为:

  1. AI Client 发起工具调用
  2. flutter_copilot_mcp 将调用转换为 Flutter 可执行的操作
  3. flutter_copilot_claw 在运行中的 App 内通过 VM Service 扩展执行操作
  4. 结果以截图、日志、状态或结构化文本返回给 AI Client

这使得 AI 可以直接基于 Flutter 运行时状态进行判断,而不是只依赖源码或屏幕像素猜测。

Quick Start

如果你是第一次接触这个项目,建议从 flutter_copilot_mcp 开始;它是主要入口,包含安装、快速开始、工具列表和 Agent 配置方式。flutter_copilot_claw 则负责 Flutter 侧运行时挂载。

1. Add flutter_copilot_claw to your Flutter app

flutter pub add flutter_copilot_claw

在 main.dart 中初始化 Flutter Copilot。一行搞定,debug/profile/release 都安全 —— release 下 captureLogs 和 ensureInitialized 自动短路为 no-op,零开销,无需 kDebugMode 分支:

import 'package:flutter/material.dart';
import 'package:flutter_copilot_claw/flutter_copilot_claw.dart';

void main() {
  FlutterCopilotBinding.captureLogs(() async {
    FlutterCopilotBinding.ensureInitialized();
    // 任何 async 初始化(SystemChrome / 插件 / 远端配置等)都可以放在这里,
    // 它们的 print() 和未捕获异常都会进入 get_logs。
    runApp(const MyApp());
  });
}

如果你只需要 UI 交互、不在意 print() 捕获,可以省掉外层 captureLogs:

void main() {
  FlutterCopilotBinding.ensureInitialized();
  runApp(const MyApp());
}

日志三路:captureLogs vs addLog vs 自动捕获

get_logs 的内容来自三个互相独立的来源,分别对应不同的入口:

来源 捕获什么 怎么开
框架错误 FlutterError.onError + PlatformDispatcher.onError 自动 —— ensureInitialized() 内部已挂好。
环境输出 所有 print() / debugPrint() 输出 + 未捕获的 async 异常 用 captureLogs(body) 包住要监听的代码块。
显式打点 你主动写的字符串 在调用点写 FlutterCopilotBinding.addLog(message, isError: false)。

addLog 和 captureLogs 完全独立:只要 ensureInitialized() 跑过,不管外面有没有 zone,都能直接 addLog。它更适合打"业务事件标记"(login:attempt / payment:step:confirm),在 MCP 日志流里一眼能 grep 到,不用跟散落的 print() 混在一起。

什么时候用哪个

  • 只用 captureLogs:零改动迁移。现有代码里所有 print() 自动进 get_logs。
  • 只用 addLog:不想多套一层 zone,想完全控制哪些事件进日志。
  • 两个都用:信息量最全。captureLogs 兜底一切,addLog 负责高信号标记。

两者都用的示例

void main() {
  FlutterCopilotBinding.captureLogs(() async {
    FlutterCopilotBinding.ensureInitialized();
    FlutterCopilotBinding.addLog('app:boot:start');
    await SomePlugin.init();
    FlutterCopilotBinding.addLog('app:boot:plugins-ready');
    runApp(const MyApp());
  });
}

// 业务页面中任何位置都能直接调
Future<void> _login() async {
  FlutterCopilotBinding.addLog('login:attempt');
  try {
    await AuthService.signIn();
    FlutterCopilotBinding.addLog('login:success');
  } catch (e) {
    FlutterCopilotBinding.addLog('login:error: $e', isError: true);
    rethrow; // 未捕获异常也会被外层 captureLogs 兜住
  }
}

release 行为:三个入口都 release-safe —— captureLogs 退化为直接 body(),addLog 变 no-op,ensureInitialized 退化为 WidgetsFlutterBinding.ensureInitialized()。所以上面所有写法都可以不加 kDebugMode 保护就直接留在生产代码里。

2. Install flutter_copilot_mcp

全局安装:

dart pub global activate flutter_copilot_mcp

或者作为开发依赖安装:

dart pub add dev:flutter_copilot_mcp

3. Run your Flutter app in debug mode

flutter run

从控制台拿到 VM Service URI,例如:

ws://127.0.0.1:12345/ws

4. Configure the MCP server in your Agent

Claude Code

claude mcp add --scope project --transport stdio flutter_copilot_mcp -- flutter_copilot_mcp

如果你是在当前仓库里直接调试源码:

claude mcp add --scope project --transport stdio flutter_copilot_mcp -- dart run ./packages/flutter_copilot_mcp/bin/flutter_copilot_mcp.dart -l FINEST

Cursor

Cursor 通过 .cursor/mcp.json 读取 MCP 配置:

{
  "mcpServers": {
    "flutter_copilot": {
      "type": "stdio",
      "command": "flutter_copilot_mcp"
    }
  }
}

5. Connect and use the app

完成配置后,推荐按下面的顺序使用:

  1. 调用 connect,传入 VM Service URI
  2. 调用 get_interactive_elements、take_screenshots、get_logs 了解当前页面状态
  3. 再调用交互工具,例如:
    • tap
    • enter_text
    • scroll_to
    • flutter_copilot_drag
    • swipe
    • long_press
    • double_tap
    • navigate
  4. 在需要时调用:
    • hot_reload
    • get_rebuild_snapshot

为了让 Agent 更稳定地操作 Flutter App,建议:

  • 优先给关键元素添加 ValueKey<String>
  • 先从核心路径开始接入,例如登录、表单、详情页
  • 调试阶段优先使用 Debug 模式
  • 在需要日志和异常信息时用 FlutterCopilotBinding.captureLogs(...) 包裹 main()

6. Use the flutter-copilot skill for auto-connect

如果你在觉得上面手动链接的方案,不方便,请使用项目使用本仓库内置的 flutter-copilot skill,可以使用更自动化的连接方案。

这个 skill 会优先从项目根目录的 .vm_service_uri 文件读取当前 Flutter App 的 VM Service URI,再完成 Flutter Copilot MCP 连接。相比手动复制 URI,这种方式更适合持续调试、截图验证和热重载后的重复连接。

推荐流程:

  1. 通过项目里的启动方式运行 Flutter App,例如 scripts/flutter_run.sh 或对应的 VS Code 启动配置
  2. 确认项目根目录下已经生成 .vm_service_uri
  3. 在 Claude Code 中使用 flutter-copilot skill,让它自动读取 URI 并连接
  4. 后续继续使用截图、点击、输入、滚动、热重载等能力

这种方式特别适合:

  • 频繁重启 App 后重新连接
  • 需要快速截图或验证 UI 修改结果
  • 把 Flutter Copilot 作为其他 skill 的前置能力

如果应用重启后 URI 变化,只需要重新使用 flutter-copilot skill,它会按新的 .vm_service_uri 重新连接。

Flutter Copilot CLI

flutter_copilot_cli(命令名 fcc 或 flutter_copilot_cli,npm 地址:https://www.npmjs.com/package/flutter_copilot_cli)是与 MCP Server 并列的另一条使用路径。它直接通过 ext.flutter.flutter_copilot.* VM Service 扩展驱动 App,不依赖 MCP 协议,也不依赖任何 AI Client。

为什么需要 CLI?

  • 给人用:在终端里直接截图、点击、热重载,免去打开 AI Client 的链路
  • 给 CI 用:在 GitHub Actions、Jenkins 等流水线中以 YAML playbook 运行冒烟测试
  • 给受限 AI 用:对于不支持 MCP 协议的 Agent(或只能执行 shell 命令的小模型),通过 fcc help-ai 输出的 JSON 规范即可让它们驱动 App

能力对照:

能力 flutter_copilot_mcp flutter_copilot_cli
tap / drag / scroll / navigate / 日志 / 截图 ✅ ✅
当前 App 连接管理 connect 工具 ✅ .vm_service_uri / connect
交互式 REPL ❌ ✅ repl
日志 / Rebuild 实时流 ❌ ✅ watch --logs --rebuilds
YAML playbook(CI/冒烟测试) ❌ ✅ run script.yaml
面向 AI 的自描述 经由 MCP ✅ help-ai(JSON)

安装

要求 Node.js >= 18。

# 全局安装(三选一)
npm install -g flutter_copilot_cli
pnpm add -g flutter_copilot_cli
yarn global add flutter_copilot_cli

# 校验
fcc --version
fcc --help

安装后会在 PATH 中注册两个等价命令:flutter_copilot_cli(全名) 与 fcc(别名)。

快速上手

先确保 Flutter App 已经初始化 flutter_copilot_claw:

void main() {
  FlutterCopilotBinding.captureLogs(() {
    FlutterCopilotBinding.ensureInitialized();
    runApp(const MyApp());
  });
}

CLI 按如下顺序解析 VM Service URI,通常无需手动传入:

  1. --uri <ws://...> — 显式指定
  2. FLUTTER_COPILOT_URI 环境变量
  3. 当前目录或任一祖先目录下的 .vm_service_uri 文件

推荐配合仓库内的 scripts/flutter_run.sh 使用,它会把 URI 写入 .vm_service_uri:

./scripts/flutter_run.sh -d macos       # 启动 App,自动写入 .vm_service_uri
fcc doctor                              # 自动读取 URI 进行健康检查
fcc --uri "$(cat .vm_service_uri)" doctor # 只检查显式传入的 URI
fcc get-interactive-elements            # 列出当前可交互元素
fcc tap --text "点击"                   # 按文本点击
fcc take-screenshots -o /tmp/shot.png   # 截图
fcc hot-reload                          # 热重载

或者手动保存当前项目连接:

fcc connect --uri ws://127.0.0.1:8181/abc/ws
fcc tap --text "点击"

实时流与自动重连

# 同时订阅日志与 rebuild 事件
fcc watch --logs --rebuilds --interval 500

# 配合 --watch-uri 可在 flutter 重启后自动重连
fcc --watch-uri watch --rebuilds

YAML Playbook(CI 场景)

# smoke.yaml
name: smoke-home
stopOnFailure: true
steps:
  - action: assert-element
    text: Flutter Copilot 功能演示
  - action: tap
    text: 点击
  - action: wait
    ms: 300
  - action: take-screenshots
    output: /tmp/fcc-smoke.png
  - action: assert-element
    text: 点击
fcc run smoke.yaml

每个步骤可附带 retry: { attempts, delay } 做自动重试。

给 AI Agent 使用

fcc help-ai                        # 输出完整命令表与脚本 schema 的 JSON
fcc --json get-interactive-elements # 所有命令都支持 --json,便于管道消费

更多命令、参数与示例参见 packages/flutter_copilot_cli/README.md。

平台支持

Platform Support Notes
Android ✅ Debug mode
iOS ✅ Debug mode
Web ✅ 部分诊断能力存在平台差异
macOS ✅ Debug mode
Windows ✅ Debug mode
Linux ✅ Debug mode

实际能力依赖 Flutter 调试能力与 VM Service,可用性以调试模式下的运行环境为准。

仓库结构

相关文档

License

Apache License 2.0