NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev
MCP server that bridges an LLM agent to a running Flutter app via the Dart VM service. Pairs with agent_wires_probe.
Last release 23 days ago
14 Sep 2026
Release timing varies
gaps range from 9 days to 4 months
Nearly every release is documented
notes for 9 of 9 stable releases
Nothing withdrawn
no release was ever pulled
4 months old
9 releases · first in 2026
One column per month.
fix(probe,mcp): real swipe deltas, visible-only scroll, offscreen gua…
fix(probe,mcp): real swipe deltas, visible-only scroll, offscreen gua…
Stops a slow probe from being mistaken for a dead connection, and makes a dropped VM-service socket recoverable without a rebuild.
wait_for_element,
wait_for_route and wait_for_idle legitimately block inside the probe for
up to their timeout_ms; with the flat 30 s call timeout a
wait_for_element(timeout_ms: 30000) timed out on the MCP side, latched
VmConnectionLostException, and every later tool call failed until
stop_app + boot_app. Sync tools now pass a per-call timeout of
timeout_ms + 10 s (VmClient.callExtensionWithTimeout).getVM liveness check: if the VM
answers, the call fails with the new non-latching VmCallTimeoutException
("probe was busy, retry or pass a longer timeout"); only a VM that stays
silent latches the connection as lost.boot_app reattaches after a lost connection (lazy sessions). A
ready session whose socket died used to hand back the dead client forever
(boot_app returned "ready" without reconnecting). It now reconnects to the
still-running flutter process's VM service and only falls back to a full
reboot when that fails; concurrent tool calls share one reconnect. Attached
sessions (serve --attach) cannot reconnect on their own and now fail with
a clear error instead of returning the dead client. app_status reports
connection_lost: true with a mode-specific hint.boot_app(timeout_minutes) raises the boot deadline (default 10, max
60) for cold caches where pod install plus a first Xcode build exceed ten
minutes and the timed-out boot would otherwise be killed mid-build.flutter run --machine reports the
build log as status-level daemon.logMessage events on stdout; the
premature-exit error only carried the stderr tail ("Could not build the
application for the simulator") and left the agent guessing. The error now
drains and includes a tail of the stdout log as well.wait_for_element gains match: "exact" | "substring" (default exact) and
documents the probe's word-boundary substring matching; snapshot
documents the new offscreen flag. Sync-tool timeout_ms accepts numbers
or numeric strings and is capped at 10 minutes. Pairs with
agent_wires_probe 0.1.10 (recommendedProbeVersion bumped).agent_wires_mcp 0.1.7 — Windows startup fix ( #15 ); pairs with probe 0…
agent_wires_mcp 0.1.7 — Windows startup fix (#15); pairs with probe 0…
ProcessSignal.sigterm.watch() throws
SignalException on 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).agent_wires_probe 0.1.9 (recommendedProbeVersion bumped) —
picks up the probe's scroll (#12) and screenshot (#13) reliability fixes.Adds the action overlay narration layer (pairs with agent_wires_probe 0.1.7). Tool count grows 24 → 25.
Adds the action overlay narration layer (pairs with agent_wires_probe
0.1.7). Tool count grows 24 → 25.
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 in
screenshot/snapshot. On by default.label_element now flashes a point-at highlight on the named element (via the
probe) so a watcher sees what was labelled.recommendedProbeVersion tracks agent_wires_probe 0.1.7.`boot_app` no longer hangs for the full timeout when the build fails. FlutterRunner.start awaited the VM-service URI (up to 10 min) but never watched
Boot reliability fix.
flutter run dies during bootboot_app no longer hangs for the full timeout when the build fails.
FlutterRunner.start awaited the VM-service URI (up to 10 min) but never
watched the flutter process itself. If flutter run --machine spawned,
printed progress ("Running Xcode build..."), then exited without
emitting a recognised failure event — a codesign/build failure, no matching
device, or flutter resolving to the wrong SDK (e.g. an fvm-managed Flutter
not on the spawned PATH) — the boot wedged on the timeout while
app_status showed a frozen progress line and no flutter/xcodebuild process
was even alive. start now also watches exitCode and 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.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.
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.
-d device 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 via list_devices +
boot_app.screenshot returns {path, …} by default (base64 via
return_base64: true).recommendedProbeVersion tracks agent_wires_probe 0.1.6.Connection- and lifecycle-hardening from a real LLM-agent driving session (physical iPhone, then simulator) where a dropped VM-service connection casc
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_status gains probe_version / probe_version_warning / paused_at_start
fields, and hot_reload / hot_restart failures gain recoverable + hint.
Service connection disposed, JSON-RPC -32603), every
ext.qa.* call used to block on the dead socket until cancelled — boot_app
ran 601s, get_logs 633s, even stop_app 219s. VmClient now bounds each
call and latches a lost-connection state the instant the socket closes, a
call returns disposed, or a call times out; subsequent calls and
isProbeAlive fail 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.stop_app bounds VM-service
disposal so it always tears down the OS process, even when the connection is
already dead.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.--start-stopped apps now run. A physical iPhone launched via
devicectl … --start-stopped boots with main() paused; nothing resumed it,
so the app sat frozen while app_status read ready. 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_status reports paused_at_start: true instead of a misleading
healthy status.DevFS synchronization failed. hot_reload /
hot_restart retry once (the failure is often transient); if it still
fails, the result carries recoverable: false and a hint to run
stop_app + boot_app, instead of a bare success: false.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.ext.qa.ping; app_status surfaces probe_version and warns when it
differs from the version this server pairs with (0.1.5).get_logs can't blow the client token budget. Oversized
message / error / stack fields 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.Hot-restart robustness from real LLM-agent driving sessions. No tool additions; app_status gains a probe_attached field.
Hot-restart robustness from real LLM-agent driving sessions. No tool
additions; app_status gains a probe_attached field.
ext.qa.* call failed with
[Sentinel kind: Collected] for the rest of the session and never
recovered. callExtension now re-resolves the live ext.qa.* isolate
and retries once on a stale-isolate error, so a single tool call
recovers transparently.app_status reports probe_attached. Distinct from state,
which only tracks the flutter run process: after a hot restart the
process stays up (state stays ready) but the probe moves to a
fresh isolate. state:"ready" with probe_attached:false now 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.AgentWiresProbe.install()), the agent gets an actionable message
instead of the raw VM-service sentinel string.Post-launch iteration. Tool count grows 18 → 23 (5 new lifecycle tools). No breaking changes.
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 with device_id and wait: 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
app_status.latest_progressapp.stop errors and error-level daemon logs (no more 10-min hangs)exited without restarting the MCP serverPerception tools — smaller, more accurate
snapshot defaults to compact mode (include_unresolved: false)screenshot writes PNG to tmpfile, returns {path, width, height, size_bytes} (was 329k chars of inline base64)inspect returns descendants + CustomPaint metadataSync — diagnose what's keeping the app awake
wait_for_idle returns structured blocked_by on timeoutignore_animations flagTool descriptions
snapshot first by default.Full notes: CHANGELOG
pub.dev: https://pub.dev/packages/agent_wires_mcp/versions/0.1.1
Requires: agent_wires_probe ^0.1.3
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.
list_devices — runs flutter devices --machine and 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_app accepts
device_id (pick the device per session), wait (false for
fire-and-forget so the agent can poll progress). Sticks the device
choice until the next stop_app.hot_reload — re-injects edited Dart sources, preserves state +
current route. Lazy mode uses flutter run --machine's app.restart
(true Flutter reload with reassemble); attached mode falls back to
VM-service reloadSources (sources swap, no reassemble).hot_restart — tears down the isolate and re-runs main(). State
lost. Only supported in lazy mode (where we own the flutter
subprocess). Attached mode returns a clear "use your own restart"
error.agent_wires_mcp run no longer blocks on
flutter run --machine before opening MCP stdio. The handshake
returns in milliseconds; flutter only starts when the agent calls
boot_app (or any other tool, via auto-boot). Previously Claude
Code's 30s connection timeout killed every cold-cache session.app.progress and non-error
daemon.logMessage event from flutter is captured on the session,
surfaced in app_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.app.stop with 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."exited reset to idle on the next
ensureReady; the agent can retry boot_app after a timeout or
stop_app without reconstructing the MCP server. Attached sessions
stay terminal (we don't own that flutter process).snapshot gains include_unresolved: false by default. The
unresolved array (the worst noise: 10–25k chars of unlabelled
Listeners, decorative Switches, FAB carriers) is hidden; the
count is reported as unresolved_count instead. Agents that need
to drive a hidden widget (pin-code fields) opt in explicitly.screenshot writes 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 via return_base64: true.inspect gains include_descendants (default true) and
descendant_depth (default 3) — returns a subtree view with
painter + size exposed for CustomPaint descendants. Lets the
agent answer "what's inside this Card?" or "is this region drawn
pixels?" in one call.wait_for_idle returns 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.ignore_animations flag — drops the frame/animation checks,
waits only for HTTP. Use on screens with continuous spring
animations that never visually settle.wait_for_* siblings) and teach the canonical
agent loop. The biggest behavioral change: agents now reach for
snapshot first by default; screenshot correctly signals
"almost always prefer snapshot."AppSession introduced as the lifecycle hub; runner + VM client
state lives there with explicit state machine (idle, booting,
ready, exited).FlutterRunner captures the appId from app.started, routes
machine-protocol responses to per-request completers, exposes a
general-purpose progress callback.DeviceLister wraps flutter devices --machine; parser tolerates
leading log lines.18 MCP tools across five categories: perception (snapshot, inspect, screenshot), action (tap, long_press, swipe, enter_text, clear_text, scroll, press
Initial public release.
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 — boots flutter 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 at
localhost:7345 for labelling unresolved widgets. Per-project
persistence in .flutter_qa/map.json.screenshot(annotated: true) overlays numbered
boxes for vision-augmented agents.agent_wires_probe
installed.Your coding agent can read these notes before it upgrades. Set up the MCP server →