Skip to content

Conversation

@tekboxs
Copy link

@tekboxs tekboxs commented Nov 26, 2025

Summary by CodeRabbit

  • New Features

    • Added Flutter Web support via a WebSocket bridge (default port 8183) and platform-specific initialization flow
    • Added Windows install flow producing a platform executable and PowerShell install script
  • Documentation

    • Expanded setup, running, and troubleshooting guidance for Web and Windows (including tool availability and limitations)
    • Added a Web setup checklist and detailed platform notes (hot reload limitations on Web)
  • Chores

    • Pinned SDK via FVM and updated ignore/settings for FVM usage

✏️ Tip: You can customize this high-level summary in your review settings.

@docs-page
Copy link

docs-page bot commented Nov 26, 2025

To view this pull requests documentation preview, visit the following URL:

docs.page/arenukvern/mcp_flutter~72

Documentation is deployed and generated using docs.page.

@coderabbitai
Copy link

coderabbitai bot commented Nov 26, 2025

Walkthrough

Adds Web platform support via a WebSocket bridge: new server-side WebBridgeSupport, client-side WebBridgeClient (web + stub), web service-extension wiring, dual-path VM/Web logic in inspector/registry, web-aware initialization APIs, docs, Windows install script, and FVM workspace configuration.

Changes

Cohort / File(s) Change Summary
Documentation & Guides
QUICK_START.md, README.md, docs/web_alternative_solutions.md, docs/WEB_SETUP_CHECKLIST.md, llm_install.md, flutter_test_app/README.md, llm_install.md
Added extensive Web platform documentation, setup/checklist, alternative solution analysis, WebSocket bridge instructions, platform-specific run/debug notes, Windows guidance, and web capability/limitation matrices.
Flutter test app & configs
flutter_test_app/lib/main.dart, flutter_test_app/.fvmrc, flutter_test_app/.gitignore, flutter_test_app/.vscode/settings.json, flutter_test_app/README.md
Main app now branches on kIsWeb to call initializeWebBridgeForWeb(...) for Web or VM init for non-web; added FVM pin, ignore rule, and VSCode SDK path.
MCP server: core & mixins
mcp_server_dart/lib/src/server.dart, mcp_server_dart/lib/src/mixins/flutter_inspector.dart, mcp_server_dart/lib/src/mixins/web_bridge_support.dart, mcp_server_dart/lib/src/mixins/dynamic_registry_integration.dart, mcp_server_dart/lib/src/dynamic_registry/registry_discovery_service.dart, mcp_server_dart/lib/src/mixins/vm_service_support.dart
Added WebBridgeSupport mixin and started bridge on init; updated MCPToolkitServer mixins list; inspector and registry now support dual VM/Web paths; enhanced VM service connection error handling and guarded connection attempts.
MCP server: workspace configs & scripts
mcp_server_dart/.fvmrc, mcp_server_dart/.gitignore, mcp_server_dart/.vscode/settings.json, mcp_server_dart/experiments/setup_cursor_mcp.sh, install.ps1
Added FVM pin and editor config, switched build scripts to use fvm, updated setup script, and added install.ps1 for Windows build producing .exe.
MCP toolkit: web bridge client & API
mcp_toolkit/mcp_toolkit/lib/src/mcp_toolkit_binding.dart, mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client.dart, mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_stub.dart, mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_web.dart, mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart, mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_stub.dart, mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_web.dart
Added conditional web client (stub + web impl) with WebSocket lifecycle, request/response correlation, 30s timeouts; introduced WebServiceExtensions mixin (stub + web) and new initializeWebBridgeForWeb binding method; wiring for registering and handling service-extension calls over bridge.

Sequence Diagram(s)

