cubicle
Provides credential and TOTP retrieval from 1Password for signing into websites through the computer. It matches 1Password items to the page's registrable domain, pastes passwords/one-time codes into focused fields without exposing them to the model, and returns needs_human when 1Password is locked.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@cubiclesign into my Gmail and tell me the subject of the newest email"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
A computer for your coding agent. Already logged in as you.
An MCP server that hands any MCP client a Linux desktop which keeps your sessions between tasks, fills passwords from 1Password without the model seeing them, and lets you take over whenever you want.
benchmark | score | what it covers |
22/24 | browser widgets, scored rewards | |
9/10 | live websites, judged on the final screenshot | |
7/7 | files, editor, terminal, archives, LibreOffice |
Your agent gets stuck on something it cannot do: sign into SharePoint, click through a dashboard, copy a value out of a web UI. So you paste a brief into some other computer-use product, wait, and paste the answer back. You are the integration.
The GIF above is a real run. bun deploy.ts fails because an API key is missing, the key
sits behind a login, and the agent signs in and fetches it without you. The form fields
come from the accessibility tree rather than from pixels, and the username, password and
one-time code are typed straight out of 1Password.
How it fits together
your Mac the cloud
----------------------------------------- -----------------------------------
Claude Code / Codex / Cursor
|
| MCP over stdio
| computer_page, computer_click, computer_paste, ...
v
cubicle MCP server ----- E2B SDK over https -----> your computer
| (Ubuntu + Xfce)
| read on demand, never |
| returned to the model +-- Chrome, signed in
v +-- accessibility tree
1Password + ~/.cubicle/stash.json +-- shell, files
|
|
your browser <---- VNC, from computer_takeover -----------+One tool call is one round trip: Claude Code asks the MCP server, the server calls the sandbox over HTTPS, the sandbox acts on the desktop and answers. Nothing listens on your Mac and the sandbox is never exposed; both connections are outbound.
Between calls the computer is paused, RAM and disk, so it stays signed in and costs nothing while idle. The first call after a pause resumes it in about a second.
computer_takeover hands you a URL for that same desktop, so you can sign in or clear a
CAPTCHA by hand and let the agent carry on.
Secrets never make the round trip. computer_paste resolves a 1Password item or a
stashed value on your Mac, sends it to the sandbox, types it with xdotool and shreds
it. The model sees {status: "pasted", chars: 20}.
Related MCP server: Boxline MCP server
Quickstart
git clone https://github.com/moritzWa/cubicle && cd cubicle
bun install
echo 'E2B_API_KEY=e2b_...' > .env # free key at https://e2b.dev
bun bin/cubicle.ts setup # builds your computer, about a minute
bun bin/cubicle.ts doctor # checks everything is in place
claude mcp add cubicle -- bun $PWD/bin/mcp.tsThen ask Claude Code for something behind a login:
check my Gmail and tell me the subject of the newest email
The first time it will hit a sign-in page. Ask for computer_takeover, open the URL,
log in by hand, and every later task starts authenticated.
Setup is a separate command because provisioning a fresh sandbox takes longer than the 60 seconds MCP clients allow for one tool call.
Tools
tool | what it does |
| the URL plus every interactive element with its screen coordinates, read from the accessibility tree |
| 1024x768 PNG |
| OS-level input, so pages see a real user |
| open a URL |
| run a command in the computer |
| press, move, release: drag-and-drop, sliders, selecting text |
| type a secret into the focused field without the model seeing it |
| names of locally stashed values, never the values |
| move files between your Mac and the computer |
| a URL where you drive the same desktop yourself |
| save all state, including logins |
Secrets
# from 1Password, matched against the page's domain
computer_paste({ from: "1password", field: "password" })
# from anything you stash locally
cubicle stash ssh_pub --file ~/.ssh/id_ed25519.pub
computer_paste({ from: "stash", name: "ssh_pub" })The value travels from your Mac into the computer over the file API, gets typed with
xdotool, then shredded. It never lands in a command line, a log, or a model's context.
The agent only handles the name.
A paste is refused when no 1Password item matches the page's registrable domain, when
the focused element is not a text field, and when a password would go anywhere that is
not a password field. A locked vault comes back as needs_human rather than hanging.
How it works
The computer is an E2B desktop sandbox running Ubuntu, Xfce and real Google Chrome. Between tasks the whole machine is paused, RAM and disk, so logins survive and idle time is free. Resuming takes about a second.
It pauses itself after 90 seconds without a tool call. That is for correctness rather than cost: a sandbox that reaches its own timeout silently reverts to the last explicit pause, and nothing raises an error.
Chrome publishes its interface over AT-SPI, so vmagent/accessibility.py can read the
focused tab's URL, the focused element and every field with its coordinates. Input goes
through xdotool against the X display, never CDP or automation flags, which keeps
navigator.webdriver false and sign-in pages well behaved.
Does it work
Three benchmarks and a login, 38 of 41 tasks passed, all of it reproducible from this repo.
Start with the login, end to end, which is the run in the GIF:
bun test/e2e-login.ts # deploys a test site into the computer, signs in, exits 0 on successAnd MiniWoB++, 130 browser tasks with scored rewards, driven by Claude Code through these tools and nothing else:
bun evals/setup-miniwob.ts # once: clone the tasks into the computer, serve them
bun evals/miniwob.ts # 24 tasks, about 20 minutes
bun evals/miniwob.ts click-pie,terminal,drag-items22 of 24 passed, median 46 seconds per task, on Claude Opus 5 with no screenshots needed for most of them:
passed | click-button 0.97, enter-text 0.96, click-checkboxes 0.96, click-tab-2 0.96, login-user 0.96, use-autocomplete 0.96, click-dialog-2 0.97, simple-algebra 0.96, click-pie 0.96, drag-items 0.96, copy-paste 0.96, count-shape 0.96, use-slider 0.95, tic-tac-toe 0.95, scroll-text 0.94, click-collapsible-2 0.90, enter-date 0.86, click-shades 0.67, choose-date-easy 0.63, terminal 0.58, search-engine 0.55, guess-number 0.27 |
failed | book-flight (long multi-step booking; hard for every agent), email-inbox-forward-nl (solved, but reward 0.16 after the time penalty) |
Rewards are time-scaled, so a low score means slow rather than wrong.
And WebVoyager, the same thing on live websites, where a second Claude call grades the answer against the final screenshot:
bun evals/webvoyager.ts
bun evals/webvoyager.ts "GitHub--0,ESPN--0"9 of 10 passed: arXiv, Wolfram Alpha, Hugging Face, GitHub, BBC News, Apple, ESPN,
Google Search, Coursera. The failure is Cambridge Dictionary, which serves a Cloudflare
challenge. That is what computer_takeover is for: solve it once by hand and the
session persists.
And a desktop set, because none of the above leaves the browser:
bun evals/desktop.ts7 of 7 passed: create a folder and rename a file in Thunar, type and save in
Mousepad, open the Terminal app and make a file with it, extract a zip with the
graphical archive manager, build a sum in LibreOffice Calc and save it as CSV, and
chmod +x through Thunar's Properties dialog. The agent is given every tool except
computer_shell, so it has to drive the GUI; setup and checking run over the shell
from the harness, so each task is pass/fail with no judge.
The evals paid for themselves: they found five real bugs, all fixed. computer_page
ignored div-built UIs, leaked the browser's own toolbar into the page listing, and
repeated each piece of text once per node down the tree. There was no way to drag.
And computer_navigate slept a fixed three seconds, so slow pages were read
half-loaded and reported as down.
The three failures: one Cloudflare challenge, one long multi-step flight booking, and one task solved so slowly the time-scaled reward fell to 0.16.
What this is not
There is no agent loop here. Cubicle is the computer; your MCP client does the thinking. There is no hosted service and no account. You run it with your own keys.
DESIGN.md has the designed-but-unbuilt parts: a backend loop so tasks outlive a closed
laptop, a takeover page with an "I'm done" button, swapping the Python accessibility
agent for cua-driver, a run_js tool that batches many
actions into one model turn, and Chrome profile hydration to drop the E2B dependency.
Things that cost me a day
A sandbox id is a credential.
https://6080-<id>.e2b.app/vnc.htmlserves the live desktop with no auth.The sandbox timeout loses data. It reverts to the last pause and
connect()still succeeds, so nothing looks wrong.Chrome joins the accessibility tree only if it starts after the a11y bus, with
--force-renderer-accessibility. Otherwise the tree is empty and nothing says why.noVNC cannot read your Mac's clipboard. Syncing it with
xclipfails too, because the X clipboard lives inside whichever process owns it, so replacingxclipempties it. Type values in instead.pkill -f foomatches the shell that is running it. Kill by port.Google did not flag the datacenter IP. A fresh profile over VNC got the usual passkey prompt and a new-sign-in email, nothing more.
The desktop image autostarts a screensaver that blanks the screen to black, which looks exactly like a broken stream.
Layout
bin/mcp.ts the MCP server
bin/cubicle.ts setup, doctor, stash
src/ computer lifecycle, VM control, accessibility, 1Password, stash
vmagent/accessibility.py runs inside the computer, reads the AT-SPI tree
evalsite/ a login site with TOTP, for deterministic tests
test/e2e-login.ts the full login, through MCP
DESIGN.md decisions, risks, what the experiments showedApache-2.0.
This server cannot be deployed
Maintenance
Related MCP Connectors
Persistent Linux computers for AI agents: desktop, signed-in browser, vault, apps and shell.
Cloud desktops for AI agents: create a Linux computer, see its screen, click, type and run tasks.
Remote Linux boxes for coding agents: Docker, a browser, screenshots, logs, human takeover.
Your own cloud computer run by an AI agent: signed-in browser, its own email, files, long jobs.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to operate disposable Linux computers via MCP, providing tools for shell, file read/write, directory listing, and port exposure. It also supports browser automation and integration with any MCP-compatible client.Apache 2.0
- AlicenseAqualityAmaintenanceEnables MCP clients such as Claude and Cursor to control an isolated cloud machine with a real browser, shell, filesystem, and web access, so agents can navigate pages, click and type, run commands, manage files, and search or fetch web content.2646 npm1MIT
- AlicenseNot gradedqualityBmaintenanceA self-hosted MCP gateway that gives an AI client control of a real headed Chromium desktop and persistent workspace, with file, shell, process, and code-editing tools routed through a single control lease. Includes server-side read-only observation, server-enforced human takeover, and pause/stop controls so a person can watch, intervene, and hand control back.5Apache 2.0
- AlicenseNot gradedqualityBmaintenanceLets coding agents drive a real headful Chromium over CDP on a remote headless box, giving each project its own persistent profile, isolated login sessions, downloads, and on-demand browser lifecycle. When a site needs a human for sign-in, a captcha, 2FA, or a passkey, the operator opens the same browser from their own machine, completes the step, and hands control back to the agent.MIT