agent_wires_mcp
MCP server that bridges an LLM agent to a running Flutter app via the Dart VM service. Pairs with agent_wires_probe.
0.1.7
mohn93/agent-wires
What this package is like to depend on
Last release 2 months ago
03 Jun 2026
Too new to tell
only 2 release windows
Nearly every release is documented
notes for 8 of 8 stable releases
Nothing withdrawn
no release was ever pulled
3 months old
8 releases · first in 2026
8 releases in the last 12 months
see the full history below
Release timeline
8 releases · May 2026 to Jun 2026Releases
latest 8-
0.1.703 Jun 2026Release notes
Open source →- Fix Windows startup crash.
ProcessSignal.sigterm.watch()throwsSignalExceptionon Windows (Failed to listen for SIGTERM ... errno = 50), killing the MCP server before it could serve. The SIGTERM shutdown listener is now guarded with!Platform.isWindows; SIGINT still handles Ctrl+C / client shutdown on Windows. Thanks @mwothman (#15). - Pairs with
agent_wires_probe0.1.9 (recommendedProbeVersionbumped) — picks up the probe's scroll (#12) and screenshot (#13) reliability fixes.
- Fix Windows startup crash.
-
0.1.602 Jun 2026Release notes
Open source →Adds the action overlay narration layer (pairs with
agent_wires_probe0.1.7). Tool count grows 24 → 25.- New
set_action_overlay(enabled)tool toggles the probe's on-screen overlay — the ripples/highlights/flashes drawn where the agent taps, types, points, and looks. It is for a human watching the device and never appears inscreenshot/snapshot. On by default. label_elementnow flashes a point-at highlight on the named element (via the probe) so a watcher sees what was labelled.recommendedProbeVersiontracksagent_wires_probe0.1.7.
- New
-
0.1.501 Jun 2026Release notes
Open source →Boot reliability fix.
Fail fast when
flutter rundies during bootboot_appno longer hangs for the full timeout when the build fails.FlutterRunner.startawaited the VM-service URI (up to 10 min) but never watched the flutter process itself. Ifflutter run --machinespawned, printed progress ("Running Xcode build..."), then exited without emitting a recognised failure event — a codesign/build failure, no matching device, orflutterresolving to the wrong SDK (e.g. an fvm-managed Flutter not on the spawnedPATH) — the boot wedged on the timeout whileapp_statusshowed a frozen progress line and no flutter/xcodebuild process was even alive.startnow also watchesexitCodeand fails the boot immediately when flutter exits early, attaching a tail of flutter's stderr and the likely causes so the agent gets an actionable error in seconds instead of a multi-minute hang.
-
0.1.401 Jun 2026Release notes
Open source →Docs-only release. No code changes — refreshes the README to match the 0.1.3 tool surface and behaviour so the pub.dev page is accurate.
- Removes the
-ddevice pin from the MCP config examples (it contradicted the "don't pin at registration" guidance and is the phone-vs-simulator stall trap); the agent picks a device at session time vialist_devices+boot_app. - Corrects the tool count to 24.
- Documents that
screenshotreturns{path, …}by default (base64 viareturn_base64: true). recommendedProbeVersiontracksagent_wires_probe0.1.6.
- Removes the
-
0.1.301 Jun 2026Release notes
Open source →Connection- and lifecycle-hardening from a real LLM-agent driving session (physical iPhone, then simulator) where a dropped VM-service connection cascaded into multi-minute hangs and leaked processes. No tool additions;
app_statusgainsprobe_version/probe_version_warning/paused_at_startfields, andhot_reload/hot_restartfailures gainrecoverable+hint.Fail-fast instead of hanging on a dead connection
- Per-call timeout + connection-lost latch. When the device VM-service
connection dropped (
Service connection disposed, JSON-RPC-32603), everyext.qa.*call used to block on the dead socket until cancelled —boot_appran 601s,get_logs633s, evenstop_app219s.VmClientnow bounds each call and latches a lost-connection state the instant the socket closes, a call returnsdisposed, or a call times out; subsequent calls andisProbeAlivefail immediately with a clear "reattach or reboot" error. A dead connection is distinguished from a stale isolate, so it no longer triggers a rebind that would re-hang. - Teardown never blocks on the VM-service.
stop_appbounds VM-service disposal so it always tears down the OS process, even when the connection is already dead.
Reap the whole flutter process tree
- No more orphaned
flutter run/ DDS / devicectl / iproxy.stop_app(and server exit on SIGINT/SIGTERM) now snapshots the descendant process tree before killing flutter — children reparent to launchd the moment flutter dies — then SIGTERM→SIGKILL the lot. Stops the per-cycle leak that left multiple servers/runs contending for the same device and VM-service.
Resume a paused-at-start launch
- Frozen
--start-stoppedapps now run. A physical iPhone launched viadevicectl … --start-stoppedboots withmain()paused; nothing resumed it, so the app sat frozen whileapp_statusreadready. Attach now resumes any paused-at-start isolate before locating the QA isolate (a paused isolate hasn't registered the probe yet). When a resume can't be confirmed,app_statusreportspaused_at_start: trueinstead of a misleading healthy status.
Hot reload/restart — recover from DevFS wedges
- Retry-then-explain on
DevFS synchronization failed.hot_reload/hot_restartretry once (the failure is often transient); if it still fails, the result carriesrecoverable: falseand ahintto runstop_app+boot_app, instead of a baresuccess: false.
Smaller robustness wins
boot_app(device_id)switches devices without a deadlock. A device switch on a running session force-stops it (process-level) instead of rejecting with "call stop_app first" — which used to deadlock when the VM-service was already dead.- Probe/server version-skew warning. The probe reports its version over
ext.qa.ping;app_statussurfacesprobe_versionand warns when it differs from the version this server pairs with (0.1.5). get_logscan't blow the client token budget. Oversizedmessage/error/stackfields are truncated (default 4000 chars each, with a dropped-char marker) so a single ~110k-char Flutter stack no longer overruns the MCP client limit. Pagination is preserved.
- Per-call timeout + connection-lost latch. When the device VM-service
connection dropped (
-
0.1.225 May 2026Release notes
Open source →Hot-restart robustness from real LLM-agent driving sessions. No tool additions;
app_statusgains aprobe_attachedfield.Self-healing isolate binding
- Recovers from hot restart automatically. A hot restart collects
the QA isolate and starts a new one. The client used to keep calling
the dead isolate id, so every
ext.qa.*call failed with[Sentinel kind: Collected]for the rest of the session and never recovered.callExtensionnow re-resolves the liveext.qa.*isolate and retries once on a stale-isolate error, so a single tool call recovers transparently. app_statusreportsprobe_attached. Distinct fromstate, which only tracks theflutter runprocess: after a hot restart the process stays up (statestaysready) but the probe moves to a fresh isolate.state:"ready"withprobe_attached:falsenow tells the agent the probe is reattaching, instead of looking healthy while every call fails. The check re-resolves and rebinds when the bound isolate has been collected.- Clearer error when the probe is truly gone. If re-resolution
fails (the app exited, or hot-restarted without
AgentWiresProbe.install()), the agent gets an actionable message instead of the raw VM-service sentinel string.
- Recovers from hot restart automatically. A hot restart collects
the QA isolate and starts a new one. The client used to keep calling
the dead isolate id, so every
-
0.1.125 May 2026Release notes
Open source →Post-launch iteration. Tool count grows 18 → 23 (5 new lifecycle tools). No breaking changes.
New: lifecycle tools
list_devices— discover what flutter can target (phones, sims, macOS, Chrome). Agent picks per-sessionboot_app— explicit boot withdevice_idandwait: false(fire-and-forget so the agent can poll progress)app_status— query state +latest_progress("Running Xcode build…", "Installing Pods…") during long bootsstop_app— tear down to retarget devicehot_reload— re-inject sources, preserve state + routehot_restart— cold restart in lazy mode (attached mode returns a clear error)
Boot: visible instead of black box
- Lazy boot — MCP handshake answers in ms; flutter only starts on first tool call. Fixes Claude Code's 30s connection timeout
- Progress streaming to stderr +
app_status.latest_progress - Fail-fast on
app.stoperrors and error-level daemon logs (no more 10-min hangs) - Recovery: lazy sessions can re-boot from
exitedwithout restarting the MCP server - Default boot timeout 5 → 10 min
Perception tools — smaller, more accurate
snapshotdefaults to compact mode (include_unresolved: false)screenshotwrites PNG to tmpfile, returns{path, width, height, size_bytes}(was 329k chars of inline base64)inspectreturns descendants + CustomPaint metadata
Sync — diagnose what's keeping the app awake
wait_for_idlereturns structuredblocked_byon timeoutignore_animationsflag
Tool descriptions
- All 23 tools rewritten to disambiguate and teach the canonical agent loop. Most user-visible fix: agents now reach for
snapshotfirst by default.
Full notes: CHANGELOG
pub.dev: https://pub.dev/packages/agent_wires_mcp/versions/0.1.1
Requires: agent_wires_probe ^0.1.3Release notes
Open source →Post-0.1.0 iteration driven by real LLM-agent driving sessions. Tool count grows from 18 → 23 (5 new lifecycle tools). Several tool input schemas gain optional flags; nothing existing breaks.
New: lifecycle tools
list_devices— runsflutter devices --machineand returns a curated[{id, name, platform, is_emulator, is_supported, sdk}, ...]list. Agent calls this when multiple devices might be connected (the classic 10-min-hang trigger: phone + sim, flutter picks the phone and stalls on signing).boot_app/app_status/stop_app— explicit lifecycle instead of "boot happens magically on first tool call."boot_appacceptsdevice_id(pick the device per session),wait(false for fire-and-forget so the agent can poll progress). Sticks the device choice until the nextstop_app.hot_reload— re-injects edited Dart sources, preserves state + current route. Lazy mode usesflutter run --machine'sapp.restart(true Flutter reload with reassemble); attached mode falls back to VM-servicereloadSources(sources swap, no reassemble).hot_restart— tears down the isolate and re-runsmain(). State lost. Only supported in lazy mode (where we own the flutter subprocess). Attached mode returns a clear "use your own restart" error.
Boot: visible instead of black box
- Lazy boot.
agent_wires_mcp runno longer blocks onflutter run --machinebefore opening MCP stdio. The handshake returns in milliseconds; flutter only starts when the agent callsboot_app(or any other tool, via auto-boot). Previously Claude Code's 30s connection timeout killed every cold-cache session. - Progress streaming. Each
app.progressand non-errordaemon.logMessageevent from flutter is captured on the session, surfaced inapp_status.latest_progress, and written to MCP-server stderr so Claude Code's MCP log viewer also shows it. A long Xcode build / pod install now reads as "Running Xcode build..." in app_status instead of a silent 5-minute wait. - Fail-fast on launch errors.
app.stopwith an error payload, or any error-level daemon log, immediately fails the boot future with that message. No more 10-minute timeouts on "No supported devices connected." - Recovery. Lazy sessions in
exitedreset toidleon the nextensureReady; the agent can retryboot_appafter a timeout orstop_appwithout reconstructing the MCP server. Attached sessions stay terminal (we don't own that flutter process). - Default boot timeout 5 min → 10 min — large apps with firebase / syncfusion / flutter_quill routinely run past 5 on a cold compile.
Perception tools — smaller, more accurate
snapshotgainsinclude_unresolved: falseby default. The unresolved array (the worst noise: 10–25k chars of unlabelled Listeners, decorative Switches, FAB carriers) is hidden; the count is reported asunresolved_countinstead. Agents that need to drive a hidden widget (pin-code fields) opt in explicitly.screenshotwrites the PNG to a tmp file and returns{path, width, height, size_bytes}by default — was 329k chars of inline base64 that the agent couldn't actually read. The old behavior is available viareturn_base64: true.inspectgainsinclude_descendants(default true) anddescendant_depth(default 3) — returns a subtree view withpainter+sizeexposed forCustomPaintdescendants. Lets the agent answer "what's inside this Card?" or "is this region drawn pixels?" in one call.
Sync — diagnose what's keeping the app awake
wait_for_idlereturns a structured payload on timeout:{idle, blocked_by, in_flight_http, has_scheduled_frame, in_transient_callback}. The agent now knows whether to wait longer, retry, or proceed.- New
ignore_animationsflag — drops the frame/animation checks, waits only for HTTP. Use on screens with continuous spring animations that never visually settle.
Tool descriptions
- All 23 tool descriptions rewritten to disambiguate (snapshot vs.
screenshot, the three
wait_for_*siblings) and teach the canonical agent loop. The biggest behavioral change: agents now reach forsnapshotfirst by default;screenshotcorrectly signals "almost always prefer snapshot."
Internal
AppSessionintroduced as the lifecycle hub; runner + VM client state lives there with explicit state machine (idle,booting,ready,exited).FlutterRunnercaptures the appId fromapp.started, routes machine-protocol responses to per-request completers, exposes a general-purpose progress callback.DeviceListerwrapsflutter devices --machine; parser tolerates leading log lines.
-
0.1.023 May 2026Release notes
Open source →Initial public release.
- 18 MCP tools across five categories: perception (
snapshot,inspect,screenshot), action (tap,long_press,swipe,enter_text,clear_text,scroll,press_back), sync (wait_for_idle,wait_for_route,wait_for_element), observability (get_logs,get_network), and memory (label_element,get_labels,recall). agent_wires_mcp run— bootsflutter run --machine, auto-discovers the VM service URI, and serves MCP over stdio in one process. Forwards--flavor,-t/--target,--dart-define.agent_wires_mcp serve --attach <ws-uri>— attaches to an already- running app.agent_wires_mcp review— local human-curation dashboard atlocalhost:7345for labelling unresolved widgets. Per-project persistence in.flutter_qa/map.json.- Snapshot enrichment — merges human labels and source-location proposals (via the analyzer package) before returning to the agent.
- Set-of-Mark mode —
screenshot(annotated: true)overlays numbered boxes for vision-augmented agents. - Requires the target app to have
agent_wires_probeinstalled.
- 18 MCP tools across five categories: perception (