AI Agent Debugging: Find Why a Web Page Is Broken

Let an AI agent debug a web page in your signed-in Chrome: read console errors and failed network requests over MCP, with exact tool calls and honest limits.

Mehmood Ur Rehman Qureshi7 min readGuide

A blank dashboard, a Save button that does nothing, a checkout that spins forever. An agent that can only read the page sees the result: an empty table, a button, a spinner. It cannot see the uncaught exception or the request that came back with a 500. This guide shows how to let an AI agent debug a web page in the Chrome you already use, with MCP Browser Extension's three observer tools: console_logs, network_log and dialogs. It covers turning them on, the exact tool calls, a prompt you can paste, and what the observers cannot see.

If you have not set up the server and extension yet, start with the quickstart.

Why debug in your own Chrome

Many bugs only show up in one browser: yours. The page breaks for a signed-in account with a particular role, after a cookie from last week, or with one of your other extensions installed. A fresh browser launched by a test tool starts signed out, so the agent first has to get past the login, and the failing state may never come back.

MCP Browser Extension runs inside the Chrome you are signed into. When the agent opens a page, it is the page you see, with your session. The logged-in Chrome page explains that model. For debugging, it means the agent can reproduce the bug where it actually happens and read the console and requests itself, so you do not have to copy errors out of DevTools and paste them into a chat.

The renamed mcp-browser-extension repository in the owner’s signed-in Chrome, with Settings and Unpin visible.
The signed-in mcp-browser-extension repository, captured 2026-10-15. Settings and Unpin show the owner’s existing session.

What the observers record

Reading the DOM tells the agent what a page looks like after it failed, not why. With observers on, an in-page hook records three things:

  • Console output and uncaught errors. Every console.* call, plus uncaught errors and unhandled promise rejections. console_logs returns them, filtered by level if you like: log, info, warn, error, debug or exception.
  • Requests made by page code. fetch and XMLHttpRequest calls with method, URL, status and duration. network_log returns them. failedOnly: true keeps only requests that errored or returned a status of 400 or above.
  • Native dialogs. alert, confirm, prompt and beforeunload. With observers on they are answered instead of left to block the page, and dialogs reports what was raised and how it was answered.

The hook is registered at document_start for the domains on your allowlist only, so it catches failures that happen while the page loads. Nothing it records leaves the page until a tool call reads it, and that read goes through the same domain gate as any other page read. The observers reference lists every argument.

Step 1: Turn on observers

Observers are off by default, and on purpose: the hook patches console, fetch, XMLHttpRequest and the dialog functions on every allowlisted page in your real browser. Turn them on with the server flag --enable-observers, and keep the allowlist to the site you are debugging while they are on. You need version 0.9.29 or later: in earlier versions the flag unlocked the tools but never reached the extension, so every call was refused.

In Claude Code, re-register the server with the flag:

claude mcp remove mcp-browser-extension -s user
claude mcp add mcp-browser-extension -s user -- \
  npx -y mcp-browser-extension@latest \
  --allow-domain app.example.com \
  --enable-mutations --enable-observers --persist-token

In Claude Desktop, Cursor and other hosts that use a JSON config, add the flag to args:

{
  "mcpServers": {
    "mcp-browser-extension": {
      "command": "npx",
      "args": ["-y", "mcp-browser-extension@latest",
               "--allow-domain", "app.example.com", "--enable-mutations",
               "--enable-observers", "--persist-token"]
    }
  }
}

Replace app.example.com with the site you are debugging. For a local dev server, allow localhost. --enable-mutations is there so the agent can navigate, click and type to reproduce the bug. Leave it out if you only want it to read a page you open yourself. Reconnect the server after the change (/mcp in Claude Code, or restart the host).

Step 2: Reproduce the bug, then read the logs

The order matters. The hook is registered at document_start, so it sees a page load only if it was registered before that load. If the tab was already open before you turned observers on, capture starts when the agent first reads the logs. Reload the page so the load-time errors are recorded.

A typical sequence:

