When an MCP client drives a simulator, I can inspect the tool calls and screenshots afterwards. I still could not sit beside the device and see the test happen as it happened.
tapflow 0.28.0 adds a watch page for an MCP session. connect_device returns a watchUrl, and opening it shows the device live in the dashboard. The page is read-only, so clicking it does not send input to the device. Up to four people can watch one session.
The page also shows an interaction list beside the device. Taps, swipes, keys, button presses, text entry, app launches, installs, cleared app data, and opened links appear as they happen. Flow runs add each step name when the step starts. The list is not stored, so it starts when the page opens.
For text entry, the action list shows only the character count. The live device screen still shows whatever the coding agent types, and any teammate signed in to the dashboard can see it. Opened links and character keys are not named in the list.
The blue cursor stays on the last tap, then glides to the next one. It makes the target of each action easier to follow.
Changes that make the automation path less fragile
The MCP server and flow runner are experimental. This release also fixes several timing and UI-tree cases around that path.
On iOS, a flow could time out on its first UI-tree step immediately after a simulator booted. For simulators that tapflow flow run or the MCP server booted, the tree runner now starts as soon as the device is ready. Simulators booted from the dashboard are not affected. Each simulator has its own runner, so two iOS simulators can be read at the same time.
Android's UI-tree reader used to wait for the screen to become idle. A continuously changing screen could therefore fail a selector step with could not get idle state. The reader now waits at most one second before reading the current screen. This is the same kind of problem I wrote about in the UI-tree post from July.
Android app launch could return before the first frame was drawn, so following input could reach the launcher or disappear. The launch path now waits for the first frame. launchApp waits until the UI tree has stayed unchanged for one second before the next input step. A splash screen that stays unchanged for longer than a second can still be treated as the first screen, and this wait does not fail the step. scroll, swipe, inputText, and pressKey immediately after launch are no longer lost for that reason.
On iOS, a flow could reject the whole UI tree when an element was reported at a position outside the screen. The agent now clips elements to the screen and leaves out only an element that is wholly outside it.
When tapOn fails because it matches nothing or more than one element, tapflow flow run prints up to three try: lines from the screen at the failure point. Each candidate is checked to tap exactly that element, and the suggestions use no AI. An input field is suggested by its id, so entered text does not enter the log.
npm install -g tapflow
tapflow start
Top comments (0)