Blolabel
← Notes
comparison 8 min read

nanoMuse gives its personal agent hands on Android but not on the iPhone; phoneshell's iPhone hands come from a Mac, and its gate misses two steps nanoMuse's catches

An open personal agent that runs on every device stops short at one of them. The iPhone gets the conversation and not the hands. phoneshell is the other answer, hands from outside the phone, and the two projects' safety rules can be compared step by step.

nanoMuse, an open-source personal agent posted on 6 October 2026, runs on Android, iOS, the desktop and the web. It has hands on every one of them except the iPhone, "since iOS lets no app operate another". phoneshell puts the hands outside the phone. A Mac drives an XCUITest runner over a cable, and six frontier models passed 322 of 349 device-graded iPhone runs through it. The two projects also gate dangerous steps differently. nanoMuse's Sentinel stops a tap on Send and a typing step that presses return. phoneshell's confirm gate stops neither.

Abstract technical illustration of a sealed glass tile with a single cable entering it from outside, light flowing along the cable

What nanoMuse shipped

Guangyi Liu, Yong Liu and Jiangning Zhang (Zhejiang University; arXiv:2610.08699) describe nanoMuse as the open counterpart to Meta's Muse, under GPL-3.0. The first release came on 25 September, the report describes v0.1.40, and v0.1.41 followed on 7 October. The Android app is a modified OpenMinis with a sandboxed Alpine Linux and a shell. The desktop app is an Electron shell. The iOS app ships through TestFlight. Hands are the last rung of a ladder: skill or CLI or MCP server first, then a page fetched with the person's login, then the browser, then the device screen, off by default. The screen rung is a one-action-per-screenshot loop: the model returns a thought, a sentence saying what it is about to press, and one gesture.

The report is plain about two gaps. On the iPhone, Table 1's note says, "no agent has a phone screen there". On every device it says: "We have no success rate and no count of human take-overs to report." The Sentinel is described as a policy boundary in the same trust domain as the agent, not a privilege boundary.

nanoMuse on AndroidnanoMuse on iPhonephoneshell on iPhoneSource
Where the agent runson the phone, in the appon the phone, in the appon a Mac, model through MCP2610.08699 Sec. 5; phoneshell README
Can operate other appsyes, screenshot loop plus accessibility textnoyes, accessibility tree plus optional screenshotsame
Extra hardwarenonenonea Mac, a cable or the same wifiphoneshell README
Phone settings needednot reportednoneDeveloper Mode, Enable UI Automationphoneshell README
After a rebootnot reportednot applicablea person must enter the passcode on the phone before the runner can startFINDINGS.md sec. 24
Gate on a "Send" tapyes, committing wordno handsno (only "send money")Sec. 5; config.py
Gate on typing that submitsyesno handsno, audit line onlySec. 5; mcp_server.py
Measured success"no success rate"none322 of 349 (92.3%) on an iPhone 14 Pro, 6 models, 9 Sep 2026Sec. 7; phoneshell-bench xv2

How the hands reach an iPhone from outside

iOS gives an App Store or TestFlight app no API to read or tap another app. The route that does exist is the testing stack. An XCUITest runner, signed by a developer account and started through the phone's developer services, can read the accessibility tree of whatever app is in front and synthesise touches. phoneshell builds Appium's WebDriverAgent at the pinned tag v16.12.4, signs it with a free Apple developer account, installs it, and talks to it over HTTP bound to the phone's loopback. Its bring-up code names 16 checks, from xcode and developer-mode to wda-launch and wda-source, and bin/phoneshell doctor reports the ones that fail. Two phone toggles cannot be set from the Mac: Developer Mode, and Settings > Developer > Enable UI Automation. Without the second, the README warns, "everything installs, launches and silently does nothing".

Where an agent's hands can sit on an iPhone iPhone nanoMuse iOS appTestFlight, v0.1.40chat, memory, Sentinelno hands other appsSettings, Mail, Maps × sandbox: "iOS lets no app operate another" XCUITest runner (WebDriverAgent 16.12.4)reads any foreground app's accessibility treetaps by coordinates, types, swipesneeds Developer Mode + Enable UI Automation after a reboot: BFU state, developer services withheld until a person enters the passcode Mac phoneshell bridge + MCP servermodel of your choice through MCPconfirm gate on taps, audit logdevice-graded benchmark, 80 tasks Xcode tools, pymobiledevice3build, sign (free Apple developer account),install and launch the runner bring-up code names 16 checks, from xcode and developer-mode to wda-source USB cable or same wifi HTTP to the runner on :8100, bound to loopback Sources: Liu, Liu and Zhang, arXiv:2610.08699, Table 1 note a and Sec. 5; phoneshell README (Get started), device.py, FINDINGS.md section 24.