sequenceDiagram
    participant App as Flutter Web App
    participant Binding as MCPToolkitBinding
    participant Client as WebBridgeClient
    participant Bridge as WebBridgeSupport
    participant Server as MCP Server
    participant Inspector as FlutterInspector

    App->>Binding: initializeWebBridgeForWeb(bridgeUrl)
    Binding->>Client: connect(bridgeUrl)
    Client->>Bridge: WebSocket.connect(ws://localhost:8183)
    Bridge->>Server: accept ws, add client

    Note over App,Inspector: Service extension request flow
    App->>Client: callServiceExtension(method, params)
    Client->>Client: create requestId, await response
    Client->>Bridge: send mcp_service_extension(requestId, method, params)
    Bridge->>Inspector: callServiceExtensionViaWeb(method, params)
    Inspector->>Bridge: result
    Bridge->>Client: send mcp_service_extension_response(requestId, result)
    Client->>App: return result
Loading
sequenceDiagram
    participant Server as MCP Server
    participant Bridge as WebBridgeSupport
    participant HTTP as HTTP/WebSocket server

    Server->>Bridge: startWebBridge(port=8183)
    Bridge->>HTTP: listen 8183
    HTTP->>Bridge: onUpgrade -> create client channel
    Bridge->>Bridge: track _webClients, _pendingRequests
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Focus review areas:
    • web_bridge_client_web.dart — WebSocket lifecycle, pending request correlation, timeout/error handling.
    • web_bridge_support.dart — HTTP upgrade, per-client tracking, concurrency and pending-request cleanup.
    • web_service_extensions_web.dart and flutter_inspector.dart — correct mapping of VM vs Web responses and consistent result shapes.
    • Initialization paths: mcp_toolkit_binding.dart and flutter_test_app/lib/main.dart to ensure correct platform guards and error propagation.
    • Windows install.ps1 and shell script updates for build reproducibility.

Possibly related PRs

Suggested reviewers

  • Arenukvern

Poem

🐰
A tiny rabbit hops on code so bright,
Built a bridge for Web through websocket light.
Requests and responses, thirty seconds to play,
From app to inspector they bounce on their way.
Hooray for cross-platform leaps today! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: web basic tools implementation' is related to the main change: introducing web platform support for the MCP toolkit with WebSocket bridge and platform-specific initialization, though it underrepresents the comprehensive nature of the changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
llm_install.md (1)

63-67: Update executable path for Windows.

The description should clarify that Windows creates a .exe executable to match the install.ps1 script behavior.

Apply this diff:

 This command will:
 
 - Install all necessary Dart dependencies from `pubspec.yaml`
 - Build the MCP server automatically
-- Create the executable at `mcp_server_dart/build/flutter_inspector_mcp`
+- Create the executable at `mcp_server_dart/build/flutter_inspector_mcp` (or `flutter_inspector_mcp.exe` on Windows)
♻️ Duplicate comments (3)
flutter_test_app/.fvmrc (1)

2-2: Verify Flutter version 3.38.3 exists.

Same concern as in mcp_server_dart/.vscode/settings.json - please verify this Flutter version is valid and available.

mcp_server_dart/.fvmrc (1)

2-2: Verify Flutter version 3.38.3 exists.

Same concern as in other .fvmrc files - please verify this Flutter version is valid and available.

flutter_test_app/.vscode/settings.json (1)

5-5: Verify Flutter version 3.38.3 exists.

Same concern as in other configuration files - please verify this Flutter version is valid and available.

🧹 Nitpick comments (10)
install.ps1 (1)

16-23: Verify FVM is available before use.

The script assumes FVM is installed and in PATH. If FVM is not available, the error message will be cryptic.

Consider adding a check at the start of the script:

# Check if FVM is available
if (-not (Get-Command fvm -ErrorAction SilentlyContinue)) {
    Write-Host "Error: FVM is not installed or not in PATH!" -ForegroundColor Red
    Write-Host "Please install FVM first: https://fvm.app/" -ForegroundColor Yellow
    exit 1
}
mcp_server_dart/lib/src/server.dart (1)

335-349: Consider making web bridge port configurable.

The port 8183 is hardcoded here and throughout the documentation. Consider adding it to VMServiceConfigurationRecord for consistency with other port configurations.

Consider this approach:

// In configuration
final class VMServiceConfigurationRecord {
  // ... existing fields
  final int webBridgePort;
  // ...
}

// In server initialization
await startWebBridge(port: configuration.webBridgePort);

This would allow users to configure the web bridge port similar to VM service ports.

mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_web.dart (1)

104-115: Stack traces in error responses may expose implementation details.

Sending stack.toString() to clients could leak internal implementation paths and line numbers. Consider limiting this to debug mode only.

     } catch (exception, stack) {
+      if (kDebugMode) {
+        debugPrint('[WebServiceExtensions] Error handling $methodName: $exception\n$stack');
+      }
       final errorResponse = {
         'type': 'mcp_service_extension_response',
         'id': requestId,
         'error': {
           'exception': exception.toString(),
-          'stack': stack.toString(),
+          if (kDebugMode) 'stack': stack.toString(),
           'method': methodName,
         },
       };
mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_stub.dart (1)

1-4: Unused imports.

dart:async and dart:convert are imported but not used in the stub implementation.

-import 'dart:async';
-import 'dart:convert';
-
 import 'package:flutter/foundation.dart';
mcp_server_dart/lib/src/mixins/flutter_inspector.dart (1)

1153-1206: Consider extracting common result parsing logic to reduce duplication.

The VM and Web paths share identical result extraction code (jsonDecodeListAs, jsonDecodeString, building CallToolResult). This pattern repeats in _getScreenshots and _getViewDetails.

Consider a helper method to reduce duplication:

({List<Map<String, dynamic>> errors, String message}) _extractAppErrorsResult(
  Map<String, dynamic>? json,
) {
  final errors = jsonDecodeListAs<Map<String, dynamic>>(json?['errors']);
  final message = jsonDecodeString(json?['message']).whenEmptyUse('No errors found');
  return (errors: errors, message: message);
}

Then both paths can use:

final resultData = vmConnected 
    ? (await callFlutterExtension(...)).json
    : (await callServiceExtensionViaWeb(...))['result'] as Map<String, dynamic>? ?? webResult;
final (:errors, :message) = _extractAppErrorsResult(resultData);
QUICK_START.md (1)

88-99: Verify initialization order for web platform.

The web initialization calls initializeWebBridgeForWeb first, then initializeFlutterToolkit(). Based on the learnings, addMcpTool() must be called after MCPToolkitBinding.initialize(). Ensure this order is consistent with the expected tool registration flow for web.

Also, for mobile/desktop, initialize() and initializeFlutterToolkit() are chained. Consider making the web path consistent with similar chaining for readability:

 if (kIsWeb) {
   // For Flutter Web: use WebSocket bridge
   await MCPToolkitBinding.instance.initializeWebBridgeForWeb(
     bridgeUrl: 'ws://localhost:8183',
   );
-  MCPToolkitBinding.instance.initializeFlutterToolkit();
+  MCPToolkitBinding.instance
+    ..initializeFlutterToolkit();
 } else {
mcp_server_dart/lib/src/mixins/web_bridge_support.dart (3)

27-63: Missing cancellation of client stream subscription on cleanup.

The channel.stream.listen() returns a StreamSubscription that is not stored. If stopWebBridge() is called while clients are connected, the stream subscriptions continue to exist until the channel is closed. Consider storing subscriptions to enable explicit cancellation, or document that closing the channel's sink handles cleanup.

Also, the HTTP server listener (_webBridgeServer!.listen(...)) returns a subscription that isn't stored — if the server needs graceful shutdown before close(force: true), this could leave lingering handlers.

+ final Map<String, StreamSubscription<dynamic>> _clientSubscriptions = {};
 
  channel.stream.listen(
    (message) => _handleWebMessage(clientId, message),
    onDone: () {
      _webClients.remove(clientId);
+     _clientSubscriptions.remove(clientId);
      log(

74-76: Client ID generation may produce duplicates under rapid connections.

Using DateTime.now().millisecondsSinceEpoch combined with _webClients.length could produce duplicates if two clients connect within the same millisecond (length would be the same at check time). Consider using a monotonically increasing counter instead:

+ int _clientIdCounter = 0;

  String _generateClientId() {
-   return 'web_client_${DateTime.now().millisecondsSinceEpoch}_${_webClients.length}';
+   return 'web_client_${_clientIdCounter++}';
  }

158-168: Error completion passes raw error data to completer.

_pendingRequests[id]!.completeError(data['error']) passes whatever is in data['error'] directly. If this is a string, the caller receives a String as an exception rather than a typed Exception. Consider wrapping it:

  if (data.containsKey('error')) {
-   _pendingRequests[id]!.completeError(data['error']);
+   _pendingRequests[id]!.completeError(Exception(data['error'].toString()));
  } else {
mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_web.dart (1)

125-129: Silent message drop when not connected.

sendMessage silently does nothing if the socket is null or not connected. Consider logging a warning or throwing an error to help diagnose issues:

  void sendMessage(Map<String, dynamic> message) {
-   if (_webSocket != null && _connected) {
+   if (_webSocket == null || !_connected) {
+     if (kDebugMode) {
+       debugPrint('[WebBridgeClient] Cannot send message: not connected');
+     }
+     return;
+   }
    _webSocket!.send(jsonEncode(message));
-   }
  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 16cb6ce and 41c70b9.

📒 Files selected for processing (24)
  • QUICK_START.md (7 hunks)
  • README.md (1 hunks)
  • docs/web_alternative_solutions.md (1 hunks)
  • flutter_test_app/.fvmrc (1 hunks)
  • flutter_test_app/.gitignore (1 hunks)
  • flutter_test_app/.vscode/settings.json (1 hunks)
  • flutter_test_app/README.md (1 hunks)
  • flutter_test_app/lib/main.dart (2 hunks)
  • install.ps1 (1 hunks)
  • llm_install.md (1 hunks)
  • mcp_server_dart/.fvmrc (1 hunks)
  • mcp_server_dart/.gitignore (1 hunks)
  • mcp_server_dart/.vscode/settings.json (1 hunks)
  • mcp_server_dart/experiments/setup_cursor_mcp.sh (3 hunks)
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart (6 hunks)
  • mcp_server_dart/lib/src/mixins/web_bridge_support.dart (1 hunks)
  • mcp_server_dart/lib/src/server.dart (3 hunks)
  • mcp_toolkit/mcp_toolkit/lib/src/mcp_toolkit_binding.dart (3 hunks)
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client.dart (1 hunks)
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_stub.dart (1 hunks)
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_web.dart (1 hunks)
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart (1 hunks)
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_stub.dart (1 hunks)
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_web.dart (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.md

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

For documentation (READMEs, technical docs), follow Google's Technical Writing Style Guide (define terms, active voice, present tense, clear/concise, logical order, use lists/tables when appropriate)

Files:

  • QUICK_START.md
  • README.md
  • flutter_test_app/README.md
  • llm_install.md
  • docs/web_alternative_solutions.md
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/dart_dev.mdc)

**/*.dart: Use async/await instead of then for asynchronous operations
Write precise, future-proof dartdoc comments that focus on the specific purpose
Include cross-references to related classes and real usage examples in dartdoc comments
Document relationships between related components in dartdoc comments
Avoid scope limitations in documentation unless absolutely necessary
Use {@template} for reusable component documentation in dartdoc comments
Include practical code samples showing real usage patterns in documentation
Document all parameters with /// in dartdoc comments
Add warning comments for important usage notes in documentation
Reference concrete implementations in the codebase within documentation
Explicit type declarations must be used
Use Dart naming conventions: PascalCase for classes, camelCase for variables/functions
Prefer const constructors
Use extension methods for added functionality (e.g., GameId)
Use required commas linter rule in Dart
Prefer arrow function style for Dart
Prefer const constructors with named parameters with const values instead of nullable ones
Use Dart 3.7 syntax for null safety, pattern matching, and more
Proper error handling and async/await for asynchronous operations
Use [] when referencing code in documentation
Generate readable, short, and concise documentation
Use {@template} and {@macro} to create and use dart doc code snippets

**/*.dart: Use Dart 3.7 syntax for null safety, pattern matching, and other new features
Use StatelessWidget, HookWidget (from flutter_hooks), or StatefulWidget appropriately
Use custom reusable widgets from ui_kit instead of methods for UI reuse
Use Cupertino or Material Design widgets as appropriate
Ensure proper error handling and use async/await for asynchronous operations
Use flutter_animate for animations
Prefer fewer, more cohesive widgets over many tiny widgets; extract new widget classes only when reused, complex (>50 lines), or logically independent
Use comments to separate logical ...

Files:

  • mcp_toolkit/mcp_toolkit/lib/src/mcp_toolkit_binding.dart
  • flutter_test_app/lib/main.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_stub.dart
  • mcp_server_dart/lib/src/server.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_web.dart
  • mcp_server_dart/lib/src/mixins/web_bridge_support.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_web.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client.dart
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_stub.dart
🧠 Learnings (37)
📓 Common learnings
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Ensure addMcpTool() is called after MCPToolkitBinding.initialize() to guarantee tool registration.
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Register custom MCP tools by calling addMcpTool() with tool or resource definitions in Dart code.

Applied to files:

  • mcp_server_dart/.gitignore
  • QUICK_START.md
  • README.md
  • flutter_test_app/README.md
  • mcp_toolkit/mcp_toolkit/lib/src/mcp_toolkit_binding.dart
  • flutter_test_app/lib/main.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_stub.dart
  • mcp_server_dart/lib/src/server.dart
  • mcp_server_dart/.fvmrc
  • mcp_server_dart/lib/src/mixins/web_bridge_support.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_web.dart
  • mcp_server_dart/.vscode/settings.json
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Ensure addMcpTool() is called after MCPToolkitBinding.initialize() to guarantee tool registration.

Applied to files:

  • mcp_server_dart/.gitignore
  • QUICK_START.md
  • flutter_test_app/README.md
  • mcp_toolkit/mcp_toolkit/lib/src/mcp_toolkit_binding.dart
  • flutter_test_app/lib/main.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_stub.dart
  • mcp_server_dart/lib/src/server.dart
  • mcp_server_dart/experiments/setup_cursor_mcp.sh
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_web.dart
  • mcp_server_dart/.fvmrc
  • mcp_server_dart/lib/src/mixins/web_bridge_support.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_web.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client.dart
  • mcp_server_dart/.vscode/settings.json
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-07-22T17:01:23.584Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/flutter_ui_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:23.584Z
Learning: Applies to **/*.dart : Use Dart 3.7 syntax for null safety, pattern matching, and other new features

Applied to files:

  • mcp_server_dart/.gitignore
  • flutter_test_app/.fvmrc
  • flutter_test_app/lib/main.dart
  • mcp_server_dart/.fvmrc
  • flutter_test_app/.vscode/settings.json
  • mcp_server_dart/.vscode/settings.json
📚 Learning: 2025-08-19T13:59:27.375Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/training.mdc:0-0
Timestamp: 2025-08-19T13:59:27.375Z
Learning: Applies to **/*.dart : Use Dart for code implementation

Applied to files:

  • mcp_server_dart/.gitignore
  • flutter_test_app/.fvmrc
  • flutter_test_app/lib/main.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart
  • mcp_server_dart/.fvmrc
  • flutter_test_app/.vscode/settings.json
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client.dart
  • mcp_server_dart/.vscode/settings.json
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to **/*.dart : Use Dart 3.7 syntax for null safety, pattern matching, and more

Applied to files:

  • mcp_server_dart/.gitignore
  • flutter_test_app/.fvmrc
  • flutter_test_app/lib/main.dart
  • mcp_server_dart/.fvmrc
  • flutter_test_app/.vscode/settings.json
  • mcp_server_dart/.vscode/settings.json
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Define custom tools using MCPCallEntry.tool with a handler function and MCPToolDefinition.

Applied to files:

  • mcp_server_dart/.gitignore
  • QUICK_START.md
  • flutter_test_app/README.md
  • mcp_toolkit/mcp_toolkit/lib/src/mcp_toolkit_binding.dart
  • mcp_server_dart/lib/src/server.dart
  • mcp_server_dart/experiments/setup_cursor_mcp.sh
  • mcp_server_dart/.vscode/settings.json
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to **/*.dart : Use Dart naming conventions: PascalCase for classes, camelCase for variables/functions

Applied to files:

  • mcp_server_dart/.gitignore
  • flutter_test_app/.vscode/settings.json
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to **/*.dart : Add warning comments for important usage notes in documentation

Applied to files:

  • mcp_server_dart/.gitignore
  • docs/web_alternative_solutions.md
📚 Learning: 2025-07-22T17:00:31.562Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/create_jules_plan.mdc:0-0
Timestamp: 2025-07-22T17:00:31.562Z
Learning: Always add as first steps: 1. Branch & Environment Setup 1.1 Create a new branch from the default branch (e.g., {name}). 1.2 Run the provided environment setup scripts to ensure Dart, FVM, and Flutter are correctly installed and configured.

Applied to files:

  • QUICK_START.md
  • flutter_test_app/.fvmrc
  • flutter_test_app/README.md
  • flutter_test_app/lib/main.dart
  • llm_install.md
  • mcp_server_dart/experiments/setup_cursor_mcp.sh
  • mcp_server_dart/.fvmrc
  • mcp_server_dart/.vscode/settings.json
📚 Learning: 2025-08-19T13:59:27.375Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/training.mdc:0-0
Timestamp: 2025-08-19T13:59:27.375Z
Learning: Use Flutter for UI implementation

Applied to files:

  • QUICK_START.md
  • flutter_test_app/.fvmrc
  • flutter_test_app/README.md
  • flutter_test_app/lib/main.dart
  • mcp_server_dart/.fvmrc
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-07-22T17:00:31.562Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/create_jules_plan.mdc:0-0
Timestamp: 2025-07-22T17:00:31.562Z
Learning: For Flutter projects without FVM, use the provided shell script to install Dart SDK and get dependencies.

Applied to files:

  • QUICK_START.md
  • flutter_test_app/.fvmrc
  • flutter_test_app/README.md
  • llm_install.md
  • mcp_server_dart/experiments/setup_cursor_mcp.sh
  • mcp_server_dart/.fvmrc
  • mcp_server_dart/.vscode/settings.json
📚 Learning: 2025-07-22T17:00:31.562Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/create_jules_plan.mdc:0-0
Timestamp: 2025-07-22T17:00:31.562Z
Learning: For Flutter projects using FVM, use the provided shell script to install Dart SDK, FVM, and Flutter, and to get dependencies.

Applied to files:

  • QUICK_START.md
  • install.ps1
  • flutter_test_app/.fvmrc
  • flutter_test_app/README.md
  • llm_install.md
  • mcp_server_dart/experiments/setup_cursor_mcp.sh
  • mcp_server_dart/.fvmrc
  • mcp_server_dart/.vscode/settings.json
📚 Learning: 2025-07-22T16:52:15.714Z
Learnt from: Arenukvern
Repo: Arenukvern/mcp_flutter PR: 61
File: docs/guides/creating_dynamic_tools.mdx:16-28
Timestamp: 2025-07-22T16:52:15.714Z
Learning: In the MCP Flutter toolkit, tool registration via addMcpTool() and addEntries() is already wrapped in assert() blocks, which ensures tools are only registered in debug builds and stripped from release builds, providing the same security as kDebugMode checks.

Applied to files:

  • QUICK_START.md
  • flutter_test_app/README.md
  • mcp_toolkit/mcp_toolkit/lib/src/mcp_toolkit_binding.dart
  • flutter_test_app/lib/main.dart
  • mcp_server_dart/lib/src/server.dart
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to lib/{main.dart,debug_tools.dart} : Place tool registration code in main.dart or in a dedicated debug_tools.dart file under lib/.

Applied to files:

  • QUICK_START.md
  • flutter_test_app/README.md
  • mcp_toolkit/mcp_toolkit/lib/src/mcp_toolkit_binding.dart
  • flutter_test_app/lib/main.dart
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Use try/catch blocks in handler functions for error handling and return MCPCallResult with error details on failure.

Applied to files:

  • README.md
📚 Learning: 2025-07-22T17:01:23.584Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/flutter_ui_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:23.584Z
Learning: Applies to **/*.dart : Use flutter_animate for animations

Applied to files:

  • flutter_test_app/.fvmrc
  • mcp_server_dart/.fvmrc
📚 Learning: 2025-08-19T13:59:27.375Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/training.mdc:0-0
Timestamp: 2025-08-19T13:59:27.375Z
Learning: Applies to lib/main.dart : Use lib/main.dart as the application entry point

Applied to files:

  • flutter_test_app/.fvmrc
  • flutter_test_app/README.md
  • flutter_test_app/lib/main.dart
  • mcp_server_dart/.fvmrc
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to **/*.dart : Generate readable, short, and concise documentation

Applied to files:

  • flutter_test_app/README.md
📚 Learning: 2025-07-22T16:52:23.065Z
Learnt from: Arenukvern
Repo: Arenukvern/mcp_flutter PR: 61
File: docs/core/dynamic_tools_registry.mdx:74-99
Timestamp: 2025-07-22T16:52:23.065Z
Learning: In the mcp_toolkit, the addEntries() and addMcpTool() methods already have debug-only protection via assert() blocks that wrap the actual service extension registration. This eliminates the need for additional kDebugMode checks in user code, as assert statements are completely stripped from release builds.

Applied to files:

  • mcp_toolkit/mcp_toolkit/lib/src/mcp_toolkit_binding.dart
📚 Learning: 2025-08-19T13:59:27.375Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/training.mdc:0-0
Timestamp: 2025-08-19T13:59:27.375Z
Learning: Applies to lib/common_imports.dart : Maintain shared/common imports in lib/common_imports.dart

Applied to files:

  • flutter_test_app/lib/main.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart
  • mcp_server_dart/lib/src/server.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client.dart
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-08-19T13:58:50.012Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/test_guide.mdc:0-0
Timestamp: 2025-08-19T13:58:50.012Z
Learning: Applies to **/*_test.dart : Keep tests self-contained and independent

Applied to files:

  • flutter_test_app/lib/main.dart
  • mcp_server_dart/lib/src/server.dart
  • flutter_test_app/.vscode/settings.json
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to lib/**/*.dart : Use common imports (lib/common_imports.dart)

Applied to files:

  • flutter_test_app/lib/main.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart
  • mcp_server_dart/lib/src/server.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client.dart
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-07-22T17:01:23.584Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/flutter_ui_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:23.584Z
Learning: Applies to **/*.dart : Use Cupertino or Material Design widgets as appropriate

Applied to files:

  • flutter_test_app/lib/main.dart
📚 Learning: 2025-08-19T14:00:51.285Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/writing_code_protocol.mdc:0-0
Timestamp: 2025-08-19T14:00:51.285Z
Learning: Applies to **/*.dart : Use context.read/context.select to subscribe to observable state in Flutter build methods

Applied to files:

  • flutter_test_app/lib/main.dart
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Access Flutter BuildContext in tools that require widget tree operations by using WidgetsBinding.instance.rootElement.

Applied to files:

  • flutter_test_app/lib/main.dart
📚 Learning: 2025-07-22T17:01:23.584Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/flutter_ui_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:23.584Z
Learning: Applies to **/*.dart : Use StatelessWidget, HookWidget (from flutter_hooks), or StatefulWidget appropriately

Applied to files:

  • flutter_test_app/lib/main.dart
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to lib/**/*.dart : Use Cupertino or Material Design as appropriate

Applied to files:

  • flutter_test_app/lib/main.dart
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Wrap tool registration in if (kDebugMode) checks to ensure tools are only registered in debug mode.

Applied to files:

  • flutter_test_app/lib/main.dart
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to **/*.dart : Use extension methods for added functionality (e.g., GameId)

Applied to files:

  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-08-19T13:59:27.375Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/training.mdc:0-0
Timestamp: 2025-08-19T13:59:27.375Z
Learning: Applies to lib/data_remote_api/**/*.dart : Place remote API implementations under lib/data_remote_api/

Applied to files:

  • mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Use static variables or singletons to maintain state between tool invocations when implementing stateful tools.

Applied to files:

  • flutter_test_app/.vscode/settings.json
📚 Learning: 2025-08-19T13:58:50.012Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/test_guide.mdc:0-0
Timestamp: 2025-08-19T13:58:50.012Z
Learning: Applies to **/*_test.dart : Prefer data-driven approaches to facilitate modifications and extensions

Applied to files:

  • flutter_test_app/.vscode/settings.json
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Use descriptive, unique, snake_case names for tools, including an action verb such as inspect_, modify_, or monitor_.

Applied to files:

  • flutter_test_app/.vscode/settings.json
📚 Learning: 2025-08-19T13:59:27.375Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/training.mdc:0-0
Timestamp: 2025-08-19T13:59:27.375Z
Learning: Applies to lib/data_resources/**/*.dart : Place resource definitions for state management under lib/data_resources/

Applied to files:

  • flutter_test_app/.vscode/settings.json
📚 Learning: 2025-08-19T13:59:27.375Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/training.mdc:0-0
Timestamp: 2025-08-19T13:59:27.375Z
Learning: Applies to lib/envs.dart : Keep environment configuration in lib/envs.dart

Applied to files:

  • mcp_server_dart/.vscode/settings.json
📚 Learning: 2025-08-19T14:00:51.285Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/writing_code_protocol.mdc:0-0
Timestamp: 2025-08-19T14:00:51.285Z
Learning: Applies to **/*.dart : Use EquatableMixin for classes to implement value equality

Applied to files:

  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
🪛 markdownlint-cli2 (0.18.1)
docs/web_alternative_solutions.md

13-13: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


65-65: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


109-109: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


148-148: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


204-204: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (34)
mcp_server_dart/.gitignore (1)

47-49: LGTM!

Properly excludes the FVM version cache from version control, following standard FVM project practices.

mcp_server_dart/experiments/setup_cursor_mcp.sh (3)

27-29: LGTM!

The prerequisite check correctly validates FVM installation with a clear error message.


38-38: LGTM!

Build command properly uses FVM-managed Dart compiler, ensuring version consistency.


153-153: LGTM!

User instructions correctly updated to use FVM-managed Flutter, maintaining consistency with the FVM adoption.

flutter_test_app/.gitignore (1)

45-47: LGTM!

Properly excludes the FVM version cache from version control, following standard FVM project practices.

flutter_test_app/lib/main.dart (2)

5-5: LGTM!

Correctly imports foundation for kIsWeb constant used in platform detection.


17-26: Based on my comprehensive verification of the codebase, I have found a critical issue with the review comment:

The review comment references code that does not exist in the file being reviewed.

Here's what I verified:

  1. Lines 17-26 do NOT contain the kIsWeb conditional shown in the review. The actual lines 16-17 are:

    MCPToolkitBinding.instance
      ..initialize()
      ..initializeFlutterToolkit();
  2. initializeWebBridgeForWeb() method does not exist in the mcp_toolkit package. I searched the entire codebase and found no such method.

  3. kIsWeb is not used anywhere in the codebase for the initialization pattern described.

  4. initialize() is not async - it's a void method, not a Future, so the async/await inconsistency concern is moot.

  5. The actual implementation has tool registration at line 19 (await _registerInitialMCPTools();) which IS properly awaited, ensuring tool registration happens after initialization.

The review comment appears to be analyzing a different version of the code or a hypothetical scenario that doesn't match the current state of the repository. All three concerns (hardcoded URL, async inconsistency, and API verification) are based on code that is not present.

Likely an incorrect or invalid review comment.

mcp_server_dart/.vscode/settings.json (1)

2-2: Flutter version 3.38.3 is valid as of November 2025.

Flutter 3.38 was released on November 12, 2025 (with patch 3.38.1 documented), making version 3.38.3 a plausible and current patch release. The original concern was understandable given the March 2025 knowledge cutoff, but the configuration is now accurate for the current date.

flutter_test_app/README.md (1)

1-53: LGTM! Clear and comprehensive web support documentation.

The documentation clearly explains the web bridge architecture, port configuration, and platform-specific limitations. The distinction between VM Service (mobile/desktop) and WebSocket Bridge (web) is well-articulated.

docs/web_alternative_solutions.md (1)

1-270: Excellent architectural documentation for web support alternatives.

This document provides a thorough analysis of different approaches to enable MCP functionality on Flutter Web. The comparison table, pros/cons analysis, and recommended implementation path are particularly valuable.

mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_stub.dart (2)

7-14: Stub implementation is correct.

The double UnsupportedError pattern is appropriate: first checks platform compatibility, second indicates stub needs web implementation. This follows standard Dart conditional compilation patterns.


4-4: Based on my investigation, the file referenced in the review comment does not exist in this repository. The path mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_stub.dart does not correspond to any actual file.

The repository structure shows that there is no lib/src/web/ directory at all. The actual Dart files in the project are in different locations (services, toolkits, utils, etc.), and there are no files named web_service_extensions_stub.dart or web_bridge_client.dart.

The review comment references non-existent code and cannot be verified.

Likely an incorrect or invalid review comment.

mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client.dart (1)

1-5: LGTM! Correct platform-specific wiring for web bridge client.

The conditional import/export mechanism properly selects the web-specific implementation when dart.library.html is available, and falls back to the stub otherwise. This is the idiomatic Dart approach for platform-specific code.

llm_install.md (1)

53-61: Windows installation instructions are clear and correct.

The PowerShell installation path is well-documented and properly formatted.

install.ps1 (1)

1-42: Windows installation script is well-structured.

The script correctly handles errors, provides colored output, and creates the Windows executable with the proper .exe extension. Error handling with $LASTEXITCODE is appropriate.

mcp_server_dart/lib/src/server.dart (2)

23-27: Web bridge support properly integrated into server mixins.

The addition of WebBridgeSupport mixin enables web platform capabilities alongside VM Service support. The mixin order is appropriate with WebBridgeSupport before FlutterInspector.


337-337: I'll help you verify the concern about startWebBridge being non-blocking. Let me search for the implementation to examine its behavior.
<function_calls>

#!/bin/bash

Search for startWebBridge implementation and definition

rg -n "startWebBridge" mcp_server_dart/lib/src/server.dart -A 20 -B 2


</function_calls>

#!/bin/bash

Find startWebBridge function definition across the codebase

ast-grep --pattern $'startWebBridge($_) {
$$$
}'


</function_calls>

#!/bin/bash

More flexible search for startWebBridge definition

rg -n "def startWebBridge|Future.startWebBridge|startWebBridge\s(" --type dart -A 20 | head -100


</function_calls>

mcp_toolkit/mcp_toolkit/lib/src/mcp_toolkit_binding.dart (3)

103-115: Consider error handling for web bridge initialization.

Unlike the server-side implementation (server.dart:335-349) which wraps web bridge startup in try-catch, this method allows exceptions from initializeWebBridge to propagate. Is this intentional? For web platform, web bridge failure is critical, but consider documenting this behavior.

If web bridge initialization failure should be handled gracefully:

Future<void> initializeWebBridgeForWeb({required String bridgeUrl}) async {
  assert(() {
    assert(
      kDebugMode,
      'MCP Toolkit should only be initialized in debug mode',
    );
    attachToFlutterError();
    return true;
  }());

  super.initialize();
  
  try {
    await initializeWebBridge(bridgeUrl: bridgeUrl);
  } catch (e, stackTrace) {
    // Log or handle web bridge initialization failure
    // Perhaps throw a more descriptive error
    rethrow;
  }
}

Otherwise, document in the dartdoc that this method will throw if web bridge connection fails.


88-102: Excellent documentation for web bridge initialization.

The dartdoc clearly explains the use case with a practical example showing platform-specific initialization. The example correctly demonstrates the kIsWeb check and alternate initialization paths.

As per coding guidelines, the documentation provides clear usage examples and cross-references.


51-51: Web service extensions properly integrated into binding.

The addition of WebServiceExtensions mixin enables web-specific initialization alongside existing error monitoring and toolkit extensions.

mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions.dart (1)

1-5: LGTM! Standard conditional import/export pattern for platform-specific implementations.

The use of dart.library.html for web platform detection is correct and follows Dart's recommended approach for platform-specific code.

README.md (1)

85-95: Clear and helpful documentation for web platform support.

The documentation effectively communicates:

  • Which tools are available on web vs native platforms
  • The WebSocket bridge architecture (port 8183)
  • Hot reload limitations on web

This follows good technical writing practices with clear lists and concise explanations.

mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_web.dart (2)

14-25: Well-structured initialization with proper platform guard.

The kIsWeb check at the start prevents accidental usage on non-web platforms. The singleton pattern for WebBridgeClient is appropriate for managing a single WebSocket connection.


118-125: Proper cleanup of resources in dispose method.

Correctly cancels subscription, disconnects client, clears state, and resets flags. This prevents memory leaks and stale connections.

mcp_server_dart/lib/src/mixins/flutter_inspector.dart (4)

43-44: Good integration of WebBridgeSupport into the mixin hierarchy.

Adding WebBridgeSupport to the mixin's on clause properly enables the dual-path (VM service vs web bridge) functionality for supported tools.


1130-1143: Well-structured dual connectivity check.

The combined check for VM service and web clients provides graceful fallback behavior, ensuring tools work on web platform when VM service is unavailable.


1252-1269: Type annotation missing for images variable.

Per coding guidelines, explicit type declarations should be used. The List<String> type is inferred but should be explicit.

The type is already declared on line 1252, so this is consistent with guidelines. LGTM.


1337-1364: Dual-path implementation for view details is correct.

The web bridge fallback properly extracts details and message from the web response, maintaining consistent behavior across platforms.

QUICK_START.md (3)

9-11: Clear and concise architecture overview.

The architecture diagram effectively communicates the different communication paths for mobile/desktop vs. web platforms.


130-138: Helpful limitations documentation.

The clear distinction between available and unavailable tools on web, along with the explanation of hot reload limitations, will help users understand platform constraints.


211-215: Useful Windows-specific guidance.

The explicit Windows path formatting guidance (including both Windows and Git Bash formats) and the reminder about the .exe extension will help Windows users avoid common configuration errors.

mcp_server_dart/lib/src/mixins/web_bridge_support.dart (3)

10-14: State initialization looks correct.

The mixin properly declares private fields for the HTTP server, client connections, pending requests, and request ID counter. The maps are lazily populated during operation.


129-156: Request is routed to only the first connected client.

_webClients.values.firstOrNull sends the request to an arbitrary (first) client. If multiple web clients are connected, this may not be the intended behavior. Consider:

  1. Documenting this as single-client-only design
  2. Or adding client targeting by ID if multi-client support is needed

Also, _requestId could overflow for very long-running servers. While unlikely in practice, using a BigInt or UUID would be more robust.

Is single-client behavior intentional for the web bridge architecture?


196-208: Good cleanup implementation with proper resource release.

The stopWebBridge method correctly closes all client channels, clears the map, and forcibly closes the HTTP server. The logging provides visibility into lifecycle events.

Create a WebSocket bridge server that communicates with Flutter Web via `postMessage` API and exposes a VM Service-like interface.

### Architecture
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block.

The architecture diagram should specify a language identifier for proper rendering.

Apply this diff:

-```
+```text
 AI Assistant → MCP Server → WebSocket Bridge → Flutter Web (postMessage) → Service Extensions

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.18.1)</summary>

13-13: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In docs/web_alternative_solutions.md around line 13, the fenced code block lacks
a language specifier; update the block to use a language tag by replacing the
existing backticks-only fence with a fenced block that begins with ```text and
contains the diagram line "AI Assistant → MCP Server → WebSocket Bridge →
Flutter Web (postMessage) → Service Extensions" then close the fence, so the
diagram renders with the specified language.


</details>

<!-- This is an auto-generated comment by CodeRabbit -->

Expose service extensions via HTTP endpoints in Flutter Web, then create a bridge that translates MCP requests to HTTP calls.

### Architecture
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block.

The architecture diagram should specify a language identifier for proper rendering.

Apply this diff:

-```
+```text
 AI Assistant → MCP Server → HTTP Bridge → Flutter Web (HTTP endpoints) → Service Extensions

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.18.1)</summary>

65-65: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In docs/web_alternative_solutions.md around line 65, the fenced code block lacks
a language specifier so the architecture diagram may not render correctly;
update the block to use a language identifier by replacing the closing fence
with a fenced block labeled "text" containing the arrow diagram line: AI
Assistant → MCP Server → HTTP Bridge → Flutter Web (HTTP endpoints) → Service
Extensions.


</details>

<!-- This is an auto-generated comment by CodeRabbit -->

Use Chrome DevTools Protocol to inspect Flutter Web and create a bridge that translates CDP to MCP.

### Architecture
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block.

The architecture diagram should specify a language identifier for proper rendering.

Apply this diff:

-```
+```text
 AI Assistant → MCP Server → CDP Bridge → Chrome DevTools Protocol → Flutter Web

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.18.1)</summary>

109-109: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In docs/web_alternative_solutions.md around line 109 the fenced code block lacks
a language specifier; update the block to use a text language identifier and
include the diagram line as its content by replacing the existing closing fence
with a fenced block like text followed by "AI Assistant → MCP Server → CDP Bridge → Chrome DevTools Protocol → Flutter Web" and a closing so the block
is rendered correctly.


</details>

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +148 to +152
```
AI Assistant → MCP Server → Hybrid Bridge
├─ HTTP → Service Extensions
└─ WebSocket → Real-time Events
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block.

The architecture diagram should specify a language identifier for proper rendering.

Apply this diff:

-```
+```text
 AI Assistant → MCP Server → Hybrid Bridge
                               ├─ HTTP → Service Extensions
                               └─ WebSocket → Real-time Events

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.18.1)</summary>

148-148: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In docs/web_alternative_solutions.md around lines 148 to 152, the fenced code
block lacks a language specifier; update the block opening fence from ``` to

one starting ```text and keep the same diagram content and closing fence).

Comment on lines +204 to +217
```
mcp_toolkit/
lib/
src/
web/
web_bridge_client.dart # PostMessage client for web
web_service_extensions.dart # Web-specific service extensions
mcp_server_dart/
lib/
src/
mixins/
web_bridge_support.dart # WebSocket bridge for web apps
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block.

The code structure diagram should specify a language identifier for proper rendering.

Apply this diff:

-```
+```text
 mcp_toolkit/
   lib/
     src/
       web/
         web_bridge_client.dart      # PostMessage client for web
         web_service_extensions.dart  # Web-specific service extensions
         
 mcp_server_dart/
   lib/
     src/
       mixins/
         web_bridge_support.dart      # WebSocket bridge for web apps

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.18.1)</summary>

204-204: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In docs/web_alternative_solutions.md around lines 204 to 217, the fenced code
block lacks a language specifier; update the opening fence to use a language
identifier (text) and ensure the closing fence remains, i.e., replace the
existing fence withtext so the block renders correctly as plain text.


</details>

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines 115 to 123
void disconnect() {
if (_webSocket != null) {
_webSocket!.close();
_webSocket = null;
}
_connected = false;
_pendingRequests.clear();
_messageController.close();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Disconnect doesn't handle pending requests gracefully.

When disconnect() is called, pending requests are cleared but their completers are never completed (neither with error nor value). This will leave callers awaiting callServiceExtension hanging indefinitely until their 30-second timeout.

  void disconnect() {
    if (_webSocket != null) {
      _webSocket!.close();
      _webSocket = null;
    }
    _connected = false;
+   // Complete pending requests with error
+   for (final completer in _pendingRequests.values) {
+     if (!completer.isCompleted) {
+       completer.completeError(StateError('Connection closed'));
+     }
+   }
    _pendingRequests.clear();
-   _messageController.close();
+   _messageController?.close();
  }
🤖 Prompt for AI Agents
In mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_web.dart around lines
115–123, disconnect() currently clears _pendingRequests without completing their
Completers, leaving callers hung; modify disconnect() to iterate over
_pendingRequests, complete each Completer with an error (e.g., StateError or a
custom exception indicating the client disconnected), then clear the map, set
_connected=false, close the websocket if non-null, and only after completing
pending completers call _messageController.close(); ensure you null out
_webSocket afterwards.

Comment on lines +67 to +72
_handleWebServiceExtensionCall(
method,
Map<String, String>.from(json['parameters'] as Map? ?? {}),
callback,
id,
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Unsafe cast may throw if parameters contain non-String values.

Map<String, String>.from(...) will throw a TypeError at runtime if any parameter value is not a String. The server could send numeric or boolean parameter values.

Consider using a safer conversion:

-            _handleWebServiceExtensionCall(
-              method,
-              Map<String, String>.from(json['parameters'] as Map? ?? {}),
-              callback,
-              id,
-            );
+            final rawParams = json['parameters'] as Map? ?? {};
+            final params = rawParams.map(
+              (key, value) => MapEntry(key.toString(), value?.toString() ?? ''),
+            );
+            _handleWebServiceExtensionCall(
+              method,
+              params,
+              callback,
+              id,
+            );

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In mcp_toolkit/mcp_toolkit/lib/src/web/web_service_extensions_web.dart around
lines 67 to 72, the code does a direct Map<String,
String>.from(json['parameters'] as Map? ?? {}), which can throw if parameter
values are not Strings; replace this unsafe cast with a defensive conversion
that accepts Map<String, dynamic> (or Map?) and builds a Map<String, String> by
iterating entries and converting each value to a String (e.g., value?.toString()
or an empty string for nulls), ensuring keys are Strings and skipping or
coercing non-String keys as needed, then pass that safe Map<String, String> into
_handleWebServiceExtensionCall.

Comment on lines +155 to 156
"command": "/path/to/your/cloned/mcp_flutter/mcp_server_dart/build/flutter_inspector_mcp.exe",
"args": [
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Path example inconsistency: RooCode config missing .exe extension.

Line 155 shows .exe for Cline, Cursor, and Claude configs, but the RooCode example on line 256 omits the extension. For consistency across all Windows examples, consider noting that Windows users should add .exe to the RooCode path as well, or explicitly mention it's a Linux/macOS example.

🤖 Prompt for AI Agents
In QUICK_START.md around lines 155–156, the RooCode example on line 256 is
inconsistent with other Windows examples that include the .exe extension; update
the RooCode path example to include the .exe suffix for Windows users (or add a
short parenthetical stating the example is for Linux/macOS) so all Windows path
examples consistently show the .exe extension and avoid confusion.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
mcp_server_dart/lib/src/dynamic_registry/registry_discovery_service.dart (1)

186-195: Web bridge response extraction may need type safety.

The web response handling assumes the response structure:

final resultData = webResult['result'] as Map<String, dynamic>? ?? webResult;

If webResult['result'] exists but is not a Map<String, dynamic>, this cast will throw. Consider defensive handling:

-        final resultData = webResult['result'] as Map<String, dynamic>? ?? webResult;
+        final rawResult = webResult['result'];
+        final resultData = rawResult is Map<String, dynamic> ? rawResult : webResult;
mcp_server_dart/lib/src/server.dart (2)

326-345: Connection-refused detection includes multilingual error messages.

The error detection checks for both English ("connection refused") and Portuguese ("recusou a conexão"). While functional, consider using a more robust approach that doesn't rely on localized error messages:

-      if (errorMessage.contains('recusou a conexão') ||
-          errorMessage.contains('connection refused') ||
-          errorMessage.contains('SocketException')) {
+      if (errorMessage.contains('SocketException') ||
+          e is SocketException) {

Alternatively, catching SocketException explicitly before the generic catch would be more reliable than string matching.


347-361: Consider making the web bridge port configurable.

The web bridge port is hardcoded to 8183. For consistency with the configurable VM service ports (vmHost, vmPort), consider adding a webBridgePort configuration option:

-      await startWebBridge(port: 8183);
+      await startWebBridge(port: configuration.webBridgePort);

This would allow users to avoid port conflicts in environments where 8183 is already in use.

mcp_server_dart/lib/src/mixins/flutter_inspector.dart (1)

1130-1212: Dual-path implementation is correct but has some duplication.

The VM and web bridge paths work correctly and handle all connection states. However, the result processing code (extracting errors and message) is duplicated between the two paths.

Consider extracting the common result processing logic into a helper method to improve maintainability.

Map<String, dynamic> _parseAppErrorsResult(Map<String, dynamic> resultData) {
  final errors = jsonDecodeListAs<Map<String, dynamic>>(resultData['errors']);
  final message = jsonDecodeString(resultData['message']).whenEmptyUse('No errors found');
  return {'errors': errors, 'message': message};
}

Then use it in both paths:

// VM path
final resultData = result.json;
final parsed = _parseAppErrorsResult(resultData!);

// Web path
final resultData = webResult['result'] as Map<String, dynamic>? ?? webResult;
final parsed = _parseAppErrorsResult(resultData);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 41c70b9 and 8a92ea2.

📒 Files selected for processing (13)
  • QUICK_START.md (8 hunks)
  • README.md (2 hunks)
  • docs/WEB_SETUP_CHECKLIST.md (1 hunks)
  • flutter_test_app/README.md (1 hunks)
  • install.ps1 (1 hunks)
  • llm_install.md (3 hunks)
  • mcp_server_dart/lib/src/dynamic_registry/registry_discovery_service.dart (1 hunks)
  • mcp_server_dart/lib/src/mixins/dynamic_registry_integration.dart (1 hunks)
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart (6 hunks)
  • mcp_server_dart/lib/src/mixins/vm_service_support.dart (1 hunks)
  • mcp_server_dart/lib/src/mixins/web_bridge_support.dart (1 hunks)
  • mcp_server_dart/lib/src/server.dart (3 hunks)
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_web.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • mcp_toolkit/mcp_toolkit/lib/src/web/web_bridge_client_web.dart
  • install.ps1
🧰 Additional context used
📓 Path-based instructions (2)
**/*.md

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

For documentation (READMEs, technical docs), follow Google's Technical Writing Style Guide (define terms, active voice, present tense, clear/concise, logical order, use lists/tables when appropriate)

Files:

  • docs/WEB_SETUP_CHECKLIST.md
  • README.md
  • flutter_test_app/README.md
  • llm_install.md
  • QUICK_START.md
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/dart_dev.mdc)

**/*.dart: Use async/await instead of then for asynchronous operations
Write precise, future-proof dartdoc comments that focus on the specific purpose
Include cross-references to related classes and real usage examples in dartdoc comments
Document relationships between related components in dartdoc comments
Avoid scope limitations in documentation unless absolutely necessary
Use {@template} for reusable component documentation in dartdoc comments
Include practical code samples showing real usage patterns in documentation
Document all parameters with /// in dartdoc comments
Add warning comments for important usage notes in documentation
Reference concrete implementations in the codebase within documentation
Explicit type declarations must be used
Use Dart naming conventions: PascalCase for classes, camelCase for variables/functions
Prefer const constructors
Use extension methods for added functionality (e.g., GameId)
Use required commas linter rule in Dart
Prefer arrow function style for Dart
Prefer const constructors with named parameters with const values instead of nullable ones
Use Dart 3.7 syntax for null safety, pattern matching, and more
Proper error handling and async/await for asynchronous operations
Use [] when referencing code in documentation
Generate readable, short, and concise documentation
Use {@template} and {@macro} to create and use dart doc code snippets

**/*.dart: Use Dart 3.7 syntax for null safety, pattern matching, and other new features
Use StatelessWidget, HookWidget (from flutter_hooks), or StatefulWidget appropriately
Use custom reusable widgets from ui_kit instead of methods for UI reuse
Use Cupertino or Material Design widgets as appropriate
Ensure proper error handling and use async/await for asynchronous operations
Use flutter_animate for animations
Prefer fewer, more cohesive widgets over many tiny widgets; extract new widget classes only when reused, complex (>50 lines), or logically independent
Use comments to separate logical ...

Files:

  • mcp_server_dart/lib/src/dynamic_registry/registry_discovery_service.dart
  • mcp_server_dart/lib/src/mixins/web_bridge_support.dart
  • mcp_server_dart/lib/src/mixins/dynamic_registry_integration.dart
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
  • mcp_server_dart/lib/src/mixins/vm_service_support.dart
  • mcp_server_dart/lib/src/server.dart
🧠 Learnings (24)
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to **/*.dart : Add warning comments for important usage notes in documentation

Applied to files:

  • docs/WEB_SETUP_CHECKLIST.md
  • flutter_test_app/README.md
  • QUICK_START.md
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to **/*.dart : Generate readable, short, and concise documentation

Applied to files:

  • docs/WEB_SETUP_CHECKLIST.md
  • flutter_test_app/README.md
📚 Learning: 2025-07-22T17:00:31.562Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/create_jules_plan.mdc:0-0
Timestamp: 2025-07-22T17:00:31.562Z
Learning: Always add as first steps: 1. Branch & Environment Setup 1.1 Create a new branch from the default branch (e.g., {name}). 1.2 Run the provided environment setup scripts to ensure Dart, FVM, and Flutter are correctly installed and configured.

Applied to files:

  • docs/WEB_SETUP_CHECKLIST.md
  • flutter_test_app/README.md
  • llm_install.md
  • QUICK_START.md
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Ensure addMcpTool() is called after MCPToolkitBinding.initialize() to guarantee tool registration.

Applied to files:

  • docs/WEB_SETUP_CHECKLIST.md
  • mcp_server_dart/lib/src/dynamic_registry/registry_discovery_service.dart
  • README.md
  • flutter_test_app/README.md
  • mcp_server_dart/lib/src/mixins/web_bridge_support.dart
  • llm_install.md
  • mcp_server_dart/lib/src/mixins/dynamic_registry_integration.dart
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
  • QUICK_START.md
  • mcp_server_dart/lib/src/server.dart
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Register custom MCP tools by calling addMcpTool() with tool or resource definitions in Dart code.

Applied to files:

  • docs/WEB_SETUP_CHECKLIST.md
  • mcp_server_dart/lib/src/dynamic_registry/registry_discovery_service.dart
  • README.md
  • flutter_test_app/README.md
  • llm_install.md
  • mcp_server_dart/lib/src/mixins/dynamic_registry_integration.dart
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
  • QUICK_START.md
  • mcp_server_dart/lib/src/server.dart
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Wrap tool registration in if (kDebugMode) checks to ensure tools are only registered in debug mode.

Applied to files:

  • mcp_server_dart/lib/src/dynamic_registry/registry_discovery_service.dart
  • mcp_server_dart/lib/src/mixins/dynamic_registry_integration.dart
  • QUICK_START.md
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to lib/{main.dart,debug_tools.dart} : Place tool registration code in main.dart or in a dedicated debug_tools.dart file under lib/.

Applied to files:

  • mcp_server_dart/lib/src/dynamic_registry/registry_discovery_service.dart
  • flutter_test_app/README.md
  • mcp_server_dart/lib/src/mixins/dynamic_registry_integration.dart
  • QUICK_START.md
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Define custom tools using MCPCallEntry.tool with a handler function and MCPToolDefinition.

Applied to files:

  • mcp_server_dart/lib/src/dynamic_registry/registry_discovery_service.dart
  • README.md
  • flutter_test_app/README.md
  • QUICK_START.md
  • mcp_server_dart/lib/src/server.dart
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Define custom resources using MCPCallEntry.resource with a handler function and MCPResourceDefinition.

Applied to files:

  • mcp_server_dart/lib/src/dynamic_registry/registry_discovery_service.dart
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Use try/catch blocks in handler functions for error handling and return MCPCallResult with error details on failure.

Applied to files:

  • README.md
  • mcp_server_dart/lib/src/mixins/vm_service_support.dart
📚 Learning: 2025-07-22T16:52:15.714Z
Learnt from: Arenukvern
Repo: Arenukvern/mcp_flutter PR: 61
File: docs/guides/creating_dynamic_tools.mdx:16-28
Timestamp: 2025-07-22T16:52:15.714Z
Learning: In the MCP Flutter toolkit, tool registration via addMcpTool() and addEntries() is already wrapped in assert() blocks, which ensures tools are only registered in debug builds and stripped from release builds, providing the same security as kDebugMode checks.

Applied to files:

  • README.md
  • flutter_test_app/README.md
  • QUICK_START.md
  • mcp_server_dart/lib/src/server.dart
📚 Learning: 2025-08-19T13:59:27.375Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/training.mdc:0-0
Timestamp: 2025-08-19T13:59:27.375Z
Learning: Use Flutter for UI implementation

Applied to files:

  • flutter_test_app/README.md
  • llm_install.md
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
  • QUICK_START.md
📚 Learning: 2025-07-22T17:00:31.562Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/create_jules_plan.mdc:0-0
Timestamp: 2025-07-22T17:00:31.562Z
Learning: For Flutter projects without FVM, use the provided shell script to install Dart SDK and get dependencies.

Applied to files:

  • flutter_test_app/README.md
  • llm_install.md
  • QUICK_START.md
📚 Learning: 2025-08-19T13:59:27.375Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/training.mdc:0-0
Timestamp: 2025-08-19T13:59:27.375Z
Learning: Applies to lib/main.dart : Use lib/main.dart as the application entry point

Applied to files:

  • flutter_test_app/README.md
  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-07-22T17:00:31.562Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/create_jules_plan.mdc:0-0
Timestamp: 2025-07-22T17:00:31.562Z
Learning: For Flutter projects using FVM, use the provided shell script to install Dart SDK, FVM, and Flutter, and to get dependencies.

Applied to files:

  • flutter_test_app/README.md
  • llm_install.md
  • QUICK_START.md
📚 Learning: 2025-08-19T13:59:27.375Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/training.mdc:0-0
Timestamp: 2025-08-19T13:59:27.375Z
Learning: Applies to lib/common_imports.dart : Maintain shared/common imports in lib/common_imports.dart

Applied to files:

  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
  • mcp_server_dart/lib/src/server.dart
📚 Learning: 2025-07-22T17:01:38.301Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/mcp_dynamic_tools.mdc:0-0
Timestamp: 2025-07-22T17:01:38.301Z
Learning: Applies to **/*.dart : Use descriptive, unique, snake_case names for tools, including an action verb such as inspect_, modify_, or monitor_.

Applied to files:

  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to lib/**/*.dart : Use common imports (lib/common_imports.dart)

Applied to files:

  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
  • mcp_server_dart/lib/src/server.dart
📚 Learning: 2025-08-19T13:58:50.012Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/test_guide.mdc:0-0
Timestamp: 2025-08-19T13:58:50.012Z
Learning: Applies to **/*_test.dart : Keep tests self-contained and independent

Applied to files:

  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
  • mcp_server_dart/lib/src/server.dart
📚 Learning: 2025-08-19T13:59:27.375Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/training.mdc:0-0
Timestamp: 2025-08-19T13:59:27.375Z
Learning: Applies to **/*.dart : Use Dart for code implementation

Applied to files:

  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to **/*.dart : Use extension methods for added functionality (e.g., GameId)

Applied to files:

  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-08-19T14:00:51.285Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/writing_code_protocol.mdc:0-0
Timestamp: 2025-08-19T14:00:51.285Z
Learning: Applies to **/*.dart : Use EquatableMixin for classes to implement value equality

Applied to files:

  • mcp_server_dart/lib/src/mixins/flutter_inspector.dart
📚 Learning: 2025-07-22T17:01:11.427Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/dart_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:11.427Z
Learning: Applies to **/*.dart : Proper error handling and async/await for asynchronous operations

Applied to files:

  • mcp_server_dart/lib/src/mixins/vm_service_support.dart
📚 Learning: 2025-07-22T17:01:23.584Z
Learnt from: CR
Repo: Arenukvern/mcp_flutter PR: 0
File: .cursor/rules/flutter_ui_dev.mdc:0-0
Timestamp: 2025-07-22T17:01:23.584Z
Learning: Applies to **/*.dart : Ensure proper error handling and use async/await for asynchronous operations

Applied to files:

  • mcp_server_dart/lib/src/mixins/vm_service_support.dart
🪛 LanguageTool
QUICK_START.md

[style] ~322-~322: Consider an alternative verb to strengthen your wording.
Context: ...will use the web bridge instead. If you see this error repeatedly, ensure: - The we...

(IF_YOU_HAVE_THIS_PROBLEM)

🪛 markdownlint-cli2 (0.18.1)
README.md

98-98: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

QUICK_START.md

54-54: Bare URL used

(MD034, no-bare-urls)


114-114: Link fragments should be valid

(MD051, link-fragments)


164-164: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (17)
mcp_server_dart/lib/src/mixins/dynamic_registry_integration.dart (1)

66-90: Dual-path connection handling looks good.

The logic correctly handles three scenarios:

  1. VM service connected → proceed with registration
  2. Web clients connected → proceed with registration
  3. Neither connected → start discovery for future connections, return early

The 2-second timeout for VM connection is reasonable for startup performance.

mcp_server_dart/lib/src/mixins/vm_service_support.dart (1)

44-73: Enhanced error handling with proper WebSocket cleanup.

Good defensive pattern: if DartToolingDaemon.connect fails after the WebSocket channel opens, the channel is properly closed before rethrowing. This prevents resource leaks in partial-failure scenarios.

Minor observation: _dartToolingDaemon doesn't need cleanup here since assignment failed, but you might consider explicitly setting it to null for consistency with _vmChannel = null pattern.

flutter_test_app/README.md (1)

55-59: Verify the 30-40 second connection wait time.

The documentation states users should "Wait 30-40 seconds after starting the app for the connection to establish." This seems unusually long for a WebSocket connection. If accurate, consider explaining why in the documentation (e.g., initialization overhead, polling intervals). If this is a conservative estimate, a more typical timeframe might improve user expectations.

docs/WEB_SETUP_CHECKLIST.md (1)

79-104: Code template demonstrates correct initialization pattern.

The template correctly shows:

  1. runZonedGuarded for error capture
  2. Platform check with kIsWeb
  3. Proper initialization order: initializeWebBridgeForWeb before initializeFlutterToolkit
  4. Cascade operator usage for non-web path

One minor consistency note: the non-web path uses cascade operators (..initialize()..initializeFlutterToolkit()), but the web path calls methods separately with await. Consider adding a note that the web path requires await because initializeWebBridgeForWeb is async.

mcp_server_dart/lib/src/server.dart (1)

22-27: WebBridgeSupport mixin integration looks correct.

The mixin chain order appears appropriate: VMServiceSupportDynamicRegistryIntegrationWebBridgeSupportFlutterInspector. This ensures VM service capabilities are available before web bridge support is mixed in.

README.md (2)

85-100: Web platform documentation is clear and comprehensive.

The web platform support section accurately documents available and unavailable tools, explains the WebSocket bridge architecture, and sets appropriate expectations about hot reload limitations on web.


135-159: Troubleshooting guidance is actionable and platform-specific.

The troubleshooting section provides clear, platform-specific commands and verification steps for web bridge connectivity issues. The 30-40 second wait time is consistently mentioned, which helps set proper user expectations.

llm_install.md (2)

96-142: Platform-specific initialization code is correct and well-documented.

The code example properly demonstrates the critical kIsWeb check and the appropriate initialization methods for each platform. The runZonedGuarded wrapper for error handling is a good practice.


257-289: Web platform documentation provides clear guidance.

The web platform support section clearly distinguishes available and unavailable tools, explains setup requirements, and sets appropriate expectations about connection timing (30-40 seconds).

mcp_server_dart/lib/src/mixins/flutter_inspector.dart (2)

1227-1324: Screenshots dual-path implementation is well-structured.

The implementation correctly handles both VM and web bridge paths, with good separation of concerns. The common file-saving logic is properly shared between both paths, demonstrating good code reuse.


1327-1409: View details dual-path implementation follows consistent patterns.

The implementation correctly handles both VM and web bridge connectivity, with proper variable scoping and consistent error handling. The pattern matches the other dual-path tools, maintaining code consistency across the mixin.

QUICK_START.md (3)

9-127: Architecture documentation and initialization code are comprehensive.

The architecture section clearly distinguishes the dual-path approach, and the initialization code example is complete with proper platform detection. The prominent warnings about platform-specific requirements help prevent common setup mistakes.


148-167: Web platform limitations are clearly documented.

The section accurately describes available and unavailable tools on the web platform, explains the technical reasons (lack of VM Service), and provides important notes about connection requirements and timing.


299-341: Troubleshooting section provides actionable solutions.

The new troubleshooting section is well-organized by problem type and provides specific, actionable solutions with platform-specific commands for verifying connectivity.

mcp_server_dart/lib/src/mixins/web_bridge_support.dart (3)

175-234: Service extension method is well-implemented with proper timeout handling.

The method correctly generates unique request IDs, sends messages to web clients, and handles timeouts appropriately. The 30-second timeout is reasonable for service extension calls.

Note: The code uses firstOrNull to select any available web client. This is appropriate for the current single-client scenario but may need adjustment if multiple web clients are supported in the future.


274-286: Shutdown method properly cleans up all resources.

The stopWebBridge method correctly closes all WebSocket channels and the HTTP server, ensuring no resource leaks during shutdown.


1-289: WebBridge implementation is comprehensive and well-structured.

The mixin provides a complete WebSocket bridge for web platform support with:

  • Proper HTTP server and WebSocket lifecycle management
  • Client connection tracking and cleanup
  • Request/response correlation with unique IDs
  • Comprehensive error handling and logging
  • Appropriate timeout handling (30 seconds)

The implementation follows Dart conventions and integrates well with the existing MCP server architecture.

Comment on lines +60 to +92
channel.stream.listen(
(final message) {
log(
LoggingLevel.debug,
'Received message from $clientId',
logger: 'WebBridge',
);
_handleWebMessage(clientId, message);
},
onDone: () {
log(
LoggingLevel.info,
'Web client stream done: $clientId',
logger: 'WebBridge',
);
if (_webClients.containsKey(clientId)) {
_webClients.remove(clientId);
log(
LoggingLevel.info,
'Web client disconnected: $clientId (remaining clients: ${_webClients.length})',
logger: 'WebBridge',
);
}
},
onError: (final error) {
log(
LoggingLevel.error,
'Web client error: $error (clientId: $clientId)',
logger: 'WebBridge',
);
},
cancelOnError: false,
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

WebSocket channel cleanup may be incomplete on disconnect.

When a client disconnects (onDone callback), the code removes the client from _webClients but doesn't explicitly close the WebSocket channel. While the stream being done might imply the channel is already closed, it's safer to explicitly close the sink to ensure proper resource cleanup.

Apply this diff to ensure proper cleanup:

onDone: () {
  log(
    LoggingLevel.info,
    'Web client stream done: $clientId',
    logger: 'WebBridge',
  );
  if (_webClients.containsKey(clientId)) {
+   // Ensure channel is properly closed before removing
+   unawaited(_webClients[clientId]?.sink.close());
    _webClients.remove(clientId);
    log(
      LoggingLevel.info,
      'Web client disconnected: $clientId (remaining clients: ${_webClients.length})',
      logger: 'WebBridge',
    );
  }
},
🤖 Prompt for AI Agents
mcp_server_dart/lib/src/mixins/web_bridge_support.dart around lines 60 to 92: on
client disconnect (onDone) the code removes the client from _webClients but does
not explicitly close the WebSocket channel; before removing the entry, ensure
the channel is closed by invoking the sink.close() on the stored WebSocket (use
unawaited(_webClients[clientId]?.sink.close()) or make the onDone handler async
and await _webClients[clientId]?.sink.close()), then remove the client and keep
the existing logs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant