From c575b9a02b6b001245354ad95ed78488eed6bdc0 Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Tue, 17 Jun 2025 22:20:28 +0000 Subject: [PATCH 1/5] add analytics support to the Dart MCP server --- pkgs/dart_mcp_server/CHANGELOG.md | 3 +- pkgs/dart_mcp_server/bin/main.dart | 1 + pkgs/dart_mcp_server/lib/src/mixins/dtd.dart | 27 +++++- pkgs/dart_mcp_server/lib/src/server.dart | 72 ++++++++++++++- .../lib/src/utils/analytics.dart | 72 +++++++++++++++ pkgs/dart_mcp_server/pubspec.yaml | 7 +- .../test/dart_tooling_mcp_server_test.dart | 88 ++++++++++++++++++- pkgs/dart_mcp_server/test/test_harness.dart | 23 +++++ pkgs/dart_mcp_server/test/tools/dtd_test.dart | 32 +++++++ 9 files changed, 317 insertions(+), 8 deletions(-) create mode 100644 pkgs/dart_mcp_server/lib/src/utils/analytics.dart diff --git a/pkgs/dart_mcp_server/CHANGELOG.md b/pkgs/dart_mcp_server/CHANGELOG.md index 55fe7827..63b268fc 100644 --- a/pkgs/dart_mcp_server/CHANGELOG.md +++ b/pkgs/dart_mcp_server/CHANGELOG.md @@ -1,4 +1,4 @@ -# Dart SDK 3.8.0 - WP +# 0.1.0 (Dart SDK 3.8.0) - WP * Add documentation/homepage/repository links to pub results. * Handle relative paths under roots without trailing slashes. @@ -39,3 +39,4 @@ * Add the beginnings of a Dart tooling MCP server. * Instruct clients to prefer MCP tools over running tools in the shell. * Reduce output size of `run_tests` tool to save on input tokens. +* Add support for injecting an `Analytics` instance to track usage. diff --git a/pkgs/dart_mcp_server/bin/main.dart b/pkgs/dart_mcp_server/bin/main.dart index 351dc72b..f9f607cf 100644 --- a/pkgs/dart_mcp_server/bin/main.dart +++ b/pkgs/dart_mcp_server/bin/main.dart @@ -40,6 +40,7 @@ void main(List args) async { ), forceRootsFallback: parsedArgs.flag(forceRootsFallback), sdk: Sdk.find(dartSdkPath: dartSdkPath, flutterSdkPath: flutterSdkPath), + analytics: null, ); }, (e, s) { diff --git a/pkgs/dart_mcp_server/lib/src/mixins/dtd.dart b/pkgs/dart_mcp_server/lib/src/mixins/dtd.dart index 1dfffe44..b9e7e296 100644 --- a/pkgs/dart_mcp_server/lib/src/mixins/dtd.dart +++ b/pkgs/dart_mcp_server/lib/src/mixins/dtd.dart @@ -10,9 +10,11 @@ import 'package:dds_service_extensions/dds_service_extensions.dart'; import 'package:dtd/dtd.dart'; import 'package:json_rpc_2/json_rpc_2.dart'; import 'package:meta/meta.dart'; +import 'package:unified_analytics/unified_analytics.dart' as ua; import 'package:vm_service/vm_service.dart'; import 'package:vm_service/vm_service_io.dart'; +import '../utils/analytics.dart'; import '../utils/constants.dart'; /// Mix this in to any MCPServer to add support for connecting to the Dart @@ -21,7 +23,8 @@ import '../utils/constants.dart'; /// /// The MCPServer must already have the [ToolsSupport] mixin applied. base mixin DartToolingDaemonSupport - on ToolsSupport, LoggingSupport, ResourcesSupport { + on ToolsSupport, LoggingSupport, ResourcesSupport + implements AnalyticsSupport { DartToolingDaemon? _dtd; /// Whether or not the DTD extension to get the active debug sessions is @@ -114,12 +117,32 @@ base mixin DartToolingDaemonSupport '"${debugSession.name}".', ); addResource(resource, (request) async { - return ReadResourceResult( + final watch = Stopwatch()..start(); + final result = ReadResourceResult( contents: [ for (var error in errorService.errorLog.errors) TextResourceContents(uri: resource.uri, text: error), ], ); + watch.stop(); + try { + analytics?.send( + ua.Event.dartMCPEvent( + client: clientInfo.name, + clientVersion: clientInfo.version, + serverVersion: implementation.version, + type: AnalyticsEvent.readResource.name, + additionalData: ReadResourceMetrics( + kind: 'runtimeErrors', + length: result.contents.length, + elapsedMilliseconds: watch.elapsedMilliseconds, + ), + ), + ); + } catch (e) { + log(LoggingLevel.warning, 'Error sending analytics event: $e'); + } + return result; }); errorService.errorsStream.listen((_) => updateResource(resource)); unawaited( diff --git a/pkgs/dart_mcp_server/lib/src/server.dart b/pkgs/dart_mcp_server/lib/src/server.dart index 52afa5f6..0cddc4f0 100644 --- a/pkgs/dart_mcp_server/lib/src/server.dart +++ b/pkgs/dart_mcp_server/lib/src/server.dart @@ -2,11 +2,14 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'dart:async'; + import 'package:dart_mcp/server.dart'; import 'package:file/file.dart'; import 'package:file/local.dart'; import 'package:meta/meta.dart'; import 'package:process/process.dart'; +import 'package:unified_analytics/unified_analytics.dart'; import 'mixins/analyzer.dart'; import 'mixins/dash_cli.dart'; @@ -14,6 +17,7 @@ import 'mixins/dtd.dart'; import 'mixins/pub.dart'; import 'mixins/pub_dev_search.dart'; import 'mixins/roots_fallback_support.dart'; +import 'utils/analytics.dart'; import 'utils/file_system.dart'; import 'utils/process_manager.dart'; import 'utils/sdk.dart'; @@ -31,17 +35,22 @@ final class DartMCPServer extends MCPServer PubSupport, PubDevSupport, DartToolingDaemonSupport - implements ProcessManagerSupport, FileSystemSupport, SdkSupport { + implements + AnalyticsSupport, + ProcessManagerSupport, + FileSystemSupport, + SdkSupport { DartMCPServer( super.channel, { required this.sdk, + this.analytics, @visibleForTesting this.processManager = const LocalProcessManager(), @visibleForTesting this.fileSystem = const LocalFileSystem(), this.forceRootsFallback = false, }) : super.fromStreamChannel( implementation: ServerImplementation( name: 'dart and flutter tooling', - version: '0.1.0-wip', + version: '0.1.0', ), instructions: 'This server helps to connect Dart and Flutter developers to ' @@ -61,4 +70,63 @@ final class DartMCPServer extends MCPServer @override final Sdk sdk; + + @override + final Analytics? analytics; + + /// Only safe to call after [initialize]. + @override + ClientImplementation get clientInfo => _clientInfo; + + /// Assigned in [initialize]. + late final ClientImplementation _clientInfo; + + @override + FutureOr initialize(InitializeRequest request) { + _clientInfo = request.clientInfo; + return super.initialize(request); + } + + @override + /// Automatically logs all tool calls via analytics by wrapping the [impl], + /// if [analytics] is not `null`. + void registerTool( + Tool tool, + FutureOr Function(CallToolRequest) impl, + ) { + // For type promotion. + final analytics = this.analytics; + + super.registerTool( + tool, + analytics == null + ? impl + : (CallToolRequest request) async { + final watch = Stopwatch()..start(); + CallToolResult? result; + try { + return result = await impl(request); + } finally { + watch.stop(); + try { + analytics.send( + Event.dartMCPEvent( + client: clientInfo.name, + clientVersion: clientInfo.version, + serverVersion: implementation.version, + type: AnalyticsEvent.callTool.name, + additionalData: CallToolMetrics( + tool: request.name, + success: result != null && result.isError != true, + elapsedMilliseconds: watch.elapsedMilliseconds, + ), + ), + ); + } catch (e) { + log(LoggingLevel.warning, 'Error sending analytics event: $e'); + } + } + }, + ); + } } diff --git a/pkgs/dart_mcp_server/lib/src/utils/analytics.dart b/pkgs/dart_mcp_server/lib/src/utils/analytics.dart new file mode 100644 index 00000000..3e81a8d5 --- /dev/null +++ b/pkgs/dart_mcp_server/lib/src/utils/analytics.dart @@ -0,0 +1,72 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:dart_mcp/server.dart'; +import 'package:unified_analytics/unified_analytics.dart'; + +/// An interface class that provides a access to an [Analytics] instance, if +/// enabled. +/// +/// Also provides a [clientInfo] getter which is required for analytics +/// requests. +/// +/// The `DartMCPServer` class implements this class so that [Analytics] +/// methods can be easily mocked during testing. +abstract interface class AnalyticsSupport { + Analytics? get analytics; + + ClientImplementation get clientInfo; +} + +enum AnalyticsEvent { callTool, readResource } + +final class ReadResourceMetrics extends CustomMetrics { + /// The kind of resource that was read. + /// + /// We don't want to record the full URI. + final String kind; + + /// The length of the resource. + final int length; + + /// The time it took to read the resource. + final int elapsedMilliseconds; + + ReadResourceMetrics({ + required this.kind, + required this.length, + required this.elapsedMilliseconds, + }); + + @override + Map toMap() => { + 'kind': 'runtimeErrors', + 'length': length, + 'elapsedMilliseconds': elapsedMilliseconds, + }; +} + +final class CallToolMetrics extends CustomMetrics { + /// The name of the tool that was invoked. + final String tool; + + /// Whether or not the tool call succeeded. + final bool success; + + /// The time it took to invoke the tool. + final int elapsedMilliseconds; + + CallToolMetrics({ + required this.tool, + required this.success, + required this.elapsedMilliseconds, + }); + + @override + Map toMap() => { + 'tool': tool, + 'success': success, + 'elapsedMilliseconds': elapsedMilliseconds, + }; +} diff --git a/pkgs/dart_mcp_server/pubspec.yaml b/pkgs/dart_mcp_server/pubspec.yaml index b560d110..52f48829 100644 --- a/pkgs/dart_mcp_server/pubspec.yaml +++ b/pkgs/dart_mcp_server/pubspec.yaml @@ -2,7 +2,6 @@ name: dart_mcp_server description: >- An MCP server for Dart projects, exposing various developer tools to AI models. - publish_to: none environment: @@ -33,6 +32,7 @@ dependencies: pool: ^1.5.1 process: ^5.0.3 stream_channel: ^2.1.4 + unified_analytics: ^8.0.1 vm_service: ^15.0.0 watcher: ^1.1.1 yaml: ^3.1.3 @@ -46,3 +46,8 @@ dev_dependencies: dependency_overrides: dart_mcp: path: ../dart_mcp + unified_analytics: + git: + url: https://github.com/jakemac53/tools.git + ref: mcp-server-events + path: pkgs/unified_analytics diff --git a/pkgs/dart_mcp_server/test/dart_tooling_mcp_server_test.dart b/pkgs/dart_mcp_server/test/dart_tooling_mcp_server_test.dart index caa0443d..8b992694 100644 --- a/pkgs/dart_mcp_server/test/dart_tooling_mcp_server_test.dart +++ b/pkgs/dart_mcp_server/test/dart_tooling_mcp_server_test.dart @@ -1,7 +1,91 @@ // Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:dart_mcp/server.dart'; +import 'package:dart_mcp_server/src/server.dart'; +import 'package:test/test.dart'; +import 'package:unified_analytics/testing.dart'; +import 'package:unified_analytics/unified_analytics.dart'; + +import 'test_harness.dart'; + void main() { - // TODO: write tests for any Dart Tooling MCP Server functionality that is - // not covered by individual feature tests. + late TestHarness testHarness; + late DartMCPServer server; + late FakeAnalytics analytics; + + setUp(() async { + testHarness = await TestHarness.start(inProcess: true); + server = testHarness.serverConnectionPair.server!; + analytics = server.analytics as FakeAnalytics; + }); + + test('sends analytics for successful tool calls', () async { + server.registerTool( + Tool(name: 'hello', inputSchema: Schema.object()), + (_) => CallToolResult(content: [Content.text(text: 'world')]), + ); + final result = await testHarness.callToolWithRetry( + CallToolRequest(name: 'hello'), + ); + expect((result.content.single as TextContent).text, 'world'); + expect( + analytics.sentEvents.single, + isA() + .having((e) => e.eventName, 'eventName', DashEvent.dartMCPEvent) + .having( + (e) => e.eventData, + 'eventData', + equals({ + 'client': server.clientInfo.name, + 'clientVersion': server.clientInfo.version, + 'serverVersion': server.implementation.version, + 'type': 'callTool', + 'tool': 'hello', + 'success': true, + 'elapsedMilliseconds': isA(), + }), + ), + ); + }); + + test('sends analytics for failed tool calls', () async { + server.registerTool( + Tool(name: 'hello', inputSchema: Schema.object()), + (_) => CallToolResult(isError: true, content: []), + ); + final result = await testHarness.mcpServerConnection.callTool( + CallToolRequest(name: 'hello'), + ); + expect(result.isError, true); + expect( + analytics.sentEvents.single, + isA() + .having((e) => e.eventName, 'eventName', DashEvent.dartMCPEvent) + .having( + (e) => e.eventData, + 'eventData', + equals({ + 'client': server.clientInfo.name, + 'clientVersion': server.clientInfo.version, + 'serverVersion': server.implementation.version, + 'type': 'callTool', + 'tool': 'hello', + 'success': false, + 'elapsedMilliseconds': isA(), + }), + ), + ); + }); + + test('Changelog version matches dart server version', () { + final changelogFile = File('CHANGELOG.md'); + expect( + changelogFile.readAsLinesSync().first.split(' ')[1], + testHarness.serverConnectionPair.server!.implementation.version, + ); + }); } diff --git a/pkgs/dart_mcp_server/test/test_harness.dart b/pkgs/dart_mcp_server/test/test_harness.dart index 6e9f5772..d52e9ad7 100644 --- a/pkgs/dart_mcp_server/test/test_harness.dart +++ b/pkgs/dart_mcp_server/test/test_harness.dart @@ -16,11 +16,13 @@ import 'package:dart_mcp_server/src/utils/sdk.dart'; import 'package:dtd/dtd.dart'; import 'package:file/file.dart'; import 'package:file/local.dart'; +import 'package:file/memory.dart'; import 'package:path/path.dart' as p; import 'package:process/process.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart'; import 'package:test_process/test_process.dart'; +import 'package:unified_analytics/unified_analytics.dart'; /// A full environment for integration testing the MCP server. /// @@ -408,11 +410,32 @@ Future _initializeMCPServer( clientController.stream, serverController.sink, ); + final analyticsFileSystem = MemoryFileSystem(); + final analyticsHomeDir = analyticsFileSystem.directory('home'); + late Analytics analytics; + // Need to create it twice, for the first run analytics are never sent. + for (var i = 0; i < 2; i++) { + analytics = Analytics.fake( + tool: DashTool.dartTool, + dartVersion: Platform.version.substring( + 0, + Platform.version.indexOf(' '), + ), + fs: analyticsFileSystem, + homeDirectory: analyticsHomeDir, + toolsMessageVersion: -2, // Required or else analytics are disabled + ); + } + // Required to enable telemetry + analytics.clientShowedMessage(); + expect(analytics.okToSend, true); + server = DartMCPServer( serverChannel, processManager: TestProcessManager(), fileSystem: fileSystem, sdk: sdk, + analytics: analytics, ); addTearDown(server.shutdown); connection = client.connectServer(clientChannel); diff --git a/pkgs/dart_mcp_server/test/tools/dtd_test.dart b/pkgs/dart_mcp_server/test/tools/dtd_test.dart index ba07aa82..08d974cb 100644 --- a/pkgs/dart_mcp_server/test/tools/dtd_test.dart +++ b/pkgs/dart_mcp_server/test/tools/dtd_test.dart @@ -9,8 +9,11 @@ import 'dart:io'; import 'package:async/async.dart'; import 'package:dart_mcp/server.dart'; import 'package:dart_mcp_server/src/mixins/dtd.dart'; +import 'package:dart_mcp_server/src/server.dart'; import 'package:dart_mcp_server/src/utils/constants.dart'; import 'package:test/test.dart'; +import 'package:unified_analytics/testing.dart'; +import 'package:unified_analytics/unified_analytics.dart' as ua; import 'package:vm_service/vm_service.dart'; import '../test_harness.dart'; @@ -148,6 +151,8 @@ void main() { }); group('[in process]', () { + late ua.FakeAnalytics analytics; + late DartMCPServer server; setUp(() async { DartToolingDaemonSupport.debugAwaitVmServiceDisposal = true; addTearDown( @@ -155,6 +160,8 @@ void main() { ); testHarness = await TestHarness.start(inProcess: true); + server = testHarness.serverConnectionPair.server!; + analytics = server.analytics! as ua.FakeAnalytics; await testHarness.connectToDtd(); }); @@ -480,6 +487,31 @@ void main() { ReadResourceRequest(uri: resource.uri), )).contents; expect(finalContents, isEmpty); + + expect( + analytics.sentEvents, + contains( + isA() + .having( + (e) => e.eventName, + 'eventName', + DashEvent.dartMCPEvent, + ) + .having( + (e) => e.eventData, + 'eventData', + equals({ + 'client': server.clientInfo.name, + 'clientVersion': server.clientInfo.version, + 'serverVersion': server.implementation.version, + 'type': 'readResource', + 'kind': 'runtimeErrors', + 'length': isA(), + 'elapsedMilliseconds': isA(), + }), + ), + ), + ); }, onPlatform: { 'windows': const Skip('https://github.com/dart-lang/ai/issues/151'), From 01fbfcddd08fa5aa66bc97cba247dd86b2c9c669 Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Wed, 18 Jun 2025 17:59:50 +0000 Subject: [PATCH 2/5] use the shared clientInfo field --- pkgs/dart_mcp_server/lib/src/server.dart | 13 ------------- pkgs/dart_mcp_server/lib/src/utils/analytics.dart | 6 ------ 2 files changed, 19 deletions(-) diff --git a/pkgs/dart_mcp_server/lib/src/server.dart b/pkgs/dart_mcp_server/lib/src/server.dart index 3820d011..2979db45 100644 --- a/pkgs/dart_mcp_server/lib/src/server.dart +++ b/pkgs/dart_mcp_server/lib/src/server.dart @@ -75,19 +75,6 @@ final class DartMCPServer extends MCPServer @override final Analytics? analytics; - /// Only safe to call after [initialize]. - @override - ClientImplementation get clientInfo => _clientInfo; - - /// Assigned in [initialize]. - late final ClientImplementation _clientInfo; - - @override - FutureOr initialize(InitializeRequest request) { - _clientInfo = request.clientInfo; - return super.initialize(request); - } - @override /// Automatically logs all tool calls via analytics by wrapping the [impl], /// if [analytics] is not `null`. diff --git a/pkgs/dart_mcp_server/lib/src/utils/analytics.dart b/pkgs/dart_mcp_server/lib/src/utils/analytics.dart index 3e81a8d5..5b6ab61d 100644 --- a/pkgs/dart_mcp_server/lib/src/utils/analytics.dart +++ b/pkgs/dart_mcp_server/lib/src/utils/analytics.dart @@ -2,21 +2,15 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:dart_mcp/server.dart'; import 'package:unified_analytics/unified_analytics.dart'; /// An interface class that provides a access to an [Analytics] instance, if /// enabled. /// -/// Also provides a [clientInfo] getter which is required for analytics -/// requests. -/// /// The `DartMCPServer` class implements this class so that [Analytics] /// methods can be easily mocked during testing. abstract interface class AnalyticsSupport { Analytics? get analytics; - - ClientImplementation get clientInfo; } enum AnalyticsEvent { callTool, readResource } From 7445996070cce7f8b5e0ed223bb3101860a2d086 Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Wed, 18 Jun 2025 20:33:18 +0000 Subject: [PATCH 3/5] code review updates --- pkgs/dart_mcp_server/lib/src/mixins/dtd.dart | 2 +- .../lib/src/utils/analytics.dart | 24 +++++++++++++------ pkgs/dart_mcp_server/test/tools/dtd_test.dart | 3 ++- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/pkgs/dart_mcp_server/lib/src/mixins/dtd.dart b/pkgs/dart_mcp_server/lib/src/mixins/dtd.dart index 1a8a8071..9dcb180f 100644 --- a/pkgs/dart_mcp_server/lib/src/mixins/dtd.dart +++ b/pkgs/dart_mcp_server/lib/src/mixins/dtd.dart @@ -134,7 +134,7 @@ base mixin DartToolingDaemonSupport serverVersion: implementation.version, type: AnalyticsEvent.readResource.name, additionalData: ReadResourceMetrics( - kind: 'runtimeErrors', + kind: ResourceKind.runtimeErrors, length: result.contents.length, elapsedMilliseconds: watch.elapsedMilliseconds, ), diff --git a/pkgs/dart_mcp_server/lib/src/utils/analytics.dart b/pkgs/dart_mcp_server/lib/src/utils/analytics.dart index 5b6ab61d..9c71dd9a 100644 --- a/pkgs/dart_mcp_server/lib/src/utils/analytics.dart +++ b/pkgs/dart_mcp_server/lib/src/utils/analytics.dart @@ -15,11 +15,12 @@ abstract interface class AnalyticsSupport { enum AnalyticsEvent { callTool, readResource } +/// The metrics for a resources/read MCP handler. final class ReadResourceMetrics extends CustomMetrics { /// The kind of resource that was read. /// /// We don't want to record the full URI. - final String kind; + final ResourceKind kind; /// The length of the resource. final int length; @@ -35,12 +36,13 @@ final class ReadResourceMetrics extends CustomMetrics { @override Map toMap() => { - 'kind': 'runtimeErrors', - 'length': length, - 'elapsedMilliseconds': elapsedMilliseconds, + _kind: kind.name, + _length: length, + _elapsedMilliseconds: elapsedMilliseconds, }; } +/// The metrics for a tools/call MCP handler. final class CallToolMetrics extends CustomMetrics { /// The name of the tool that was invoked. final String tool; @@ -59,8 +61,16 @@ final class CallToolMetrics extends CustomMetrics { @override Map toMap() => { - 'tool': tool, - 'success': success, - 'elapsedMilliseconds': elapsedMilliseconds, + _tool: tool, + _success: success, + _elapsedMilliseconds: elapsedMilliseconds, }; } + +enum ResourceKind { runtimeErrors } + +const _elapsedMilliseconds = 'elapsedMilliseconds'; +const _kind = 'kind'; +const _length = 'length'; +const _success = 'success'; +const _tool = 'tool'; diff --git a/pkgs/dart_mcp_server/test/tools/dtd_test.dart b/pkgs/dart_mcp_server/test/tools/dtd_test.dart index 08d974cb..713fd1a2 100644 --- a/pkgs/dart_mcp_server/test/tools/dtd_test.dart +++ b/pkgs/dart_mcp_server/test/tools/dtd_test.dart @@ -10,6 +10,7 @@ import 'package:async/async.dart'; import 'package:dart_mcp/server.dart'; import 'package:dart_mcp_server/src/mixins/dtd.dart'; import 'package:dart_mcp_server/src/server.dart'; +import 'package:dart_mcp_server/src/utils/analytics.dart'; import 'package:dart_mcp_server/src/utils/constants.dart'; import 'package:test/test.dart'; import 'package:unified_analytics/testing.dart'; @@ -505,7 +506,7 @@ void main() { 'clientVersion': server.clientInfo.version, 'serverVersion': server.implementation.version, 'type': 'readResource', - 'kind': 'runtimeErrors', + 'kind': ResourceKind.runtimeErrors.name, 'length': isA(), 'elapsedMilliseconds': isA(), }), From cb4a27c64e3d24f5db48d3353ab45af747e8a010 Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Tue, 24 Jun 2025 17:38:06 +0000 Subject: [PATCH 4/5] use the published unified_analytics --- pkgs/dart_mcp_server/pubspec.yaml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pkgs/dart_mcp_server/pubspec.yaml b/pkgs/dart_mcp_server/pubspec.yaml index d55a15fe..b78cbf73 100644 --- a/pkgs/dart_mcp_server/pubspec.yaml +++ b/pkgs/dart_mcp_server/pubspec.yaml @@ -32,7 +32,7 @@ dependencies: pool: ^1.5.1 process: ^5.0.3 stream_channel: ^2.1.4 - unified_analytics: ^8.0.1 + unified_analytics: ^8.0.2 vm_service: ^15.0.0 watcher: ^1.1.1 web_socket: ^1.0.1 @@ -47,8 +47,3 @@ dev_dependencies: dependency_overrides: dart_mcp: path: ../dart_mcp - unified_analytics: - git: - url: https://github.com/jakemac53/tools.git - ref: mcp-server-events - path: pkgs/unified_analytics From b41395a3c2553a60a9206df1e10897d5bc4748c3 Mon Sep 17 00:00:00 2001 From: Jake Macdonald Date: Tue, 24 Jun 2025 18:08:31 +0000 Subject: [PATCH 5/5] skip flaky logs test --- pkgs/dart_mcp_server/test/dart_tooling_mcp_server_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/dart_mcp_server/test/dart_tooling_mcp_server_test.dart b/pkgs/dart_mcp_server/test/dart_tooling_mcp_server_test.dart index 2857be0a..606be7fd 100644 --- a/pkgs/dart_mcp_server/test/dart_tooling_mcp_server_test.dart +++ b/pkgs/dart_mcp_server/test/dart_tooling_mcp_server_test.dart @@ -123,7 +123,7 @@ void main() { // Wait for the process to release the file. await doWithRetries(() => File(logDescriptor.io.path).delete()); - }); + }, skip: 'https://github.com/dart-lang/ai/issues/181'); }); }