MCP
How an outside agent reaches the device through the companion: manage it, show the user a screen and get the answer back, or install a real app.
Some things that reach the device live on it — a glance you scroll to, an app in its flash. MCP is the one that does not. An agent running on your Mac — Claude Code, Cursor, anything that speaks MCP — reaches the device through the companion, and never lands on it. The agent stays where it already runs.
Over that one connection, an agent can do three things.
One connection, three things an agent can do
Your agent
Claude Code, Cursor — anything that speaks MCP.
- managesThe device
See it, read its state, change its settings — the whole tool surface.
- shows onThe screen
Ask a question, or draw a screen of its own — and get the answer back.
- installsA real app
Put an app on the device that then runs on its own, with no agent attached.
Nothing is installed on the device
The companion runs a small server that only your Mac can reach. Your agent connects to it with a token you create on the companion's MCP page. The first time a new token calls in, the companion asks you to approve it — until you do, every call is refused. A token you created is not yet a token you trust.
After that, all three verbs are open. No build step, no bundle, nothing flashed to the device.
The endpoint, if you are wiring it up yourself
The server listens only on your own machine, at
http://127.0.0.1:<port>/mcp, and every call carries a bearer token you
mint on the companion's MCP page. The full walkthrough is in
Connect Claude Code.
Manage the device
The first verb is plain control. An agent can list every device the companion knows, read one device's full state, change its settings, move around its screens, put it to sleep or wake it — the same things you would do by hand in the companion, done by the agent instead.
This is the widest part of the surface and the least surprising. Agents over MCP lists every tool and what each one is allowed to touch.
Show the user something
The second verb is the interesting one. An agent can put something on the device's screen for a moment, and — this is the part that is easy to miss — get the user's answer back. It can ask, with a shape the device already knows, or show a screen it designs itself.
Ask: a shape the device already knows
For the common cases there is a small set of ready-made shapes. The agent picks one, fills in the words, and the device draws it:
| Shape | What the user sees |
|---|---|
| A bell | A count on the device — how many of something is waiting. |
| A status line | One live line the agent keeps up to date. |
| A card | A small notice: an icon, a title, a line of text. |
| A full-screen alert | Takes the whole screen and wakes it. The agent needs your permission for that one; without it, the alert becomes a quiet card instead. |
| A question | Up to three options, one on each of the device's buttons. The device holds it on screen, and the call waits — it returns carrying the option you pressed. |
That last one is the whole point. The agent asks "Approve deploy to prod?" on a device sitting on your desk. The question stays up, the agent is stopped on that call, and when your thumb lands on a button the call returns with your answer. Your agent asked, you pressed a button, your agent continued — and it never left the call.
A question, and the answer that comes back
A few things fill out the contract:
| A default | The agent can name a fallback option and a time limit. If nobody answers in the window, that fallback is what the call returns. |
| A dismissal | If the question is waved away, the call is told it was dismissed. A question that was never answered never pretends it was. |
| No waiting | The agent can post a question and not wait — it goes up, and the call returns straight away. |
Show: a screen the agent designs
When a ready-made shape is not enough, the agent hands over a screen of its own — with sliders, toggles, choices and buttons the user works through. When the user is done, the whole result comes back to the agent as one typed answer: the button they ended on, every value they set, and the path they took to get there.
The agent can also keep a live screen up — one that stays on the device and reports each button press back as it happens, so the agent can react while you are still looking at it.
It draws on a free spot. A screen an installed app already owns stays that app's — the app would redraw it a moment later and paint over the agent — so the agent is told so at once, rather than left believing a screen is up.
The calls behind this, if you are writing the agent
notify posts every ready-made shape — the bell, the status line, the
card, the full-screen alert, and the question that waits and returns the
chosen option. Its richer form carries a multi-page body and returns the
terminal action, the values the user set, and the steps taken to get there.
push_screen puts up a live screen, and subscribe_intents streams each
button press back to the agent over a stateful session that survives the
device reconnecting. The full-screen alert needs the urgent scope, or it
downgrades to a card; a push can carry a ttl_seconds and the companion
clears the screen when it elapses.
Every tool, its arguments, and the scope each one needs are in Agents over MCP.
Install a real app
The first two verbs are live — they last only while the agent is connected. The third one is not. An agent can put a real app on the device: one that runs on its own, in the device's flash, and needs no agent attached to keep working.
Today the agent installs a published app from the catalog — the same apps you could install by hand, installed by the agent instead. An agent that writes a brand-new app of its own — building the bundle itself, not just picking one off the shelf — is a direction we are building toward.
Once installed, the app is the device's. It keeps running with your Mac closed, because nothing about it lives on your Mac. That is the line between this verb and the last one.
The lifecycle calls, if you are writing the agent
app_install puts an app on a device — a published catalog app, a local
app file, or one compiled into the companion — and app_uninstall,
app_set_enabled and app_list round out the lifecycle. Every tool and its
scope is in Agents over MCP.
Where the agent lives
The agent is the host. It runs wherever it already runs, and that is the whole trade.
If the agent goes away, the last screen it drew goes stale.
It stays on the device, showing whatever it last said. Nothing on the device recomputes it, because the thing that computes it is on your Mac.
Code that must keep working with your Mac asleep belongs in an installed app, in the device's own flash.
| Show or ask | Install an app | |
|---|---|---|
| What reaches the device | a screen, drawn live | a real app |
| Where the logic runs | on your Mac | on the device |
| With your Mac asleep | the screen goes stale | a Standalone app keeps running |
| To start | connect, approve once, call a tool | pick one from the catalog |
Next
- Agents over MCP — every tool, and the scope each one needs.
- The three calls, in order — asking, showing, and hearing the press back.
- WASM or MCP? — which surface a given idea belongs on.
- Connect Claude Code — the endpoint, the token, the approval.