feat(dart_mcp_server): add HTTP network inspection tools#422
feat(dart_mcp_server): add HTTP network inspection tools#422ThangVuNguyenViet wants to merge 10 commits intodart-lang:mainfrom
Conversation
- Auto-enable HTTP profiling on all isolates when VM service connects - Implement get_network_logs, clear_network_logs, get_network_request tools - Register tools in initialize() and add to allTools static list
…ameters experiment
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
jakemac53
left a comment
There was a problem hiding this comment.
Awesome, this is a great start! 🚀 🥳
One higher level comment is that we are moving to a pattern of "meta tools" generally in order to save on tool counts (and tokens). To be consistent with that please migrate these all to a single "network" tool, with a "command" argument. See the DTD tool as an example.
| description: | ||
| 'Fetches recorded HTTP requests from the running app. ' | ||
| 'HTTP profiling is enabled automatically when the app connects, so ' | ||
| 'requests are captured from app start. Use updatedSince to poll only ' |
There was a problem hiding this comment.
nit: logs are not actually captured from app start, they are only captured once we connect.
I think we actually should have an explicit tool call though to start capturing logs, and also to stop capturing them. Otherwise I think we will implicitly have a bit of a memory leak here?
| late TestHarness testHarness; | ||
|
|
||
| group('network inspector tools', () { | ||
| group('[in-process]', () { |
There was a problem hiding this comment.
nit: I would just make all these tests uses an in process test harness - we really only need a few total tests that use an out of process MCP server, and its much easier to debug when its in process
| @@ -0,0 +1,698 @@ | |||
| # Network Inspector Implementation Plan | |||
There was a problem hiding this comment.
nit: Please remove these docs from the PR :)
| @@ -0,0 +1,2 @@ | |||
| enable_experiment: | |||
There was a problem hiding this comment.
nit: we should not be enabling experiments in any code we land here, even for tests
| models. | ||
| publish_to: none | ||
| environment: | ||
| sdk: ^3.12.0-257.0.dev |
There was a problem hiding this comment.
This needs to remain at the old constraint - some of our tools do rely on stuff that only exists after this dev release (listing active DTD URIs)
|
|
||
| expect(result.isError, isNot(true)); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
We should add another test fixture that does make network requests, so that we can test that actual network logs can be captured, cleared, etc.
| .toList(); | ||
| return CallToolResult( | ||
| content: [TextContent(text: jsonEncode(requests))], | ||
| structuredContent: {'requests': requests}, |
There was a problem hiding this comment.
nit: I would remove the structured content here unless we need it for something. The text content can already easily just be decoded as JSON if some tooling wants to explicitly do that.
| callback: (vmService) async { | ||
| try { | ||
| final vm = await vmService.getVM(); | ||
| final isolateId = vm.isolates!.first.id!; |
There was a problem hiding this comment.
Above we enable network logging for all isolates, but here we only will return logs for the first one.
Supporting only the root isolate for now is probably fine, but we should also only enable capturing logs for the first isolate then.
We should also file a bug and add a TODO for supporting additional isolates.
| callback: (vmService) async { | ||
| try { | ||
| final vm = await vmService.getVM(); | ||
| final isolateId = vm.isolates!.first.id!; |
There was a problem hiding this comment.
Same here, we should either consistently support all the isolates or only the first one.
PR HealthChangelog Entry ✔️
Changes to files need to be accounted for in their respective changelogs. This check can be disabled by tagging the PR with |
|
I'd like to see how we can share code with the Dart DevTools network inspector here rather than maintain two copies of code that is fetching network requests from the VM service. |
|
Hey sorry. I did not have the intention to open this PR this the first place. I was going to, after I review what Claude did and try the work myself, which I haven't. I was afraid I'm gonna make another AI slop PR so I panicky closed the PR. But really thanks for the comments. I'll address them and reopen the PR once it's done on my end |
|
@ThangVuNguyenViet fwiw this PR is quite reasonable, I wouldn't call it AI slop :D, but in general yes its a good idea to review AI code prior to sending it out. However, I wouldn't have been able to tell this was AI without the planning docs in there 🤣 |
|
@kenzieschmoll lets discuss at the meeting today |
Summary
Implements the network inspection tools proposed in #269.
ext.dart.io.httpEnableTimelineLogging) on every isolate when a VM service connects, so requests are captured from app start with no app-side code changes requiredget_network_logs— fetch recorded HTTP requests, with optionalupdatedSincefor pollingclear_network_logs— reset the HTTP profile bufferget_network_request— fetch full detail (headers + body) for a single request by IDnetworkInspectorfeature category (child ofdartToolingDaemon), disabled by default — opt in via--enable=networkInspectorUses
ext.dart.io.*extensions registered by the Dart runtime itself for anydart:ioapp in debug mode.Closes #269 (partial — web/CDP transport not included in this PR)
Test plan
dart test --enable-experiment=private-named-parameters test/tools/network_inspector_test.dart --name "in-process"^3.12.0-257.0.dev)flutter run+--enable=networkInspectorflagNotes
dart_test.yamlwithenable_experiment: [private-named-parameters]added to allow running tests locally with Dart stable SDK during development; this can be removed once the repo targets a released SDKchore: relax SDK constraintcommit is for local development only and should be reverted before merge