A Chrome of My Own

A Chrome of My Own

I love the Claude in Chrome extension. Being able to manipulate a browser from your CLI session is pretty amazing — incredibly helpful for debugging, automating sites that don’t want to be automated, and all kinds of things I didn’t expect when I first installed it.

But I also use Chrome as myself. Personal tabs, work tabs, client tabs. And I found it annoying and confusing to have some tabs that Claude can access and some it can’t. Sometimes Claude opens tabs in background windows, sometimes in the foreground, and I end up with even more tab mess than I already had. So I started wondering: could a Claude instance have a dedicated Chrome instance, one-to-one?

The problem

The Chrome extension pairs globally — one pairing in ~/.claude.json, shared across all Claude profiles. There’s no way to say “this Claude profile should talk to this Chrome profile.” There are open feature requests for per-profile targeting, but nothing built in yet.

The idea

Instead of the Chrome extension, use the Chrome DevTools MCP server maintained by the Chrome DevTools team. It connects to Chrome via the DevTools Protocol on a specific port. If you launch Chrome with --remote-debugging-port, the MCP can connect directly — no extension needed.

The trick is that Chrome requires a non-default --user-data-dir to enable the debug port. That means a separate data directory, which means a fresh Chrome environment: no sign-in, no extensions, no history. You sign in once, install your extensions, and it persists from there. It’s a one-time cost.

What I built

Three pieces:

  1. A macOS .app wrapper that launches Chrome with the right flags and a custom icon
  2. A Claude MCP config that points chrome-devtools-mcp at the debug port
  3. A shell script that orchestrates everything: normal Chrome, debug Chrome, and Claude Code

The app wrapper

A minimal .app bundle gives the debug Chrome its own identity in the Dock and Cmd+Tab. The launcher script inside is straightforward:

The --user-data-dir points to a dedicated directory (not Chrome’s default), which is what enables the debug port. --profile-directory picks which profile inside that directory to load.

The Info.plist registers it as a proper macOS app:

I tinted Chrome’s icon amber to tell the two apart at a glance. There’s a small Swift script in the gist that does this using CoreImage.

The MCP config

Add this to your Claude Code profile’s .claude.json (the profile-specific one, not the global):

Change the port if you’re running multiple debug instances. Once connected, you get about 30 tools: navigate_page, take_screenshot, evaluate_script, click, fill, and more. It’s actually more capable than the Chrome extension, and in my experience, more reliable.

The orchestrator

One command to rule them all:

It opens normal Chrome first (so Spotlight and the Dock point to your real browser), then launches the debug instance, waits for the port, and starts Claude Code with the right profile.

Try it yourself

There’s a setup script called claude-chrome that handles everything. Download it and run install:

curl -sL https://gist.githubusercontent.com/jcasimir/d22ede06bc00bd13319d1c334b109144/raw/claude-chrome.sh -o /tmp/claude-chrome.sh && bash /tmp/claude-chrome.sh install

It’ll ask you a few questions — what to call the profile, which port, where your Claude config lives — then create the app wrapper, tint the icon, configure the MCP, and generate the orchestrator script.

If something goes wrong or you want to start over, the same script handles cleanup:

bash /tmp/claude-chrome.sh uninstall

And to check what you’ve got set up:

bash /tmp/claude-chrome.sh status

You can also just run the script with no arguments and it’ll give you a menu.

After installing, launch the app once, sign into your Google account, and install any extensions you need (1Password, etc.). They’ll persist across restarts.

Verifying it works

Once your debug Chrome is running, you can confirm the port is active:

curl -s http://127.0.0.1:9223/json/version

You should see Chrome’s version info and a WebSocket URL. If you get nothing back, Chrome didn’t accept the debug flag — make sure you’re using a non-default --user-data-dir.

From inside Claude Code, the chrome-devtools MCP tools should be available. Try asking Claude to navigate to a URL and take a screenshot. If it shows up in the right Chrome window, you’re set.

Things I learned along the way

Chrome resolves symlinks. I first tried symlinking the real Chrome data dir to fake a “non-default” path. Chrome saw right through it. You need a genuinely separate directory.

The debug data dir is its own world. Your sign-in, extensions, and bookmarks don’t carry over. The profile data directory inside it is independent. This is actually a feature — it keeps your debug browser clean and predictable.

Launch order matters. If the debug Chrome starts before normal Chrome, Spotlight and the Dock will send everything to the debug instance. The orchestrator script handles this by opening normal Chrome first.

The profile picker is a red herring. The debug Chrome inherits profile metadata from the original data dir and shows a profile picker with stale entries. Ignore it. Just use the profile the launcher opens.

What I ended up with

My jsl command opens a terminal, fires up both Chrome instances (personal and project), and drops into Claude Code with full browser control over the right window. Claude can navigate pages, take screenshots, inject JavaScript for visual debugging, fill forms — all in an isolated browser that’s signed into the right accounts.

The full gist has all the files, including the setup script and icon tinting tool.


Jeff Casimir
Jeff Casimir
Principal, Jumpstart Lab
jeff@jumpstartlab.com

Does your team need help rolling Claude Code into everyday work? Through workshops and coaching, I can help them reach their potential.

Book a Conversation