re-implement most of #440 for the current stable release (#441)
diff --git a/pkgs/dart_mcp_server/CHANGELOG.md b/pkgs/dart_mcp_server/CHANGELOG.md
index d5b5cb4..57d534d 100644
--- a/pkgs/dart_mcp_server/CHANGELOG.md
+++ b/pkgs/dart_mcp_server/CHANGELOG.md
@@ -1,4 +1,9 @@
-# 0.1.2 (Dart SDK 3.11.0) - WIP
+# 0.1.2+1 (Dart SDK 3.11.5)
+
+- Always enable roots fallback, and merge them with client roots that are set
+  (if any).
+
+# 0.1.2 (Dart SDK 3.11.0)
 
 - Add `--tools=dart|all` argument to allow enabling only vanilla Dart tools for
   non-flutter projects.
diff --git a/pkgs/dart_mcp_server/README.md b/pkgs/dart_mcp_server/README.md
index 6ea2dc9..6ff58d1 100644
--- a/pkgs/dart_mcp_server/README.md
+++ b/pkgs/dart_mcp_server/README.md
@@ -18,10 +18,6 @@
 experience with the Dart MCP server, an MCP client should also support
 [Roots](https://modelcontextprotocol.io/docs/concepts/roots).
 
-If you are using a client that claims it supports roots but does not actually
-set them, pass `--force-roots-fallback` which will instead enable tools for
-managing the roots.
-
 Here are specific instructions for some popular tools:
 
 ### Gemini CLI
@@ -91,7 +87,6 @@
       "args": [
         "mcp-server",
         "--experimental-mcp-server", // Can be removed for Dart 3.9.0 or later
-        "--force-roots-fallback" // Workaround for a Cursor issue with Roots support
       ]
     }
   }
diff --git a/pkgs/dart_mcp_server/lib/src/arg_parser.dart b/pkgs/dart_mcp_server/lib/src/arg_parser.dart
index c01bdb6..6667432 100644
--- a/pkgs/dart_mcp_server/lib/src/arg_parser.dart
+++ b/pkgs/dart_mcp_server/lib/src/arg_parser.dart
@@ -35,12 +35,13 @@
         ..addFlag(
           forceRootsFallbackFlag,
           negatable: true,
-          defaultsTo: false,
+          defaultsTo: true,
           help:
               'Forces a behavior for project roots which uses MCP tools '
               'instead of the native MCP roots. This can be helpful for '
               'clients like Cursor which claim to have roots support but do '
               'not actually support it.',
+          hide: true,
         )
         ..addOption(
           logFileOption,
diff --git a/pkgs/dart_mcp_server/lib/src/mixins/flutter_launcher.dart b/pkgs/dart_mcp_server/lib/src/mixins/flutter_launcher.dart
index 0430ea0..43aca5c 100644
--- a/pkgs/dart_mcp_server/lib/src/mixins/flutter_launcher.dart
+++ b/pkgs/dart_mcp_server/lib/src/mixins/flutter_launcher.dart
@@ -106,6 +106,7 @@
           '--device-id',
           device,
           if (target != null) '--target',
+          // ignore: use_null_aware_elements
           if (target != null) target,
         ],
         workingDirectory: root,
diff --git a/pkgs/dart_mcp_server/lib/src/mixins/pub.dart b/pkgs/dart_mcp_server/lib/src/mixins/pub.dart
index a064253..77ac94c 100644
--- a/pkgs/dart_mcp_server/lib/src/mixins/pub.dart
+++ b/pkgs/dart_mcp_server/lib/src/mixins/pub.dart
@@ -69,6 +69,7 @@
 
     return runCommandInRoots(
       request,
+      // ignore: use_null_aware_elements
       arguments: ['pub', command, if (packageNames != null) ...packageNames],
       commandDescription: 'dart|flutter pub $command',
       processManager: processManager,
diff --git a/pkgs/dart_mcp_server/lib/src/mixins/pub_dev_search.dart b/pkgs/dart_mcp_server/lib/src/mixins/pub_dev_search.dart
index 45c31d7..f5d8dc5 100644
--- a/pkgs/dart_mcp_server/lib/src/mixins/pub_dev_search.dart
+++ b/pkgs/dart_mcp_server/lib/src/mixins/pub_dev_search.dart
@@ -108,6 +108,7 @@
                   'latest',
                   'version',
                 ]),
