Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkgs/dart_mcp_server/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Add `--tools=dart|all` argument to allow enabling only vanilla Dart tools for
non-flutter projects.
- Include the device name and target platform in the list_devices tool.
- Fix analyze tool handling of invalid roots.
- Fix erroneous SDK version error messages when connecting to a VM Service
instead of DTD URI.

Expand Down
4 changes: 2 additions & 2 deletions pkgs/dart_mcp_server/lib/src/mixins/analyzer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ base mixin DartAnalyzerSupport
fileSystem: fileSystem,
);

if (validated.errorResult != null) {
return errorResult!;
if (validated.errorResult case final error?) {
return error;
}

final rootUri = Uri.parse(validated.root!.uri);
Expand Down
39 changes: 39 additions & 0 deletions pkgs/dart_mcp_server/test/tools/analyzer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,45 @@ void main() {
);
});

test('handles invalid roots list', () async {
// We still need a root registered with the server so that the
// prerequisites check passes.
final example = d.dir('example', [
d.file('main.dart', 'void main() => 1;'),
]);
await example.create();
final exampleRoot = testHarness.rootForPath(example.io.path);
testHarness.mcpClient.addRoot(exampleRoot);
await pumpEventQueue();

final request = CallToolRequest(
name: analyzeTool.name,
arguments: {
ParameterNames.roots: [
{'root': 'file:///invalid/root'},
],
},
);
final result = await testHarness.callToolWithRetry(
request,
expectError: true,
);
expect(result.isError, isTrue);
expect(
result.content.single,
isA<TextContent>().having(
(t) => t.text,
'text',
allOf(
contains(
'Invalid root file:///invalid/root, must be under one of the registered project roots:',
),
contains(example.io.uri.toString()),
),
),
);
});

test('can analyze files in multiple roots', () async {
final projectA = d.dir('project_a', [
d.file('main.dart', 'void main() => 1 + "a";'),
Expand Down
Loading