arenukvern / flutter-mcp-toolkit-maintain-web
Maintains showcase/flutter_test_app and intentcall web targets (Chrome, web codegen, WebMCP bootstrap, web-showcase, webmcp verify, Chrome DevTools MCP). Use when editing web/index.html, agent_manifest.json, intentcall_webmcp.generated.js, web platform sync, Chrome dogfood, WebMCP modelContext, or agent WebMCP list/execute.
<!-- @FMTMODEPRELUDE -->
Maintain Web (Chrome + WebMCP)
Dogfood app: showcase/flutter_test_app. Canonical platform doc: showcase/flutter_test_app/INTENTCALL_PLATFORM.md.
WebMCP vs VM MCP
| Path | Proves |
|---|---|
VM extensions + fmt_* tools | MCP toolkit dogfood (always) |
navigator.modelContext / document.modelContext | True WebMCP (Chrome flags / --web-browser-flag) |
ADR: decisions/0008_web_agent_invoke_js_only.mdx — JS fetch('/agent/invoke') 404 by design; Dart invokeDirect works when modelContext exists.
Launch (repeatable WebMCP)
make web-showcase
# WS_URI from .showcase/web_app.log (re-grep after hot reload)
grep -Eo 'ws://127\.0\.0\.1:[0-9]+/[A-Za-z0-9_=-]+/ws' .showcase/web_app.log | tail -1dart run mcp_server_dart/bin/flutter_mcp_toolkit.dart webmcp chrome-args
dart run mcp_server_dart/bin/flutter_mcp_toolkit.dart webmcp verify --web-port 8080Stop: make showcase-stop.
Do not rely on chrome://flags alone across machines — use CLI flags / make web-showcase / VS Code launch args.
VS Code / Cursor launch
Use config showcase/flutter_test_app Chrome + WebMCP in .vscode/launch.json:
--web-browser-flag=--user-data-dir=${workspaceFolder}/.showcase/chrome-webmcp-profile— persistent profile sochrome://flagssurvive stop/start (Flutter default is a temp profile every run).--web-browser-flag=--enable-features=WebMCPTesting,WebModelContext,DevToolsWebMCPSupport--web-browser-flag=--enable-experimental-web-platform-features
Path must not include literal quotes in the value (avoids a dir named "./…").
Chrome 149+ Application → WebMCP pane also needs #devtools-webmcp-support / feature DevToolsWebMCPSupport (API alone is not enough for that UI).
Agent WebMCP (Chrome DevTools MCP) — preferred for live invoke
Prefer chrome-devtools MCP (list_webmcp_tools, execute_webmcp_tool) over flutter_mcp_toolkit webmcp verify --tool-name when an agent should drive page tools.
Install (once)
Grok (~/.grok/config.toml):
[mcp_servers.chrome-devtools]
command = "npx"
args = [
"-y",
"chrome-devtools-mcp@latest",
"--categoryExperimentalWebmcp",
"--chromeArg=--enable-features=WebMCP,WebModelContext,DevToolsWebMCPSupport,WebMCPTesting",
"--chromeArg=--enable-experimental-web-platform-features",
"--userDataDir=/Users/YOU/.cache/chrome-devtools-mcp/chrome-profile-webmcp",
"--no-usage-statistics",
]
enabled = true
startup_timeout_sec = 90Or: grok mcp add chrome-devtools -- npx -y chrome-devtools-mcp@latest --categoryExperimentalWebmcp ...
Cursor — same command/args under mcpServers.chrome-devtools in ~/.cursor/mcp.json.
Restart the agent session after install. Doctor: grok mcp doctor chrome-devtools.
Live flow
- App must serve (e.g.
make web-showcaseor VS Code Chrome + WebMCP on:8080). list_pages— chrome-devtools may start its own browser (about:blank).navigate_page→http://localhost:8080/(or your app URL).- Wait for Flutter/Dart bootstrap (first
list_webmcp_toolscan be empty). list_webmcp_tools— expect IntentCall tools + oftenmcp_*toolkit tools registered onmodelContext.execute_webmcp_toolwithtoolName+ JSON-stringinputwhen required.
Example IntentCall tools: app_enable_switch (no args), app_set_greeting ({"text":"…"}), app_intentcall_bridge_ping ({"echo":"…"}), app_get_agent_showcase_state.
execute_webmcp_tool
toolName: app_enable_switch
input: {}Fallback (CLI, no chrome-devtools MCP)
dart run mcp_server_dart/bin/flutter_mcp_toolkit.dart webmcp verify --web-port 8080 \
--tool-name app_enable_switch --tool-args '{}'Codegen & hooks
dart run mcp_server_dart/bin/flutter_mcp_toolkit.dart codegen sync \
--platform web,android,ios,macos,linux,windows \
--project-dir showcase/flutter_test_app
dart run mcp_server_dart/bin/flutter_mcp_toolkit.dart init intentcall-platform \
--project-dir showcase/flutter_test_app --check| Artifact | Source |
|---|---|
web/intentcall_webmcp.generated.js | codegen sync from web/agent_manifest.json |
web/index.html | init intentcall-platform script tag |
| Dart bootstrap | projection the app registers — showcase: ShowcaseWebMcpProjection (in intentcall_showcase_bootstrap.dart), wrapping projectEntriesToWebMcp from intentcall_platform_sync; wired via MCPToolkitBinding.addEntryListener (ADR-0016) |
Runtime validate
dart run mcp_server_dart/bin/flutter_mcp_toolkit.dart --save-images \
--output-dir .showcase/web_iter validate-runtime \
--target "$WS_URI" \
--flutter-device chrome \
--timeout-ms 45000Pass --web-browser-debugging-port <cdp> if CDP discovery fails.
Known issues
- Duplicate tool name — generated JS + the WebMCP projection (
projectEntriesToWebMcp) both callregisterTool; dedupe or gate one path (agent_web_mcp_bootstrap_web.dartname cache). - CDP probe —
webmcp verifymay reportwebmcp_active_log_evidencewhile CDPhasModelContextis false (Flutter execution context). - Stale WS_URI — always grep fresh token after hot restart before eval/validate.
- Empty WebMCP list right after navigate — wait until Dart hook / registration finishes, then list again.
- Temp Chrome profile — without
--user-data-dir, Flutter wipeschrome://flagsevery stop/start. - Two browsers — chrome-devtools MCP profile ≠ Flutter-launched Chrome unless you attach with
--browser-url=http://127.0.0.1:<cdpPort>.
Related
docs/superpowers/evals/2026-05-26-webmcp-verification.mdflutter-mcp-cli-runtime-validation— validate-runtime detailsflutter-mcp-toolkit-dogfood-iterations— scored iterationsflutter-mcp-e2e-harness— programmatic scenarios over this showcase (packages/harness,--web --detachvariant)- Chrome DevTools MCP: https://github.com/ChromeDevTools/chrome-devtools-mcp (WebMCP tools need
--categoryExperimentalWebmcp+ Chrome 149+)