Skip to content

Repository files navigation

Flutter Devtools MCP

An MCP server that lets AI agents see and interact with your running Flutter app — tap buttons, type text, scroll, take screenshots, hot reload, and more — all through the VM Service protocol.

Quick Start

Prerequisites: Flutter SDK (includes Dart)

git clone https://github.com/user/fdtools.git
cd fdtools
dart pub get
dart compile exe bin/server.dart -o bin/fdtools_server

Add to your editor's MCP config:

VS Code (.vscode/mcp.json):

{
  "servers": {
    "flutter": {
      "command": "/absolute/path/to/fdtools/bin/fdtools_server",
      "args": []
    }
  }
}

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "flutter": {
      "command": "/absolute/path/to/fdtools/bin/fdtools_server"
    }
  }
}

Restart your editor / MCP client and the tools are ready.


Tool Reference

Connection

Tool Arguments Description
attach vmServiceUrl (required) Connect via VM Service URL from flutter run output
launch workingDirectory (required), platform (required), timeout Run flutter run --debug and auto-connect
disconnect Close connection, kill managed flutter run if any
status {"connected": true/false}

Inspection

Tool Arguments Description
widget_tree Full widget tree as JSON (types, labels, keys, bounds, children)
inspect nodeId or selector, optional property Deep properties by nodeId or selector; filter to one value with property

Interaction

Tool Arguments Description
tap selector (required), duration Tap (or long-press via duration) widget by selector
type_text selector (required), text (required) Focus field and enter text
scroll selector (required), direction, amount Scroll a scrollable widget
drag selector (required), targetSelector or dx/dy Drag-and-drop gesture
screenshot Capture screen as base64 PNG
navigate route, action, arguments Push a named route (action: "push") or pop the current route (action: "pop")

Waiting

Tool Arguments Description
wait_for selector (required), condition, timeout Wait for widget condition (visible, exists, gone)
wait_until_settlement timeout Wait for animations/frame callbacks to complete

Development

Tool Arguments Description
hot_reload Apply code changes, preserve state
hot_restart Full restart, reset app state

Theme & Platform

Tool Arguments Description
toggle_dark_mode enable (bool) Switch between light and dark mode

Vision / OCR

Tool Arguments Description
inspect_screen Full immersive inspection: screenshot + OCR + widget tree → unified element list with types, text, bounds, and click coordinates
read_screen Screenshot + OCR — extract all visible text with bounding boxes and click coords
find_text query (required) Search for text via OCR — returns matches with clickable center coordinates
click_text query (required) Compound: screenshot → OCR → find text → tap at coordinates

Diagnostics

Tool Arguments Description
diagnose Run comprehensive diagnostics on the running Flutter app — widget tree health, app lifecycle, screen metrics, blank/stuck screen detection

Selectors

Target widgets with any of these formats (tried in order):

Format Example Best for
semantics:Label semantics:Submit Stable across rebuilds, accessibility-aligned
key:value key:submit_btn Widgets with explicit Key
text:Content text:Submit Visible text content
index:Type:N index:ElevatedButton:0 Last resort — fragile, use with caution

Ambiguous matches return an explicit error — the server never silently picks one.


How It Works

Flutter App (debug mode)
  └── VM Service WebSocket (ws://127.0.0.1:PORT/TOKEN=/ws)
        └── fdtools (Dart native binary)
              └── stdio JSON-RPC 2.0
                    └── AI Agent / MCP Client
Capability Mechanism
Read widget tree ext.flutter.inspector.* VM Service extensions
Interact (tap, scroll) evaluate()WidgetsBinding.handlePointerEvent()
Type text evaluate()TextEditingController.text = ...
Screenshots _flutter.screenshot extension → PNG
OCR / Vision Rust native binary (ocrs engine) → text + coordinates
Hot reload reloadSources() VM Service API
Connect vmServiceConnectUri() WebSocket handshake

Security

  • Only localhost (127.0.0.1, localhost, ::1) VM Service URLs are accepted
  • Auth tokens in URLs are masked in all log output
  • The managed flutter run process is killed on disconnect

Development

# Run unit tests
dart test

# Build vision OCR binary (requires Rust toolchain)
cd vision && cargo build --release && cd ..

# Run integration tests (requires running test fixture app)
export FLUTTER_VM_SERVICE_URL=ws://127.0.0.1:<port>/ws
dart test --tags integration

# Static analysis
dart analyze lib/ bin/ --fatal-infos

# Format code
dart format .

# Build native binary
dart compile exe bin/server.dart -o bin/fdtools_server

See doc/ARCHITECTURE.md for internals, doc/DESIGN_DECISIONS.md for v1 design rationale.

License

MIT — see LICENSE for details.

About

An MCP server that lets AI agents see and interact with your running Flutter app — tap buttons, type text, scroll, take screenshots, hot reload, and more — all through the VM Service protocol.

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages