
Flutter MCP Toolkit
io.github.Arenukvern由 GitHub 账号 Arenukvern 发布v7.0.1更新于 Oct 24, 2026
Inspect and drive Flutter debug apps/games: semantic snapshots, search, and custom client tools
概览
一个本地 MCP 服务器,让助手检查并操控正在运行的 Flutter 调试应用:语义快照、控件交互、截图、热重载与 VM 诊断。
- 可以做什么
- 发现并连接正在运行的 Flutter 调试应用,通过 Dart VM 服务管理会话,存在多个目标时可显式选择。采集 UI 快照、截图和视图详情,检查指定坐标的控件,或导出语义、渲染、图层与焦点树。以“先快照再引用”的方式与应用交互:点击、长按、输入文本、滚动、滑动、拖拽,并定位屏幕外目标。执行热重载或热重启,可与新截图和错误报告合并执行,并运行临时 Dart 表达式。读取应用错误与近期日志,运行诊断和运行时校验,创建或对比可复现的快照与打包产物。调用动态客户端工具与资源。
- 适用场景
- 适合在开发 Flutter 应用或游戏时,让助手查看运行中的界面、定位并点击控件、读取错误和日志,或在热重载后验证改动。面向本地调试构建,而非生产应用。
- 运行要求
- 以本地进程运行(容器镜像发布在 ghcr.io),需要桌面环境,Flutter 应用以调试模式运行且其 Dart VM 服务可访问,通常为 localhost 的 8181 端口。应用需引入 mcp_toolkit 包并初始化工具包绑定,否则检查会被阻止。macOS 上原生窗口截图需要“屏幕录制”权限。
安装
在 SourceWeft 中
- 打开 控制台中的 Flutter MCP Toolkit,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
MCP Toolkit Server (Dart)
Migrating from v2.x
Tool names on MCP are prefixed with fmt_, binaries and mcpServers keys were renamed — see Migrating from v2.x to v3.0.
Architecture
This project now uses a shared core execution layer:
flutter-mcp-toolkitis the canonical command surface (connect, inspect, execute, diagnostics).fmtkis the short alias for the same CLI entrypoint.flutter-mcp-toolkit-serveris a thin MCP protocol adapter that maps MCP tool/resource calls to the same core executor.- MCP
tools/listnames use thefmt_capability prefix; CLIexec --nameuses command catalog names or aliases outside the MCPtools/callnamespace. Resource URIs are unchanged.
The shared core module is available as flutter_mcp_core inside this package.
Golden Path
Use this sequence first on macOS:
- Add
mcp_toolkitto the app and callMCPToolkitBinding.instance.bootstrapFlutter(...). - Launch the app in debug mode.
- Run
fmtk validate-runtime(or the canonical long formflutter-mcp-toolkit validate-runtime). - Query dynamic entries in this order:
fmt_list_client_tools_and_resources,fmt_client_tool,fmt_client_resource.
Treat exec as expert mode. validate-runtime is the default first-pass proof command.
CLI v3 Surface (Hard Cut)
The CLI is now agent-first and exposes a canonical interface:
exec --name <command> --args <json>schema [--name <command>]capabilitiesserve(JSON-RPC 2.0 over stdio)snapshot create --name <id> [--args <json>]snapshot diff --from <id> --to <id>bundle create --from-snapshot <id> [--output <dir>]doctor [--json] [--target <path>] [--timeout-ms <n>]permissions status|request|open-settings [--kind visual_capture]
Safe-write flags for write-producing commands:
snapshot create:--check --diff --backup --no-overwritebundle create:--check --diff --backup --no-overwrite
exec targets commands in the shared CommandCatalog (CLI command names may
be bare because they appear only after --name; the CLI is not the MCP
tools/call namespace):
connect, session_start, session_exec, session_end, diagnose, watch, explain_errors, status, discover_debug_apps, get_vm, get_extension_rpcs, hot_reload_flutter, hot_restart_flutter, get_active_ports, get_app_errors, get_screenshots, focus_window, get_view_details, inspect_widget_at_point, capture_ui_snapshot, debug_dump_layer_tree, debug_dump_semantics_tree, debug_dump_render_tree, debug_dump_focus_tree, fmt_list_client_tools_and_resources, fmt_client_tool, fmt_client_resource, dynamicRegistryStats, semantic_snapshot, tap_widget, long_press, enter_text, reveal_search, scroll, swipe, drag, hot_reload_and_capture, evaluate_dart_expression, get_recent_logs.
MCP names. When invoked via MCP
tools/call, exposed tools use thefmt_capability prefix (e.g.fmt_tap_widget,fmt_hot_reload_and_capture). The dynamic-registry host trio is exposed asfmt_list_client_tools_and_resources,fmt_client_tool, andfmt_client_resourcewhere enabled.dynamicRegistryStatsremains available from the CLI catalog for low-level diagnostics and is not part of the default MCP tool surface.
Interaction tools (catalog names: semantic_snapshot → tap_widget / enter_text / reveal_search / scroll / swipe / long_press / drag) follow a Playwright-style ref model: take a snapshot, then pass ref: "s_N" (and optional snapshotId for staleness detection) into the interaction tool. reveal_search is the bounded helper for off-screen semantic targets: it snapshots, matches one narrow selector, scrolls up to maxAttempts, and returns a fresh ref/snapshotId plus trace. hot_reload_and_capture fuses reload + screenshot + fresh snapshot + errors. evaluate_dart_expression runs an ad-hoc Dart expression against the app's root library. See docs/start_here/cli_quick_recipes.mdx and docs/guides/interaction_cookbook.mdx for the full surface and golden paths.
Packaged installs include both flutter-mcp-toolkit and fmtk; examples below use dart run for source-tree development. Prefer fmtk for compact local loops and keep flutter-mcp-toolkit in onboarding, install, PATH, and MCP config docs where the searchable canonical name helps.
CLI runs the same shared command catalog/executor as MCP. Preferred debugging path:
discover_debug_apps -> capture_ui_snapshot -> inspect_widget_at_point.
get_active_ports and dynamicRegistryStats remain available in CLI for low-level diagnostics, but are intentionally not MCP-exposed by default.
CLI Quick Use (v3)
CLI runtime gate for app inspection:
- Require
ext.mcp.toolkit.app_errors,ext.mcp.toolkit.view_details,ext.mcp.toolkit.view_screenshots, andext.mcp.toolkit.inspect_widget_at_pointfromget_extension_rpcs. - If missing, app-level screenshot/layout/error inspection is blocked until
mcp_toolkitis installed, initialized, and the app is hot restarted or rerun. - If screenshots show a black rectangle where a map/camera/web view should be, check
captureHintsonget_view_detailsor screenshot payloads (platformViewsDetectedorweakSignalsDetected). Usemode: desktop_window(or keepauto, which upgrades on macOS host when strong signals are present) instead offlutter_layer. - Host capture runs one automatic focus+capture recovery cycle on retryable failures (
desktopCaptureRetriedin the payload). You can also callfocus_windowthen retryget_screenshotswithdesktop_window. - If first explicit-URI connect times out, retry once and validate with
doctor --json --target <ws_uri> --timeout-ms 10000. - When
--output-diris set,validate-runtimemirrors its JSON envelope to<output-dir>/validate-runtime.jsonand screenshot files are written under<output-dir>/.mcp_screenshots/. validate-runtimetries hostdesktop_windowfirst whenautoselects it. Executor recovery retries focus+capture once (desktopCaptureRetried). Ifdesktop_windowstill fails, validate-runtime retries once withflutter_layer(including when platform views are detected, e.g. the showcaseAppKitView). Checkdata.summary.capturePlatformViewsDetected,captureFocusAttempted, andcaptureFallbackUsed. Web headful capture options: ADR 0007.
Visual Capture Permissions
doctorstays read-only. It now reportsvisual_capture_backend,visual_capture_permission,visual_capture_truth_mode, andapp_permission_bridge.- Interactive CLI capture flows default to
auto_request_onceforexec get_screenshots,exec capture_ui_snapshot, andvalidate-runtime. Raw command schemas still default tocheck_only. - macOS truthful capture is
desktop_window(including iOS Simulator and Chrome / web on a Mac host). Screen Recording permission belongs to the host process runningflutter-mcp-toolkit, not the Flutter app. Usepermissions requestfor the native prompt andpermissions open-settingsafter a denial. get_view_detailsandview_screenshotsincludecaptureHintswhen native platform views are detected (AndroidView,UiKitView,AppKitView,HtmlElementView,PlatformViewLink).TexturesetsweakSignalsDetectedwith a soft warning (noautoupgrade). Hybrid engines without platform views can useMCPToolkitBinding.captureHintsContributorin the app.- Image-only
get_screenshotsMCP responses include routing metadata inmetaand a leading JSON text block whencaptureHints/warningsare present. - Showcase Capture section:
AppKitViewon macOS (make showcase),HtmlElementViewon web (flutter run -d chrome). Usemake showcase-stopbefore a new macOS run. - Web (
chrome/web/web-server):desktop_windowuses macOS ScreenCaptureKit → Chrome CDP (Page.captureScreenshot) →flutter_layer. Global flags:--web-browser-debugging-port,--web-port. Opt-in live test:RUN_WEB_CDP_INTEGRATION=1 dart test test/web_cdp_integration_test.dart. See ADR 0007. - App-owned capture targets such as iOS/Android/Linux must have a reachable VM
target selected before
permissionsordoctorcan verify bridge-backed permission tools/resources. Use--target <ws_uri>or the global--vm-service-uri <ws_uri>when probing those platforms. desktop_windownever silently falls back.automay fall back toflutter_layer, but responses always reportrequestedMode,actualMode,permissionStatus, andfallbackReason.
Troubleshooting:
- If macOS capture is denied, rerun
flutter-mcp-toolkit permissions statusfirst. If status is stilldenied, open System Settings from the CLI and grant Screen Recording to the terminal or client process you are using. - If
doctor --jsonshowsvisual_capture_truth_mode=flutter_layeron macOS, you are not getting native window pixels yet. - If web
desktop_windowfails, useflutter_layeror pass--web-browser-debugging-portfrom Chrome’s--remote-debugging-port. For web targets, pass--flutter-device chromeonvalidate-runtime.validate-runtimestill retriesflutter_layerafter a faileddesktop_windoweven when platform views are detected. - If post-reload capture fails once on macOS desktop-window mode, that is usually a host capture race rather than an app failure.
validate-runtimeretries those failures before returning red, and may also retry withflutter_layerafter a faileddesktop_windowscreenshot.
Failure matrix:
missing_mcp_toolkit_wiring: app did not expose the required toolkit extensions. Fix app bootstrap and hot restart.bad_target_uri_or_unreachable_vm_service: explicit target URI is wrong or the VM service is not reachable.permission_denied: host capture backend lacks permission.host_capture_backend_instability: native capture backend flaked during desktop-window capture, usually around reload.
Migration (v2.x -> v3.0.0)
- Error metadata moved under
error.descriptor; do not parse legacy top-level fields. - Typed arguments are strict. String-encoded booleans/objects/lists/integers now fail validation.
- For write-producing automation, run with
--check --diffbefore actual writes. - Handle
write_blockedexplicitly when using--no-overwrite. - Add
flutter-mcp-toolkit doctor --jsonas preflight before VM-dependent execution.
Machine Envelope
One-shot commands return one JSON envelope with stable fields:
Failures use one strict envelope in error:
code, message, details, descriptor (category, retryable, exitCode, httpLikeStatus), recovery.
The full contract table is documented in docs/ai_agents/troubleshooting.mdx.
Daemon Protocol
serve runs JSON-RPC 2.0 over stdio. Key methods:
- requests:
initialize,capabilities/get,schema/get,command/execute,watch/start,watch/stop,snapshot/create,snapshot/diff,bundle/create,session/start,session/end - notifications:
watch/event,session/changed
Watch notifications are NDJSON JSON-RPC notifications with monotonic seq per watch.
Targeting contracts:
command/execute: optionalparams.args.connectionwatch/start: optionalparams.args.connection(applied once before watch loop starts)snapshot/create: per-step optionalargs.commands[i].args.connection
State + Locking
- State root defaults to
.flutter_mcp/ - state file:
.flutter_mcp/state.json - lock file:
.flutter_mcp/state.lock - snapshots:
.flutter_mcp/snapshots/ - bundles:
.flutter_mcp/bundles/
State operations use a lock with stale-lock TTL recovery to support concurrent agents safely.
Connection Resolution UX
The server keeps startup non-blocking and defers target lock until a VM-dependent call is executed.
Resolution policy for VM-dependent commands/resources:
- Reuse active connection if still healthy.
- Else reuse sticky target if it exists in current discovery results.
- Else auto-attach if exactly one target is discovered.
- Else fail with
connection_selection_requiredwhen multiple targets exist and no explicit target is provided.
Selection-required errors are returned as structured JSON so agents can retry immediately:
CLI one-shot and daemon calls use the same handshake semantics. For ambiguous multi-target sessions, retry with an explicit selector:
All VM-dependent MCP tools now accept optional arguments.connection:
Notes:
targetIdis the preferred selector and must be full VM websocket URI.- Legacy
host:porttarget IDs are rejected; use URI target IDs orconnection.uri. - Safest selector is
connection.uriwith exact Flutter machineapp.debugPort.wsUri. - If
targetIdlookup misses but URI is a full tokenized VM path (/<token>/ws), server attempts direct connect fallback. - CLI
exec --argsand daemoncommand/execute/watch/startaccept the same optional nestedconnectionobject. connect_debug_appaccepts the sameconnectionshape.- Dynamic registry tools (
fmt_list_client_tools_and_resources,fmt_client_tool,fmt_client_resource) accept the same optionalconnection. - Resource reads also support query targeting:
targetId,mode,host,port,uri,forceReconnect. - Flat top-level connection aliases like
host/port/uriin tool arguments are intentionally rejected by strict schemas. - For
connectandsession_start, native selector args (mode,targetId,host,port,uri,force) cannot be mixed with nestedconnection.
Zero-mistake recipe:
- Read machine
app.debugPort.wsUri. - Use
{"connection":{"uri":"<that exact wsUri>"}}. - If using
targetId, copy exactly fromavailableTargets/discover_debug_apps.
Flutter Web Discovery
Discovery order is:
- Flutter machine discovery (
flutter attach --machine) - Port-scan fallback
Both CLI and MCP server accept:
--flutter-project-dir--flutter-device(for examplechrome)--flutter-discovery-timeout-ms--scan-ports(for example8765-8767,9100)--prefer-target-label(for examplestaging)
The port scan recognizes dart/flutter processes. A desktop app hosts its VM
service inside its own native process and an app started with --no-dds has no
Dart process, so neither is found by name. Start such an app on a fixed VM
service port (flutter run -d macos --device-vmservice-port=8765) and pass that
port to the scanner with --scan-ports=8765.
When several debug apps run at once, let each name itself with
MCPToolkitBinding.instance.setAppIdentity(label: 'my_app · staging'):
discovery reports the label on every target, and --prefer-target-label lets
auto-attach pick one without the caller naming an endpoint. The label narrows
the candidates only at the auto-attach step, so an active connection and a
target connected to explicitly still win; a value that matches no running app
is ignored, so discovery keeps behaving as it would without it.
Manual fallback remains available:
- CLI:
--vm-service-uri ws://127.0.0.1:59490/<token>/ws - MCP tool/resource calls:
arguments.connection.uri
Quick Start
📦 Installation from GitHub (Currently Recommended)
For developers who want to contribute to the project or run the latest version directly from source, follow these steps:
-
Clone the repository:
-
Install and build dependencies:
This command installs all necessary dependencies listed in
pubspec.yamland then builds the MCP server. -
Add
mcp_toolkitPackage to Your Flutter App:The
mcp_toolkitpackage provides the necessary service extensions within your Flutter application. You need to add it to your app'spubspec.yaml.Run this command in your Flutter app's directory to add the
mcp_toolkitpackage:or add it to your
pubspec.yamlmanually:Then run
flutter pub getin your Flutter app's directory. -
Initialize in Your App: In your Flutter application's
main.dartfile (or equivalent entry point), initialize the bridge binding: -
Start your Flutter app in debug mode
Adjust
-dfor your device. Prefer the exactapp.debugPort.wsUrifrom machine output inarguments.connection.uriorconnection.targetId. -
🛠️ Add Flutter MCP Toolkit to your AI client
Recommended (skills + MCP config):
Skills only via the open Agent Skills ecosystem:
See docs/ai_agents/overview.mdx for install paths, lockfiles, and skills.sh.
Manual
mcpServersJSON (advanced — use ifinitis not an option):Use registry key
flutter-mcp-toolkitundermcpServers(canonical). The keyflutter-inspectoris legacy but still accepted if your config predates the rename. That string is only amcpServersid — it is not the Claude Code subagent name. The bundled runtime subagent isflutter-mcp-toolkit-runtime(plugin/agents/flutter-mcp-toolkit-runtime.md).Recommended server args:
--resources,--images,--dynamics(defaults are on for resources/images;--dynamicsenables the dynamic registry).Note for Local Development (GitHub Install):
If you installed from GitHub and built locally, point
commandatmcp_server_dart/build/flutter-mcp-toolkit-server. See Installation from GitHub above.Cline Setup
- Add to your
.cline/config.json: - Restart Cline
- The Flutter MCP toolkit tools will be available in your conversations
- Try: "Please get a screenshot of my app" (MCP tools use the
fmt_prefix, e.g.fmt_get_screenshots)
Cursor Setup
Badge
Install the server (edit the path in Cursor after clicking):
Note: fix
commandpath after installation.Manual Setup
-
Open Cursor's settings
-
Go to the Features tab
-
Under "Model Context Protocol", add the server:
-
Restart Cursor
-
Open Agent Panel (cmd + L on macOS)
-
Tool calls use
fmt_*names on the MCP wire (e.g.fmt_capture_ui_snapshot).
Claude Setup
- Add to your Claude configuration file:
- Restart Claude
- The Flutter MCP toolkit tools will be available
- Try: "Please get screenshot of my app"
- Add to your
Development
Command Line Options
Image File Saving Mode
When --save-images is enabled, the server will:
- Save all captured screenshots as PNG files in a
.mcp_screenshotsfolder in the current working directory - Return file URLs (
file://) instead of base64 encoded image data - Automatically clean up screenshots older than 24 hours
- Use timestamped filenames like
screenshot-2025-01-27T10-30-15.123Z.png
This mode is useful when:
- Working with AI tools that prefer file references over base64 data
- Needing to persist screenshots for later analysis
- Reducing memory usage by avoiding large base64 strings in responses
Basic Usage
-
Start your Flutter app in debug mode:
-
Run the MCP server:
来源:mcp_server_dart/README.md,提交 b3e278c
工具
0版本历史
4- v7.0.1最新Oct 17, 2026
- v7.0.0Oct 3, 2026
- v6.0.0Oct 3, 2026
- v5.1.0Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分