MCP Flutter enables AI assistants like Claude Code to interact with Flutter applications in real-time, providing screenshot capture, error monitoring, hot reload integration, and direct app interaction.
Prerequisites:
- Flutter SDK 3.0.0+
- Claude Code CLI
- MCP Flutter server built from source
- Flutter app with MCP Toolkit package
The Model Context Protocol (MCP) is an open-source standard announced by Anthropic on November 25, 2024. It provides a universal protocol for connecting AI systems with data sources and tools, replacing fragmented integrations with a single standard.
Built by @Arenukvern and contributors as an open-source project, released in March 2025.
GitHub Repository: github.com/Arenukvern/mcp_flutter
MCP Server (flutter_inspector_mcp)
- MCP server to be configured in Claude Code
- Connects to Flutter's VM service to access debug information
- Handles screenshot capture, error monitoring, and app inspection
- Built from source and runs on your development machine
MCP Toolkit (mcp_toolkit)
- Flutter package that integrates into your app
- Enables the app to expose information to the MCP server
- Only works in debug mode (wrapped in assert statements for safety)
- Acts as the bridge between your Flutter app and the MCP server
Claude Code ←→ MCP Server ←→ Flutter Debug Service ←→ Your Flutter App (with MCP Toolkit)
# Clone the repository to your development tools directory
cd ~/Developer
git clone https://github.com/Arenukvern/mcp_flutter
# Build the MCP server
cd mcp_flutter
make installThis will create the executable at: mcp_flutter/mcp_server_dart/build/flutter_inspector_mcp
cd your_flutter_app
flutter pub add mcp_toolkitModify your main.dart:
import 'package:mcp_toolkit/mcp_toolkit.dart';
import 'dart:async';
Future<void> main() async {
runZonedGuarded(
() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize MCP Toolkit
MCPToolkitBinding.instance
..initialize()
..initializeFlutterToolkit();
// Your existing app initialization code here...
runApp(MyApp());
},
(error, stack) {
// Handle zone errors for MCP
MCPToolkitBinding.instance.handleZoneError(error, stack);
// Your existing error handling...
},
);
}Option A: Set a specific port (Recommended)
flutter run --debug --host-vmservice-port=[PORT] --enable-vm-service --disable-service-auth-codesOption B: Let Flutter pick a port
flutter run --debugLook for the debug service message in Flutter's output:
Debug service listening on ws://127.0.0.1:[PORT]/ws
Note the port number ([PORT] in this example).
You can ask Claude to do this, but you'll need to close and restart your Claude Code session for the new MCP config to take effect.
Using the port from Step 4:
claude mcp add flutter-inspector ~/Developer/mcp_flutter/mcp_server_dart/build/flutter_inspector_mcp -- --dart-vm-host=localhost --dart-vm-port=[PORT] --no-resources --imagesReplace [PORT] with your actual port number.
Now open Claude Code - the MCP connection will be active immediately.
Once setup is complete, you can ask Claude Code to:
-
Take Screenshots
- "Take a screenshot of my app"
- "Show me the current UI"
- "Capture the screen after hot restart"
-
Monitor Errors
- Errors are automatically captured and made available to Claude
- More precise than console messages, avoiding duplicates
-
Interact with Your App
- "List all available tools from my Flutter app"
- "Hot reload the app"
- "Get app info"
-
mcp__flutter-inspector__get_screenshots- Captures screenshots of the running Flutter app
- Returns compressed images in base64 format
- Example: "Get a screenshot of the app"
-
mcp__flutter-inspector__get_vm- Returns Dart VM information including version, architecture, and process details
- Shows active isolates and system isolates
- Example output: Dart 3.7.2, iOS ARM64, process ID
-
mcp__flutter-inspector__get_extension_rpcs- Lists all available Flutter and Dart extension RPCs
- Includes Flutter inspector, debugging, and custom extensions
- Useful for discovering advanced debugging capabilities
-
mcp__flutter-inspector__get_active_ports- Shows all active ports used by the Flutter app
- Example output: [[PORT1], [PORT2], [PORT3], [PORT4]]
- Helps verify VM service connectivity
-
mcp__flutter-inspector__get_app_errors- Retrieves recent application errors from Dart VM
- Returns "No errors found" if the app is running without issues
- Captures errors that occurred after MCP server connection
-
mcp__flutter-inspector__get_view_details- Returns device and view metrics
- Includes device pixel ratio, physical/logical sizes, padding, and brightness
- Useful for understanding app's rendering context
-
mcp__flutter-inspector__hot_reload_flutter- Triggers hot reload of the Flutter app
- Returns success status (may be false if no changes to reload)
- Maintains app state during code updates
-
mcp__flutter-inspector__listClientToolsAndResources- Intended to discover dynamically registered tools from the Flutter app
- Currently fails with "Extension call returned null" error
- Requires custom MCPCallEntry implementations in the app
-
mcp__flutter-inspector__runClientTool- Executes dynamically registered tools
- Works but requires tools to be registered first via MCPCallEntry.tool()
- Returns "Tool not found" if no custom tools are registered
-
mcp__flutter-inspector__runClientResource- Reads dynamically registered resources
- Works but requires resources to be registered first via MCPCallEntry.resource()
- Returns "Resource not found" if no custom resources are registered
To use the dynamic tools (listClientToolsAndResources, runClientTool, runClientResource), you need to register custom tools in your Flutter app:
// Example: Register a custom tool in your Flutter app
import 'package:mcp_toolkit/mcp_toolkit.dart';
// In your app initialization or widget:
MCPToolkitBinding.instance.addMcpTool(
MCPCallEntry.tool(
name: 'get_user_data',
description: 'Get current user data',
inputSchema: {
'type': 'object',
'properties': {},
},
handler: (params) async {
// Your tool implementation
return MCPCallResult(
content: [
{'type': 'text', 'text': 'User data here...'}
],
);
},
),
);After registering tools and hot reloading, they become available through the dynamic tool discovery system.
--dart-vm-host: Host for Dart VM connection (default: localhost)--dart-vm-port: Port for Dart VM connection (default: [DEFAULT_PORT])--resources: Enable resources support--images: Enable screenshot capture--save-images: Save screenshots as files instead of base64--no-resources: Disable resources (required for some AI tools like Cursor)
IMAGES_SUPPORTED=true: Alternative way to enable screenshot support
- ✅ macOS
- ✅ iOS Simulator
- ✅ Android Emulator
- 🔄 Android Device (in testing)
- ❌ Web (currently not working)
Problem: MCP server can't connect to Flutter app Solution:
- Verify Flutter is running with exact port specified in MCP config
- Check Flutter output for "VM Service is available at:" and note the port
- Ensure MCP server is configured with the same port
Problem: Using --resources flag causes "type 'Null' is not a subtype" errors
Solution: Use --no-resources flag instead when configuring MCP server
Problem: "spawn stdio ENOENT" error when starting Claude Code Solution: Restart Claude Code - configuration changes require a restart to take effect
Problem: Flutter shows a different port than expected Context: DDS (Dart Development Service) is a proxy that sits between your app and debugging tools Solution: Use the port that Flutter displays in its output (e.g., "VM Service is available at: http://127.0.0.1:[PORT]/")
Instead of specifying a port, you can let Flutter choose:
flutter run --debugNote the port from Flutter's output (e.g., "VM Service is available at: http://127.0.0.1:[PORT]/"), then configure MCP:
claude mcp update flutter-inspector -- --dart-vm-host=localhost --dart-vm-port=[PORT] --no-resources --imagesFor macOS:
flutter run -d macos --debug --host-vmservice-port=[PORT] --enable-vm-service --disable-service-auth-codesFor iOS Simulator:
flutter run -d iphone --debug --host-vmservice-port=[PORT] --enable-vm-service --disable-service-auth-codesTo check which Flutter apps are running and their VM service ports:
# Quick check for common Flutter VM service ports
lsof -iTCP:[PORT_RANGE] -P | grep LISTEN
# Verify which ports have active Flutter VM services
for p in $(lsof -iTCP:[PORT_RANGE] -P | grep LISTEN | awk '{print $9}' | cut -d: -f2 | sort -u); do
curl -s http://localhost:$p/getVM >/dev/null 2>&1 && echo "Flutter VM on port: $p"
doneTo switch MCP to a different Flutter instance:
# Update configuration
claude mcp update flutter-inspector -- --dart-vm-host=localhost --dart-vm-port=[NEW_PORT] --no-resources --images
# IMPORTANT: Restart Claude Code for changes to take effectCheck MCP configuration:
claude mcp listCheck if Flutter is using the expected port:
lsof -i :[PORT]Check MCP server logs:
ls -la ~/Library/Caches/claude-cli-nodejs/-Users-[YOUR_USERNAME]-Developer-[PROJECT_NAME]/mcp-logs-flutter-inspector/- ✓ Is Claude Code restarted after MCP configuration?
- ✓ Is Flutter running with the required debug flags (
--host-vmservice-port,--enable-vm-service,--disable-service-auth-codes)? - ✓ Does Flutter output show the VM Service URL with the expected port?
- ✓ Is MCP configured with the same port as Flutter (with
--no-resources --imagesflags)? - ✓ Is the MCP Toolkit initialized in your app's main.dart?
- Debug Mode Required - Always run your app in debug mode
- Local Development - Keep MCP server in your Developer folder, not in project
- Version Control - Don't commit MCP server to your project repository
- MCP Flutter GitHub Repository
- Model Context Protocol Documentation
- Claude Code Documentation
- MCP Hub - Community MCP Servers
MCP Flutter is actively maintained with regular updates. To update:
cd ~/Developer/mcp_flutter
git pull
make installThen restart Claude Code to use the updated version.
Thank you