Direct control from a coding agent (research preview)
Let Claude Code, Codex or Cursor drive the computer and see the screen.
View as MarkdownWith the task tools, your coding agent asks Sai to do something and reads Sai's description of the result. With the control tools, your coding agent drives the computer itself: it runs Simulang blocks on it and gets each block's screenshot as an image its own model can see. See Direct control for the model.
Direct control is open to every account. The model calls the code makes (callLLM, ground, stateSatisfies) are billed to your account as usual.
Setup
The control tools come with the Sai MCP server, next to the task tools; there is nothing to turn on. To leave them out, set SAI_CONTROL=0 on the server.
In Codex, also set tool_timeout_sec = 120 in the [mcp_servers.sai] table: Codex's default of 60 seconds is shorter than a block's default time limit.
Tools
machine_id comes from sai_machines.
timeout_s defaults to 90 and is capped at 110, under the clients' tool timeouts. For a longer step, split it into several blocks.
The server also publishes the Simulang reference as the MCP resource sai://simulang/reference. The server's instructions tell the model to read it first. It is the same reference as Simulang in direct control.
Try it
Take control of my Sai computer, open https://news.ycombinator.com in the browser, and tell me the top three stories. Close control when you are done.The model opens control, runs a few blocks (open a tab, snapshot, read the outline), looks at the screenshots that come back, and closes control.
Screenshots per client
Where the model does not see images, it can still read the screen as text: page.snapshot() and app.snapshot() return outlines with refs it can act on.
Gotchas
- Control holds the computer. Your Sai tasks on it wait until the model closes control, or until it sits idle for 10 minutes.
- The control tools address the computer by
machine_id. They have nothing to do with thesession_idthatsai_task_startreturns. - A free plan's computer is deleted when control closes.