FlutterSDK Dusk について
FlutterSDK Duskは、実行中のFlutterアプリ向けのエンドツーエンドドライバーで、CLIとstdio MCP サーバーを備えています。テストファイルを作成せずにUIを調査・操作したい開発者やコーディングエージェント向けです。
主な機能
- 01Semanticsツリーのスナップショット
- 02タップ・入力・スクロール操作
- 03スクリーンショットと状態確認
- 04CLIとMCPツール
- 05操作前の実行可能性チェック
- 06ホットリロード後のスナップショット
活用シーン
- 01実行中アプリのUI構造を調査
- 02タップやフォーム入力を自動化
- 03スクリーンショットで操作結果を確認
- 04エージェントを使ってFlutterアプリをデバッグ
MCP 対応
ランタイムのstdio MCP サーバーは、実行中のFlutterアプリを操作する39個の`dusk_*`ツールを公開します。Duskのドキュメントを検索する`search-docs`ツールを持つホスト型ドキュメントMCPとは別のものです。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Dusk
Flutter アプリ向けのエンドツーエンドドライバー。人が読み、AI エージェントが操作します。
Semantics ツリーのスナップショット取得、あらゆるジェスチャーの実行、スクリーンショットの撮影、ライブ状態の監視を、単一の CLI と stdio MCP サーバーから行えます。
メモ
Dart SDK >= 3.4.0 および Flutter >= 3.22.0 が必要です。dusk はデバッグ専用です。Web、デスクトップ、モバイル向けの本番ビルドでは、ドライバー全体がツリーシェイクされます。
インストール
flutter pub add fluttersdk_dusk
dart run fluttersdk_dusk dusk:install # patches lib/main.dart + scaffolds ./bin/fsa + registers dusk plugin
これで完了です。2つ目のコマンドを実行すると、41個すべての dusk:* コマンドが ./bin/fsa <cmd>(ウォーム時約110ms)または dart run fluttersdk_dusk <cmd>(同じように動作し、起動に約3秒)から使えるようになります。また、dart run fluttersdk_dusk mcp:install を実行するだけで MCP サーバーを利用できます。fastcli(./bin/fsa)がない場合、mcp:install は .mcp.json に dart run fluttersdk_dusk mcp:serve を自動で書き込みます。手動での編集は不要です。クライアントごとの設定方法については、MCP のインストール:8つのクライアントをご覧ください。手動設定、Magic スタックとの統合、コマンドごとのすべてのフラグのリファレンスは、スタートガイドに記載されています。
ヒント
fastcli は、
./bin/fsaとして提供される AOT コンパイル済みの artisan ディスパッチャー(ウォーム時約110ms)です。dusk:installが自動でセットアップします(ベストエフォート方式。dartが PATH にない場合は警告を表示して続行します)。セットアップ後は、すべての./bin/fsa <cmd>が高速な実行方法になります。CLI は同じコマンド体系でdart run fluttersdk_dusk <cmd>としても実行できますが、呼び出しごとに約3秒遅くなります。
Dusk を選ぶ理由
Flutter のエンドツーエンドテストは、これまで常に複数の仕組みをつなぎ合わせる作業でした。flutter_driver は、ホットリスタートに耐えられない単発のソケットプロトコルを提供します。integration_test は、シミュレートされた WidgetTester に対してプロセス内で実行されますが、テストファイルを作成し、ビルドして、実行し、完了を待つ必要があります。実行中のアプリを操作したい AI コーディングエージェントは、場当たり的な flutter test の呼び出しに頼り、スタックトレースをプロンプトにコピーして戻し、スクリーンショットを貼り付けて、これをワークフローと呼んでいます。
Dusk がそのループを完結させます。 単一の VM Service 拡張機能ファミリー(ext.dusk.*)、単一の CLI 名前空間(dusk:*)、単一の stdio MCP サーバーが、41 個の CLI コマンドと39 個の MCP ツール(33 個の ext.dusk.* + 基盤を経由してルーティングされる 6 個の artisan:dusk:*)を支えます。同じ契約が、人間によるターミナルからの呼び出しと、エージェントによる MCP ツールの呼び出しを支えます。dusk:tap --ref=e7(CLI)と dusk_tap(MCP)は、まったく同じコードパスに到達します。テストハーネスも、テストファイルも、ビルド手順も必要ありません。実行中のアプリに接続すれば、エージェントは目(dusk_snap、dusk_screenshot、dusk_observe)と手(dusk_tap、dusk_type、dusk_scroll、dusk_drag)を使えます。Flutter Web では、artisan を --cdp-port を指定して起動した場合、dusk:screenshot CLI コマンドは CDP の Page.captureScreenshot にフォールバックし、CanvasKit でハングするインプロセス拡張機能を回避します。一方、dusk_screenshot MCP ツールは引き続きインプロセスでディスパッチされるため、Web エージェントはスクリーンショットに CLI を使用してください。dusk_exceptions は、パッケージ内で致命的でない FlutterError(オーバーフローを含む)をキャプチャするため、telescope がなくても診断できます。
| ツール | 機能 | Dusk の位置づけ |
|---|---|---|
| integration_test(Flutter SDK) | プロセス内の WidgetTester ラッパー。flutter drive でテストを実行します | 異なる用途です。integration_test は 作成したテストファイル を担当し、Dusk は スクリプト化されていない実行中のアプリ を担当します。両方を使用できます。 |
| patrol(Leancode、694 likes) | integration_test にネイティブ UI の権限とダイアログを追加します | 互いに補完する用途です。patrol は ネイティブダイアログを使う作成済みテスト を担当し、Dusk は 人間と AI エージェントによるスクリプト化されていない自動化 を担当します。 |
| flutter_driver(Flutter SDK、レガシー) | 単発のソケットプロトコル。段階的に廃止されています | Dusk は registerExtensionIdempotent(21 個のアグリゲーター登録関数)によってホットリスタートに対応し、CLI と MCP で共通の契約を使用します。テストハーネスも、別のアイソレートも不要です。 |
| maestro(13.7K stars) | OS のアクセシビリティレイヤー上で動作する YAML DSL | Dusk は Flutter のウィジェットツリーを直接操作します(Semantics ノード + RenderObjects)。Flutter Desktop の制限がなく、作成する YAML もゼロです。 |
| mcp_flutter(298 stars) | fmt_* ツールを備えた Flutter MCP ツールキット | Dusk は検証済みの公開元とともに pub.dev で公開され、フレームワークネイティブの Artisan プラグイン、e<N> と q<N> の ref システム、6 段階の操作可能性ゲートを備えています。 |
| playwright-mcp(33K stars) | アクセシビリティツリーと [ref=eN] トークンを利用するブラウザー MCP | Flutter ネイティブ版にあたります。Dusk の q<N> ハンドルは Playwright の getByRole() に相当します。dusk_observe は Stagehand の「一度観察し、何度も操作する」パターンを取り入れ、Flutter Semantics 向けに移植したものです。 |
特長
| 特長 | 説明 | |
|---|---|---|
| 🌳 | セマンティクススナップショット | dusk_snap は安定した [ref=eN] トークンを含む YAML ツリーを出力します。すべてのアクションは ref を対象とするため、不安定な XPath や座標の推測は不要です |
| 🛠️ | 41 個の CLI コマンド | snap、tap、type、fill、drag、scroll、hover、dblclick、right_click、triple_click、focus、blur、clear、set_checkbox、select_option、press_key、wait、find、observe、navigate、navigate_back、get_routes、modal、reset_overlays、screenshot、hot_reload_and_snap、CDP resize + device、close_app、install、doctor、wait_for_network_idle、console、exceptions、perf_begin + perf_end + perf_insight + perf_run + perf_compare + perf_trace + perf_campaign |
| 🤖 | 39 個の MCP ツール | CLI の全機能に dusk_evaluate を加えたものを、Claude Code、Cursor、Windsurf、VS Code Copilot、および MCP 互換のあらゆるエージェント向けに、stdio JSON-RPC ツールとして公開します |
| 🚪 | 6 段階の操作可能性ゲート | すべてのジェスチャーは、defunct(事前確認)→ enabled → zero-rect → off-viewport(自動スクロール)→ stable(2 フレーム間の矩形のずれ)→ receives-events(ヒットテスト経路)を通過します。不安定なタップは発生せず、最後の確認ができなかった場合は、黙って成功とせず checks ブロックを返します |
| 🔖 | Playwright スタイルのロケーター | dusk_find による q<N> の再解決可能なハンドルは、アクションのたびにライブの Semantics ツリーをたどります。古くなったハンドルは例外を発生させ、誤ったウィジェットに黙って作用することはありません |
| 🔄 | ホットリロード + スナップショットの往復処理 | dusk_hot_reload_and_snap は、1 回の呼び出しで {reloaded, durationMs, snapshot, screenshot, exceptions} を返します |
| 🖥️ | CDP デバイスエミュレーション | dusk_resize_viewport と dusk_device_profile(iphone-x、pixel-5、desktop-1440、その他 5 種)が Chrome DevTools Protocol を操作します |
| 📈 | フレーム帰属セッション | dusk_perf_begin / dusk_perf_end は、操作を実行するセッションを開始・終了し、構築されたウィジェットの種類、回数、所要時間を、wind のキャッシュヒット/ミス/バイパスカウンターや magic のコントローラー通知と併せて報告します。エンジンを通じて描画されなかったセッションは、ゼロの一覧が「高速」と受け取られるため、報告せずに拒否します |
| 🎨 | スナップショット拡張プラグイン | DuskPlugin.enrichers.add() により、magic と wind は String? Function(Element, RefRegistry) の固定された契約を介して、フレームワーク固有の YAML フラグメントを追加できます |
| 🔒 | リリース時のツリーシェイク | 利用側は DuskPlugin.install() を !kReleaseMode で囲みます。これにより、デバッグビルドとプロファイルビルドにはドライバーが含まれ、リリースビルドでは Web、デスクトップ、モバイル全体でツリーシェイクされます |
| 📡 | AI ファーストの配布 | skills/fluttersdk-dusk/ に正規の fluttersdk-dusk スキルを用意し、ホスト型ドキュメント MCP を mcp.fluttersdk.com で提供します。fluttersdk/ai を通じて 8 つ以上のエージェント(Claude Code、Cursor、OpenCode、Gemini CLI、VS Code Copilot、Codex CLI、Cline、Roo Code)に配布しています。Flutter エコシステムで初めて、独自の LLM エージェントスキルバンドルとドキュメント MCP を同梱した、エンドツーエンドのドライバーです。 |
重要
デバッグビルドとプロファイルビルドに含めるため、
lib/main.dartの呼び出し箇所ではDuskPlugin.install()をif (!kReleaseMode) { ... }で囲む必要があります(dusk:perf_runはプロファイルビルドを計測します)。これ以前にkDebugModeの条件下で組み込んだアプリは、デバッグでは動作しますが、プロファイルビルドではext.dusk.*が登録されません。ガードが存在する場合に限り、リリースビルドでは Web(dart2js)、デスクトップ(dart2native)、モバイル(AOT)全体でドライバー全体がツリーシェイクされます。ガードがないと、dusk はリリースバイナリに含まれます。
AI コーディングアシスタント
Dusk は AI ファーストで提供されています。skills/fluttersdk-dusk/SKILL.md のスキルでは、6 つのコア原則、e<N> / q<N> の ref 文法、6 段階のアクション可能性に関する語彙、39 個の MCP ツール群、エージェントワークフローのプレイブックをエージェントに教えます。同じスキルは fluttersdk/ai を通じて Claude Code、Cursor、OpenCode、Gemini CLI、VS Code Copilot、Codex CLI、Cline、Roo Code 向けに配布されています。コマンドは 1 つです。
npx skills add fluttersdk/ai --skill fluttersdk-dusk
mcp.fluttersdk.com のホステッド MCP サーバーは、Dusk のドキュメントコーパスを直接検索する必要があるエージェント向けに、Streamable HTTP(認証不要)で search-docs ツールを公開しています。stdio のみをサポートするクライアントには、npx @fluttersdk/mcp ブリッジが stdio を上流の HTTP サーバーにプロキシします。LLM が読み取れるインベントリは llms.txt にあります。複数クライアントの完全な接続手順と OpenCode レジストリ URL は fluttersdk/ai README に記載されています。
これは Dusk 自体のランタイム MCP サーバー(./bin/fsa mcp:serve、次のセクションで説明)とは別のものです。ドキュメント MCP はエージェントに Dusk について教え、ランタイム MCP は実行中の Flutter アプリを操作するための視覚と手段をエージェントに提供します。
MCP のインストール:8 クライアント
Dusk は、ランタイムテレメトリーではなくUI オートメーション(タップ、スナップショット、スクリーンショット、観察)に重点を置いた、初の Flutter MCP サーバーです。39 個の dusk_* ツールは、あらゆる MCP 対応エージェントから利用できます。
メモ
以下の設定では
./bin/fsa(fastcli ラッパー。README の冒頭を参照)を使用します。fastcli がまだスキャフォールドされていない場合は、すべてのクライアントの行で./bin/fsa mcp:serveをdart run fluttersdk_dusk mcp:serveに置き換えてください。
標準設定(プロジェクトルートの .mcp.json を読み込むクライアント向け):
{
"mcpServers": {
"fluttersdk": {
"command": "./bin/fsa",
"args": ["mcp:serve"],
"cwd": "."
}
}
}
| クライアント | インストール |
|---|---|
| Claude Code | claude mcp add fluttersdk -- ./bin/fsa mcp:serve |
| VS Code | code --add-mcp '{"name":"fluttersdk","command":"./bin/fsa","args":["mcp:serve"]}'、または標準設定を .vscode/mcp.json に配置します |
| Cursor | Settings > MCP > Add new MCP Server、または標準設定を ~/.cursor/mcp.json に配置します |
| Windsurf | 標準設定を ~/.codeium/windsurf/mcp_config.json に配置します |
| Goose | Advanced settings > Extensions > Add custom extension を選択し、標準設定を貼り付けます |
| Warp | Settings > AI > Manage MCP Servers、または標準設定を指定して /add-mcp スラッシュコマンドを実行します |
| Claude Desktop | claude_desktop_config.json(macOS:~/Library/Application Support/Claude/、Windows:%APPDATA%\Claude\)を編集し、mcpServers の下に標準設定を追加します |
| Codex | codex mcp add fluttersdk ./bin/fsa mcp:serve |
Dusk 導入前/導入後
| Dusk なし | Dusk あり |
|---|---|
| ホットリロードして結果をスクリーンショットに撮り、PNG を Claude にドラッグして、「カウンターボタンがタップできるはずなのにできません。原因は何ですか?」と入力し、スクロールして、関連するウィジェットのソースをコピーして貼り付けます。 | Claude が dusk_snap を呼び出し、[ref=eN] トークンを含む YAML ツリーを読み取ります。Claude が dusk_tap --ref=e7 を呼び出すと、ゲートが作動してカウンターが増加し、Claude が新たなスナップショットで確認します。あなたが介在しなくてもループが完結します。 |
失敗するテストがタイミングの問題なのか、本当のバグなのか判断できません。Future.delayed(Duration(seconds: 2)) を追加して、もう一度実行します。 | すべてのジェスチャーの前に、6 段階のアクション可能性ゲートが作動します。対象が破棄済み、無効、矩形がゼロ、ビューポート外、安定していない、別のウィジェットに隠されている場合に検出します。エラーにはエージェントが解析できる理由文字列が含まれます。 |
一般的なエージェントセッション
[agent] artisan_start { device: macos } # launch the app
[agent] dusk_snap {} # semantic tree with stable refs
[agent] dusk_observe {} # structured candidate list (Stagehand-style)
[agent] dusk_tap { ref: "e7" } # tap a button by ref
[agent] dusk_screenshot { format: "jpeg" } # verify visually
[agent] dusk_hot_reload_and_snap {} # reload + snap in one round-trip
[agent] artisan_stop # tear down
各ツールの完全な入力スキーマと呼び出し例は、MCP ツールリファレンスを参照してください。接続時に構造化されたプロジェクトコンテキストを読み込むエージェント向けの正式なエントリーポイントは llms.txt です。39 個の MCP ツール名に加え、コマンド一覧、ref トークンの文法、6 段階のアクション可能性に関する語彙がインラインで記載されています。サイトでは、人間向けには通常の URL を、LLM エージェント向けには .md サフィックスを付けた同じパスを提供しています(例:https://fluttersdk.com/dusk/getting-started.md)。
例
example/ ディレクトリには、1 つのルートで各 CLI コマンドを実際に操作できるウィジェットに結び付けた、標準的な Flutter のショーケースが含まれています。TextField、Dropdown、Checkbox、Switch、カウンターボタン、Draggable + DragTarget、ダイアログ、ボトムシート、スクロール用の 30 行の ListTile、3 つの名前付きルート間を移動するナビゲーションボタンを備えています。
cd example && flutter pub get
dart run fluttersdk_dusk start --device=macos
ドキュメント
実際に操作できるサンプルを含むドキュメント全文は fluttersdk.com/dusk にあります。コマンド一覧、MCP ツールリファレンス、6 ステップのアクショナビリティリファレンス、Magic と Wind の統合ガイド、スナップショットエンリッチャーの作成ガイドを掲載しています。コントリビューター向けの内部アーキテクチャについては、ARCHITECTURE.md をご覧ください。
コントリビューション
git clone https://github.com/fluttersdk/dusk.git
cd dusk && flutter pub get
flutter test && dart analyze
CI では、master へのプッシュごと、および master に戻すすべての PR で、lib/ の行カバレッジ 80% 以上、analyze の問題ゼロ、lib/、test/、bin/ のフォーマット差分ゼロを必須としています。新しい動作は、まず失敗するテストを追加してから実装します(レッド、グリーン、リファクタリング)。
プルリクエストを作成する前に、CI と同じチェックを実行してください。
dart format --output=none --set-exit-if-changed lib/ test/ bin/
dart analyze lib/ test/ bin/
flutter test --exclude-tags=integration --coverage --timeout=30s
dart pub publish --dry-run
ライセンス
MIT です。詳細は LICENSE をご覧ください。
FlutterSDK が心を込めて開発しました
Dusk によってデバッグ時間を短縮できたら、スターを付けてください。ほかの人が見つけやすくなります。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。