flutter-skill-mcp 0.2.0

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/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # flutter-skill-mcp
2
+
3
+ > MCP Server for Flutter app automation - Give your AI Agent eyes and hands inside your Flutter app
4
+
5
+ [![npm version](https://badge.fury.io/js/flutter-skill-mcp.svg)](https://www.npmjs.com/package/flutter-skill-mcp)
6
+ [![pub version](https://img.shields.io/pub/v/flutter_skill.svg)](https://pub.dev/packages/flutter_skill)
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install -g flutter-skill-mcp
12
+ # or use directly with npx
13
+ npx flutter-skill-mcp
14
+ ```
15
+
16
+ **Prerequisites**: [Flutter SDK](https://docs.flutter.dev/get-started/install) or [Dart SDK](https://dart.dev/get-dart)
17
+
18
+ ## MCP Configuration
19
+
20
+ Add to your MCP config (Cursor, Windsurf, Claude Desktop):
21
+
22
+ ```json
23
+ {
24
+ "flutter-skill": {
25
+ "command": "npx",
26
+ "args": ["flutter-skill-mcp"]
27
+ }
28
+ }
29
+ ```
30
+
31
+ Or if installed globally:
32
+
33
+ ```json
34
+ {
35
+ "flutter-skill": {
36
+ "command": "flutter-skill-mcp"
37
+ }
38
+ }
39
+ ```
40
+
41
+ ## Features
42
+
43
+ - **UI Inspection**: Widget tree, text content, element properties
44
+ - **Interactions**: Tap, double tap, long press, swipe, drag, scroll
45
+ - **State Validation**: Text values, checkbox state, wait for elements
46
+ - **Screenshots**: Full app or specific elements
47
+ - **Navigation**: Routes, go back, navigation stack
48
+ - **Debug**: Logs, errors, performance metrics
49
+
50
+ ## 25+ MCP Tools
51
+
52
+ | Category | Tools |
53
+ |----------|-------|
54
+ | Connection | `connect_app`, `launch_app` |
55
+ | UI Inspection | `inspect`, `get_widget_tree`, `get_widget_properties`, `get_text_content`, `find_by_type` |
56
+ | Interactions | `tap`, `double_tap`, `long_press`, `swipe`, `drag`, `scroll_to`, `enter_text` |
57
+ | State | `get_text_value`, `get_checkbox_state`, `get_slider_value`, `wait_for_element`, `wait_for_gone` |
58
+ | Screenshot | `screenshot`, `screenshot_element` |
59
+ | Navigation | `get_current_route`, `go_back`, `get_navigation_stack` |
60
+ | Debug | `get_logs`, `get_errors`, `get_performance`, `clear_logs` |
61
+ | Dev | `hot_reload`, `pub_search` |
62
+
63
+ ## Links
64
+
65
+ - [GitHub](https://github.com/ai-dashboad/flutter-skill)
66
+ - [pub.dev](https://pub.dev/packages/flutter_skill)
67
+ - [Documentation](https://github.com/ai-dashboad/flutter-skill#readme)
68
+
69
+ ## License
70
+
71
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const path = require('path');
5
+ const fs = require('fs');
6
+
7
+ // Find the dart directory
8
+ const dartDir = path.join(__dirname, '..', 'dart');
9
+ const serverScript = path.join(dartDir, 'bin', 'server.dart');
10
+
11
+ // Check if Dart is installed
12
+ function checkDart() {
13
+ try {
14
+ require('child_process').execSync('dart --version', { stdio: 'ignore' });
15
+ return true;
16
+ } catch (e) {
17
+ return false;
18
+ }
19
+ }
20
+
21
+ // Check if Flutter is installed
22
+ function checkFlutter() {
23
+ try {
24
+ require('child_process').execSync('flutter --version', { stdio: 'ignore' });
25
+ return true;
26
+ } catch (e) {
27
+ return false;
28
+ }
29
+ }
30
+
31
+ if (!checkDart()) {
32
+ console.error('Error: Dart SDK not found. Please install Flutter/Dart first.');
33
+ console.error(' https://docs.flutter.dev/get-started/install');
34
+ process.exit(1);
35
+ }
36
+
37
+ if (!checkFlutter()) {
38
+ console.error('Warning: Flutter SDK not found. Some features may not work.');
39
+ }
40
+
41
+ // Check if server script exists
42
+ if (!fs.existsSync(serverScript)) {
43
+ console.error('Error: Server script not found at:', serverScript);
44
+ process.exit(1);
45
+ }
46
+
47
+ // Get dependencies first (use flutter pub for Flutter packages)
48
+ const pubCmd = checkFlutter() ? 'flutter' : 'dart';
49
+ const pubGet = spawn(pubCmd, ['pub', 'get'], {
50
+ cwd: dartDir,
51
+ stdio: 'inherit'
52
+ });
53
+
54
+ pubGet.on('close', (code) => {
55
+ if (code !== 0) {
56
+ console.error('Failed to get dependencies');
57
+ process.exit(1);
58
+ }
59
+
60
+ // Start the MCP server
61
+ const server = spawn('dart', ['run', serverScript], {
62
+ cwd: dartDir,
63
+ stdio: 'inherit'
64
+ });
65
+
66
+ server.on('close', (code) => {
67
+ process.exit(code || 0);
68
+ });
69
+
70
+ // Forward signals
71
+ process.on('SIGINT', () => server.kill('SIGINT'));
72
+ process.on('SIGTERM', () => server.kill('SIGTERM'));
73
+ });
@@ -0,0 +1,196 @@
1
+ {
2
+ "configVersion": 2,
3
+ "packages": [
4
+ {
5
+ "name": "async",
6
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/async-2.13.0",
7
+ "packageUri": "lib/",
8
+ "languageVersion": "3.4"
9
+ },
10
+ {
11
+ "name": "boolean_selector",
12
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/boolean_selector-2.1.2",
13
+ "packageUri": "lib/",
14
+ "languageVersion": "3.1"
15
+ },
16
+ {
17
+ "name": "characters",
18
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/characters-1.4.1",
19
+ "packageUri": "lib/",
20
+ "languageVersion": "3.4"
21
+ },
22
+ {
23
+ "name": "clock",
24
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/clock-1.1.2",
25
+ "packageUri": "lib/",
26
+ "languageVersion": "3.4"
27
+ },
28
+ {
29
+ "name": "collection",
30
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/collection-1.19.1",
31
+ "packageUri": "lib/",
32
+ "languageVersion": "3.4"
33
+ },
34
+ {
35
+ "name": "fake_async",
36
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/fake_async-1.3.3",
37
+ "packageUri": "lib/",
38
+ "languageVersion": "3.3"
39
+ },
40
+ {
41
+ "name": "flutter",
42
+ "rootUri": "file:///Users/cw/development/flutter/packages/flutter",
43
+ "packageUri": "lib/",
44
+ "languageVersion": "3.9"
45
+ },
46
+ {
47
+ "name": "flutter_test",
48
+ "rootUri": "file:///Users/cw/development/flutter/packages/flutter_test",
49
+ "packageUri": "lib/",
50
+ "languageVersion": "3.9"
51
+ },
52
+ {
53
+ "name": "http",
54
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/http-1.6.0",
55
+ "packageUri": "lib/",
56
+ "languageVersion": "3.4"
57
+ },
58
+ {
59
+ "name": "http_parser",
60
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/http_parser-4.1.2",
61
+ "packageUri": "lib/",
62
+ "languageVersion": "3.4"
63
+ },
64
+ {
65
+ "name": "leak_tracker",
66
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/leak_tracker-11.0.2",
67
+ "packageUri": "lib/",
68
+ "languageVersion": "3.2"
69
+ },
70
+ {
71
+ "name": "leak_tracker_flutter_testing",
72
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/leak_tracker_flutter_testing-3.0.10",
73
+ "packageUri": "lib/",
74
+ "languageVersion": "3.2"
75
+ },
76
+ {
77
+ "name": "leak_tracker_testing",
78
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/leak_tracker_testing-3.0.2",
79
+ "packageUri": "lib/",
80
+ "languageVersion": "3.2"
81
+ },
82
+ {
83
+ "name": "lints",
84
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/lints-3.0.0",
85
+ "packageUri": "lib/",
86
+ "languageVersion": "3.0"
87
+ },
88
+ {
89
+ "name": "logging",
90
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/logging-1.3.0",
91
+ "packageUri": "lib/",
92
+ "languageVersion": "3.4"
93
+ },
94
+ {
95
+ "name": "matcher",
96
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/matcher-0.12.18",
97
+ "packageUri": "lib/",
98
+ "languageVersion": "3.7"
99
+ },
100
+ {
101
+ "name": "material_color_utilities",
102
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/material_color_utilities-0.13.0",
103
+ "packageUri": "lib/",
104
+ "languageVersion": "3.5"
105
+ },
106
+ {
107
+ "name": "meta",
108
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/meta-1.17.0",
109
+ "packageUri": "lib/",
110
+ "languageVersion": "3.5"
111
+ },
112
+ {
113
+ "name": "path",
114
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/path-1.9.1",
115
+ "packageUri": "lib/",
116
+ "languageVersion": "3.4"
117
+ },
118
+ {
119
+ "name": "sky_engine",
120
+ "rootUri": "file:///Users/cw/development/flutter/bin/cache/pkg/sky_engine",
121
+ "packageUri": "lib/",
122
+ "languageVersion": "3.9"
123
+ },
124
+ {
125
+ "name": "source_span",
126
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/source_span-1.10.1",
127
+ "packageUri": "lib/",
128
+ "languageVersion": "3.1"
129
+ },
130
+ {
131
+ "name": "stack_trace",
132
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/stack_trace-1.12.1",
133
+ "packageUri": "lib/",
134
+ "languageVersion": "3.4"
135
+ },
136
+ {
137
+ "name": "stream_channel",
138
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/stream_channel-2.1.4",
139
+ "packageUri": "lib/",
140
+ "languageVersion": "3.3"
141
+ },
142
+ {
143
+ "name": "string_scanner",
144
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/string_scanner-1.4.1",
145
+ "packageUri": "lib/",
146
+ "languageVersion": "3.1"
147
+ },
148
+ {
149
+ "name": "term_glyph",
150
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/term_glyph-1.2.2",
151
+ "packageUri": "lib/",
152
+ "languageVersion": "3.1"
153
+ },
154
+ {
155
+ "name": "test_api",
156
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/test_api-0.7.8",
157
+ "packageUri": "lib/",
158
+ "languageVersion": "3.7"
159
+ },
160
+ {
161
+ "name": "typed_data",
162
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/typed_data-1.4.0",
163
+ "packageUri": "lib/",
164
+ "languageVersion": "3.5"
165
+ },
166
+ {
167
+ "name": "vector_math",
168
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/vector_math-2.2.0",
169
+ "packageUri": "lib/",
170
+ "languageVersion": "3.1"
171
+ },
172
+ {
173
+ "name": "vm_service",
174
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/vm_service-14.3.1",
175
+ "packageUri": "lib/",
176
+ "languageVersion": "3.3"
177
+ },
178
+ {
179
+ "name": "web",
180
+ "rootUri": "file:///Users/cw/.pub-cache/hosted/pub.flutter-io.cn/web-1.1.1",
181
+ "packageUri": "lib/",
182
+ "languageVersion": "3.4"
183
+ },
184
+ {
185
+ "name": "flutter_skill",
186
+ "rootUri": "../",
187
+ "packageUri": "lib/",
188
+ "languageVersion": "3.0"
189
+ }
190
+ ],
191
+ "generator": "pub",
192
+ "generatorVersion": "3.11.0-296.4.beta",
193
+ "flutterRoot": "file:///Users/cw/development/flutter",
194
+ "flutterVersion": "3.41.0-0.1.pre",
195
+ "pubCache": "file:///Users/cw/.pub-cache"
196
+ }
@@ -0,0 +1,258 @@
1
+ {
2
+ "roots": [
3
+ "flutter_skill"
4
+ ],
5
+ "packages": [
6
+ {
7
+ "name": "flutter_skill",
8
+ "version": "0.2.0",
9
+ "dependencies": [
10
+ "flutter",
11
+ "http",
12
+ "logging",
13
+ "path",
14
+ "vm_service"
15
+ ],
16
+ "devDependencies": [
17
+ "flutter_test",
18
+ "lints"
19
+ ]
20
+ },
21
+ {
22
+ "name": "lints",
23
+ "version": "3.0.0",
24
+ "dependencies": []
25
+ },
26
+ {
27
+ "name": "flutter_test",
28
+ "version": "0.0.0",
29
+ "dependencies": [
30
+ "clock",
31
+ "collection",
32
+ "fake_async",
33
+ "flutter",
34
+ "leak_tracker_flutter_testing",
35
+ "matcher",
36
+ "meta",
37
+ "path",
38
+ "stack_trace",
39
+ "stream_channel",
40
+ "test_api",
41
+ "vector_math"
42
+ ]
43
+ },
44
+ {
45
+ "name": "logging",
46
+ "version": "1.3.0",
47
+ "dependencies": []
48
+ },
49
+ {
50
+ "name": "path",
51
+ "version": "1.9.1",
52
+ "dependencies": []
53
+ },
54
+ {
55
+ "name": "http",
56
+ "version": "1.6.0",
57
+ "dependencies": [
58
+ "async",
59
+ "http_parser",
60
+ "meta",
61
+ "web"
62
+ ]
63
+ },
64
+ {
65
+ "name": "vm_service",
66
+ "version": "14.3.1",
67
+ "dependencies": []
68
+ },
69
+ {
70
+ "name": "flutter",
71
+ "version": "0.0.0",
72
+ "dependencies": [
73
+ "characters",
74
+ "collection",
75
+ "material_color_utilities",
76
+ "meta",
77
+ "sky_engine",
78
+ "vector_math"
79
+ ]
80
+ },
81
+ {
82
+ "name": "stream_channel",
83
+ "version": "2.1.4",
84
+ "dependencies": [
85
+ "async"
86
+ ]
87
+ },
88
+ {
89
+ "name": "meta",
90
+ "version": "1.17.0",
91
+ "dependencies": []
92
+ },
93
+ {
94
+ "name": "collection",
95
+ "version": "1.19.1",
96
+ "dependencies": []
97
+ },
98
+ {
99
+ "name": "leak_tracker_flutter_testing",
100
+ "version": "3.0.10",
101
+ "dependencies": [
102
+ "flutter",
103
+ "leak_tracker",
104
+ "leak_tracker_testing",
105
+ "matcher",
106
+ "meta"
107
+ ]
108
+ },
109
+ {
110
+ "name": "vector_math",
111
+ "version": "2.2.0",
112
+ "dependencies": []
113
+ },
114
+ {
115
+ "name": "stack_trace",
116
+ "version": "1.12.1",
117
+ "dependencies": [
118
+ "path"
119
+ ]
120
+ },
121
+ {
122
+ "name": "clock",
123
+ "version": "1.1.2",
124
+ "dependencies": []
125
+ },
126
+ {
127
+ "name": "fake_async",
128
+ "version": "1.3.3",
129
+ "dependencies": [
130
+ "clock",
131
+ "collection"
132
+ ]
133
+ },
134
+ {
135
+ "name": "matcher",
136
+ "version": "0.12.18",
137
+ "dependencies": [
138
+ "async",
139
+ "meta",
140
+ "stack_trace",
141
+ "term_glyph",
142
+ "test_api"
143
+ ]
144
+ },
145
+ {
146
+ "name": "test_api",
147
+ "version": "0.7.8",
148
+ "dependencies": [
149
+ "async",
150
+ "boolean_selector",
151
+ "collection",
152
+ "meta",
153
+ "source_span",
154
+ "stack_trace",
155
+ "stream_channel",
156
+ "string_scanner",
157
+ "term_glyph"
158
+ ]
159
+ },
160
+ {
161
+ "name": "web",
162
+ "version": "1.1.1",
163
+ "dependencies": []
164
+ },
165
+ {
166
+ "name": "http_parser",
167
+ "version": "4.1.2",
168
+ "dependencies": [
169
+ "collection",
170
+ "source_span",
171
+ "string_scanner",
172
+ "typed_data"
173
+ ]
174
+ },
175
+ {
176
+ "name": "async",
177
+ "version": "2.13.0",
178
+ "dependencies": [
179
+ "collection",
180
+ "meta"
181
+ ]
182
+ },
183
+ {
184
+ "name": "sky_engine",
185
+ "version": "0.0.0",
186
+ "dependencies": []
187
+ },
188
+ {
189
+ "name": "material_color_utilities",
190
+ "version": "0.13.0",
191
+ "dependencies": [
192
+ "collection"
193
+ ]
194
+ },
195
+ {
196
+ "name": "characters",
197
+ "version": "1.4.1",
198
+ "dependencies": []
199
+ },
200
+ {
201
+ "name": "leak_tracker_testing",
202
+ "version": "3.0.2",
203
+ "dependencies": [
204
+ "leak_tracker",
205
+ "matcher",
206
+ "meta"
207
+ ]
208
+ },
209
+ {
210
+ "name": "leak_tracker",
211
+ "version": "11.0.2",
212
+ "dependencies": [
213
+ "clock",
214
+ "collection",
215
+ "meta",
216
+ "path",
217
+ "vm_service"
218
+ ]
219
+ },
220
+ {
221
+ "name": "term_glyph",
222
+ "version": "1.2.2",
223
+ "dependencies": []
224
+ },
225
+ {
226
+ "name": "string_scanner",
227
+ "version": "1.4.1",
228
+ "dependencies": [
229
+ "source_span"
230
+ ]
231
+ },
232
+ {
233
+ "name": "source_span",
234
+ "version": "1.10.1",
235
+ "dependencies": [
236
+ "collection",
237
+ "path",
238
+ "term_glyph"
239
+ ]
240
+ },
241
+ {
242
+ "name": "boolean_selector",
243
+ "version": "2.1.2",
244
+ "dependencies": [
245
+ "source_span",
246
+ "string_scanner"
247
+ ]
248
+ },
249
+ {
250
+ "name": "typed_data",
251
+ "version": "1.4.0",
252
+ "dependencies": [
253
+ "collection"
254
+ ]
255
+ }
256
+ ],
257
+ "configVersion": 1
258
+ }
@@ -0,0 +1 @@
1
+ 3.41.0-0.1.pre
@@ -0,0 +1,3 @@
1
+ import 'package:flutter_skill/src/cli/server.dart';
2
+
3
+ void main(List<String> args) => runServer(args);