Chrome DevTools MCP + Ubuntu Desktop: Watch Your Agent Work
Run your AI agent in a real Chrome on Ubuntu Desktop, with your extensions and logins, and watch it live so you can take over at 2FA or CAPTCHA.
Headless browser agents are great until they hit a login page. The agent fills the email, presses Enter, and then a 2FA prompt, a CAPTCHA or an "is this you?" email shows up. At that point you're reading its logs, guessing what it saw, and restarting the whole run.
What I wanted was a real computer the agent drives while I can watch the screen live and grab the mouse when it gets stuck. It turns out Elestio's Ubuntu Desktop gives you exactly that: a full Linux desktop in a browser tab, with Chrome already installed. Add Chrome DevTools MCP and the agent can drive that Chrome while you watch the same window.
What's Actually in the Box
I pulled the image apart before writing this. Elestio's Ubuntu Desktop is built on Kasm's workspace images: an XFCE desktop streamed to your browser by KasmVNC on port 6901, running as kasm-user with passwordless sudo. It comes with Chrome, VS Code, Telegram, Wine for Windows programs, and Node.js.
You can also install Chrome extensions into that Chrome. Your password manager, an ad blocker, your company's SSO helper: you install them once by hand, and every session the agent runs gets them too. A throwaway headless Chromium can't easily do that.
What you need:
- Ubuntu Desktop on Elestio. It starts at $16/month (2 CPU / 4 GB). Chrome, a desktop and an agent all on one box want more room, so I'd pick the 4 CPU / 8 GB plan at $29/month.
- Claude Code with an Anthropic account (subscription or API key), or any other MCP client that runs on Linux.
- Ten minutes.
Step 1: Start a Debuggable Chrome on the Desktop
Open the desktop from your Elestio service URL and log in with the credentials shown in the dashboard. Open a terminal on the desktop and start a second Chrome with remote debugging switched on:
google-chrome \
--remote-debugging-port=9222 \
--user-data-dir="$HOME/agent-profile" \
--no-sandbox \
--no-first-run \
https://example.com &
Since Chrome 136 you can't use remote debugging with your default profile, so --user-data-dir is required. That's a good rule anyway: the agent gets its own profile, separate from yours. --no-sandbox is there because Chrome's sandbox doesn't work inside this container; the Kasm Chrome launcher on the desktop passes the same flag.
Check that the debugging endpoint is up:
curl -s http://127.0.0.1:9222/json/version
You should get JSON with a webSocketDebuggerUrl. That window on the desktop is now the agent's browser.
Step 2: Install Extensions Into the Agent's Profile
Do this by hand, in the window you just opened. Go to the Chrome Web Store and install what the agent needs. Log in to the sites it will work on, and leave the window open.
You can't script this part with flags, and that's on purpose. Chrome 137 removed --load-extension from Google-branded builds, so the Web Store (or "Load unpacked" in chrome://extensions) is how extensions get in. You only do it once per profile.
My rule: the agent profile only gets the accounts and extensions it needs for its job. If you add a password manager, give it a dedicated vault for the agent, not your personal one.
Step 3: Run the Agent Next to the Browser
Node.js is already on the desktop, so I run the agent there too. Install Claude Code and add the MCP server:
curl -fsSL https://claude.ai/install.sh | bash
claude mcp add chrome-devtools -- npx -y chrome-devtools-mcp@latest \
--browser-url=http://127.0.0.1:9222 \
--category-extensions=true
--browser-url tells the MCP server to attach to the Chrome you started instead of launching its own headless one. --category-extensions adds a list_extensions tool, so the agent can check what's installed before it relies on it.
Now start claude and give it a job plus a handoff rule:
Use the chrome-devtools tools. Open our supplier portal, download last
month's invoices and list their totals. If you hit a login, 2FA prompt
or CAPTCHA, stop and tell me. I'll handle it in the desktop and reply "done".
Keep the Kasm tab open next to the terminal. You'll see the tab open, the fields fill and the pages change while it happens.
The Handoff Is the Whole Point
Taking over doesn't need any special mode. When the agent stops at a 2FA screen, you click into the desktop, type the code and reply "done". Chrome DevTools MCP works from text snapshots of the page's accessibility tree, so on its next step the agent takes a fresh snapshot and sees the page you left it on. Just don't type while it's mid-step: you're both acting on the same page, and its next click can land on something you just changed.
| Situation | Headless agent browser | Ubuntu Desktop + DevTools MCP |
|---|---|---|
| 2FA or CAPTCHA | Run fails, you read logs | You type it, the agent continues |
| Watching the run | Screenshots after the fact | Live, in a browser tab |
| Extensions and logins | Rebuilt every run | Installed once, kept in the profile |
| Non-browser apps | Not available | On the desktop for you; DevTools MCP itself only drives Chrome |
The Parts That Can Bite You
Never publish port 9222. The DevTools protocol has no authentication. Anyone who can reach that port controls a browser that is logged in to your accounts. That's why the agent runs on the desktop next to Chrome and the port stays on 127.0.0.1. If your agent has to run elsewhere, use an SSH tunnel, never a public port.
The view-only account isn't a separate secret. In the Kasm startup script this image is built on, the read-only kasm_viewer login gets the same password as the main user. Don't hand it out thinking it's a safe "watch only" link.
Web pages can talk to your agent. Any page the agent reads can contain instructions meant for it. A logged-in profile is what makes this setup useful, and it's also what makes prompt injection expensive. Keep the profile scoped, and tell the agent to ask before it submits, pays or deletes anything.
Troubleshooting
curl to port 9222 returns nothing. Another Chrome probably grabbed the profile first, or the launcher dropped your flags. Close every Chrome window and run the command again. On Kasm-based images the real binary is usually at /usr/bin/google-chrome-orig; launch that one directly with the same flags.
The agent opens its own invisible browser. The --browser-url flag didn't make it into the MCP config. Check with claude mcp list, remove the server and add it again.
Logins vanish after a restart. Before you spend an afternoon logging into things, restart the service from the Elestio dashboard and check that ~/agent-profile is still there. If your setup doesn't keep it, move the profile to a mounted volume.
The desktop is sluggish while the agent works. Chrome, the KasmVNC stream and Node all share the same CPU. Move up a plan, or lower the stream quality in the KasmVNC side panel.
Wrapping Up
Most agent browser setups either hide the browser or take the agent out of the loop when a human steps in. This one does neither: there's one screen, the agent drives, and you take over whenever it needs a hand. Deploy Ubuntu Desktop on Elestio, install the extensions your agent needs, and try it on a task that has always failed at the login page.
Thanks for reading ❤️ See you in the next one 👋