Moving from Orgo or E2B
Orgo computers, E2B Desktop sandboxes and Mandala computers do the same basic job. Each is a Linux desktop that your code or your agent can screenshot, click, type into and run commands on. Most code moves over one call at a time. This page maps the calls and then lists the differences that change how you write the code around them.
Install and authenticate
pip install mandala-computer # Python 3.10+
npm install mandala-computer # Node 22+, also installs the mandala CLICreate an API key in Settings → Credentials → API keys and put it in MANDALA_API_KEY, where ORGO_API_KEY or E2B_API_KEY used to be. Or run mandala login once, which saves a profile that both SDKs read.
Orgo to Mandala (Python)
| Orgo | Mandala |
|---|---|
Computer() | client.computers.launch(template="base") |
Computer(ram=4, cpu=2) | client.computers.launch(cpu=2, ram_mb=4096), or size="standard" |
Computer(computer_id=id) | client.computers.get(id) |
computer.screenshot() (PIL image) | Image.open(io.BytesIO(computer.screenshot())) |
computer.screenshot_base64() | base64.b64encode(computer.screenshot()).decode() |
computer.left_click(x, y) | computer.click(x, y) |
computer.right_click(x, y), double_click(x, y) | computer.right_click(x, y), computer.double_click(x, y) |
computer.drag(sx, sy, ex, ey) | computer.drag(ex, ey, from_x=sx, from_y=sy) |
computer.scroll("down", 3) | computer.scroll(direction="down", amount=3) |
computer.type("hello") | computer.type("hello") |
computer.key("Enter"), key("ctrl+c") | computer.key("Return"), computer.key("ctrl", "c") |
computer.wait(2) | computer.wait(2) |
computer.bash("ls") | computer.exec("ls").stdout_text |
computer.exec(python_code) | computer.write_file("/tmp/job.py", code) then computer.exec("python3 /tmp/job.py") |
computer.prompt("…") | computer.agent("…", model_key=ANTHROPIC_API_KEY) |
computer.status() | computer.refresh().status |
computer.restart() | computer.restart() |
computer.destroy() | computer.delete() |
computer.start_stream(...) | computer.vnc.embed_url, to watch in a browser (or computer.vnc.view_url, a WebSocket for your own noVNC client) |
Orgo's project and workspace arguments group computers. In Mandala, a workspace does that job. A key issued for a workspace sees and creates computers only in that workspace, so with one key per workspace the code needs no project argument. An account-wide key can instead pass workspace_id when it creates or lists computers.
E2B Desktop to Mandala (Python)
| E2B Desktop | Mandala |
|---|---|
Sandbox.create() | client.computers.launch(template="base") |
Sandbox.create(resolution=(1920, 1080)) | client.computers.launch(resolution="1920x1080") |
Sandbox.connect(sandbox_id) | client.computers.get(computer_id) |
desktop.screenshot() (bytes) | computer.screenshot(fresh=True) |
desktop.left_click(x, y) | computer.click(x, y) |
desktop.right_click, middle_click, double_click | computer.right_click, middle_click, double_click |
desktop.move_mouse(x, y) | computer.move(x, y) |
desktop.drag((x1, y1), (x2, y2)) | computer.drag(x2, y2, from_x=x1, from_y=y1) |
desktop.mouse_press(), mouse_release() | computer.mouse_down(), computer.mouse_up() |
desktop.scroll("down", 3) | computer.scroll(direction="down", amount=3) |
desktop.write("hello") | computer.type("hello"), or computer.paste(text) for long text |
desktop.press("enter"), press(["ctrl", "c"]) | computer.key("Return"), computer.key("ctrl", "c") |
desktop.wait(1000) (milliseconds) | computer.wait(1) (seconds) |
desktop.get_cursor_position() | computer.cursor_position() |
desktop.get_screen_size() | computer.screen |
desktop.open(url) | computer.open(url) |
desktop.launch("google-chrome") | computer.start_exec("chromium", desktop=True) |
desktop.commands.run("ls") | computer.exec("ls") |
desktop.commands.run(cmd, background=True) | computer.start_exec(cmd) |
desktop.files.write(path, data), files.read(path) | computer.write_file(path, data), computer.read_file(path) |
desktop.stream.start(), stream.get_url() | computer.vnc.embed_url (a watch-only page); for control, computer.vnc.url is a WebSocket for a noVNC client — there is no hosted full-control page, so use the dashboard |
desktop.set_timeout(seconds) | closest: computer.set_idle_suspend(minutes) (suspends, never deletes) |
desktop.pause(), connect() | computer.suspend(), computer.start() |
desktop.create_snapshot() | computer.snapshot() |
desktop.kill() | computer.delete() |
The TypeScript SDK uses camelCase for most of these (rightClick, mouseDown, writeFile, and so on), but two differ in name: Python's start_exec(cmd) is computer.execBackground(cmd) in TypeScript (with { desktop: true } where the Python call passes desktop=True), and Python's set_idle_suspend(minutes) is computer.update({ idleSuspendMin: minutes }).
What behaves differently
A computer lasts until you delete it. An E2B sandbox ends when its timeout runs out. A Mandala computer keeps its disk, files and installed software through stops, restarts and suspends, and is billed while it runs. When nobody has used it for the idle window, it suspends itself, and the next input or command resumes it. The window is 30 minutes by default, but the operator can set a host's window differently, or turn it off; to be sure of a computer's window, set idle_suspend_min on it with computer.set_idle_suspend(minutes). Delete computers you no longer need, or use client.computers.ephemeral(...), which deletes the computer when the with block ends.
Launch waits for readiness. launch() creates the computer, starts it and returns once its guest agent answers, typically in a few seconds for a size from client.sizes.list(). A custom CPU and RAM shape boots from cold and takes longer. create() returns straight away if you want to manage the waits yourself.
Commands run as root, without a display. exec() runs as root in a login shell with no DISPLAY. That is right for installing packages. A program with a window needs exec(..., desktop=True) or start_exec(..., desktop=True), which run as the desktop user inside the graphical session. open(url) opens the desktop's browser.
Commands wait, up to a limit. exec() waits for the command, 30 seconds by default and at most 600. On the hosted service a request with no answer for about two minutes can be cut off by the proxy, so start anything slower with start_exec() and poll it.
Screenshots can be cached. screenshot() may return a frame up to 1.5 seconds old (up to 30 seconds while the computer is busy), which is cheap enough for thumbnails. Pass fresh=True whenever the image feeds a decision.
Key names are X11 names. Return, BackSpace, Page_Down and ctrl+c style chords all work, and so do the common spellings enter, esc and CTRL. An unknown key is refused by name rather than skipped.
Text over 400 characters needs a split or a paste. type() takes up to 400 characters. paste() takes up to 8 KB, and is much faster.
The resolution is fixed at create time. Choose it with resolution= when you create the computer. It is the coordinate space for every click and the size of every screenshot.
A ported script
An Orgo or E2B script that opens a page, reads a value with a command and saves a screenshot looks like this on Mandala:
from mandala_computer import Client
client = Client() # reads MANDALA_API_KEY
with client.computers.ephemeral(template="base", name="ported-script") as computer:
computer.wait_for_guest()
width, height = computer.screen
# A command, as root, without a display.
kernel = computer.exec("uname -r")
print("kernel:", kernel.stdout_text.strip())
# Files in and out.
computer.write_file("/tmp/hello.txt", "hello from the SDK\n")
print(computer.read_text_file("/tmp/hello.txt").strip())
# A program with a window, on the desktop.
computer.start_exec("xfce4-terminal", desktop=True)
computer.wait(3)
computer.click(width // 2, height // 2)
computer.type("echo typed on the desktop > /tmp/typed.txt")
computer.key("Return")
computer.wait(1)
print(computer.read_text_file("/tmp/typed.txt").strip())
with open("screen.png", "wb") as f:
f.write(computer.screenshot(fresh=True))
print("saved screen.png", width, "x", height)Agents and MCP
- Orgo's
computer.prompt()maps to Mandala's built-in computer agent. Send your own Anthropic key for BYOK (computer.agent(task, model_key=...)in Python), or omitX-Model-KeyonPOST /api/v1/computers/{id}/agentto use Mandala AI credits when enabled for your account. Funded runs require a plan, a supported Stripe billing country, and at least $0.25 available. They default to Sonnet 5.5, with Opus 5.5 selectable; provider fallbacks can use other priced models. Usage costs 1.3× Anthropic's API list price. Solo/Studio/Swarm grants are $5/$10/$50 per monthly billing period and expire at period end. $10/$25/$50 top-ups expire 12 months from purchase. Plan loss freezes existing credits without extending expiry; a purchase paid after plan loss is issued on resubscription only if unexpired. The final call can exceed a run'smax_cost_usdadmission budget. Usage beyond remaining credits creates debt that survives expiry and is paid first from future grants and top-ups. See the funded and BYOK guide for the boundary: credits cover the built-in loop only, while/chat/completionsand agents inside a computer still use your own provider. - Orgo's
thread_idon/v1/chat/completionsand its/v1/threadsmap to Mandala'sthread_idonPOST /api/v1/computers/{id}/agentand/api/v1/chat/completions, andGET/DELETE /api/v1/agent/threads. A Mandala thread belongs to one computer and is kept server-side, so a client that resends the wholemessageshistory with athread_idgets the same run as one that sends only the new message. In the SDKs (0.16.0 and later), passthread_id=tocomputer.agent()(threadIdin TypeScript), and list, read or delete threads withclient.agent_threads(client.agentThreads). - Orgo's handoffs (
/api/v1/handoffs,orgo handoff start/status/cancel) map to background runs:POST /api/v1/computers/{id}/agent/runsstarts one and answers with its id,GET /api/v1/agent/runs/{run}reads its status, steps and cost, andPOST /api/v1/agent/runs/{run}/cancelstops it. In the SDKs that isclient.agent_runs.start(),get(),wait()andcancel()(client.agentRunsin TypeScript); over MCP,start_agent_run,get_agent_runandcancel_agent_run. - To run the loop yourself with a chosen model, see the Claude, OpenAI, Gemini and LangChain guides.
- MCP clients can use the hosted server at
https://app.mandala.computer/mcp, which signs in through the browser, or runnpx -y mandala-computer-mcplocally with an API key. - Agents that read instructions can load the Mandala skill from /skill.md.
See also: Troubleshooting and the API reference.