SIMPLIFIED_DYNAMIC_REGISTRATION.md•8.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.