flutterflow-mcp 0.1.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.
Files changed (83) hide show
  1. package/README.md +124 -0
  2. package/build/api/flutterflow.d.ts +11 -0
  3. package/build/api/flutterflow.js +61 -0
  4. package/build/index.d.ts +2 -0
  5. package/build/index.js +54 -0
  6. package/build/prompts/dev-workflow.d.ts +2 -0
  7. package/build/prompts/dev-workflow.js +68 -0
  8. package/build/prompts/generate-page.d.ts +2 -0
  9. package/build/prompts/generate-page.js +36 -0
  10. package/build/prompts/inspect-project.d.ts +2 -0
  11. package/build/prompts/inspect-project.js +30 -0
  12. package/build/prompts/modify-component.d.ts +2 -0
  13. package/build/prompts/modify-component.js +39 -0
  14. package/build/resources/docs.d.ts +2 -0
  15. package/build/resources/docs.js +76 -0
  16. package/build/resources/projects.d.ts +3 -0
  17. package/build/resources/projects.js +60 -0
  18. package/build/tools/find-component-usages.d.ts +7 -0
  19. package/build/tools/find-component-usages.js +225 -0
  20. package/build/tools/find-page-navigations.d.ts +7 -0
  21. package/build/tools/find-page-navigations.js +228 -0
  22. package/build/tools/get-component-summary.d.ts +22 -0
  23. package/build/tools/get-component-summary.js +193 -0
  24. package/build/tools/get-page-by-name.d.ts +3 -0
  25. package/build/tools/get-page-by-name.js +56 -0
  26. package/build/tools/get-page-summary.d.ts +22 -0
  27. package/build/tools/get-page-summary.js +220 -0
  28. package/build/tools/get-yaml-docs.d.ts +6 -0
  29. package/build/tools/get-yaml-docs.js +217 -0
  30. package/build/tools/get-yaml.d.ts +3 -0
  31. package/build/tools/get-yaml.js +47 -0
  32. package/build/tools/list-files.d.ts +3 -0
  33. package/build/tools/list-files.js +30 -0
  34. package/build/tools/list-pages.d.ts +25 -0
  35. package/build/tools/list-pages.js +101 -0
  36. package/build/tools/list-projects.d.ts +3 -0
  37. package/build/tools/list-projects.js +19 -0
  38. package/build/tools/sync-project.d.ts +3 -0
  39. package/build/tools/sync-project.js +144 -0
  40. package/build/tools/update-yaml.d.ts +3 -0
  41. package/build/tools/update-yaml.js +24 -0
  42. package/build/tools/validate-yaml.d.ts +3 -0
  43. package/build/tools/validate-yaml.js +22 -0
  44. package/build/utils/cache.d.ts +48 -0
  45. package/build/utils/cache.js +162 -0
  46. package/build/utils/decode-yaml.d.ts +7 -0
  47. package/build/utils/decode-yaml.js +31 -0
  48. package/build/utils/page-summary/action-summarizer.d.ts +9 -0
  49. package/build/utils/page-summary/action-summarizer.js +291 -0
  50. package/build/utils/page-summary/formatter.d.ts +13 -0
  51. package/build/utils/page-summary/formatter.js +121 -0
  52. package/build/utils/page-summary/node-extractor.d.ts +17 -0
  53. package/build/utils/page-summary/node-extractor.js +207 -0
  54. package/build/utils/page-summary/tree-walker.d.ts +6 -0
  55. package/build/utils/page-summary/tree-walker.js +55 -0
  56. package/build/utils/page-summary/types.d.ts +56 -0
  57. package/build/utils/page-summary/types.js +4 -0
  58. package/build/utils/parse-folders.d.ts +9 -0
  59. package/build/utils/parse-folders.js +29 -0
  60. package/docs/ff-yaml/00-overview.md +137 -0
  61. package/docs/ff-yaml/01-project-files.md +513 -0
  62. package/docs/ff-yaml/02-pages.md +572 -0
  63. package/docs/ff-yaml/03-components.md +413 -0
  64. package/docs/ff-yaml/04-widgets/README.md +122 -0
  65. package/docs/ff-yaml/04-widgets/button.md +444 -0
  66. package/docs/ff-yaml/04-widgets/container.md +358 -0
  67. package/docs/ff-yaml/04-widgets/dropdown.md +579 -0
  68. package/docs/ff-yaml/04-widgets/form.md +256 -0
  69. package/docs/ff-yaml/04-widgets/image.md +276 -0
  70. package/docs/ff-yaml/04-widgets/layout.md +355 -0
  71. package/docs/ff-yaml/04-widgets/misc.md +553 -0
  72. package/docs/ff-yaml/04-widgets/text-field.md +326 -0
  73. package/docs/ff-yaml/04-widgets/text.md +302 -0
  74. package/docs/ff-yaml/05-actions.md +843 -0
  75. package/docs/ff-yaml/06-variables.md +834 -0
  76. package/docs/ff-yaml/07-data.md +591 -0
  77. package/docs/ff-yaml/08-custom-code.md +715 -0
  78. package/docs/ff-yaml/09-theming.md +592 -0
  79. package/docs/ff-yaml/10-editing-guide.md +454 -0
  80. package/docs/ff-yaml/README.md +105 -0
  81. package/package.json +55 -0
  82. package/skills/ff-widget-patterns.md +141 -0
  83. package/skills/ff-yaml-dev.md +58 -0
