// FIELD NOTE
Chrome DevTools MCP Kept Conflicting — 5-Line Wrapper Fixed It

Cory LaNou

Chrome DevTools MCP Kept Conflicting — 5-Line Wrapper Fixed It
Overview
Chrome DevTools MCP is one of the best tools I've added to my AI coding workflow. It gives your coding agent a real browser — click buttons, fill forms, take screenshots, run full end-to-end tests. I run three or four projects doing their own e2e testing simultaneously while I'm still writing and reviewing code. But the shared Chrome profile creates conflicts when you do that, and the built-in fix (--isolated) kills the login credentials you need for real testing. A wrapper script solved everything.
[youtube-short:dmeRmkMs7l4]
Stop Clicking Through Things
If you're still manually clicking through your application to verify that things work, you're doing it wrong. I don't mean that as a judgment — I did it too. For years. But that's exactly what end-to-end testing tools exist to solve, and Chrome DevTools MCP takes it to a level that traditional tools never could.
The basic pitch is simple: it's an MCP server that gives your AI coding agent full control over a real Chrome browser. It works with Claude Code, Cursor, Copilot, Gemini — any MCP-compatible client. Your agent can navigate pages, click buttons, fill forms, upload files, handle dialogs, take screenshots, and run through complete user workflows.
But that's what Playwright does too, right? Yes — and there's actually a Playwright MCP server now too. So let's be honest about the comparison.
Browser MCP Tools: What They All Do
Both Chrome DevTools MCP and Playwright MCP give your AI agent a real browser to work with. They can both navigate pages, click elements, fill forms, take screenshots, read console logs, and monitor network requests. Playwright MCP even has a built-in "Healer" agent that can auto-repair failing tests. These are both serious tools.
The reason I personally landed on Chrome DevTools MCP comes down to what I needed most: deep debugging when things go wrong.
What Both Can Do
Any browser MCP tool gives your AI agent abilities that manual testing can't match:
- DOM inspection — The agent reads the actual rendered state of the page, not just your source code. It sees what the browser sees after JavaScript has run, styles have applied, and dynamic content has loaded.
- Console monitoring — Console errors, warnings, uncaught exceptions. The agent reads them in real time and correlates them with the action that triggered them.
- Network analysis — Failed API calls, CORS errors, slow responses, missing resources. The agent can inspect requests and responses to diagnose backend issues.
- Screenshot capture — Visual verification of what the page actually looks like, not what you assume it looks like.
- Device emulation — Viewport resizing, touch events, mobile simulation.
This is the baseline. If you're not using any browser MCP tool, you're missing all of this.
Where Chrome DevTools MCP Goes Deeper
Chrome DevTools MCP connects directly to Chrome's DevTools Protocol, which gives it access to lower-level capabilities that matter when you're debugging complex issues:
- Computed CSS styles — Not just the CSS you wrote, but what the browser actually applied. Which rules are overriding which, where layout issues originate, what the cascade resolved to. When a visual bug appears, this is how the agent figures out why.
- Performance traces — The agent can record full performance traces and extract metrics like Largest Contentful Paint, total blocking time, and layout shifts. This is the same data you'd get from Chrome's Performance panel.
- JavaScript evaluation — Run arbitrary JavaScript in the page context to inspect state, trigger actions, or verify conditions that aren't exposed through the DOM alone.
- Screenshot comparison with context — Combined with DOM access and computed styles, the agent can detect visual regressions and understand why something shifted — not just that it did.
Where Playwright MCP Has the Edge
To be fair, Playwright MCP has strengths that Chrome DevTools MCP doesn't:
- Cross-browser testing — Playwright supports Chromium, Firefox, and WebKit. If you need to verify behavior across browsers, Chrome DevTools MCP only works with Chrome.
- Accessibility tree access — Playwright MCP uses structured accessibility snapshots for element interaction, which can be more reliable than pixel-based approaches and doesn't require vision models.
- Built-in test agents — Playwright has Planner, Generator, and Healer agents purpose-built for test creation and repair.
Why I Chose Chrome DevTools MCP
For my workflow — running autonomous e2e tests across multiple projects, often overnight — the depth of debugging access was the deciding factor. When an agent hits a failure at 2am, I need it to be able to investigate thoroughly: read computed styles, check performance, evaluate JavaScript state, and understand why something broke, not just that it broke. Chrome DevTools MCP gives it the full toolkit to do that.
What This Looks Like In Practice
CyberAgent's team used Chrome DevTools MCP to audit all 236 stories in their Storybook design system. The agent navigated through every component, detected runtime errors and warnings from the console, traced them back to the source code, applied fixes, and verified the fixes — all in about an hour with zero manual intervention. That's the kind of thing that would take a developer half a day of tedious clicking and context switching.
Here's what my workflow looks like:
- Parallel e2e testing — I have three or four different projects all running their own end-to-end tests while I'm reviewing code on something else entirely. The agents work through login flows, form submissions, multi-step workflows, edge cases — all autonomously.
- Overnight testing — Set up a test plan and walk away. The agent works through entire workflows. Create accounts, configure settings, test edge cases, verify error handling. Come back in the morning to a report.
- Self-healing tests — When the agent encounters an issue, it doesn't just log a failure. It inspects the page, checks the console, looks at network requests, takes a screenshot, and figures out why it failed. Then it either fixes the issue in the code or adjusts its approach and continues testing.
- Visual debugging — The agent can detect that a button is 3 pixels off, that a modal is rendering behind another element, that a responsive layout breaks at a specific viewport width. It sees what you see — as Addy Osmani put it, Chrome DevTools MCP "removes the blindfold" that AI coding tools have traditionally operated under.
This isn't theoretical. I'm doing this right now across multiple production projects. The agents handle the repetitive verification work while I focus on writing actual features.
The Problem: Running Multiple Projects at Once
Here's where the profile management issue comes in. All of the above works great — until you try to do it across multiple projects simultaneously.
Almost every project I test requires login credentials. Staging environments, admin dashboards, OAuth flows, API consoles. I set those up once in the browser profile and expect them to stay. That's the whole point — set up auth once, then the agent can test authenticated workflows without re-logging in every session.
Chrome DevTools MCP handles this with Chrome's --user-data-dir — a directory where Chrome persists everything about your session. But the default configuration only has one.
How Chrome Profiles Actually Work
When Chrome launches, it needs a user data directory — a folder where it stores everything about your browsing session. This is the Chrome user data directory, and it contains:
- Cookies — Session tokens, authentication cookies, CSRF tokens
- Login Data — Saved passwords (encrypted using your OS keyring)
- Local Storage / IndexedDB — Site-specific data that many apps use for auth state
- History — Browsing history within that profile
- Preferences — Browser settings, extensions, configurations
Each profile is a complete, isolated browser identity. Two different --user-data-dir paths mean two completely independent Chrome instances that share nothing.
The critical detail: Chrome locks the user data directory when it's in use. Two Chrome instances cannot share the same directory simultaneously. If one instance has it open, the second one fails.
How Chrome DevTools MCP Uses Profiles
By default, Chrome DevTools MCP stores its profile at:
~/.cache/chrome-devtools-mcp/chrome-profile-stable
Every time your MCP client launches the browser, it uses this one directory. Your logins persist between sessions. Cookies survive restarts. Auth tokens stick around. This is --user-data-dir in action — Chrome reads and writes everything to that folder.
What --isolated Does Differently
The --isolated flag tells Chrome DevTools MCP to create a temporary user data directory. A fresh, empty profile every time. When the browser closes, it's deleted.
No conflicts — every instance gets its own temporary directory. But also: - No saved logins - No cookies - No auth state - No persistence of any kind
You're starting from zero on every session. For testing projects that require authentication — which is almost all of them — this is a non-starter. You'd have to re-authenticate at the start of every single agent session. That kills the entire workflow of setting up credentials once and letting agents test autonomously.
The Conflict
So you have two options out of the box:
--user-data-dir (default behavior)
- Credentials persist between sessions
- Can only run one browser instance at a time
- Second project throws: Error: The browser is already running for this browser context...
--isolated
- Multiple instances work simultaneously
- Credentials wiped every session
- Re-authenticate at the start of every test run
Neither works for my use case: persistent credentials across multiple simultaneous projects.
The Fix: Project-Scoped Profiles
The solution: give each project its own --user-data-dir. Same persistence mechanism Chrome DevTools MCP already uses, just with a unique directory per project.
Step 1: Create the Wrapper Script
The wrapper lives at ~/.local/bin/chrome-devtools-mcp-wrapper. This directory is a standard location for user-installed scripts on macOS and Linux. Make sure it's in your $PATH.
mkdir -p ~/.local/bin
Create the wrapper:
#!/bin/bash
PROJECT_HASH=$(echo "$PWD" | shasum | cut -c1-8)
PROFILE_DIR="$HOME/.cache/chrome-devtools-mcp/profiles/project-$PROJECT_HASH"
mkdir -p "$PROFILE_DIR"
exec npx -y chrome-devtools-mcp@latest --user-data-dir="$PROFILE_DIR" "$@"
Make it executable:
chmod +x ~/.local/bin/chrome-devtools-mcp-wrapper
If ~/.local/bin isn't already in your $PATH, add it to your shell profile (~/.zshrc, ~/.bashrc, etc.):
export PATH="$HOME/.local/bin:$PATH"
Step 2: Wire It Into Your MCP Client
The wrapper replaces the direct chrome-devtools-mcp call in your MCP configuration. Instead of your client launching the tool directly, it launches the wrapper, which sets up the project-scoped profile and then hands off to the real tool.
For Claude Code, the MCP config lives in ~/.claude.json under the mcpServers key:
{
"mcpServers": {
"chrome-devtools-mcp": {
"type": "stdio",
"command": "/Users/yourname/.local/bin/chrome-devtools-mcp-wrapper",
"args": [],
"env": {}
}
}
}
Note the full absolute path to the wrapper. Claude Code resolves this at launch, so using the full path avoids any $PATH issues.
You can set this up through Claude Code's settings (/mcp command) or by editing ~/.claude.json directly.
For other MCP clients (Cursor, Copilot, etc.), update their respective MCP configuration to point command at the wrapper path instead of npx -y chrome-devtools-mcp@latest.
Step 3: Verify It Works
Launch your agent and use the browser. Check that a project-specific profile was created:
ls ~/.cache/chrome-devtools-mcp/profiles/
You should see a directory like project-ac2fd056 (the hash will match your project directory). Open a second project — it should get its own profile with a different hash. No conflicts.
Every project now gets its own persistent Chrome profile automatically. Same project = same hash = same credentials. Different project = different hash = no conflicts.
Handling Git Worktrees
If you use git worktrees (and you should — they're great for working on multiple branches simultaneously), there's a subtlety. Worktrees live at different paths than your main repo:
/projects/myapp/ → hash: ac2fd056
/projects/myapp-issue-142-fix/ → hash: b2bc10f2
The basic wrapper hashes $PWD, so each worktree gets a completely separate Chrome profile. That means credentials you set up in the main repo don't carry over to worktrees.
The Worktree-Aware Wrapper
This version detects when you're in a worktree, finds the main repo's Chrome profile, and copies it as a starting point for the worktree's profile. The worktree gets its own independent profile — no locking conflicts — but it starts with all the credentials already in place.
#!/bin/bash
PROFILE_BASE="$HOME/.cache/chrome-devtools-mcp/profiles"
PROJECT_HASH=$(echo "$PWD" | shasum | cut -c1-8)
PROFILE_DIR="$PROFILE_BASE/project-$PROJECT_HASH"
if [ ! -d "$PROFILE_DIR" ]; then
mkdir -p "$PROFILE_DIR"
# If we're in a git worktree, seed from the main repo's profile
COMMON_DIR=$(git rev-parse --git-common-dir 2>/dev/null)
if [ -n "$COMMON_DIR" ] && [ "$COMMON_DIR" != ".git" ]; then
MAIN_REPO=$(dirname "$COMMON_DIR")
MAIN_HASH=$(echo "$MAIN_REPO" | shasum | cut -c1-8)
MAIN_PROFILE="$PROFILE_BASE/project-$MAIN_HASH"
if [ -d "$MAIN_PROFILE" ] && [ "$MAIN_HASH" != "$PROJECT_HASH" ]; then
cp -a "$MAIN_PROFILE/." "$PROFILE_DIR/" 2>/dev/null
fi
fi
fi
exec npx -y chrome-devtools-mcp@latest --user-data-dir="$PROFILE_DIR" "$@"
How It Works
- Hash
$PWDto get a unique profile path (same as the basic version) - If the profile directory doesn't exist yet, check if we're in a git worktree
- If we are, find the main repo's path via
git rev-parse --git-common-dir - If the main repo has an existing Chrome profile, copy it into the new worktree profile
- From that point on, the worktree's profile is independent — its own cookies, its own auth state, no conflicts with the main repo
First launch in a worktree: Copies credentials from the main repo. Already logged in.
Subsequent launches: Uses its own profile. Credentials persist independently.
Running main repo + worktree simultaneously: No conflicts. Separate --user-data-dir paths.
The Full Picture
| Setup | Credentials Persist | Multiple Projects | Multiple Worktrees | Auth Setup |
|---|---|---|---|---|
| Default (shared profile) | Yes | No — conflicts | No — conflicts | Once |
–isolated
|
No | Yes | Yes | Every session |
| Basic wrapper | Yes, per project | Yes | Yes, but separate auth | Once per worktree |
| Worktree-aware wrapper | Yes, per project | Yes | Yes, seeded from main | Once per project |
Why This Matters
I'm not manually clicking through test flows anymore. I have agents running end-to-end tests across multiple projects simultaneously while I'm writing code on something else entirely. When an agent hits an issue, it doesn't just fail — it has full access to Chrome DevTools to investigate, debug, and often fix the problem before I even look at it.
That workflow falls apart without persistent credentials. And it falls apart if only one project can use the browser at a time.
This wrapper is the glue that makes the whole thing work. Set up credentials once per project. Run as many projects as you want. Each one maintains its own auth state. Each one tests independently.
If you're still manually verifying your UI, or writing brittle Playwright scripts that fail with unhelpful error messages, give Chrome DevTools MCP a try. And when you inevitably start running it across multiple projects, you'll want this wrapper.
Links
- Chrome DevTools MCP on GitHub
- Chrome DevTools MCP on npm
- Playwright MCP on GitHub
- Chrome for Developers: Chrome DevTools MCP
- Addy Osmani: Give Your AI Eyes
- CyberAgent: Automated Runtime Error Fixing
- Playwright MCP vs Chrome DevTools MCP Comparison
- Chrome User Data Directory (Chromium docs)
- Claude Code MCP docs
- Model Context Protocol
Final Thought
Chrome DevTools MCP is genuinely one of the best tools in my AI development workflow. It replaced manual testing, it replaced fragile Playwright scripts, and it gives my agents the same debugging access I'd have sitting in front of the browser myself.
The profile conflict was the one thing that kept tripping me up. A wrapper script fixed it, and I haven't thought about it since.


