Cupertino 1.15.0
Version 1.15.0 ·
Added
Cupertino can drive any app on the Mac now, not only the seven it brokers. The new Desktop surface reads and operates interfaces through the Accessibility API: list what is running, walk a window's element tree, find a control by name, press it, expand a disclosure. It is a capability rather than a broker — there is no target app, and it reaches whatever is in front of you.
This lane had been closed three times here, on numbers that were measuring something else. Every Accessibility measurement this project took before it went through
osascriptand System Events, one Apple Event per attribute, so the 33.6 ms round trip in the Safari notes and the ~14 s place card in the Maps notes were the price of the transport rather than of the API. Called natively the same Maps card walks in 0.177 s, and 13,960 nodes across seven apps average 1.24 ms a round trip. 86% of pressable elements carry an identifier, title or description, so a control is addressed by name rather than by guessing at coordinates.It arrives switched off, with its writes gated, the way Screen and Sound do. The Accessibility grant is per-process and all-or-nothing: it hands over every window on the machine, far past anything Cupertino is asked to broker, so it is switched on by the person who wants it rather than found already on.
A tool list can be traded for a searchable index now. Listing every tool across the eight servers with writes on costs ~106 KB — roughly 26.5k tokens, paid by every client on every connect, whether or not one tool is ever called.
*_LAZY_TOOLS, off by default, swaps the list forsearch_tools,describe_toolandcall_tool, plus a separatecall_write_toolwhen writes are on, so a host's read/write permission boundary survives the facade rather than collapsing into one anonymous name.diagnosticsstays eagerly listed, since it is what every surface guide points at first on a refusal.In the app it is a per-surface Load tools on demand control, defaulted app-wide in General and overridable in each surface's Access card. Activity still names the tool that actually ran —
apple_mail_send_message, not the dispatcher that carried it.
Changed
Every tool listing is 4.6% smaller, on every server and without opting in to anything. The MCP SDK stamps a generated
"$schema"key onto everyinputSchemaandoutputSchemait emits, and nothing in the protocol ever reads it back. It is dropped from the outgoing listing now.
Fixed
The Maps notes no longer describe a favourite that never got written. Four claims there had been read off read-only dumps of the interface; pressing the control for real falsifies all four. It opens a naming sheet instead of writing a favourite, what lands is an unfiled saved place rather than a favourites row, the control is not a toggle, and the state bit lives on the sibling button beside it. Only the addressing claim survived.
The website describes what actually ships now. Desktop was missing from the surface list entirely; the whole list sat under "each surface is its own npm package", true of only eight of the eleven; and the menu-bar mock captioned every row "automation allowed", including Maps and the three capabilities, which send no Apple Event at all. The site reads
KIND,USES_APPLE_EVENTSandSUPPORTS_WRITESgenerated fromsurfaces.jsonnow, so a card or a caption cannot drift from the manifest again.The pricing note no longer promises a ladder that was retired. The surface list claimed that adding a surface raises the price, and
docs/licensing.mdcarried the promise and its retraction in one document — a table still saying "rising with the surface count" above a section describing the ladder as retired. The price stayed flat across the whole 1.x line through three new surfaces, and listing one commits to support at the price already paid.