---
title: "I stopped babysitting the browser and switched the agent stack to Playwright"
canonical: https://dxdev.com/blog/2026-04-06_stopped-babysitting-chrome-mcp/
datePublished: 2026-04-06
---
On April 6, partway through an IP review run on ten queued tickets, Claude stopped and told me Chrome wasn't reachable on port 9222.

This was the third time that week. The setup I'd been running was Chrome DevTools MCP. The premise is straightforward: launch Chrome with `--remote-debugging-port=9222`, and Claude gets a CDP connection to your browser. It can navigate pages, fill forms, take screenshots, click through admin UI that doesn't expose a clean API. Good tool. Works when everything is ready.

The word "when" is doing a lot of work there.

## the ceremony nobody wrote down

To use Chrome DevTools MCP, I had to launch Chrome with the right flags before starting any session where browser access might be needed. This was my responsibility, not Claude's. There is no automatic launch, no process manager, no health check. If I forgot, Claude would get partway through a workflow and then stop to ask me to do my part.

I had not written this down anywhere. It was a learned reflex. Open Chrome first, then start Claude. Except on the days I forgot, which happened often enough that I started counting.

The problem is not that the tool is bad. Chrome DevTools MCP is a reasonable way to wire a browser to an agent if your agent is a human developer who controls the session setup manually. I was treating it as infrastructure for autonomous workflows. Those are different use cases.

## why this is worse than normal dev friction

In normal local development, a manual prerequisite is just friction. You get used to it. Source the env file. Start the Docker stack. Forward the port. These feel normal because you already know them, and the loop you're in has a human at every step by design.

In an agentic loop, the human is supposed to be out of the loop. That is the point. I was running multi-step workflows: process ten IP review tickets in sequence, navigate each case, apply the verdict, move to the next. The expected result is a completed run and a summary. I should be distracted by something else while this happens.

A manual prerequisite does not just add friction in this context. It inserts me into the loop at exactly the wrong moment. Mid-task. Claude is waiting on me. I get a notification. I have to remember what state the run was in, what it was trying to do, why it needs a browser right now. That context switch costs more than the thirty seconds it takes to launch Chrome.

The dependency was not just annoying. It was structurally incompatible with the autonomy I was trying to build.

## what playwright mcp actually changes

On April 6, as part of a tooling cleanup pass on ITEM-6750 and ITEM-6748, I swapped Chrome DevTools MCP for Playwright MCP.

The Playwright MCP server manages the browser lifecycle itself. When Claude needs a browser, the server spawns a Chromium instance under its own process tree. It handles SSL, sessions, and cleanup. There is no manual launch step. No port. No ceremony. Claude opens a session, the browser is there, the workflow runs.

The functional surface is nearly identical. Claude navigates to the same admin pages, fills the same forms, takes the same screenshots. But the operational behavior is completely different. The IP review run that had been halting on port 9222 ran to completion without me. I got the summary. I was not interrupted.

The agent now owns the browser from first navigate to last screenshot. That is the correct ownership model for autonomous work.

## the same class of problem in the jira tooling

The ITEM-6750 and ITEM-6748 cluster also included a fix to how Claude handled JIRA transitions. The transition IDs in the agent tooling were calibrated against a stale assumption about workflow state. Claude would attempt the transition, receive an error, and either halt or guess at a fallback path.

Different symptom. Same root cause. The environment had encoded a wrong assumption, and Claude was executing against it faithfully. Claude was not confused. Claude was doing exactly what the configuration told it to do. The configuration was wrong.

The fix in both cases was the same: update the assumption the environment encoded, not the symptom it was producing.

This is the more general pattern I keep tripping on. When an agent fails mid-workflow, the first question I ask now is whether Claude misunderstood something, or whether the environment Claude was handed misrepresented something. Most of the time it is the second thing. The agent is a good executor of bad premises.

## removing the last babysitting dependencies

After the Playwright switch, I did a pass to identify every other step in my agent workflows that required manual setup. I found three. A credential that had to be loaded into a shell before a certain script would run. A directory that had to exist but was not in the repo. A port-forward I had been doing by habit before sessions that touched the beelink.

None of these were documented. All of them were in my head. Each one was a potential mid-task interruption I had been avoiding only by remembering to do setup work I had not acknowledged as setup work.

I fixed all three. The credential now loads from `.secrets/` automatically. The directory is created on first use. The port-forward dependency turned out to be stale and was removed entirely.

These were small changes. The effect on friction was not small.

If your AI workflow depends on you remembering a secret handshake first, it is not a workflow yet.
