{"slug": "show-hn-chrome-relay-background-tabs-in-your-real-chrome-for-coding-agents", "title": "Show HN: Chrome Relay – background tabs in your real Chrome for coding agents", "summary": "Developer aindeev released Chrome Relay, an open-source tool that lets coding agents including Claude Code, Codex, Cursor and Paseo drive the user's everyday Chrome with real logins from the command line in background tabs, at roughly 0.15 seconds per command. The tool requires macOS, Google Chrome, Node.js 20+ and Vercel Labs' agent-browser, and is opt-in: it installs no extension automatically and runs only on Macs whose owner set it up. Chrome Relay authenticates each agent connection with a per-Mac secret stored in ~/.chrome-relay/token and an allowlist of agent apps, and refuses connections carrying a browser Origin header, though the author notes it is not a boundary against malware already running as the user.", "body_md": "**Website:** [https://agent-chrome-relay.aindeev.com](https://agent-chrome-relay.aindeev.com)\n\nLets your coding agents (Claude Code, Codex, Cursor, Paseo) use **your everyday Chrome**, with your real\nlogins, from the command line, **in background tabs**: nothing takes focus, no dialogs, ~0.15s per command.\n\n```\nagent-browser --cdp \"$(chrome-relay url you@company.com)\" open https://app.example.com/\nagent-browser snapshot -i          # the page's buttons, links and fields, each with a ref like @e5\nagent-browser click @e5\nagent-browser close\n```\n\nIt's opt-in: nothing installs the extension for you, and it only runs on Macs whose owner set it up.\n\n```\nagent-browser (CLI) ──ws──▶ relay (127.0.0.1:9333, LaunchAgent) ──ws──▶ Chrome Relay extension ──chrome.debugger──▶ agent tab\n```\n\n- **Extension** (`extension/` , MV3, one per Chrome profile you load it in): opens each agent tab**inactive** in a collapsed \"Agents\" tab group and runs DevTools commands in it via`chrome.debugger` . No remote-debugging\nport, so Chrome never shows \"Allow remote debugging?\". Chrome does show \"Chrome Relay started debugging this\nbrowser\" while agents work.\n- **Relay** (`relay/relay.mjs` ): a DevTools endpoint per agent. Each agent sees and controls only the tabs it\nopened; commands that could raise or focus the browser are swallowed.\n- **CLI** (`bin/chrome-relay` ): setup, the connection URL, diagnostics, audit trail.\n\nFastest: paste [this prompt](https://agent-chrome-relay.aindeev.com/setup-prompt.txt) into Claude Code, Codex or\nCursor and let your agent do it. By hand:\n\nNeeds macOS, Google Chrome, Node.js 20+ and [`agent-browser`](https://github.com/vercel-labs/agent-browser)\n(`npm i -g agent-browser`).\n\n```\ngit clone https://github.com/aindeev/agent-chrome-relay\ncd agent-chrome-relay\nbin/chrome-relay setup     # secret, background service, identities, `chrome-relay` on PATH, Claude Code skill\n```\n\nThen, **in each Chrome profile agents should use**: open `chrome://extensions`, turn on **Developer mode**,\n**Load unpacked**, and pick the `extension` folder of your clone. Check with `chrome-relay doctor`.\n\nAfter `git pull`: `chrome-relay update` (restarts the relay, reloads the extension in every profile).\nTo remove: `chrome-relay uninstall`, then remove the extension in each profile.\n\nClaude Code: `setup` links the skill (`skill/SKILL.md`) into `~/.claude/skills/chrome-relay`, so every\nrepo gets it. Codex, Cursor and others: point them at the same file, e.g. a line in your global\n`~/.codex/AGENTS.md`: *\"For any browser step that needs my logins, follow\n`<path>/agent-chrome-relay/skill/SKILL.md`.\"* A repo's `CLAUDE.md`/` AGENTS.md` only needs a\none-line pointer to the skill.\n\nTwo checks on every agent connection:\n\n1. **This Mac's secret** : generated at setup in`~/.chrome-relay/token` (mode 600) and embedded in the URL\nthat`chrome-relay url` prints.\n2. **An allowed agent app** : the connecting process must come from Claude Code, Codex, Cursor or Paseo. The\nrelay looks the process up (`lsof` ,`ps` ) and checks the markers those apps set in their child processes\n(`CLAUDECODE` ,`CODEX_*` ,`CURSOR_*` ,`PASEO_AGENT_ID` ), then its parent processes.\n\nConnections that carry a browser `Origin` header (a web page) are refused even with the secret. Only **this\ncheckout's extension** may connect as the extension: Chrome derives an unpacked extension's ID from its folder,\n`setup` records that ID in `~/.chrome-relay/config.json`, the relay checks the connection's\n`Origin: chrome-extension://<id>` (which pages cannot fake), and the connecting process must be Chrome.\n\nThis keeps other local tools, web pages and accidents out. It is not a boundary against malware already running as you, which could read the secret and fake the markers.\n\nAgents never type credentials. When a site bounces through Google and the right account is **already signed\nin**, the extension clicks the account and **Continue/Allow** itself (page scripting, so it works even with\n1Password's frame on the page). A password, passkey, 2-step screen or signed-out account stops the hop, and the\nagent gets `SIGN-IN NEEDED: ...` and asks you to sign in in your own window.\n\nWhich Google account a site uses comes from `~/.chrome-relay/identities.json` (`chrome-relay identities`):\nyour Chrome profiles (filled in by setup), optional hand-set `sites.rules`, and `sites.learned`, which the\nrelay fills in after each successful hop. Default: the profile's own account.\n\nEvery agent action is recorded in `~/.chrome-relay/audit/YYYY-MM-DD.jsonl`; read it with `chrome-relay audit`:\nwho connected (app, Claude/Paseo session id, working folder, `AGENT_BROWSER_SESSION`), pages, clicks with\npositions, special keys, the agent's own scripts, screenshots, uploads, popups, sign-in clicks and blocked\npages. Typed text is stored only as a character count, and URLs lose their query string.\n\n- **Popups and `target=_blank` links** open as new hidden tabs owned by the same agent; popup sign-in flows\nthat`postMessage` back to the opener and close themselves keep working. Message origins are the ones the relay\nsaw each tab load (never what the page claims), and`targetOrigin` is enforced. A safety net adopts any tab an agent\npage opens anyway and hands focus back to the tab you were on.\n- **1Password** : Chrome drops an extension's debugger from a page that contains another extension's frame\n(1Password's menu on login forms). The agent's commands wait while the extension re-attaches.\n- **Self-cleaning** : tabs of an agent silent for 30 minutes are closed. When the relay restarts, the extension\ncloses the agent tabs it opened (tracked by tab id, so your own tab groups are never touched).\n- **Real input in background tabs** : focus emulation is on in every agent tab, so clicks and typing land.\n\n```\ncd relay && npm install && npm test     # who may connect: secret, allowed apps, Chrome-only extension, audit\n```\n\nLogs: `chrome-relay logs` (`~/.chrome-relay/relay.log`). Testing extension changes: edit `extension/`, then\n`chrome-relay update`. `CHROME_RELAY_HOME` and `CHROME_RELAY_PORT` override the data folder and port.\n\nMade by **Alexey Indeev**, co-founder and CTO of [Spare](https://sparelabs.com). I write about building more\nwith AI, whether you code or not, at **[The Leveraged Mind](https://read.aindeev.com)**.\n\n- Blog: [https://read.aindeev.com](https://read.aindeev.com)\n- X: [@AlexeyIndeev](https://x.com/AlexeyIndeev)\n- LinkedIn: [https://www.linkedin.com/in/alexey-indeev/](https://www.linkedin.com/in/alexey-indeev/)\n- GitHub: [@aindeev](https://github.com/aindeev)\n\nQuestions, ideas or bugs: open an [issue](https://github.com/aindeev/agent-chrome-relay/issues) or reach out on X.\n\nMIT. See [LICENSE](https://github.com/aindeev/agent-chrome-relay/blob/main/LICENSE).", "url": "https://wpnews.pro/news/show-hn-chrome-relay-background-tabs-in-your-real-chrome-for-coding-agents", "canonical_source": "https://github.com/aindeev/agent-chrome-relay", "published_at": "2026-10-10 08:15:19+00:00", "updated_at": "2026-10-10 08:40:02.932356+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools"], "entities": ["Chrome Relay", "aindeev", "Claude Code", "Codex", "Cursor", "Paseo", "Google Chrome", "agent-browser"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-chrome-relay-background-tabs-in-your-real-chrome-for-coding-agents", "markdown": "https://wpnews.pro/news/show-hn-chrome-relay-background-tabs-in-your-real-chrome-for-coding-agents.md", "text": "https://wpnews.pro/news/show-hn-chrome-relay-background-tabs-in-your-real-chrome-for-coding-agents.txt", "jsonld": "https://wpnews.pro/news/show-hn-chrome-relay-background-tabs-in-your-real-chrome-for-coding-agents.jsonld"}}