@@ -0,0 +1,454 @@
1
+ # 10 - Editing FlutterFlow via MCP API
2
+
3
+ How to use the MCP tools to read, inspect, modify, and push FlutterFlow YAML. This covers the complete workflow from syncing a project to pushing widget changes, including critical rules for adding new widgets.
4
+
5
+ ---
6
+
7
+ ## 1. Reading Workflow
8
+
9
+ ### Step 1: Sync the project to local cache
10
+
11
+ Download all YAML files for fast offline reads. Run this once per project.
12
+
13
+ ```
14
+ sync_project(projectId)
15
+ ```
16
+
17
+ This creates a local cache at `.ff-cache/<projectId>/` containing every YAML file in the project. To force a re-sync (e.g., after making changes in the FlutterFlow UI):
18
+
19
+ ```
20
+ sync_project(projectId, force: true)
21
+ ```
22
+
23
+ ### Step 2: Get quick summaries from cache
24
+
25
+ Use cache-based tools for fast overviews -- no API calls needed.
26
+
27
+ ```
28
+ get_page_summary(projectId, pageName: "Welcome")
29
+ ```
30
+
31
+ Returns: widget tree structure, actions (with triggers), page parameters, page state variables, and disabled action indicators.
32
+
33
+ ```
34
+ get_component_summary(projectId, componentName: "PhoneSignInComponent")
35
+ ```
36
+
37
+ Returns: component widget tree, parameters, and actions.
38
+
39
+ ### Step 3: Find navigation flow and component usage
40
+
41
+ ```
42
+ find_page_navigations(projectId, pageName: "PaywallPage")
43
+ ```
44
+
45
+ Returns: all actions across the project that navigate to the specified page, including the source page, trigger type, disabled status, and any passed parameters.
46
+
47
+ ```
48
+ find_component_usages(projectId, componentName: "MyComponent")
49
+ ```
50
+
51
+ Returns: every page and component where `MyComponent` is embedded, with parameter pass details.
52
+
53
+ ### Step 4: Fetch specific YAML for detailed reading
54
+
55
+ For full page YAML (name, widget tree, class model):
56
+
57
+ ```
58
+ get_page_by_name(projectId, "Welcome")
59
+ ```
60
+
61
+ For a specific file by key (node-level widget, config file, component):
62
+
63
+ ```
64
+ get_project_yaml(projectId, "page/id-Scaffold_XXX/page-widget-tree-outline/node/id-Button_YYY")
65
+ ```
66
+
67
+ ### Reading tool selection guide
68
+
69
+ | Goal | Tool | API Calls? |
70
+ |------|------|------------|
71
+ | Quick page overview | `get_page_summary` | No (cache) |
72
+ | Quick component overview | `get_component_summary` | No (cache) |
73
+ | Find where a component is used | `find_component_usages` | No (cache) |
74
+ | Find navigation sources | `find_page_navigations` | No (cache) |
75
+ | Full page YAML by name | `get_page_by_name` | Yes |
76
+ | Specific node/config YAML | `get_project_yaml` | Yes |
77
+ | List all pages with names | `list_pages` | Yes |
78
+ | List all file keys | `list_project_files` | Yes |
79
+
80
+ ---
81
+
82
+ ## 2. Editing Workflow
83
+
84
+ ### The standard edit cycle
85
+
86
+ ```
87
+ Read --> Modify --> Validate --> Push
88
+ ```
89
+
90
+ ### Step 1: Read the current YAML
91
+
92
+ Fetch the **node-level** file for the widget you want to edit (not the full page):
93
+
94
+ ```
95
+ get_project_yaml(projectId, "page/id-Scaffold_7o6kzmdm/page-widget-tree-outline/node/id-Button_7c3kwr61")
96
+ ```
97
+
98
+ To find the widget key, first fetch the full page via `get_page_by_name`, locate the widget in the tree, and note its `key` field (e.g., `Button_7c3kwr61`).
99
+
100
+ ### Step 2: Modify the YAML
101
+
102
+ Change the values you need. **Critical rule:** always update BOTH `inputValue` AND `mostRecentInputValue` to the same value.
103
+
104
+ ```yaml
105
+ # CORRECT
106
+ textValue:
107
+ inputValue: New Label
108
+ mostRecentInputValue: New Label
109
+
110
+ # WRONG -- will cause sync issues in FlutterFlow
111
+ textValue:
112
+ inputValue: New Label
113
+ mostRecentInputValue: Old Label
114
+ ```
115
+
116
+ ### Step 3: Validate before pushing
117
+
118
+ ```
119
+ validate_yaml(projectId, fileKey, modifiedYaml)
120
+ ```
121
+
122
+ This returns `{ success: true }` or a list of validation errors. Always validate before pushing.
123
+
124
+ ### Step 4: Push the changes
125
+
126
+ ```
127
+ update_project_yaml(projectId, { fileKey: modifiedYaml })
128
+ ```
129
+
130
+ Returns `{ success: true }` on success.
131
+
132
+ ### Complete edit example
133
+
134
+ **Task:** Change a button label from "Old Text" to "New Text" on the Welcome page.
135
+
136
+ ```
137
+ Step 1: list_pages(projectId)
138
+ --> Find Welcome page: scaffoldId = Scaffold_7o6kzmdm
139
+
140
+ Step 2: get_page_by_name(projectId, "Welcome")
141
+ --> Read full page YAML, find the button widget
142
+ --> Button key: Button_7c3kwr61
143
+
144
+ Step 3: get_project_yaml(projectId,
145
+ "page/id-Scaffold_7o6kzmdm/page-widget-tree-outline/node/id-Button_7c3kwr61")
146
+ --> Get fresh node-level YAML for just the button
147
+
148
+ Step 4: Modify the YAML -- change textValue.inputValue AND mostRecentInputValue
149
+
150
+ Step 5: validate_yaml(projectId, fileKey, modifiedYaml)
151
+ --> Confirm { success: true }
152
+
153
+ Step 6: update_project_yaml(projectId, { fileKey: modifiedYaml })
154
+ --> Confirm { success: true }
155
+ ```
156
+
157
+ ---
158
+
159
+ ## 3. Adding Widgets (CRITICAL)
160
+
161
+ Adding new widgets to a page is the most error-prone operation. The full page YAML file (`page/id-Scaffold_XXX`) only stores page metadata -- the server **strips any inline children**. You MUST push widgets as individual node-level files.
162
+
163
+ ### Required files for adding widgets
164
+
165
+ You need to push **three types of files** in a **single** `update_project_yaml` call:
166
+
167
+ | File | Key Pattern | Purpose |
168
+ |------|-------------|---------|
169
+ | Widget tree outline | `page/id-Scaffold_XXX/page-widget-tree-outline` | Defines the tree structure (which children belong to which parent) |
170
+ | Parent node | `page/id-Scaffold_XXX/page-widget-tree-outline/node/id-Column_YYY` | The container widget (Column, Row, Stack, etc.) |
171
+ | Each child node | `page/id-Scaffold_XXX/page-widget-tree-outline/node/id-Widget_ZZZ` | Individual widget YAML with full props |
172
+
173
+ ### File key pattern breakdown
174
+
175
+ ```
176
+ page/id-{ScaffoldKey} # Page metadata
177
+ page/id-{ScaffoldKey}/page-widget-tree-outline # Tree structure
178
+ page/id-{ScaffoldKey}/page-widget-tree-outline/node/id-{WidgetKey} # Individual widget node
179
+ ```
180
+
181
+ ### Step-by-step example
182
+
183
+ **Task:** Add a Text widget and Button to the "testing" page (Scaffold_tjgkshke, body Column_gjy4w42f).
184
+
185
+ **File 1 -- Widget tree outline:**
186
+ ```yaml
187
+ # File key: page/id-Scaffold_tjgkshke/page-widget-tree-outline
188
+ node:
189
+ key: Scaffold_tjgkshke
190
+ body:
191
+ key: Column_gjy4w42f
192
+ children:
193
+ - key: Text_mytext01
194
+ - key: Button_mybtn01
195
+ ```
196
+
197
+ **File 2 -- Text widget node:**
198
+ ```yaml
199
+ # File key: page/id-Scaffold_tjgkshke/page-widget-tree-outline/node/id-Text_mytext01
200
+ key: Text_mytext01
201
+ type: Text
202
+ props:
203
+ text:
204
+ fontFamily: Open Sans
205
+ themeStyle: BODY_MEDIUM
206
+ isCustomFont: false
207
+ selectable: false
208
+ textValue:
209
+ inputValue: Hello World
210
+ fontSizeValue:
211
+ inputValue: 24
212
+ colorValue:
213
+ inputValue:
214
+ themeColor: PRIMARY_TEXT
215
+ fontWeightValue:
216
+ inputValue: w700
217
+ responsiveVisibility: {}
218
+ opacity:
219
+ opacityValue:
220
+ inputValue: 1
221
+ mostRecentInputValue: 1
222
+ name: myText
223
+ parameterValues: {}
224
+ valueKey: {}
225
+ ```
226
+
227
+ **File 3 -- Button widget node:**
228
+ ```yaml
229
+ # File key: page/id-Scaffold_tjgkshke/page-widget-tree-outline/node/id-Button_mybtn01
230
+ key: Button_mybtn01
231
+ type: Button
232
+ props:
233
+ button:
234
+ text:
235
+ themeStyle: TITLE_SMALL
236
+ textValue:
237
+ inputValue: Click Me
238
+ mostRecentInputValue: Click Me
239
+ colorValue:
240
+ inputValue:
241
+ themeColor: PRIMARY_BACKGROUND
242
+ fontWeightValue:
243
+ inputValue: w700
244
+ borderRadius:
245
+ type: FF_BORDER_RADIUS_ALL
246
+ allValue:
247
+ inputValue: 40
248
+ mostRecentInputValue: 40
249
+ dimensions:
250
+ width:
251
+ pixelsValue:
252
+ inputValue: Infinity
253
+ mostRecentInputValue: Infinity
254
+ height:
255
+ pixelsValue:
256
+ inputValue: 48
257
+ elevationValue:
258
+ inputValue: 0
259
+ mostRecentInputValue: 0
260
+ fillColorValue:
261
+ inputValue:
262
+ themeColor: PRIMARY
263
+ responsiveVisibility: {}
264
+ opacity:
265
+ opacityValue:
266
+ inputValue: 1
267
+ mostRecentInputValue: 1
268
+ parameterValues: {}
269
+ valueKey: {}
270
+ ```
271
+
272
+ **Push all files in one call:**
273
+ ```
274
+ update_project_yaml(projectId, {
275
+ "page/id-Scaffold_tjgkshke/page-widget-tree-outline": treeOutlineYaml,
276
+ "page/id-Scaffold_tjgkshke/page-widget-tree-outline/node/id-Column_gjy4w42f": columnNodeYaml,
277
+ "page/id-Scaffold_tjgkshke/page-widget-tree-outline/node/id-Text_mytext01": textNodeYaml,
278
+ "page/id-Scaffold_tjgkshke/page-widget-tree-outline/node/id-Button_mybtn01": buttonNodeYaml
279
+ })
280
+ ```
281
+
282
+ ### Validation tip
283
+
284
+ Validate the tree outline first. It reports `"File is referenced but is empty"` for missing node files, telling you exactly which node files you still need to create.
285
+
286
+ ---
287
+
288
+ ## 4. Common Validation Errors
289
+
290
+ | Error | Cause | Fix |
291
+ |-------|-------|-----|
292
+ | `"Unknown field name 'X'"` | Invalid YAML field name for this widget type | Check the widget YAML reference. Field names are specific to each widget type (e.g., `text:` not `textValue:` at the widget props level). |
293
+ | `"Unknown enum value"` | Invalid enum constant (wrong case, typo, or unsupported value) | Use exact enum values: `BODY_MEDIUM`, `ALIGN_CENTER`, `w700`, `FF_PADDING_ALL`, etc. |
294
+ | `"File is referenced but is empty"` | The widget tree outline references a node key, but no node file exists for it | Create the missing node file with that key and push it alongside the tree outline. |
295
+ | `"Duplicate key"` | Two nodes in the tree have the same key | Generate a unique key for each widget (format: `Type_randomchars`, e.g., `Button_abc12345`). |
296
+ | Buffer/size error | Page YAML is too large to fetch or decode | Use node-level sub-files instead of fetching the full page. |
297
+
298
+ ---
299
+
300
+ ## 5. Anti-Patterns (Things That Do NOT Work)
301
+
302
+ ### Embedding widget children in full page YAML
303
+
304
+ The full page file (`page/id-Scaffold_XXX`) only stores page metadata. The FlutterFlow server strips any inline children from this file. You MUST push widgets as individual node files.
305
+
306
+ ```
307
+ BAD: Push children inside page/id-Scaffold_XXX
308
+ GOOD: Push each widget as page/id-Scaffold_XXX/page-widget-tree-outline/node/id-Widget_ZZZ
309
+ ```
310
+
311
+ ### Using shell commands to construct YAML
312
+
313
+ Shell escaping (especially with newlines, quotes, and special characters) will corrupt the YAML. The MCP tools handle JSON serialization automatically.
314
+
315
+ ```
316
+ BAD: echo "key: value\ntype: Button" | some_command
317
+ GOOD: Pass YAML as a normal multi-line string directly to MCP tools
318
+ ```
319
+
320
+ ### Forgetting to sync inputValue and mostRecentInputValue
321
+
322
+ Every value field in FlutterFlow YAML has two copies. If they diverge, the FlutterFlow editor will show inconsistent state and may overwrite your changes.
323
+
324
+ ```yaml
325
+ # BAD -- values out of sync
326
+ textValue:
327
+ inputValue: New Text
328
+ mostRecentInputValue: Old Text
329
+
330
+ # GOOD -- always identical
331
+ textValue:
332
+ inputValue: New Text
333
+ mostRecentInputValue: New Text
334
+ ```
335
+
336
+ ### Fetching all YAML without a fileName
337
+
338
+ Calling `get_project_yaml` without specifying a `fileName` downloads the entire project. This can exceed buffer/transport limits on large projects and is almost never what you want.
339
+
340
+ ```
341
+ BAD: get_project_yaml(projectId) # Downloads everything
342
+ GOOD: get_project_yaml(projectId, "theme.yaml") # Downloads one file
343
+ ```
344
+
345
+ ### Using list_project_files to find pages
346
+
347
+ `list_project_files` returns raw file keys, which are scaffold IDs with no human-readable names. Use `list_pages` instead -- it returns page names, scaffold IDs, and folder assignments.
348
+
349
+ ```
350
+ BAD: list_project_files(projectId) # Returns raw keys like "page/id-Scaffold_abc123"
351
+ GOOD: list_pages(projectId) # Returns { name: "Welcome", scaffoldId: "Scaffold_abc123", folder: "Auth" }
352
+ ```
353
+
354
+ ### Editing full page YAML for a single widget change
355
+
356
+ Fetching and re-pushing the full page YAML risks overwriting concurrent changes and is unnecessarily slow. Use node-level file keys for targeted edits.
357
+
358
+ ```
359
+ BAD: get_project_yaml(projectId, "page/id-Scaffold_XXX") # Full page
360
+ GOOD: get_project_yaml(projectId, "page/id-Scaffold_XXX/page-widget-tree-outline/node/id-Button_YYY") # Just the button
361
+ ```
362
+
363
+ ### Pushing without validating
364
+
365
+ Always call `validate_yaml` before `update_project_yaml`. Pushing invalid YAML can corrupt the page state in FlutterFlow.
366
+
367
+ ---
368
+
369
+ ## 6. YAML Content Formatting
370
+
371
+ When passing YAML content to `validate_yaml` and `update_project_yaml`:
372
+
373
+ - Pass YAML as a **normal multi-line string**
374
+ - Do NOT escape newlines as literal `\n` characters
375
+ - Do NOT use shell commands to construct YAML
376
+ - The MCP SDK handles JSON serialization automatically
377
+
378
+ ---
379
+
380
+ ## 7. Tool Reference Summary
381
+
382
+ ### Discovery tools
383
+
384
+ | Tool | Input | Output |
385
+ |------|-------|--------|
386
+ | `list_projects` | (none) | All projects with IDs |
387
+ | `list_pages` | `projectId` | Pages with names, scaffold IDs, folders |
388
+ | `list_project_files` | `projectId` | All raw file keys (rarely needed) |
389
+
390
+ ### Cache tools (require `sync_project` first)
391
+
392
+ | Tool | Input | Output |
393
+ |------|-------|--------|
394
+ | `sync_project` | `projectId`, optional `force` | Downloads all YAML to local cache |
395
+ | `get_page_summary` | `projectId`, `pageName` or `scaffoldId` | Widget tree, actions, params, state |
396
+ | `get_component_summary` | `projectId`, `componentName` or `componentId` | Widget tree, params, actions |
397
+ | `find_component_usages` | `projectId`, `componentName` or `componentId` | All pages/components using the component |
398
+ | `find_page_navigations` | `projectId`, `pageName` or `scaffoldId` | All navigate actions targeting the page |
399
+
400
+ ### Read tools (API calls)
401
+
402
+ | Tool | Input | Output |
403
+ |------|-------|--------|
404
+ | `get_page_by_name` | `projectId`, `pageName` | Full page YAML resolved by name |
405
+ | `get_project_yaml` | `projectId`, `fileName` | Any YAML file by key |
406
+
407
+ ### Write tools (API calls)
408
+
409
+ | Tool | Input | Output |
410
+ |------|-------|--------|
411
+ | `validate_yaml` | `projectId`, `fileKey`, `fileContent` | Validation result |
412
+ | `update_project_yaml` | `projectId`, `fileKeyToContent` (map) | Push result |
413
+
414
+ ---
415
+
416
+ ## 8. Recommended Workflow Patterns
417
+
418
+ ### Inspecting a project for the first time
419
+
420
+ ```
421
+ list_projects
422
+ --> sync_project(projectId)
423
+ --> get_page_summary(projectId, pageName: "HomePage")
424
+ --> get_component_summary(projectId, componentName: "NavBar")
425
+ ```
426
+
427
+ ### Editing an existing widget
428
+
429
+ ```
430
+ list_pages(projectId)
431
+ --> get_page_by_name(projectId, "PageName")
432
+ --> get_project_yaml(projectId, "page/id-Scaffold_XXX/.../node/id-Widget_YYY")
433
+ --> [modify YAML]
434
+ --> validate_yaml(projectId, fileKey, yaml)
435
+ --> update_project_yaml(projectId, { fileKey: yaml })
436
+ ```
437
+
438
+ ### Adding new widgets to a page
439
+
440
+ ```
441
+ list_pages(projectId)
442
+ --> get_page_by_name(projectId, "PageName")
443
+ --> [construct tree outline + node files]
444
+ --> validate_yaml for each file
445
+ --> update_project_yaml(projectId, { treeOutlineKey: ..., nodeKey1: ..., nodeKey2: ... })
446
+ ```
447
+
448
+ ### Understanding navigation flow
449
+
450
+ ```
451
+ sync_project(projectId)
452
+ --> find_page_navigations(projectId, pageName: "TargetPage")
453
+ --> get_page_summary for each source page
454
+ ```
@@ -0,0 +1,105 @@
1
+ # FlutterFlow YAML Reference for AI Agents
2
+
3
+ A structured reference catalog of FlutterFlow's YAML schema, derived from real production projects. Use this to read, create, and modify FlutterFlow project files programmatically via the MCP API. Each document covers one domain with exact field names, valid enum values, and copy-paste-ready templates.
4
+
5
+ ---
6
+
7
+ ## Which file do I need?
8
+
9
+ | I want to... | Read this |
10
+ |---|---|
11
+ | Understand FF project structure | `00-overview.md` |
12
+ | Read/modify project settings | `01-project-files.md` |
13
+ | Work with pages | `02-pages.md` |
14
+ | Work with components | `03-components.md` |
15
+ | Build/modify a specific widget | `04-widgets/` (see index inside) |
16
+ | Add/modify action chains | `05-actions.md` |
17
+ | Bind dynamic data to widgets | `06-variables.md` |
18
+ | Define data models | `07-data.md` |
19
+ | Write custom Dart code | `08-custom-code.md` |
20
+ | Customize colors/fonts | `09-theming.md` |
21
+ | Push changes via MCP API | `10-editing-guide.md` |
22
+
23
+ ---
24
+
25
+ ## Universal patterns
26
+
27
+ These four patterns appear across all FlutterFlow YAML files. Internalize them before reading any other document.
28
+
29
+ ### 1. `inputValue` / `mostRecentInputValue` sync
30
+
31
+ Every settable value uses a dual-field pattern. **Both fields must always contain the same value.** Failing to sync them causes silent data corruption in the FlutterFlow editor.
32
+
33
+ ```yaml
34
+ # Correct
35
+ textValue:
36
+ inputValue: Hello World
37
+ mostRecentInputValue: Hello World
38
+
39
+ # Wrong -- will cause sync issues
40
+ textValue:
41
+ inputValue: Hello World
42
+ mostRecentInputValue: Old Value
43
+ ```
44
+
45
+ This applies to most value types: text, color, numeric, boolean, enum, icon, dimension, opacity, border radius, padding, and alignment values.
46
+
47
+ **Exceptions — fields that only accept `inputValue`:**
48
+ - `fontWeightValue` — does NOT support `mostRecentInputValue`
49
+ - `fontSizeValue` — does NOT support `mostRecentInputValue`
50
+
51
+ Adding `mostRecentInputValue` to these fields will cause a validation error (`Unknown field name 'mostRecentInputValue'`). When in doubt, check the field reference table for the specific widget.
52
+
53
+ ### 2. `identifier: { name, key }` pattern
54
+
55
+ Named entities (params, state fields, data types, components) are referenced via an identifier block:
56
+
57
+ ```yaml
58
+ identifier:
59
+ name: userName # Human-readable name
60
+ key: Parameter_abc123 # Unique machine key
61
+ ```
62
+
63
+ When creating new identifiers, generate a unique key using the pattern `<Type>_<8 alphanumeric chars>` (e.g., `Parameter_k7m2x9p1`).
64
+
65
+ ### 3. Theme color references
66
+
67
+ Colors can be literal ARGB or theme references. Theme references use a fixed set of token names:
68
+
69
+ ```yaml
70
+ # Theme reference (preferred)
71
+ colorValue:
72
+ inputValue:
73
+ themeColor: PRIMARY
74
+ mostRecentInputValue:
75
+ themeColor: PRIMARY
76
+
77
+ # Literal ARGB (decimal string)
78
+ colorValue:
79
+ inputValue:
80
+ value: "4294940319"
81
+ mostRecentInputValue:
82
+ value: "4294940319"
83
+ ```
84
+
85
+ **Valid `themeColor` tokens:** `PRIMARY`, `SECONDARY`, `TERTIARY`, `ALTERNATE`, `PRIMARY_TEXT`, `SECONDARY_TEXT`, `PRIMARY_BACKGROUND`, `SECONDARY_BACKGROUND`, `ACCENT1`, `ACCENT2`, `ACCENT3`, `ACCENT4`, `SUCCESS`, `WARNING`, `ERROR`, `INFO`.
86
+
87
+ ### 4. File key naming
88
+
89
+ File keys map directly to API endpoints. The naming convention encodes hierarchy:
90
+
91
+ ```
92
+ page/id-Scaffold_XXX # Page metadata
93
+ page/id-Scaffold_XXX/page-widget-tree-outline # Widget tree structure
94
+ page/id-Scaffold_XXX/page-widget-tree-outline/node/id-Widget_YYY # Individual widget node
95
+ component/id-Container_XXX # Component metadata
96
+ component/id-Container_XXX/component-widget-tree-outline # Component widget tree
97
+ api-endpoint/id-XXX # API endpoint
98
+ custom-actions/id-XXX # Custom action
99
+ ```
100
+
101
+ Rules:
102
+ - Keys use `/` as separator, never `\`
103
+ - IDs are prefixed with `id-`
104
+ - Page scaffolds use `Scaffold_` prefix; components use `Container_` prefix
105
+ - Widget nodes use type-specific prefixes: `Text_`, `Button_`, `Column_`, `Row_`, `Container_`, `Image_`, `Icon_`, `TextField_`, etc.
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "flutterflow-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for the FlutterFlow Project API — AI-assisted FlutterFlow development through Claude and other MCP-compatible clients",
5
+ "type": "module",
6
+ "main": "build/index.js",
7
+ "bin": {
8
+ "flutterflow-mcp": "build/index.js"
9
+ },
10
+ "files": [
11
+ "build",
12
+ "docs/ff-yaml",
13
+ "skills"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc && chmod 755 build/index.js",
17
+ "dev": "tsc --watch",
18
+ "start": "node build/index.js",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "keywords": [
22
+ "mcp",
23
+ "flutterflow",
24
+ "model-context-protocol",
25
+ "ai",
26
+ "claude",
27
+ "yaml",
28
+ "no-code",
29
+ "low-code"
30
+ ],
31
+ "author": "mohn93",
32
+ "license": "MIT",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/mohn93/ff-mcp.git"
36
+ },
37
+ "homepage": "https://github.com/mohn93/ff-mcp#readme",
38
+ "bugs": {
39
+ "url": "https://github.com/mohn93/ff-mcp/issues"
40
+ },
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
44
+ "dependencies": {
45
+ "@modelcontextprotocol/sdk": "^1.26.0",
46
+ "adm-zip": "^0.5.16",
47
+ "yaml": "^2.8.2",
48
+ "zod": "^4.3.6"
49
+ },
50
+ "devDependencies": {
51
+ "@types/adm-zip": "^0.5.7",
52
+ "@types/node": "^25.2.3",
53
+ "typescript": "^5.9.3"
54
+ }
55
+ }