+                // ignore: use_null_aware_elements
                 if (dig<String?>(versionListing, [
                       'latest',
                       'pubspec',
@@ -115,6 +116,7 @@
                     ])
                     case final description?)
                   'description': description,
+                // ignore: use_null_aware_elements
                 if (dig<String?>(versionListing, [
                       'latest',
                       'pubspec',
@@ -122,6 +124,7 @@
                     ])
                     case final homepage?)
                   'homepage': homepage,
+                // ignore: use_null_aware_elements
                 if (dig<String?>(versionListing, [
                       'latest',
                       'pubspec',
@@ -129,6 +132,7 @@
                     ])
                     case final repository?)
                   'repository': repository,
+                // ignore: use_null_aware_elements
                 if (dig<String?>(versionListing, [
                       'latest',
                       'pubspec',
diff --git a/pkgs/dart_mcp_server/lib/src/mixins/roots_fallback_support.dart b/pkgs/dart_mcp_server/lib/src/mixins/roots_fallback_support.dart
index 0eb1a8c..845956b 100644
--- a/pkgs/dart_mcp_server/lib/src/mixins/roots_fallback_support.dart
+++ b/pkgs/dart_mcp_server/lib/src/mixins/roots_fallback_support.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:async/async.dart';
 import 'package:dart_mcp/server.dart';
 import 'package:meta/meta.dart';
 
@@ -45,14 +46,24 @@
       // if they do. If we are implementing the support, we always support it.
       _fallbackEnabled ? true : super.supportsRootsChanged;
 
+  /// Combines the client stream and the fallback controller stream.
   @override
-  Stream<RootsListChangedNotification?>? get rootsListChanged =>
-      // If the client supports roots, just use their stream (or lack thereof).
-      // If they don't, use our own stream.
-      _fallbackEnabled
-      ? _rootsListChangedFallbackController?.stream
-      : super.rootsListChanged;
+  Stream<RootsListChangedNotification?>? get rootsListChanged {
+    final clientStream = super.rootsListChanged;
+    if (clientStream == null) {
+      return _rootsListChangedFallbackController?.stream;
+    } else if (_rootsListChangedFallbackController == null) {
+      return clientStream;
+    } else {
+      return StreamGroup.merge([
+        clientStream,
+        _rootsListChangedFallbackController!.stream,
+      ]);
+    }
+  }
 
+  /// Broadcast controller for roots list changed events from usage of the
+  /// roots tool.
   StreamController<RootsListChangedNotification?>?
   _rootsListChangedFallbackController;
 
@@ -71,13 +82,30 @@
     }
   }
 
-  /// Delegates to the inherited implementation if fallback mode is not enabled,
-  /// otherwise returns our own custom roots.
+  /// Returns the custom roots combined with the client's roots.
   @override
-  Future<ListRootsResult> listRoots([ListRootsRequest? request]) async =>
-      _fallbackEnabled
-      ? ListRootsResult(roots: _customRoots.toList())
-      : super.listRoots(request);
+  Future<ListRootsResult> listRoots([ListRootsRequest? request]) async {
+    final clientRoots = <Root>[];
+    if (super.supportsRoots) {
+      try {
+        final result = await super.listRoots(request);
+        clientRoots.addAll(result.roots);
+      } catch (e, s) {
+        log(LoggingLevel.error, 'Failed to list roots from client: $e\n$s');
+      }
+    }
+
+    final seenUris = <String>{};
+    final allRoots = <Root>[];
+
+    for (final root in clientRoots.followedBy(_customRoots)) {
+      if (seenUris.add(root.uri)) {
+        allRoots.add(root);
+      }
+    }
+
+    return ListRootsResult(roots: allRoots);
+  }
 
   /// Adds the roots in [request] the custom roots and calls [updateRoots].
   ///
diff --git a/pkgs/dart_mcp_server/lib/src/server.dart b/pkgs/dart_mcp_server/lib/src/server.dart
index d9e0220..f560638 100644
--- a/pkgs/dart_mcp_server/lib/src/server.dart
+++ b/pkgs/dart_mcp_server/lib/src/server.dart
@@ -77,7 +77,7 @@
   }) : super.fromStreamChannel(
          implementation: Implementation(
            name: 'dart and flutter tooling',
-           version: '0.1.2',
+           version: '0.1.2+1',
          ),
          instructions:
              'This server helps to connect Dart and Flutter developers to '
diff --git a/pkgs/dart_mcp_server/test/tools/roots_fallback_support_test.dart b/pkgs/dart_mcp_server/test/tools/roots_fallback_support_test.dart
index a93865a..3b4848e 100644
--- a/pkgs/dart_mcp_server/test/tools/roots_fallback_support_test.dart
+++ b/pkgs/dart_mcp_server/test/tools/roots_fallback_support_test.dart
@@ -13,7 +13,7 @@
 import 'package:test/test.dart';
 
 void main() {
-  late RootsTrackingSupport server;
+  late TestServer server;
   late ServerConnection serverConnection;
   final rootA = Root(uri: 'file:///a/');
   final rootB = Root(uri: 'file:///b/');
@@ -149,38 +149,97 @@
         await server.roots; // wait for the first listRoots request to complete
       });
 
