flutter-devtools-mcp 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +208 -0
- package/README.zh-CN.md +292 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/services/ai-analysis.d.ts +6 -0
- package/dist/services/ai-analysis.d.ts.map +1 -0
- package/dist/services/ai-analysis.js +728 -0
- package/dist/services/ai-analysis.js.map +1 -0
- package/dist/services/collect-progress.d.ts +6 -0
- package/dist/services/collect-progress.d.ts.map +1 -0
- package/dist/services/collect-progress.js +23 -0
- package/dist/services/collect-progress.js.map +1 -0
- package/dist/services/cpu-profiler-service.d.ts +42 -0
- package/dist/services/cpu-profiler-service.d.ts.map +1 -0
- package/dist/services/cpu-profiler-service.js +208 -0
- package/dist/services/cpu-profiler-service.js.map +1 -0
- package/dist/services/cpu-symbol-filter.d.ts +10 -0
- package/dist/services/cpu-symbol-filter.d.ts.map +1 -0
- package/dist/services/cpu-symbol-filter.js +90 -0
- package/dist/services/cpu-symbol-filter.js.map +1 -0
- package/dist/services/http-profile-parser.d.ts +4 -0
- package/dist/services/http-profile-parser.d.ts.map +1 -0
- package/dist/services/http-profile-parser.js +71 -0
- package/dist/services/http-profile-parser.js.map +1 -0
- package/dist/services/json-parse-aggregate.d.ts +30 -0
- package/dist/services/json-parse-aggregate.d.ts.map +1 -0
- package/dist/services/json-parse-aggregate.js +155 -0
- package/dist/services/json-parse-aggregate.js.map +1 -0
- package/dist/services/network-aggregate.d.ts +50 -0
- package/dist/services/network-aggregate.d.ts.map +1 -0
- package/dist/services/network-aggregate.js +185 -0
- package/dist/services/network-aggregate.js.map +1 -0
- package/dist/services/network-capture-service.d.ts +50 -0
- package/dist/services/network-capture-service.d.ts.map +1 -0
- package/dist/services/network-capture-service.js +187 -0
- package/dist/services/network-capture-service.js.map +1 -0
- package/dist/services/network-capture.d.ts +2 -0
- package/dist/services/network-capture.d.ts.map +1 -0
- package/dist/services/network-capture.js +2 -0
- package/dist/services/network-capture.js.map +1 -0
- package/dist/services/performance-session.d.ts +41 -0
- package/dist/services/performance-session.d.ts.map +1 -0
- package/dist/services/performance-session.js +697 -0
- package/dist/services/performance-session.js.map +1 -0
- package/dist/services/performance-thresholds.d.ts +17 -0
- package/dist/services/performance-thresholds.d.ts.map +1 -0
- package/dist/services/performance-thresholds.js +19 -0
- package/dist/services/performance-thresholds.js.map +1 -0
- package/dist/services/profiler.d.ts +71 -0
- package/dist/services/profiler.d.ts.map +1 -0
- package/dist/services/profiler.js +314 -0
- package/dist/services/profiler.js.map +1 -0
- package/dist/services/rebuild-business-resolver.d.ts +24 -0
- package/dist/services/rebuild-business-resolver.d.ts.map +1 -0
- package/dist/services/rebuild-business-resolver.js +599 -0
- package/dist/services/rebuild-business-resolver.js.map +1 -0
- package/dist/services/rebuild-tracker-service.d.ts +45 -0
- package/dist/services/rebuild-tracker-service.d.ts.map +1 -0
- package/dist/services/rebuild-tracker-service.js +196 -0
- package/dist/services/rebuild-tracker-service.js.map +1 -0
- package/dist/services/session-types.d.ts +240 -0
- package/dist/services/session-types.d.ts.map +1 -0
- package/dist/services/session-types.js +180 -0
- package/dist/services/session-types.js.map +1 -0
- package/dist/services/threshold-alerts.d.ts +49 -0
- package/dist/services/threshold-alerts.d.ts.map +1 -0
- package/dist/services/threshold-alerts.js +258 -0
- package/dist/services/threshold-alerts.js.map +1 -0
- package/dist/services/timeline-cpu-parser.d.ts +28 -0
- package/dist/services/timeline-cpu-parser.d.ts.map +1 -0
- package/dist/services/timeline-cpu-parser.js +174 -0
- package/dist/services/timeline-cpu-parser.js.map +1 -0
- package/dist/services/timeline-extras.d.ts +61 -0
- package/dist/services/timeline-extras.d.ts.map +1 -0
- package/dist/services/timeline-extras.js +449 -0
- package/dist/services/timeline-extras.js.map +1 -0
- package/dist/services/vm-service-client.d.ts +123 -0
- package/dist/services/vm-service-client.d.ts.map +1 -0
- package/dist/services/vm-service-client.js +418 -0
- package/dist/services/vm-service-client.js.map +1 -0
- package/dist/tools/connection.d.ts +4 -0
- package/dist/tools/connection.d.ts.map +1 -0
- package/dist/tools/connection.js +127 -0
- package/dist/tools/connection.js.map +1 -0
- package/dist/tools/debug-actions.d.ts +4 -0
- package/dist/tools/debug-actions.d.ts.map +1 -0
- package/dist/tools/debug-actions.js +210 -0
- package/dist/tools/debug-actions.js.map +1 -0
- package/dist/tools/discover.d.ts +4 -0
- package/dist/tools/discover.d.ts.map +1 -0
- package/dist/tools/discover.js +183 -0
- package/dist/tools/discover.js.map +1 -0
- package/dist/tools/memory.d.ts +4 -0
- package/dist/tools/memory.d.ts.map +1 -0
- package/dist/tools/memory.js +145 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/network.d.ts +4 -0
- package/dist/tools/network.d.ts.map +1 -0
- package/dist/tools/network.js +265 -0
- package/dist/tools/network.js.map +1 -0
- package/dist/tools/performance-session.d.ts +4 -0
- package/dist/tools/performance-session.d.ts.map +1 -0
- package/dist/tools/performance-session.js +105 -0
- package/dist/tools/performance-session.js.map +1 -0
- package/dist/tools/profiling.d.ts +5 -0
- package/dist/tools/profiling.d.ts.map +1 -0
- package/dist/tools/profiling.js +142 -0
- package/dist/tools/profiling.js.map +1 -0
- package/dist/tools/rebuild-tracker.d.ts +4 -0
- package/dist/tools/rebuild-tracker.d.ts.map +1 -0
- package/dist/tools/rebuild-tracker.js +228 -0
- package/dist/tools/rebuild-tracker.js.map +1 -0
- package/dist/tools/snapshot-diff.d.ts +4 -0
- package/dist/tools/snapshot-diff.d.ts.map +1 -0
- package/dist/tools/snapshot-diff.js +235 -0
- package/dist/tools/snapshot-diff.js.map +1 -0
- package/dist/tools/widget-tree.d.ts +4 -0
- package/dist/tools/widget-tree.d.ts.map +1 -0
- package/dist/tools/widget-tree.js +156 -0
- package/dist/tools/widget-tree.js.map +1 -0
- package/docs/README.md +9 -0
- package/docs/performance-audit-requirements.md +403 -0
- package/docs/performance-metrics-guide.md +207 -0
- package/docs/performance-session-simple-design.md +399 -0
- package/examples/app_network_image.dart +242 -0
- package/examples/app_network_image_README.md +51 -0
- package/package.json +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dragan Bajic
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# flutter-devtools-mcp
|
|
2
|
+
|
|
3
|
+
Connect AI agents to running Flutter apps for runtime inspection, profiling, and debugging through the Dart VM Service Protocol.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
┌─────────────────┐ stdio ┌──────────────────────┐ WebSocket ┌─────────────────┐
|
|
7
|
+
│ AI Agent │◄──────────────►│ flutter-devtools-mcp │◄─────────────►│ Flutter App │
|
|
8
|
+
│ (Cursor/Claude) │ │ (MCP Server) │ VM Service │ (debug/profile) │
|
|
9
|
+
└─────────────────┘ └──────────────────────┘ └─────────────────┘
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
[中文文档](./README.zh-CN.md)
|
|
13
|
+
|
|
14
|
+
## 1) Capabilities
|
|
15
|
+
|
|
16
|
+
- Auto-discover and connect to running Flutter apps
|
|
17
|
+
- Inspect widget tree and locate rebuild hotspots with source references
|
|
18
|
+
- Run session-based performance collection (frames, CPU, memory, network)
|
|
19
|
+
- Save and compare memory snapshots
|
|
20
|
+
- Execute debug actions (hot reload/restart, evaluate expression, screenshot)
|
|
21
|
+
|
|
22
|
+
## 2) Quick Start
|
|
23
|
+
|
|
24
|
+
### Prerequisites
|
|
25
|
+
|
|
26
|
+
- Node.js >= 18
|
|
27
|
+
- A Flutter app running in `debug` or `profile` mode (recommended: `profile`)
|
|
28
|
+
|
|
29
|
+
### Install and build
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git clone https://github.com/draganbajic/flutter-devtools-mcp.git
|
|
33
|
+
cd flutter-devtools-mcp
|
|
34
|
+
npm install
|
|
35
|
+
npm run build
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### MCP config examples
|
|
39
|
+
|
|
40
|
+
#### Cursor (`.cursor/mcp.json`)
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"mcpServers": {
|
|
45
|
+
"flutter-devtools": {
|
|
46
|
+
"command": "node",
|
|
47
|
+
"args": ["/path/to/flutter-devtools-mcp/dist/index.js"]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Claude Desktop (`claude_desktop_config.json`)
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": {
|
|
58
|
+
"flutter-devtools": {
|
|
59
|
+
"command": "node",
|
|
60
|
+
"args": ["/path/to/flutter-devtools-mcp/dist/index.js"]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### VS Code / Copilot (`.vscode/mcp.json`)
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"servers": {
|
|
71
|
+
"flutter-devtools": {
|
|
72
|
+
"command": "node",
|
|
73
|
+
"args": ["/path/to/flutter-devtools-mcp/dist/index.js"]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### CodeBuddy (`.codebuddy/mcp.json`)
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"mcpServers": {
|
|
84
|
+
"flutter-devtools": {
|
|
85
|
+
"command": "node",
|
|
86
|
+
"args": ["/path/to/flutter-devtools-mcp/dist/index.js"]
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 3) Recommended Flow: 30s Session Collection
|
|
93
|
+
|
|
94
|
+
Start your app:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
flutter run --profile
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Then ask your AI assistant:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
Connect Flutter app, collect performance data for 30s (scenario: home feed scroll), and provide optimization suggestions based on code.
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The AI calls `collect_performance_session` (blocking for 30s), then reads `filesToInspect` and returns P0/P1/P2 suggestions.
|
|
107
|
+
|
|
108
|
+
Design docs:
|
|
109
|
+
|
|
110
|
+
- Metrics guide: [`docs/performance-metrics-guide.md`](docs/performance-metrics-guide.md)
|
|
111
|
+
- Session design: [`docs/performance-session-simple-design.md`](docs/performance-session-simple-design.md)
|
|
112
|
+
- Doc index: [`docs/README.md`](docs/README.md)
|
|
113
|
+
- Image URL sample: [`examples/app_network_image_README.md`](examples/app_network_image_README.md)
|
|
114
|
+
|
|
115
|
+
## 4) Regression Commands
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Android debug regression
|
|
119
|
+
npm run test:regression:android
|
|
120
|
+
|
|
121
|
+
# Android profile regression (default duration)
|
|
122
|
+
npm run test:regression:android:profile
|
|
123
|
+
|
|
124
|
+
# Android profile regression (30s)
|
|
125
|
+
npm run test:regression:android:profile:30s
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 5) Tool List (22)
|
|
129
|
+
|
|
130
|
+
### Performance Session
|
|
131
|
+
| Tool | Description |
|
|
132
|
+
|------|-------------|
|
|
133
|
+
| `collect_performance_session` | Block for N seconds (default 30), return JSON with frames/rebuilds/CPU/memory/network |
|
|
134
|
+
|
|
135
|
+
### Discovery & Connection
|
|
136
|
+
| Tool | Description |
|
|
137
|
+
|------|-------------|
|
|
138
|
+
| `discover_apps` | Auto-discover and connect to running Flutter apps |
|
|
139
|
+
| `connect` | Connect by VM Service URI |
|
|
140
|
+
| `disconnect` | Disconnect from current app |
|
|
141
|
+
| `get_app_info` | VM / isolate / platform / extension capability info |
|
|
142
|
+
|
|
143
|
+
### Widget Inspection
|
|
144
|
+
| Tool | Description |
|
|
145
|
+
|------|-------------|
|
|
146
|
+
| `get_widget_tree` | Widget hierarchy with source locations and project filtering |
|
|
147
|
+
| `inspect_widget` | Deep inspect widget properties/constraints/render info |
|
|
148
|
+
|
|
149
|
+
### Rebuild Tracking
|
|
150
|
+
| Tool | Description |
|
|
151
|
+
|------|-------------|
|
|
152
|
+
| `start_tracking_rebuilds` | Start rebuild tracking |
|
|
153
|
+
| `stop_tracking_rebuilds` | Rebuild report with counts, source locations, and suggestions |
|
|
154
|
+
|
|
155
|
+
### Performance Profiling
|
|
156
|
+
| Tool | Description |
|
|
157
|
+
|------|-------------|
|
|
158
|
+
| `start_profiling` | Start timeline profiling |
|
|
159
|
+
| `stop_profiling` | Frame/jank/hotspot/build-layout-paint analysis |
|
|
160
|
+
|
|
161
|
+
### Memory Analysis
|
|
162
|
+
| Tool | Description |
|
|
163
|
+
|------|-------------|
|
|
164
|
+
| `get_memory_snapshot` | Heap snapshot with class distribution and suspicious allocations |
|
|
165
|
+
| `save_snapshot` | Save named snapshot |
|
|
166
|
+
| `compare_snapshots` | Compare two snapshots |
|
|
167
|
+
| `list_snapshots` | List saved snapshots |
|
|
168
|
+
|
|
169
|
+
### Network
|
|
170
|
+
| Tool | Description |
|
|
171
|
+
|------|-------------|
|
|
172
|
+
| `start_network_capture` | Start HTTP traffic capture |
|
|
173
|
+
| `stop_network_capture` | URL/status/time/size/error report |
|
|
174
|
+
|
|
175
|
+
### Debug Actions
|
|
176
|
+
| Tool | Description |
|
|
177
|
+
|------|-------------|
|
|
178
|
+
| `hot_reload` | Trigger hot reload |
|
|
179
|
+
| `hot_restart` | Trigger hot restart |
|
|
180
|
+
| `take_screenshot` | Capture screenshot |
|
|
181
|
+
| `toggle_debug_paint` | Toggle debug paint |
|
|
182
|
+
| `evaluate_expression` | Evaluate Dart expression |
|
|
183
|
+
|
|
184
|
+
## 6) Recommendations and Limitations
|
|
185
|
+
|
|
186
|
+
- Prefer `profile` mode for accurate performance metrics: `flutter run --profile`
|
|
187
|
+
- `debug` mode adds overhead; use it for trend checks only
|
|
188
|
+
- Rebuild tracking extension is unavailable in `profile` mode (auto-degraded)
|
|
189
|
+
- Network capture depends on `dart:io` `HttpClient` timeline events
|
|
190
|
+
- `projectTopFunctions` tracks app `lib/` methods; hit rate can be low on Android profile. Use 30~60s collection and active interactions
|
|
191
|
+
- To attribute image decode to a **URL**, use the shared loader sample: [`examples/app_network_image.dart`](./examples/app_network_image.dart) (see [`examples/app_network_image_README.md`](./examples/app_network_image_README.md))
|
|
192
|
+
|
|
193
|
+
## 7) Roadmap
|
|
194
|
+
|
|
195
|
+
- [x] Auto-discover running Flutter apps
|
|
196
|
+
- [x] Widget rebuild tracking with source locations
|
|
197
|
+
- [x] Network traffic inspection
|
|
198
|
+
- [x] Before/after snapshot comparison
|
|
199
|
+
- [x] Session-based performance collection (`collect_performance_session`)
|
|
200
|
+
- [ ] Continuous monitoring mode (real-time jank watcher)
|
|
201
|
+
- [ ] Integration test runner with performance baselines
|
|
202
|
+
- [ ] Shader compilation jank detection
|
|
203
|
+
- [ ] npm publish for `npx flutter-devtools-mcp`
|
|
204
|
+
|
|
205
|
+
## 8) License
|
|
206
|
+
|
|
207
|
+
MIT
|
|
208
|
+
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# flutter-devtools-mcp
|
|
2
|
+
|
|
3
|
+
连接 AI 助手与运行中的 Flutter App(Dart VM Service),让 AI 可以直接做运行时排查、性能采集和调试分析。
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
┌─────────────────┐ stdio ┌──────────────────────┐ WebSocket ┌─────────────────┐
|
|
7
|
+
│ AI Agent │◄──────────────►│ flutter-devtools-mcp │◄─────────────►│ Flutter App │
|
|
8
|
+
│ (Cursor/Claude) │ │ (MCP Server) │ VM Service │ (debug/profile) │
|
|
9
|
+
└─────────────────┘ └──────────────────────┘ └─────────────────┘
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
[English](./README.md)
|
|
13
|
+
|
|
14
|
+
## 1. 你能用它做什么
|
|
15
|
+
|
|
16
|
+
- 自动发现并连接 Flutter 进程(无需手抄 VM URI)
|
|
17
|
+
- 查看 Widget 树、定位重建热点(含源码位置)
|
|
18
|
+
- 采集性能会话(帧、CPU、内存、网络)并输出结构化结果
|
|
19
|
+
- 做快照对比(内存前后变化)
|
|
20
|
+
- 执行调试动作(hot reload/restart、表达式求值、截图等)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## 2. 快速开始
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### 2.1 前置条件
|
|
29
|
+
|
|
30
|
+
- Node.js >= 18
|
|
31
|
+
- Flutter App 运行在 `debug` 或 `profile` 模式(建议 `profile`)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### 2.2 安装与构建
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
git clone https://github.com/draganbajic/flutter-devtools-mcp.git
|
|
39
|
+
cd flutter-devtools-mcp
|
|
40
|
+
npm install
|
|
41
|
+
npm run build
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
### 2.3 MCP 配置
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
#### Cursor (`.cursor/mcp.json`)
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"mcpServers": {
|
|
55
|
+
"flutter-devtools": {
|
|
56
|
+
"command": "node",
|
|
57
|
+
"args": ["/path/to/flutter-devtools-mcp/dist/index.js"]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
#### Claude Desktop (`claude_desktop_config.json`)
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"mcpServers": {
|
|
70
|
+
"flutter-devtools": {
|
|
71
|
+
"command": "node",
|
|
72
|
+
"args": ["/path/to/flutter-devtools-mcp/dist/index.js"]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
#### VS Code / Copilot (`.vscode/mcp.json`)
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"servers": {
|
|
85
|
+
"flutter-devtools": {
|
|
86
|
+
"command": "node",
|
|
87
|
+
"args": ["/path/to/flutter-devtools-mcp/dist/index.js"]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
#### CodeBuddy (`.codebuddy/mcp.json`)
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"mcpServers": {
|
|
100
|
+
"flutter-devtools": {
|
|
101
|
+
"command": "node",
|
|
102
|
+
"args": ["/path/to/flutter-devtools-mcp/dist/index.js"]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
## 3. 推荐主流程:30s 性能会话
|
|
111
|
+
|
|
112
|
+
先启动 App:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
flutter run --profile
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
然后在 AI 中直接说:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
连接 Flutter App,开始采集性能数据 30s,场景:首页滚动,结合代码给优化方案
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
AI 会调用 `collect_performance_session`(阻塞 30s)并返回结构化结果,随后结合 `filesToInspect` 源码给出 P0/P1/P2 优化建议。
|
|
125
|
+
|
|
126
|
+
**文档:**
|
|
127
|
+
|
|
128
|
+
- 指标怎么读(GC / 重建 / 图片解码等):`[docs/performance-metrics-guide.md](docs/performance-metrics-guide.md)`
|
|
129
|
+
- 产品与数据结构:`[docs/performance-session-simple-design.md](docs/performance-session-simple-design.md)`
|
|
130
|
+
- 文档索引:`[docs/README.md](docs/README.md)`
|
|
131
|
+
- 图片 URL 埋点样板:`[examples/app_network_image_README.md](examples/app_network_image_README.md)`
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
## 4. 回归命令
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Android debug 回归
|
|
139
|
+
npm run test:regression:android
|
|
140
|
+
|
|
141
|
+
# Android profile 回归(默认时长)
|
|
142
|
+
npm run test:regression:android:profile
|
|
143
|
+
|
|
144
|
+
# Android profile 回归(30s)
|
|
145
|
+
npm run test:regression:android:profile:30s
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
## 5. 工具清单(22)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
### Performance Session
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
| Tool | Description |
|
|
158
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
159
|
+
| `collect_performance_session` | 阻塞采集 N 秒(默认 30),返回 JSON:帧/jank、耗时函数(Self>20ms 异常)、重建(debug)、GC、滚动FPS、图片解码、Isolate、内存、网络;并生成带「开发者结论」的 `.ai.md` |
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
### Discovery & Connection
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
| Tool | Description |
|
|
168
|
+
| --------------- | --------------------------- |
|
|
169
|
+
| `discover_apps` | 自动发现并连接运行中的 Flutter App |
|
|
170
|
+
| `connect` | 通过 VM Service URI 手动连接 |
|
|
171
|
+
| `disconnect` | 断开连接 |
|
|
172
|
+
| `get_app_info` | 获取 VM / isolate / 平台信息与扩展能力 |
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
### Widget Inspection
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
| Tool | Description |
|
|
181
|
+
| ----------------- | --------------------------- |
|
|
182
|
+
| `get_widget_tree` | 获取 Widget 层级(含源码位置与项目过滤) |
|
|
183
|
+
| `inspect_widget` | 深度查看 widget 属性/约束/render 信息 |
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
### Rebuild Tracking
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
| Tool | Description |
|
|
192
|
+
| ------------------------- | ------------------ |
|
|
193
|
+
| `start_tracking_rebuilds` | 开始追踪重建 |
|
|
194
|
+
| `stop_tracking_rebuilds` | 输出重建报告(次数、源码位置、建议) |
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
### Performance Profiling
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
| Tool | Description |
|
|
203
|
+
| ----------------- | -------------------------------------- |
|
|
204
|
+
| `start_profiling` | 开始 timeline profiling |
|
|
205
|
+
| `stop_profiling` | 输出帧、jank、hotspot、build/layout/paint 分析 |
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
### Memory Analysis
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
| Tool | Description |
|
|
214
|
+
| --------------------- | ---------------- |
|
|
215
|
+
| `get_memory_snapshot` | 获取堆快照(含类分布、疑似异常) |
|
|
216
|
+
| `save_snapshot` | 保存命名快照 |
|
|
217
|
+
| `compare_snapshots` | 对比两个快照差异 |
|
|
218
|
+
| `list_snapshots` | 列出所有快照 |
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
### Network
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
| Tool | Description |
|
|
227
|
+
| ----------------------- | ---------------------- |
|
|
228
|
+
| `start_network_capture` | 开始抓取 HTTP 流量 |
|
|
229
|
+
| `stop_network_capture` | 输出 URL、状态码、耗时、体积、错误等统计 |
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
### Debug Actions
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
| Tool | Description |
|
|
238
|
+
| --------------------- | -------------- |
|
|
239
|
+
| `hot_reload` | 触发 Hot Reload |
|
|
240
|
+
| `hot_restart` | 触发 Hot Restart |
|
|
241
|
+
| `take_screenshot` | 截图 |
|
|
242
|
+
| `toggle_debug_paint` | 切换 Debug Paint |
|
|
243
|
+
| `evaluate_expression` | 执行 Dart 表达式 |
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
## 6. 使用建议与限制
|
|
249
|
+
|
|
250
|
+
- 推荐在 `profile` 模式采集性能数据:`flutter run --profile`
|
|
251
|
+
- `debug` 有额外检查开销,性能数据仅供趋势参考
|
|
252
|
+
- `profile` 下不支持 Widget 重建追踪扩展(会自动降级)
|
|
253
|
+
- 网络采集基于 `dart:io` `HttpClient` timeline 事件,部分第三方实现可能无法完整采集
|
|
254
|
+
- `projectTopFunctions` 为业务 `lib/` 方法列表,Android profile 下命中率可能偏低,建议 30~60s 并持续业务交互
|
|
255
|
+
- 图片解码若要带 **URL/尺寸**,请业务侧使用统一入口样板:`[examples/app_network_image.dart](./examples/app_network_image.dart)`(说明见 `[examples/app_network_image_README.md](./examples/app_network_image_README.md)`)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
## 7. 路线图
|
|
260
|
+
|
|
261
|
+
- [x] 自动发现并连接运行中的 Flutter 应用
|
|
262
|
+
- [x] 支持带源码位置的 Widget 重建追踪
|
|
263
|
+
- [x] 支持网络流量检查
|
|
264
|
+
- [x] 支持前后快照对比
|
|
265
|
+
- [x] 支持会话式性能采集(`collect_performance_session`)
|
|
266
|
+
- [ ] 持续监控模式(实时卡顿监视)
|
|
267
|
+
- [ ] 集成测试运行器(含性能基线对比)
|
|
268
|
+
- [ ] Shader 编译卡顿检测
|
|
269
|
+
- [x] 发布到 npm(支持 `npx flutter-devtools-mcp`)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
## 8. 发版(GitHub Actions → npm)
|
|
274
|
+
|
|
275
|
+
1. 仓库 Settings → Secrets and variables → Actions,新增 **`NPM_TOKEN`**([npm Access Tokens](https://www.npmjs.com/settings/~/tokens) 选 Automation)
|
|
276
|
+
2. 改版本并提交:
|
|
277
|
+
```bash
|
|
278
|
+
cd flutter-devtools-mcp
|
|
279
|
+
npm version patch # 0.3.0 → 0.3.1,会改 package.json 并打 git tag
|
|
280
|
+
git push origin main --tags
|
|
281
|
+
```
|
|
282
|
+
3. GitHub → **Releases** → Draft a new release,Tag 选刚推的 `v0.3.1` → Publish
|
|
283
|
+
→ 自动跑 [`.github/workflows/publish-npm.yml`](../.github/workflows/publish-npm.yml) 发布到 npmjs.com
|
|
284
|
+
也可在 Actions 里对 **Publish npm** 点 Run workflow 手动触发。
|
|
285
|
+
|
|
286
|
+
> Tag 版本(去掉前缀 `v`)必须与 `package.json` 的 `version` 一致。
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
## 9. License
|
|
291
|
+
|
|
292
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { FlutterVmServiceClient } from "./services/vm-service-client.js";
|
|
5
|
+
import { Profiler } from "./services/profiler.js";
|
|
6
|
+
import { registerConnectionTools } from "./tools/connection.js";
|
|
7
|
+
import { registerWidgetTreeTools } from "./tools/widget-tree.js";
|
|
8
|
+
import { registerProfilingTools } from "./tools/profiling.js";
|
|
9
|
+
import { registerMemoryTools } from "./tools/memory.js";
|
|
10
|
+
import { registerDebugActionTools } from "./tools/debug-actions.js";
|
|
11
|
+
import { registerRebuildTrackerTools } from "./tools/rebuild-tracker.js";
|
|
12
|
+
import { registerDiscoverTools } from "./tools/discover.js";
|
|
13
|
+
import { registerNetworkTools } from "./tools/network.js";
|
|
14
|
+
import { registerSnapshotDiffTools } from "./tools/snapshot-diff.js";
|
|
15
|
+
import { RebuildTrackerService } from "./services/rebuild-tracker-service.js";
|
|
16
|
+
import { NetworkCaptureService } from "./services/network-capture-service.js";
|
|
17
|
+
import { CpuProfilerService } from "./services/cpu-profiler-service.js";
|
|
18
|
+
import { PerformanceSession } from "./services/performance-session.js";
|
|
19
|
+
import { registerPerformanceSessionTools } from "./tools/performance-session.js";
|
|
20
|
+
const server = new McpServer({
|
|
21
|
+
name: "flutter-devtools-mcp",
|
|
22
|
+
version: "0.3.0",
|
|
23
|
+
});
|
|
24
|
+
const vmClient = new FlutterVmServiceClient();
|
|
25
|
+
const profiler = new Profiler(vmClient);
|
|
26
|
+
const rebuildTracker = new RebuildTrackerService(vmClient);
|
|
27
|
+
const networkCapture = new NetworkCaptureService(vmClient);
|
|
28
|
+
const cpuProfiler = new CpuProfilerService(vmClient);
|
|
29
|
+
const performanceSession = new PerformanceSession(vmClient, profiler, rebuildTracker, networkCapture, cpuProfiler);
|
|
30
|
+
registerDiscoverTools(server, vmClient);
|
|
31
|
+
registerConnectionTools(server, vmClient);
|
|
32
|
+
registerWidgetTreeTools(server, vmClient);
|
|
33
|
+
registerProfilingTools(server, vmClient, profiler);
|
|
34
|
+
registerMemoryTools(server, vmClient);
|
|
35
|
+
registerRebuildTrackerTools(server, vmClient);
|
|
36
|
+
registerNetworkTools(server, vmClient);
|
|
37
|
+
registerSnapshotDiffTools(server, vmClient);
|
|
38
|
+
registerDebugActionTools(server, vmClient);
|
|
39
|
+
registerPerformanceSessionTools(server, performanceSession);
|
|
40
|
+
vmClient.on("error", (err) => {
|
|
41
|
+
console.error("[flutter-devtools-mcp] VM Service error:", err);
|
|
42
|
+
});
|
|
43
|
+
vmClient.on("disconnected", () => {
|
|
44
|
+
console.error("[flutter-devtools-mcp] Disconnected from Flutter app VM Service");
|
|
45
|
+
});
|
|
46
|
+
async function main() {
|
|
47
|
+
const transport = new StdioServerTransport();
|
|
48
|
+
await server.connect(transport);
|
|
49
|
+
console.error("[flutter-devtools-mcp] Server started on stdio transport");
|
|
50
|
+
}
|
|
51
|
+
main().catch((err) => {
|
|
52
|
+
console.error("[flutter-devtools-mcp] Fatal error:", err);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type PerformanceSessionResult } from "./session-types.js";
|
|
2
|
+
export interface AiAnalysisOptions {
|
|
3
|
+
projectRoot?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function generateAiAnalysis(result: PerformanceSessionResult, options?: AiAnalysisOptions): Promise<string>;
|
|
6
|
+
//# sourceMappingURL=ai-analysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-analysis.d.ts","sourceRoot":"","sources":["../../src/services/ai-analysis.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,oBAAoB,CAAC;AAkB5B,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA2cD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,EAChC,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,MAAM,CAAC,CA8ZjB"}
|