11 KiB
| name | description |
|---|---|
| flutterflow-designer | Use when building Flutter UI screens in FlutterFlow. Triggers include "build UI in FlutterFlow", "create screens in FlutterFlow", "design app in FlutterFlow", "FlutterFlow automation", "orbit", or when the user wants to visually design and export Flutter screens. Uses the FlutterFlow AI Designer for rapid screen generation, FF Orbit MCP for programmatic refinement, and Chrome browser automation for interaction. |
FlutterFlow Designer — AI Designer + Orbit MCP + Browser Automation Skill
Build production Flutter screens in FlutterFlow using three complementary interfaces:
- FlutterFlow AI Designer (primary) — Prompt-based AI tool at
https://designer.flutterflow.io/dashboardthat generates complete app screens from text descriptions. Fastest way to create multiple screens at once. - FF Orbit MCP (secondary) — Programmatic API with 70+ commands for pages, widgets, themes, routes, and changesets. Use for precise refinement after AI generation.
- Chrome Browser Automation (tertiary) — Visual verification, previewing, and manual operations via
mcp__claude-in-chrome__*tools.
Prerequisites
Required: Chrome Browser with Claude-in-Chrome Extension
The FlutterFlow AI Designer and Builder both require browser automation:
- Chrome browser with Claude-in-Chrome extension
- MCP tools:
mcp__claude-in-chrome__* - Verify:
tabs_context_mcp
Optional: FF Orbit MCP
For programmatic refinement after AI-generated screens. Check .mcp.json in the project root:
{
"mcpServers": {
"ff_orbit_mcp": {
"command": "npm",
"args": ["start"],
"cwd": "/Users/alainbagmi/flutterflow-mcp",
"env": {
"FLUTTERFLOW_API_TOKEN": "<your-token>",
"FLUTTERFLOW_API_MIN_INTERVAL_MS": "1000",
"ORBIT_POLICY_SAFE_MODE": "guidedWrite"
}
}
}
}
Quick Start — Build Screens with AI Designer (Preferred)
Step 1: Navigate to FlutterFlow AI Designer
1. tabs_context_mcp → check for existing tabs
2. tabs_create_mcp → create new tab
3. navigate → https://designer.flutterflow.io/dashboard
Step 2: Enter Prompt
1. find → "text input field for prompt" → get ref for the textbox
2. click on textbox ref to focus it
3. type → comprehensive prompt describing all screens with:
- App name and theme (colors, background, accent)
- Each screen numbered with name and key UI elements
- Specific data examples (currencies, names, locations)
4. Press Enter OR click submit arrow to generate
Step 3: AI Generates Screens
- The AI will navigate to a new design session URL
- Wait 10-15 seconds for generation to complete
- Screens appear as frames in the left sidebar
- Scroll through canvas to verify all screens
Step 4: Add More Screens (Follow-up Prompts)
To add screens to an existing session, navigate back to the dashboard and submit a new prompt. Each submission creates a new design session.
Key Tips for AI Designer
- Be specific: Include exact colors (#AAFF00), currency (XAF), data examples
- Batch screens: Submit up to ~10 screens per prompt for best results
- Dark theme: Specify background (#0D0F14), card surfaces (#1A1C24), text colors
- Flutter Web quirks: The text input is a Flutter web widget — use
findto get ref,typefor keyboard input,Returnkey to submit - Submit button: If clicking the arrow doesn't work, focus the textbox and press Enter/Return
Using Orbit MCP (For Refinement)
1. List projects: orbit({ cmd: "projects.list" })
2. Create snapshot: orbit({ cmd: "snapshots.create", args: { projectId: "..." } })
3. Create page: orbit({ cmd: "page.create", args: { name: "SplashScreen", apply: true } })
4. Add widgets: orbit({ cmd: "widget.create", args: { nameOrId: "SplashScreen", type: "Stack", apply: true } })
5. Configure widgets: orbit({ cmd: "widget.set", args: { nameOrId: "SplashScreen", nodeId: "...", ... } })
6. Preview via browser: Open FlutterFlow in Chrome to visually verify
Using FlutterFlow Builder (Manual)
1. tabs_context_mcp → check for FlutterFlow tab
2. navigate → https://app.flutterflow.io
3. Open project → build widgets via UI interaction
4. See builder-reference.md for complete UI mapping
Core Workflow: Orbit MCP
Step 1: Resolve Project and Snapshot
Always start by establishing context:
orbit({ cmd: "projects.list" })
→ Find ZIVVO project ID
orbit({ cmd: "snapshots.create", args: { projectId: "<id>" } })
→ Creates local snapshot of project state
orbit({ cmd: "snapshots.info" })
→ Verify snapshot is fresh and complete
If snapshot exists but may be stale:
orbit({ cmd: "snapshots.ensureFresh" })
Step 2: Create or Navigate to Page
# List existing pages
orbit({ cmd: "pages.list" })
# Create new page
orbit({ cmd: "page.create", args: { name: "SplashScreen", apply: true } })
# Get page details (full widget tree)
orbit({ cmd: "page.get", args: { nameOrId: "SplashScreen" } })
Step 3: Build Widget Tree
Build top-down — add outermost layout first, then children:
# Add root Stack widget
orbit({ cmd: "widget.create", args: {
nameOrId: "SplashScreen",
type: "Stack",
apply: true
}})
# Add child Container inside Stack
orbit({ cmd: "widget.create", args: {
nameOrId: "SplashScreen",
type: "Container",
parentNodeId: "<stack-node-id>",
apply: true
}})
# Add Column inside Stack (for centered content)
orbit({ cmd: "widget.create", args: {
nameOrId: "SplashScreen",
type: "Column",
parentNodeId: "<stack-node-id>",
apply: true
}})
Step 4: Configure Widget Properties
# Set widget properties
orbit({ cmd: "widget.set", args: {
nameOrId: "SplashScreen",
nodeId: "<widget-node-id>",
props: {
"width": "double.infinity",
"height": "double.infinity",
"color": "#FAFAF7"
},
apply: true
}})
# Update text content
orbit({ cmd: "widget.set", args: {
nameOrId: "SplashScreen",
nodeId: "<text-node-id>",
text: "ZIVVO",
apply: true
}})
Step 5: Batch Operations
For efficiency, use batch commands:
# Update multiple widgets at once
orbit({ cmd: "widgets.updateMany", args: {
nameOrId: "SplashScreen",
filter: { type: "Text" },
updates: { ... },
apply: true
}})
# Find all text fields on a page
orbit({ cmd: "textfields.list", args: { nameOrId: "SplashScreen" } })
Step 6: Safe Writes with Changesets
For complex multi-step edits, use the changeset pipeline:
# 1. Create changeset
orbit({ cmd: "changeset.new" })
# 2. Add patches
orbit({ cmd: "changeset.add", args: { changesetId: "chg_...", patches: [...] } })
# 3. Preview changes (diff)
orbit({ cmd: "changeset.preview", args: { changesetId: "chg_..." } })
# 4. Validate
orbit({ cmd: "changeset.validate", args: { changesetId: "chg_..." } })
# 5. Apply safely (handles rate limiting)
orbit({ cmd: "changeset.applySafe", args: { changesetId: "chg_...", confirm: true } })
Only claim success when applied === true.
Step 7: Scaffold Pages from Templates
FlutterFlow MCP includes built-in page recipes:
orbit({ cmd: "page.scaffold", args: {
recipe: "auth.login",
name: "LoginPage",
apply: true
}})
Available recipes: auth.login, auth.signup, settings.basic, list.cards.search, detail.basic
Command-First Policy
Always prefer deterministic first-class commands over exploratory probing:
| Intent | Command |
|---|---|
| List pages | pages.list |
| Page details | page.get { nameOrId } |
| Widget inventory | widgets.list { nameOrId, type?, include? } |
| Text fields | textfields.list { nameOrId } |
| Single widget | widget.get { nameOrId, nodeId } |
| Create widget | widget.create { nameOrId, type, parentNodeId } |
| Update widget | widget.set { nameOrId, nodeId, ... } |
| Update text | widget.set { nameOrId, nodeId, text: "..." } |
| Wrap widget | widget.wrap { nameOrId, nodeId, wrapperType } |
| Move widget | widget.move { nameOrId, nodeId, newParentNodeId } |
| Delete widget | widget.delete { nameOrId, nodeId } |
| Batch update | widgets.updateMany { nameOrId, filter, updates } |
| Create page | page.create { name } |
| Rename page | page.update { nameOrId, key: "name", value: "..." } |
| Delete page | page.remove { nameOrId } |
| Clone page | page.clone { nameOrId, newName } |
| Manage routes | routes.upsert / routes.delete / routes.list |
| Search project | search { query } |
| Natural language | intent.run { text: "..." } |
Snapshot Freshness
- Default to the latest snapshot unless user pins one
- If data looks stale or incomplete:
snapshots.refresh - Conservative refresh:
{ mode: "incremental", fetchStrategy: "auto", maxFetch: 25, concurrency: 1, sleepMs: 250 } - Under heavy rate limiting:
snapshots.refreshSlow - Only treat snapshot as authoritative when
authoritative: trueandpruneApplied: true - Never infer deletions from partial refreshes
Policy Guardrails
The Orbit policy engine enforces write safety:
- safeMode:
readOnly|guidedWrite|fullWrite - Files matching
denyFileKeyPrefixesare blocked from edits - Custom code (
lib/custom_code/,lib/main.dart) is denied by default - If a write is blocked, report the exact
fileKeyand policy reason - Never report success when apply is policy-blocked
Check policy: orbit_policy_get()
Visual Verification via Browser
After building with Orbit, optionally verify visually:
1. tabs_context_mcp → check for FlutterFlow tab
2. navigate → open the project in FlutterFlow web UI
3. read_page / screenshot → verify the screen looks correct
4. Use gif_creator to record verification for documentation
See builder-reference.md for complete FlutterFlow UI mapping.
Error Recovery
Orbit Command Fails
- Check error message — often contains the fix
- Run
orbit({ cmd: "help", args: { cmd: "<command>" } })to verify args - If stale data:
snapshots.refresh - If rate limited (429): use
changeset.applySafewith retry controls
Widget/Page Not Found
- Resolve via
pages.listfirst - Use returned
pageId/nodeIdexplicitly (don't guess from names) - Check
includeDeleted: trueif page may have been soft-deleted
Rate Limiting (429)
- Use
changeset.applySafewith bounded retries - For refreshes:
snapshots.refreshSlowwith conservative pacing - Report
rateLimited,retryAfterSeconds, andnextRetryAtto user
File Reference
| File | Contents |
|---|---|
orbit-commands.md |
Complete Orbit command reference — all 70+ commands |
orbit-setup.md |
VSCode / Claude Code setup and configuration |
builder-reference.md |
FlutterFlow web UI map — panels, buttons, properties |
widget-catalog.md |
All widgets with properties and automation steps |
design-system-setup.md |
ZIVVO design system — colors, typography, theme widgets |
screen-blueprints.md |
Screen-by-screen widget trees for all 4 roles |
code-export.md |
Export workflows and Melos monorepo integration |
Safety Notes
- Never delete pages without user confirmation
- Use
page.preflightDeletebefore removing pages - Use changeset preview/validate before applying complex edits
- For browser automation: stop and ask user if tools fail 2-3 times
- Respect policy guardrails — never force-write blocked files