ios toolset · the table is a generation behindWill it drive the new iPhone?
Apple's event has not happened as this page is written, so nothing here describes hardware it has not announced. The more useful question is already answerable: macos-mcp's device profile table stops at the iPhone 16 Pro, so it is already behind the phone in your pocket. Here is what that costs, and what it does not.
Requires iPhone Mirroring, whatever the phone is: iOS 18+, the same Apple Account on both devices, the handset locked and nearby. Apple does not offer iPhone Mirroring in the EU.
Will macos-mcp work with the new iPhone?
Yes, for a conventional new iPhone — the eight iphone_* tools keep working the day it arrives, with no update from us, and a tap still lands on the control you aimed at. The sharper answer is in the present tense: DeviceProfile.known has no row for the iPhone 17 line, on sale since last autumn, so this was never a story about hardware announced today. An iPhone 17 in front of macos-mcp right now is already a phone the table does not know.
On the wire that reads quality: "nearest" rather than matched, device_candidates comes back empty, and the profile named belongs to an older phone that is merely the closest shape. (A handset whose shape falls within one percent of an existing row reports matched instead, under that older model's name. Either way the table has no entry for your phone.) Taps land where you aimed them. The reported point size is approximate, and there is nothing you can do today to make it exact — that last one is a real gap, named below rather than glossed.
Why a phone the table has never seen still works
1. The table stops at the iPhone 16 Pro, and shipping hardware already passed it
DeviceProfile.known is eleven entries, keyed by portrait point size and named for the models sharing it — 320×568 for the iPhone SE (1st gen) and 5s, 375×812 for the X, XS, 11 Pro and the minis, 393×852 for the 14 Pro, 15, 15 Pro and 16, up to 402×874 for the iPhone 16 Pro and 440×956 for the 16 Pro Max. Those are the newest rows in the shipping binary. There is no iPhone 17 entry, and this page will not invent one: nobody here has measured that phone, and printing a size we have not checked against a real window is the guess this design exists to refuse.
2. Absent from the table is not absent from the tools
Coordinates are device points, and PhoneGeometry turns one into a place on your Mac's screen by proportion: divide by the profile's logical size, multiply by the observed content rect. Both directions run through the same contentRect, so a device_center that iphone_find just reported maps back to the pixel it was read from. A profile that is the wrong shape by two percent moves every coordinate by the same two percent, and the source states the consequence outright: a wrong-by-2% profile still maps taps to the correct control, because the mapping is proportional. The missing row is a labelling problem, not a functional one.
3. The quality of the match travels with the match
A shape is compared against the table within a 1% tolerance, and the answer carries how good it is. matched means at least one profile fits; nearest means none does and the profile reported is only the closest; pinned means you passed device, so the shape was never consulted. In the nearest case device_candidates comes back empty on purpose — that emptiness is the finding, so a guess never arrives looking like a fit. Older code put the nearest profile in that list, making a guess and a fit indistinguishable on the wire; a real mirrored window forced the split, at 369×807 and aspect 2.187 with nothing inside the tolerance and iPhone 16 Pro, 2.1741, sitting 0.0129 away. The repo does not name that handset's model, so neither does this page. But nearest is the everyday state for a phone newer than the table, and it is the toolset telling the truth rather than failing. Verified, not claimed.
4. The shape gate is deliberately generous
DeviceProfile.isPlausiblePhoneShape admits aspect ratios from 1.5 to 2.6, and the comment above it says why: the band is generous "so an unreleased phone is never refused for being new. It exists to catch shapes that are not phones, not to police the ones that are." The table's own profiles cluster near 1.78 and 2.16–2.17, so a conventional new iPhone sits inside it comfortably. The gate followed a measured defect: on a dark Settings page the detector found only the status bar and reported a 337×63.5 region at aspect 5.31, so an iphone_key back swipe built on that band landed in a settings row and the change check called it verified. That shape is refused as content_unreadable now, before it becomes a coordinate space. No false successes.
What each device_match.quality value means
quality | What was observed | device_candidates | What to do |
|---|---|---|---|
matched | At least one profile fits the shape within tolerance. | Every profile that fits, closest first. | Nothing — though the name may be an older model sharing that shape. |
nearest | Nothing fits; the profile reported is the closest shape, deviation away. | Empty — the finding itself. | Keep going: taps land correctly. Nothing makes the point size exact until a profile exists. |
pinned | You passed device, so shape was never consulted; deviation is zero. | The one id you pinned. | Read aspect_ratio to check the pin is sane — nothing else did. |
What you cannot do: pin your way out
Every iphone_* tool takes an optional device argument, and it is worth being exact about what it fixes. IOSToolset.profile resolves the id through DeviceProfile.known(id:) and throws invalid_argument for anything else, listing the eleven ids it accepts. The argument takes only a profile already in the table. A phone the table does not know has no id, so there is nothing to pin: no user-side remedy today, only the honest nearest.
iphone_status {}
→ phone.device_match: { quality: "nearest", approximate: true,
aspect_ratio: 2.187, deviation: 0.0129,
tolerance: 0.01, candidate_count: 0 }
phone.device_candidates: []
iphone_tap { "x": 52, "y": 566, "device": "iphone-17-pro" }
→ invalid_argument: param "device",
expected "one of: iphone-se-1, iphone-se, … iphone-16-pro-max"
Pinning a neighbouring id is worse than leaving it alone: a pinned call never consults the shape, so it returns quality: "pinned", approximate: false, deviation: 0 — exactness the answer does not have, which is the one thing this subsystem was rebuilt to stop. The remedy is a measured profile, not a flag.
The foldable question, carefully
Apple has announced no foldable iPhone. It is widely reported and nothing more, so this page will not name it, size it, or promise it. What can be said is what the code does with a shape it does not expect. The 1.5–2.6 band is a sanity check on the detector, not a compatibility list: a window that is not phone-shaped usually means the region found is not the phone. A device whose unfolded aspect ratio sat far outside that band would be refused there — content_unreadable, naming the region and aspect measured, instead of a coordinate the toolset does not trust. That is the design working. Folded, a phone-shaped display passes the gate like any other unknown phone and reports nearest. So: driving such a device unfolded would need a profile of its own and possibly a widened band first — a small, known change, and not a promise with a date on it.
How to help
A profile is an id, a display name and a portrait size in points, and the table is one generation short — the iPhone 17 line is the first thing it wants. Once a phone's point size is measured on real glass, open an issue with those numbers and the iphone_status output behind them at github.com/Ark0N/macos-mcp/issues. Nothing goes into that table on the strength of a spec sheet nobody has checked against a window.
Next
The ios toolset is the whole picture: eight tools, OCR as the primary locator because the mirrored window has no accessibility tree, every action read back, never assumed, off by default. macOS 27 Golden Gate covers the platform side. macos-mcp is 44 tools, 24 on by default; signed, notarized, audited; MIT, no telemetry.
Questions
Will macos-mcp work with the iPhone 18 Pro?
Apple has not announced this year's iPhones as this is written, so nothing here describes them. What can be said is what the code does with any iPhone it has never seen, and that is not hypothetical — it already applies to the iPhone 17 line on sale now. The eight iphone_* tools keep working with no update from us and taps land on the control you aimed at, because the window-pixels to device-points mapping is proportional rather than table-driven. What you lose is the reported point size being exact: phone.device_match.quality comes back nearest, device_candidates comes back empty, and the profile named belongs to an older phone that is the closest shape.
Does macos-mcp have a device profile for the iPhone 17 Pro?
No. The newest rows in DeviceProfile.known are the iPhone 16 Pro at 402x874 points and the 16 Pro Max at 440x956, and there is no iPhone 17 entry — the table is a generation behind shipping hardware. This page does not print what those numbers should be, because nobody here has measured that phone. The practical effect is that no device_match result can name your handset: either nothing fits within the 1% tolerance and you get nearest with an empty candidate list, or your phone's shape happens to land within a percent of an older row and you get matched under that older model's name.
What does device_match.quality: nearest mean?
It means no profile in the shipped table fits the window's shape within the 1% tolerance, and the profile being reported is only the closest one. device_candidates is empty in that case, deliberately, so a guess never looks like a fit. It is not a failure: taps still land correctly because the mapping is proportional, and deviation against tolerance tells you how far off the reported point size is. It is measured behaviour, not theory — a real 369x807 mirrored window came back at aspect 2.187 with nothing inside the tolerance, iPhone 16 Pro at 2.1741 sitting 0.0129 away.
Can I pin my iPhone 17 with the device argument?
No, and this is the honest limitation. Every iphone_* tool takes an optional device argument, but IOSToolset.profile resolves it through DeviceProfile.known(id:) and throws invalid_argument for anything not already in the table, listing the eleven ids it will accept. There is no id for a phone that has no profile, so there is nothing to pin. Pinning a neighbouring id is worse than leaving it alone: a pinned call never consults the shape, so it reports quality: pinned, approximate: false and deviation: 0 — exactness the answer does not actually have. The remedy is a measured profile in the table, not a flag.
Do taps land in the right place if the device profile is wrong?
Yes, within the accuracy of the detected content rect. PhoneGeometry divides a device point by the profile's logical size and multiplies by the observed content rect, and both directions — OCR pixels in, screen points out — go through the same contentRect, so a device_center that iphone_find just reported maps back to the pixel it was read from. A profile that is the wrong shape by two percent moves every coordinate by the same two percent. The source says it directly: a wrong-by-2% profile still maps taps to the correct control, because the mapping is proportional.
Will macos-mcp drive a foldable iPhone?
Apple has announced no foldable iPhone; it is widely reported and nothing more, and we are not going to size it or date it. What is checkable today is the code's behaviour with an unexpected shape. DeviceProfile.isPlausiblePhoneShape admits aspect ratios from 1.5 to 2.6, and a device whose unfolded screen fell far outside that band would be refused by the gate: the toolset reports content_unreadable, naming the region and aspect it measured, rather than handing out a coordinate it does not trust. Driving such a device unfolded would need a profile of its own and possibly a widened band — a small, known change, with no timeline attached to it here.
Can I control a new iPhone from my Mac on launch day?
If iPhone Mirroring itself works with it, yes. macos-mcp drives the handset through Apple's own iPhone Mirroring window, so the requirements are Apple's: iOS 18 or later, the same Apple Account on the iPhone and the Mac, the phone locked and nearby, and macOS 15 or later on Apple Silicon. Apple does not offer iPhone Mirroring in the EU, and nothing here works around that. The ios toolset is off by default; an agent has to call enable_toolset ios first.