Skip to main content
Glama

Flutter Inspector MCP Server

SIMPLIFIED_DYNAMIC_REGISTRATION.md8.94 kB
# Simplified Dynamic Registration System ## Overview This document describes the **simplified and optimized** dynamic tool registration system for the Flutter MCP project. Based on the insight that when VM Service connects, we're already connected to the Flutter isolate, this system eliminates complex multi-isolate discovery and uses event-driven updates instead of polling. **Key Improvements:** - ✅ **Immediate Registration**: Call `registerDynamics` as soon as VM service connects - ✅ **Event-Driven Updates**: Use DTD events for re-registration when tools change - ✅ **Simplified Architecture**: No complex polling or multi-isolate discovery - ✅ **DTD Integration**: Leverage Dart Tooling Daemon for robust event handling ## Architecture ### Simplified Flow ``` MCP Server ↔ VM Service ↔ Flutter App (Same Isolate) ↓ ↓ DTD Events ← Flutter Events ↓ Re-registration ``` **Registration Flow:** 1. **VM Service Connects** → **Immediate `registerDynamics` Call** 2. **Flutter Tool Changes** → **DTD Event Posted** → **Auto Re-registration** ## Key Components ### 1. SimplifiedDiscoveryService **Purpose**: Manages immediate registration and event-driven updates **Key Features:** - **Immediate Registration**: Calls `registerDynamics` immediately when VM service connects - **DTD Event Listening**: Listens for `MCPToolkit.ToolRegistration` events - **Single Isolate Focus**: Works with the assumption that VM service connection = Flutter isolate - **Event-Driven Re-registration**: Automatically re-registers when tools change ```dart final discoveryService = SimplifiedDiscoveryService( dynamicRegistry: dynamicRegistry, logger: logger, vmServiceGetter: () => vmService, dtdGetter: () => dartToolingDaemon, ); // Immediate registration + event listener setup await discoveryService.startDiscovery(); ``` ### 2. Enhanced Flutter Side Events **DTD Event Integration**: Flutter apps now post structured DTD events: ```dart // Posted when tools are registered/changed developer.postEvent('MCPToolkit.ToolRegistration', { 'kind': 'ToolRegistration', 'timestamp': DateTime.now().toIso8601String(), 'toolCount': toolNames.length, 'resourceCount': resourceUris.length, 'toolNames': toolNames, 'resourceUris': resourceUris, 'appId': appId, }); ``` ### 3. Event-Driven Re-registration **DTD Event Handling**: MCP server listens for specific events: - `MCPToolkit.ToolRegistration`: New tools registered → Full re-registration - `MCPToolkit.ServiceExtensionStateChanged`: Tool state changed → Conditional re-registration ## Implementation Benefits ### Performance Improvements - **No Polling Overhead**: Eliminates 10-second polling intervals - **Immediate Response**: Tools available as soon as VM service connects - **Event-Driven**: Only re-registers when actual changes occur - **Reduced Complexity**: Single isolate assumption simplifies logic significantly ### Developer Experience - **Instant Tool Discovery**: Tools appear immediately when Flutter app starts - **Hot Reload Support**: Changes reflected immediately via DTD events - **Simplified Configuration**: No complex multi-isolate setup needed - **Better Error Handling**: Clearer error messages and simpler failure paths ### System Architecture - **DTD Integration**: Leverages official Dart tooling infrastructure - **Event Standards**: Uses established DTD event patterns - **Single Responsibility**: Each component has a clear, focused purpose - **Maintainable**: Much simpler codebase to understand and maintain ## Usage Examples ### Basic Flutter App Setup ```dart import 'package:flutter/material.dart'; import 'package:mcp_toolkit/mcp_toolkit.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); // Initialize the MCP toolkit MCPToolkitBinding.instance ..initialize() ..initializeFlutterToolkit(); // Register tools - will be automatically discovered await _registerAppTools(); runApp(MyApp()); } Future<void> _registerAppTools() async { final calculatorTool = MCPCallEntry( methodName: const MCPMethodName('calculate'), handler: (request) => MCPCallResult( message: 'Calculation completed', parameters: {'result': 42}, ), toolDefinition: MCPToolDefinition( name: 'calculate', description: 'Perform calculations', inputSchema: { 'type': 'object', 'properties': { 'expression': {'type': 'string', 'description': 'Math expression'}, }, }, ), ); // This will trigger DTD events for automatic server discovery await MCPToolkitBinding.instance.addEntries( entries: {calculatorTool}, ); } ``` ### MCP Server Configuration ```dart // Server automatically uses simplified discovery final server = MCPToolkitServer.connect( channel, configuration: VMServiceConfigurationRecord( vmHost: 'localhost', vmPort: 8181, dynamicRegistrySupported: true, // Enables simplified discovery // ... other config ), ); ``` ## Event Flow Details ### 1. Initial Registration ``` MCP Server Startup ↓ VM Service Connection ↓ SimplifiedDiscoveryService.startDiscovery() ↓ _performInitialRegistration() ↓ vmService.callServiceExtension('ext.mcp.toolkit.registerDynamics') ↓ Tools Registered in DynamicRegistry ``` ### 2. Event-Driven Updates ``` Flutter App: Tool Added/Changed ↓ developer.postEvent('MCPToolkit.ToolRegistration', {...}) ↓ DTD forwards event to MCP Server ↓ SimplifiedDiscoveryService._handleMCPToolkitEvent() ↓ _performInitialRegistration() (re-registration) ↓ Updated Tools Available ``` ## Comparison with Previous System | Aspect | Previous (Complex) | New (Simplified) | |--------|-------------------|------------------| | **Discovery Method** | Multi-isolate polling | Single isolate + immediate call | | **Update Mechanism** | 10-second polling | DTD events | | **Performance** | High overhead | Minimal overhead | | **Responsiveness** | Up to 10s delay | Immediate | | **Complexity** | High (400+ lines) | Low (300+ lines) | | **Error Handling** | Complex edge cases | Straightforward | | **DTD Integration** | Basic | Full integration | ## Configuration ### Required Dependencies ```yaml dependencies: dart_mcp: ^latest dtd: ^latest vm_service: ^latest ``` ### Environment Setup ```bash # Ensure DTD is available (automatically handled by IDEs/CLI) flutter run --debug # DTD starts automatically ``` ## Troubleshooting ### Common Issues 1. **Immediate Registration Fails**: - Check Flutter app is running in debug mode - Verify `ext.mcp.toolkit.registerDynamics` is registered - Ensure VM service port is accessible 2. **DTD Events Not Received**: - Verify DTD connection is established - Check event names match expected patterns - Look for DTD connection errors in logs 3. **Tools Not Re-registering**: - Verify DTD event posting in Flutter app - Check MCP server DTD event listener setup - Ensure proper event data structure ### Debug Commands ```bash # Check DTD connection curl -X POST http://localhost:3535/mcp/call \ -H "Content-Type: application/json" \ -d '{"method":"tools/call","params":{"name":"getRegistryStats"}}' # List registered tools curl -X POST http://localhost:3535/mcp/call \ -H "Content-Type: application/json" \ -d '{"method":"tools/call","params":{"name":"listClientToolsAndResources"}}' ``` ## References - [DTD ConnectedAppService](https://github.com/dart-lang/sdk/issues/60540) - Official DTD service for app management - [Dart MCP Server](https://github.com/dart-lang/ai/tree/main/pkgs/dart_mcp_server) - Reference implementation - [Flutter Daemon Protocol](https://github.com/flutter/flutter/blob/master/packages/flutter_tools/doc/daemon.md) - Flutter tooling integration ## Future Considerations ### Potential Enhancements - **Multi-App Support**: Extend to handle multiple Flutter apps when needed - **Tool Versioning**: Add version tracking for tool definitions - **Performance Metrics**: Add timing and success rate monitoring - **Advanced Events**: More granular DTD event types for different tool states ### Migration Path The simplified system is fully backward compatible. Existing setups will automatically benefit from the improved performance and responsiveness without any configuration changes. ## Conclusion The simplified dynamic registration system provides: - **Better Performance**: No polling overhead, immediate registration - **Improved Developer Experience**: Instant tool discovery and updates - **Cleaner Architecture**: Leverages DTD properly, simpler codebase - **Future-Proof Design**: Aligns with official Dart tooling patterns This architecture is production-ready and provides a solid foundation for future enhancements while maintaining simplicity and reliability.

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Arenukvern/mcp_flutter'

If you have feedback or need assistance with the MCP directory API, please join our Discord server