Desktops and MCP
A desktop is an agent whose machine has a real screen: a Linux desktop at 1280 by 800, Google Chrome, LibreOffice and a file manager. Like any agent it keeps everything, sleeps when idle and comes back exactly as it was, open windows and signed-in websites included. It is ready about two seconds after you ask for it, and wakes in 0.2 seconds.
Two ways to use one
- An agent with a screen. Deploy with
--desktop(or"desktop": true). The harness inside the machine learns that it has a screen and how to use it, so you can just ask: "open this site and tell me what you see". - A computer for your own agent. Your agent runs wherever you want, and drives a Waken desktop over MCP. One persistent desktop per end user of your product.
Driving a desktop over HTTP
| Route | What it does |
|---|---|
| GET /agents/{id}/desktop/screenshot | A PNG of the screen, in about 0.1 second |
| POST /agents/{id}/desktop/actions | Up to 50 actions in order, stops at the first failure |
| POST /agents/{id}/desktop/viewer | A link to watch and control the desktop live in a browser, valid one hour |
{ "actions": [{ "type": "open_url", "url": "https://example.com" },{ "type": "wait", "ms": 2000 },{ "type": "click", "x": 640, "y": 400 },{ "type": "type", "text": "hello" },{ "type": "key", "keys": "Enter" }] }
Actions: open_url, click (with button and double), move, type, key (for example ctrl+l), scroll (dx, dy), drag (x, y, to_x, to_y), wait. Coordinates are pixels on the 1280 by 800 screen. These routes need the computers scope.
The MCP server
Endpoint: https://api.waken.sh/mcp (streamable HTTP). Authenticate with an API key that has the computers scope.
claude mcp add --transport http waken https://api.waken.sh/mcp \--header "Authorization: Bearer $WAKEN_KEY"
| Tool | What it does |
|---|---|
| get_computer | The persistent desktop of one end user (user_id is your own id for them). Created on the first call, woken on the next ones |
| computer | One action, then a screenshot of the result |
| computer_batch | Up to 50 actions, then one screenshot |
| run_shell | A shell command on the computer, 30 seconds at most |
| read_file, write_file | Text files, 8 MiB at most |
| request_takeover | Ask a person to take the mouse and keyboard. Returns a link to give them |
| takeover_status | none, pending, done or expired |
| close_computer | End the session: the computer sleeps now |
When a human is needed
Logins, CAPTCHAs and payments should be done by a person. Your agent calls request_takeover with a reason. You send the returned link to your user. They see the live screen with the reason, do what is needed, and press "I'm done". Your agent polls takeover_status and continues. You also receive a computer.takeover_requested webhook with the link.
Because the desktop persists, your user signs in to a site once. The session is still there next week.
Next: container images