Three open-source browser agents hit the Hacker News front page today. An autoscaling one, Yamak, and yet another AI Browser Agent Leaderboard thread. I opened all three READMEs out of habit, and by the second paragraph of each quickstart I was reading the exact same line I’ve read maybe forty times this year:

chrome --remote-debugging-port=9222

Nobody ever explains what that does. It sits there in a code block between npm install and npm start, formatted like a build step, and you paste it because the alternative is not getting the demo to run.

So let’s actually look at what you just turned on.

A door, no lock, no doorbell

Port 9222 is an HTTP server that Chrome runs for you. Hit http://localhost:9222/json/list in any tab and you get back a JSON array of every target the browser has open: every tab, its title, its URL, and a webSocketDebuggerUrl for each one. Connect a WebSocket to that URL and you’re speaking the Chrome DevTools Protocol, which is the same protocol DevTools itself uses, which means it can do everything DevTools can do.

Network.getAllCookies hands over every cookie in the profile, HttpOnly included. Runtime.evaluate runs arbitrary JavaScript in the page origin. Page.captureScreenshot takes a picture of whatever you’re looking at. Page.navigate sends a tab wherever it likes. Target.createTarget opens new ones.

There is no authentication step anywhere in that sequence. No token, no handshake, no prompt. If a process on your machine can open a TCP connection to localhost, it has your Gmail, your Okta session, your bank tab, your company Notion, and your GitHub, all at once, with no log entry anywhere that you’d ever think to check.

Chrome does defend one flank. Since the DNS rebinding writeups years back it validates the Host header on that endpoint, so a random website you visit can’t just fetch localhost:9222 and walk off with everything. That’s a real mitigation and it holds. But it only covers the network boundary. It does nothing about the Electron app you installed last week, the VS Code extension with 400 stars, or the npm postinstall script three levels deep in a dependency tree. Those are local processes. Local processes are trusted.

Why your relay keeps dying

Here’s the part that shows up in the GitHub issues rather than the security writeups.

Chrome 136 changed the rules: you can no longer use --remote-debugging-port against your default user data directory. It’s blocked. So every quickstart now pairs the flag with --user-data-dir=/tmp/chrome-debug or similar, and the moment you do that you’ve launched a brand-new profile that has never logged into anything. Blank Chrome. No cookies. The agent connects successfully, reports itself healthy, and then tells you it can’t find your inbox.

The workaround people land on is copying their real profile directory, which works right up until it doesn’t, because Chrome holds locks on that directory and the copy drifts out of sync with the original the second you use both.

Then you restart your machine. Chrome comes back through the normal launcher, or an auto-update relaunches it, and the flag is gone. The port is closed. Your agent is talking to nothing. We wrote about why browser relays keep dropping after restart and the CDP layer is most of the answer: the connection is a side effect of how the binary happened to be started, not a property of the browser.

That’s a hell of a foundation to build a product on.

The extension path

A side-panel extension doesn’t need a debug port because it isn’t outside the browser trying to get in. Dassi runs as a Chrome extension with a declared permission set, and it reads the tab you’re already sitting in, in the profile you’re already logged into. Chrome’s extension model handles the access control, the same way it does for a password manager.

No flag. No second profile. No relaunch ritual after every restart.

Relay’s team went to Chrome

Relay.app shut down last month and its team landed on Google’s Chrome org. I keep thinking about that. The whole category of “stand up a server, tunnel into someone’s browser” is quietly being absorbed into the browser itself, because that’s where the login state has been sitting the entire time. Our take on the three ways agents connect to your browser covers the rest of the map.

If you already run a debug port, at minimum go check what else on your box can reach it. lsof -i :9222 is a start.

And if a setup guide ever tells you the flag is fine because it only binds to localhost, that person has never audited an npm lockfile. Dassi’s in the Chrome Web Store, free, bring your own key or sign in with ChatGPT. It has never once asked me to relaunch anything.