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:
- A macOS
.appwrapper that launches Chrome with the right flags and a custom icon - A Claude MCP config that points
chrome-devtools-mcpat the debug port - 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.
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