The price shows up in operations. After a cold boot the phone sits in BFU, the state before the passcode is first entered, and developer services do not come up until a person types the passcode on the phone. WebDriverAgent is what would type the passcode, and WebDriverAgent cannot start. phoneshell's findings call this a security property rather than a bug. Their rule for unattended runs is that a reboot ends the session. Apple's own route is narrower and in-process: apps expose App Intents, which Siri can call with awareness of what is on screen, the subject of a WWDC26 session on 8 June 2026. That reaches only the actions an app's developer chose to expose.

The two gates, step by step

nanoMuse's Sentinel runs a fixed order: denied tools, the person's own rules, the always-allow and always-ask lists, taint, risk against the chosen mode, and last a set of warnings no list can wave through. For the screen rung it judges the model's sentence and the label at the landing point. On Android it also reads the accessibility text under the finger, and the stricter reading decides. A label with a committing word (confirm payment, transfer, place order, send, delete) makes the step sensitive, approved every time. "A typing step that submits in one go is sensitive, because Enter in a messenger is a send." A step whose target has no label carries a warning.

phoneshell's gate is 14 regular expressions in config.py, applied to the tapped element's label by phone_tap and phone_do. They cover order, pay, checkout, buy, purchase, send money, transfer, book, subscribe, delete, remove, log out and sign out. phone_type with submit=True writes an audit line and presses return, with no gate. The README says actions that look irreversible, naming "send", are refused the first time. The pattern list does not contain send. We found the same gap with different data on 5 October.

Three steps, two gates nanoMuse Sentinel (v0.1.40) phoneshell confirm gate tap a button labelled "Send" messenger, mail sensitive: approve every time"send" is a committing word goes throughonly "send money" is a pattern type a message, submit = return "Enter in a messenger is a send" sensitivea typing step that submits in one go goes throughphone_type: audit line, no gate tap an icon with no label unlabelled button warning, once-only grantno mode or list can wave it through goes throughnothing to match Sources: arXiv:2610.08699 Sec. 5 (Sentinel, Hands); phoneshell config.py confirm_patterns, mcp_server.py phone_tap and phone_type, read 7 October 2026.

What it means if you want an agent to use someone's iPhone

Check it yourself

# nanoMuse: the iPhone note and the gate rules
https://arxiv.org/abs/2610.08699      (Table 1, note a; Sec. 5, "Sentinel" and "Hands")
gh api repos/nano-muse/nanoMuse/releases --jq '.[0:3][] | .tag_name+" "+.published_at'

# phoneshell: the route, the toggles, the gate
sed -n '/## Get started/,/### Watch/p' README.md
grep -oh 'Check("[a-z-]*"' phoneshell/device.py phoneshell/bringup.py | sort -u | wc -l   # 16 named checks
grep -n -A16 "confirm_patterns" phoneshell/config.py
sed -n '/def phone_type/,/return _act_and_report/p' phoneshell/mcp_server.py   # audit, no gate
sed -n '/## 24. A reboot/,/## 25/p' FINDINGS.md

# the measured number
curl -sLO https://huggingface.co/datasets/blolabel/phoneshell-bench/resolve/main/results/xv2.jsonl
python3 -c "import json;R=[json.loads(l) for l in open('xv2.jsonl')];print(sum(r['passed'] for r in R),len(R))"   # 322 349

What would prove this wrong

Our claim is that iPhone hands for a third-party agent come only from outside the phone. By 31 March 2027 we expect nanoMuse's iOS app still to have no screen rung, and any iPhone hands it gains to run from a desktop peer through XCUITest or a similar testing route. If a TestFlight or App Store build of nanoMuse, or of any third-party agent, taps inside another app with no computer attached and no developer settings, the constraint as we state it is wrong. On our side, by 31 December 2026 phoneshell's gate will cover send and typing with submit. Rerun on the 388 audited taps from our earlier note, the widened list should flag at least one step the current one passes.

Sources