Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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.

# 0.1.1 (Dart SDK 3.10.0)

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