-      test('registers no tools', () async {
+      test('registers tools to add and remove roots', () async {
         final tools = await serverConnection.listTools(ListToolsRequest());
-        expect(tools.tools, isEmpty);
+        expect(
+          tools.tools,
+          unorderedEquals([
+            RootsFallbackSupport.addRootsTool,
+            RootsFallbackSupport.removeRootsTool,
+          ]),
+        );
       });
 
-      test('Gives roots changed notifications when roots are added', () async {
-        final notifications = StreamQueue(server.rootsListChanged!);
-        client.addRoot(rootA);
-        expect(await notifications.hasNext, true);
-        await notifications.next;
+      test(
+        'Gives roots changed notifications when roots are added by the client',
+        () async {
+          final notifications = StreamQueue(server.rootsListChanged!);
+          client.addRoot(rootA);
+          expect(await notifications.hasNext, true);
+          await notifications.next;
 
-        client.removeRoot(rootA);
-        expect(await notifications.hasNext, true);
-        await notifications.next;
-      });
+          client.removeRoot(rootA);
+          expect(await notifications.hasNext, true);
+          await notifications.next;
+        },
+      );
 
-      test('can add, remove, and list roots', () async {
+      test(
+        'Gives roots changed notifications when roots are added by the tool',
+        () async {
+          var next = server.rootsListChanged!.first;
+          unawaited(
+            serverConnection.callTool(
+              CallToolRequest(
+                name: RootsFallbackSupport.addRootsTool.name,
+                arguments: {
+                  ParameterNames.roots: [rootA],
+                },
+              ),
+            ),
+          );
+          await next;
+
+          next = server.rootsListChanged!.first;
+          unawaited(
+            serverConnection.callTool(
+              CallToolRequest(
+                name: RootsFallbackSupport.removeRootsTool.name,
+                arguments: {
+                  ParameterNames.uris: [rootA.uri],
+                },
+              ),
+            ),
+          );
+          await next;
+        },
+      );
+
+      test('can add, remove, and list roots using client or tools', () async {
         expect((await server.listRoots(ListRootsRequest())).roots, isEmpty);
 
-        client
-          ..addRoot(rootA)
-          ..addRoot(rootB);
+        client.addRoot(rootA);
+        await serverConnection.callTool(
+          CallToolRequest(
+            name: RootsFallbackSupport.addRootsTool.name,
+            arguments: {
+              ParameterNames.roots: [rootB],
+            },
+          ),
+        );
+        await pumpEventQueue();
         expect(
           (await server.listRoots(ListRootsRequest())).roots,
           unorderedEquals([rootA, rootB]),
         );
 
-        client.removeRoot(rootB);
+        client.removeRoot(rootA);
+        await pumpEventQueue();
         expect(
           (await server.listRoots(ListRootsRequest())).roots,
-          unorderedEquals([rootA]),
+          unorderedEquals([rootB]),
         );
+
+        await serverConnection.callTool(
+          CallToolRequest(
+            name: RootsFallbackSupport.removeRootsTool.name,
+            arguments: {
+              ParameterNames.uris: [rootB.uri],
+            },
+          ),
+        );
+        await pumpEventQueue();
+        expect((await server.listRoots(ListRootsRequest())).roots, isEmpty);
       });
     });
   });
@@ -221,7 +280,7 @@
   TestServer(
     super.channel, {
     super.protocolLogSink,
-    this.forceRootsFallback = false,
+    this.forceRootsFallback = true,
   }) : super.fromStreamChannel(
          implementation: Implementation(name: 'test server', version: '0.1.0'),
          instructions: 'A test server with roots fallback support',