navigate     { "url": "https://app.example.com/reports" }
console_logs { "level": "exception" }        // uncaught errors and unhandled rejections
console_logs { "level": "error" }            // what the app logged with console.error
network_log  { "failedOnly": true }          // requests that errored or returned >= 400
screenshot   {}                              // what the user actually sees

Uncaught errors are recorded at the exception level, separate from console.error calls, so ask for both, or leave level out to get everything. If the failure needs a click, do the click and read again with sinceSeq set to the last sequence number you saw, so you only get what is new:

click        { "role": "button", "name": "Export" }
network_log  { "urlContains": "/api/export", "sinceSeq": 42 }
console_logs { "sinceSeq": 17 }

If a click seems to hang, check dialogs. A confirm() behind a delete button used to block the renderer until the command timed out. With observers on it is dismissed by default (confirm returns false, prompt returns null) and recorded. To let the flow continue, switch the policy:

dialogs { "policy": "accept" }               // answer confirm() with true from here on

When a script, image or stylesheet seems to be missing, add includeResources: true to network_log. Those entries come from Resource Timing and carry timing and size, but no status code, so they tell you whether a file loaded and how long it took, not whether the server returned a 404.

An example prompt

You do not have to type the tool calls. Describe the bug and say which tools to use:

The Reports page at https://app.example.com/reports shows an empty table
for my account. Reload it, then call console_logs (both "exception" and
"error"), network_log with failedOnly true, and take a screenshot.
Tell me which request or error explains the empty table, and point me to
the code in this repo that most likely causes it.

Run in Claude Code inside the app's repository, this gives the agent both halves: the failing request or stack trace from your browser, and the source code to match it against. The companion use case, find why a page is broken from the console and network log, walks through one run of this from start to finish.

What the observers cannot see

The observers are a hook inside the page, not a debugger attached to Chrome. That trade has costs, and they are worth knowing before you rely on them:

  • No document request, redirects or headers. network_log sees requests made by page code. If the HTML itself returns a 500, or a redirect loop sends you to the wrong place, it will not appear.
  • No status for resources. Resource Timing entries have timing and size only.
  • Allowlisted domains only. A page the agent may not read is not instrumented, and frames whose origin is not on your allowlist are skipped.
  • No performance traces or memory tools. There is no Lighthouse audit, CPU profile or heap snapshot here.

Chrome DevTools MCP takes the other approach. It uses the Chrome DevTools Protocol and, by default, starts its own Chrome with a dedicated profile, or attaches to your running Chrome with --autoConnect. It offers console messages with source-mapped stack traces, network requests, performance traces, Lighthouse and memory tools. If you need deep performance or memory work, it is the better tool. MCP Browser Extension is a reasonable Chrome DevTools MCP alternative when the bug lives behind your login and you want the agent working in the session you already have, with a deny-all domain allowlist that gates reads as well as clicks. The Chrome DevTools MCP vs Playwright MCP comparison covers the other options, and use cases shows more tasks people run with the extension.

FAQ

Can an AI agent read the browser console?

Yes, with MCP Browser Extension started with --enable-observers. console_logs returns console output, uncaught errors and unhandled promise rejections recorded on allowlisted pages. Without the flag the tool is not available.

How do I see failed network requests through MCP?

Call network_log { "failedOnly": true }. It lists fetch and XMLHttpRequest calls that errored or returned a status of 400 or above, with method, URL, status and duration. It does not include the document request, redirects or headers.

Can I debug a website with Claude without copying from DevTools?

Yes. Add the MCP server with --enable-observers, allow the site's domain, and ask Claude to reproduce the problem and read console_logs and network_log. It reads the errors from your own Chrome directly.

Why does a click time out when the page opens a confirm dialog?

alert, confirm and prompt block the page's renderer, so scripts injected into it stall until the command times out. With observers on, dialogs are answered (dismissed by default) and recorded. Use dialogs { "policy": "accept" } to answer them with OK.

Is this a full replacement for Chrome DevTools MCP?

No. It covers console errors, page requests and dialogs in your signed-in Chrome. It has no performance traces, Lighthouse or memory tools, and it cannot see the document request or headers. For that work, Chrome DevTools MCP is the better choice.

Set it up in a few minutes

One command for the server, one click for the extension.