●MCP — Support for the 2026-07-28 spec is rolling out across Claude. The protocol moves from bidirectional and stateful to request/response, so MCP servers can now live on serverless and edge infrastructure●EXTENSIONS — Three official extensions have landed: MCP Apps for server-rendered UI, Tasks for async and long-running work, and Enterprise Managed Auth for IdP-based org-wide provisioning●ADOPTION — MCP passed 400 million monthly SDK downloads, roughly 4x growth this year, settling into its role as the standard way to connect agents to applications●QUOTA — Today, August 19, is the last day of the 50 percent weekly usage boost for Claude Code subscribers. If you have long agent runs queued, this is the window●PRICING — Claude Sonnet 5's introductory rate of $2 per million input tokens and $10 output ends August 31; standard pricing of $3 and $15 takes over on September 1, twelve days out●FIX — A bug where MCP v2 connections endlessly reopened subscriptions against servers with fixed timeouts is resolved, and a forward_user_identity setting was added for user attribution●MCP — Support for the 2026-07-28 spec is rolling out across Claude. The protocol moves from bidirectional and stateful to request/response, so MCP servers can now live on serverless and edge infrastructure●EXTENSIONS — Three official extensions have landed: MCP Apps for server-rendered UI, Tasks for async and long-running work, and Enterprise Managed Auth for IdP-based org-wide provisioning●ADOPTION — MCP passed 400 million monthly SDK downloads, roughly 4x growth this year, settling into its role as the standard way to connect agents to applications●QUOTA — Today, August 19, is the last day of the 50 percent weekly usage boost for Claude Code subscribers. If you have long agent runs queued, this is the window●PRICING — Claude Sonnet 5's introductory rate of $2 per million input tokens and $10 output ends August 31; standard pricing of $3 and $15 takes over on September 1, twelve days out●FIX — A bug where MCP v2 connections endlessly reopened subscriptions against servers with fixed timeouts is resolved, and a forward_user_identity setting was added for user attribution
Claude in Chrome Not Working? A Practical Troubleshooting Guide
Buttons that do nothing, pages that never load, tasks that report success but change nothing. Symptom-by-symptom fixes, plus the 42-run log where adding waits and verification steps moved completion from 62% to 95%.
You set up Claude in Chrome, wrote a careful prompt, and then — it stopped halfway through. Or the button click did nothing. Or the page loaded but Claude couldn't read it.
When I first handed my weekly AdMob report pull to Claude in Chrome, two out of every five runs died somewhere in the middle. I rewrote the prompt again and again without ever establishing where things were actually breaking.
The pattern turned out to be simpler than I expected. Almost none of the failures were about Claude's capability. They came from a mismatch between the state of the page and the assumptions baked into my instructions.
This guide walks through the most common issues by symptom, and includes the numbers from three weeks of running the same task.
Buttons Don't Respond When Clicked
Claude reports "I clicked the button" but the page doesn't change, or nothing happens at all.
Common causes:
The most frequent culprit is timing: the button is rendered dynamically, and Claude tries to click it before it actually exists in the DOM. Another cause is how the click handler is wired up — if it uses addEventListener instead of a simple onclick attribute, Claude's simulated click may not fire the event correctly. And occasionally, an element is visually present but sits behind a transparent overlay that intercepts clicks.
What to try:
Start with the simplest fix: ask Claude to reload the page and try again. If that doesn't help, add an explicit wait in your prompt — "wait 3 seconds after the page loads before clicking" gives the DOM time to settle. You can also experiment with keyboard navigation, which is often more reliable than click simulation for interactive elements. Try: "press Tab to focus the button, then press Enter to activate it." For dropdown menus and custom components, specifying the element by its visible label text usually works better than trying to click by position.
Pages Don't Load Correctly or Can't Be Scrolled
Claude says it opened the page but can't read the content, or infinite scroll doesn't work and only the first screen of content is retrieved.
Typical scenarios:
Infinite scroll pages are a common pain point — Claude fetches the initial load and stops, missing everything below the fold. Single-page applications (SPAs) are another: the URL changes, but the content hasn't updated in the DOM yet when Claude reads it. There's also the basic case where Claude starts interacting before the page finishes loading.
What to try:
For slow-loading pages, add an explicit wait instruction: "wait until the page is fully loaded before reading." A prompt like "confirm the page title before proceeding" forces Claude to verify the page is ready.
For infinite scroll, break it into steps: "scroll down three times, then read the visible content." You can repeat this pattern to collect data across multiple scrolls without overloading a single instruction.
For SPAs, after navigation prompt Claude to "re-read the current page content" — this triggers a fresh DOM capture rather than using a cached state from the previous page. If the content still looks stale, try navigating directly to the target URL rather than clicking through the app.
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦A three-week, 42-run measurement showing how explicit waits and verification steps moved task completion from 62% to 95%
✦A ready-to-run Node preflight script that catches MCP port conflicts, missing environment variables, and unreachable servers before a task starts
✦A five-step isolation procedure and a symptom-to-fix priority table for deciding what to try first
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
The form gets filled in correctly, but after submitting, Claude can't proceed to the authenticated area. Or the session expires mid-task.
Main causes:
Two-factor authentication (2FA) is the most common blocker — Claude in Chrome cannot complete authentication app codes, SMS codes, or hardware key prompts. SSO redirects through identity providers (Okta, Google, Microsoft) can also stall the workflow. And for longer-running tasks, session cookies sometimes expire before the task finishes.
What to try:
For services with 2FA, log in manually in your browser before starting the Claude in Chrome task. The existing session is inherited, so Claude can proceed from an already-authenticated state without needing to handle credentials.
For session expiry, add a health check at the beginning of your prompt: "first verify I'm logged into [service name] by checking whether my account name is visible. If I appear to be logged out, navigate to the login page and log in." This catches session issues before they derail the main task.
A practical tip: keep your most-used service tabs open and logged in before starting Claude in Chrome tasks. This is especially helpful for automation that runs across multiple sites.
Stopped by a CAPTCHA
Claude in Chrome cannot solve CAPTCHAs. This is a deliberate design limitation, not a bug.
Practical workarounds:
For Google services, being logged into your Google account before running tasks significantly reduces CAPTCHA frequency — Google uses account reputation to decide when to skip the challenge. For other services, having an existing browser session with valid cookies often bypasses CAPTCHAs as well, since you've already demonstrated human-like behavior.
If a service consistently presents CAPTCHAs mid-task, it's actively detecting automation. At that point, fully automated Claude in Chrome operation probably isn't the right tool — consider whether a manual-assisted workflow or an official API integration would serve better.
One pattern that works well: use Claude in Chrome for the decision-making and navigation logic, and pause at CAPTCHA steps for manual intervention. You can structure your prompt to ask Claude to "stop and report back if it encounters a CAPTCHA."
Can't Read PDFs or Dynamically Generated Content
Asking Claude to read a web-based PDF or extract data from a JavaScript-rendered chart fails to return useful results.
For PDFs:
Browser-embedded PDF viewers don't expose their text through the DOM in a way Claude can reliably access — the viewer renders the PDF as a canvas or image layer, not as selectable text. The practical workaround: ask Claude to copy the PDF's URL from the address bar, then paste that URL into a Claude.ai chat window and upload the file there. Claude's native PDF parsing is much more reliable than DOM-based extraction.
For dynamically loaded content:
API-fetched data isn't in the page's initial HTML. If Claude is reading the page source rather than the rendered result, it'll miss this content entirely. Try asking Claude to "read only the text currently visible on screen, not the page source." This forces it to work from the visual rendering rather than the DOM.
For visual data like charts and graphs, the screenshot approach often works better than structured extraction: "take a screenshot of the chart and describe what you see." Claude can then interpret the visual information and summarize it — which is more reliable than trying to parse SVG elements or canvas data.
Task Stops Midway or Ends With an Error
Multi-step tasks sometimes halt partway through without completing, often with a vague error message or no message at all.
Context overflow:
Long sessions accumulate context — conversation history, page contents, screenshots — and can hit the context window limit. When this happens, Claude typically stops or produces degraded results. The fix is to break large tasks into smaller chunks: "process URLs 1 through 10" in one session, "process URLs 11 through 20" in the next. This keeps each session well within limits and makes failures easier to resume.
Network timeouts:
Slow-loading pages can cause timeouts that interrupt the task flow. Adding "if the page times out, wait 10 seconds and try again" to your prompt gives Claude permission to retry automatically rather than stopping.
Checking whether it's really Claude's fault:
Before debugging your prompt, open the target page in your browser manually. If the page is down, returning 403 errors, or behaving strangely for regular users, that's a service-side problem. Claude in Chrome will fail in the same way humans would.
Task Completes But Results Are Wrong
Claude reports success, but the actual outcome isn't what you expected.
Common examples:
Form data was entered but the save button was never clicked. Only the first page of results was processed, not all of them. Items that don't match your filter criteria were included anyway. Or Claude misinterpreted "delete all" as "delete the selected items."
What to try:
Add explicit verification steps to your prompt: "after saving the form, confirm you see a success message. If not, try submitting again." This catches the failure case where Claude thinks it succeeded but the action didn't actually go through.
For multi-page processing, define your exit condition clearly: "continue clicking 'Next page' until the button is grayed out or disappears, then stop and report the total count." Without an explicit end condition, Claude may stop at the first page or loop indefinitely.
For filtering tasks, describe the acceptance criteria: "only process items where the status shows 'Active' — skip anything else and include a count of skipped items in your report." Explicit criteria leave less room for ambiguity.
If you're using Claude in Chrome alongside Cowork's MCP integrations, connection errors can appear when the server isn't reachable.
Check the Cowork settings panel first — if the MCP server shows as "Disconnected," restarting the Cowork app resolves this in most cases. If it doesn't, run the MCP server from your terminal to see its logs directly. The two most common issues are port conflicts (another process using the same port) and missing environment variables that the server expects at startup.
For persistent connection issues, double-check that your firewall isn't blocking the MCP server's port, and verify the server process is actually running before starting the Claude in Chrome session.
Isolating the Cause in Five Steps
Rewriting the whole prompt is tempting, and almost always slower than finding the layer that broke. Here is the order I work through.
Do the same action by hand. Does the page open, does the button respond, does the login go through? If it fails here, the service is the problem and no prompt will fix it.
Cut the task down to one step. Replace "log in, open the report page, download the CSV" with "open the report page and read me the column headers." This pins down exactly which step breaks.
Insert a wait before the failing step. If "wait 5 seconds before clicking" fixes it, the cause was timing. If it doesn't, the cause is DOM structure or permissions.
Switch to the visual path. Ask Claude to "take a screenshot and list the labels of every button you can see." Elements Claude cannot perceive reveal themselves here.
Make the verification permanent. Once the prompt works, append: "after the action, confirm the success message is visible. If it isn't, stop and report."
Skipping steps 3 and 4 to rewrite the whole prompt feels faster. In my experience it mostly trades one failure for a different one.
What the Docs Don't Tell You
Here is what three weeks and 42 runs taught me. The task: pull the weekly report from the AdMob console, and read the sales screen in App Store Connect.
Three seconds isn't enough for some screens. A plain page settles in three seconds. The AdMob console, which paints its charts asynchronously, did not — Claude read an empty table. Stretching the wait to six seconds took empty reads from a recurring annoyance to zero across twelve runs. "Wait until the page is fully loaded" sounds sufficient, but Claude's idea of "loaded" and the renderer's idea of "finished" are not the same event. Name the number of seconds.
The verification step mattered more than anything else. With no waits and no verification, 26 of 42 runs (about 62%) reached the end. Adding two things — a wait with an explicit duration, and "confirm the success condition visually after the action; stop and report if it isn't met" — moved completion to 40 of 42 runs (about 95%). Average runtime grew from 1m48s to 2m21s. Thirty-three seconds, against the several minutes a failed run costs in manual rework.
The two remaining failures were loud, not silent. After the verification step went in, a failing run always stops and says "I could not confirm the success message." It no longer returns a wrong answer quietly. That change mattered more to me than the percentage did.
The same site behaves differently by time of day. First paint on the console felt roughly twice as slow during weekday mornings. If you put a task on a schedule, set the wait generously by default.
Stretching three seconds to six fixed one screen at one time of day. If first paint really is twice as slow during the morning rush, six seconds will eventually be too short — and on a quiet afternoon it throws away four seconds on every run.
What held up better was to stop guessing the number and describe the condition instead.
Check every 2 seconds, for up to 30 seconds, until the heading "This week'searnings" is visible and the table below it has at least one row of data.If it has not appeared after 30 seconds, take a screenshot, stop, and tell mehow far the page had rendered.
Three things are doing work in that phrasing.
The thing being waited on is a concrete object on screen — a heading string and a table row — not the abstract idea of "loaded"
The polling interval and the ceiling are both given as numbers
What happens at the ceiling is spelled out
Drop the third one and Claude decides for itself when to give up and move on. "Wait until it appears" leaves the stopping rule entirely on the reader's side of the conversation.
The practical difference from a fixed wait: fast days proceed immediately, slow days keep waiting. My weekly report prompt got visibly longer, but I stopped adjusting the number by time of day.
Applying this to every action is a mistake, though. The prompt balloons, and a sprawling prompt becomes its own failure mode. I keep a fixed duration as the default for scheduled runs and convert only the one or two genuinely slow screens — the AdMob console being the obvious one — to the polling form.
What the Visual Path Costs You Instead
Switching to screenshots at step four of the isolation procedure works. It is not free, though, and leaving "show me the screen if you get stuck" permanently in a production prompt comes back as a different symptom.
Images are billed by area. The estimate given in the documentation is width in pixels × height in pixels ÷ 750, with anything longer than 1568px on its long edge scaled down into that bound before the conversion. Running common viewports through the formula:
Captured size
Size used for conversion
Approximate tokens
1280 × 800
1280 × 800
~1,365
1512 × 982
1512 × 982
~1,980
1920 × 1080
1568 × 882
~1,844
3024 × 1964 (2× Retina)
1568 × 1018
~2,128
1568 × 1568 (near the downscale bound)
1568 × 1568
~3,278
These come from the formula, not from a bill, so treat them as order-of-magnitude figures. Two things fall out of the table. Capturing at a higher resolution barely matters, because the downscale pulls everything back toward roughly 2,000 tokens. And that figure is still an order of magnitude above reading a heading and a table as text, which lands in the hundreds to low thousands.
Ask for a screenshot after each of ten steps and the images alone add up to around 20,000 tokens. Priced at $3 per million input tokens that is about six cents a run — not a number worth thinking about for a weekly task.
Context is where it actually bites, well before billing does. Some of the mid-task stops described earlier turned out to be self-inflicted: I had switched to the visual path to diagnose something and never switched back, then filled the window with my own screenshots. Show the screen while you are hunting for the cause; return to the text path once you have found it. I treat the visual path as a diagnostic instrument rather than something that lives in the production prompt. The only screenshot I leave behind is the success check on the final step.
Verify the MCP Server Before the Task Starts
Miss a "Disconnected" badge, run the task anyway, collect an empty result ten minutes later. After doing that more than once, I collapsed the checks into a single script. It settles three things before anything else runs: port conflicts, missing environment variables, and reachability.
// preflight.mjs — verify MCP servers before running a Claude in Chrome task// Run with: node preflight.mjsimport net from 'node:net';const CHECKS = [ { name: 'my-mcp-server', host: '127.0.0.1', port: 3333, env: ['MCP_API_KEY'] }, { name: 'sheets-mcp', host: '127.0.0.1', port: 3334, env: ['GOOGLE_CREDENTIALS_PATH'] },];function probe(host, port, timeoutMs = 1500) { return new Promise((resolve) => { const socket = net.connect({ host, port }); const done = (reachable) => { socket.destroy(); resolve(reachable); }; socket.setTimeout(timeoutMs); socket.once('connect', () => done(true)); socket.once('timeout', () => done(false)); socket.once('error', () => done(false)); });}const failures = [];for (const check of CHECKS) { const missing = check.env.filter((key) => !process.env[key]); const reachable = await probe(check.host, check.port); if (missing.length > 0) { failures.push(`${check.name}: missing environment variables (${missing.join(', ')})`); } if (!reachable) { failures.push(`${check.name}: cannot reach ${check.host}:${check.port}`); } if (missing.length === 0 && reachable) { console.log(`OK ${check.name} (${check.host}:${check.port})`); }}if (failures.length > 0) { console.error('\nPreflight failed:'); for (const line of failures) console.error(` - ${line}`); process.exit(1);}console.log('\nAll checks passed. Safe to start the task.');
The important line is process.exit(1). A script that only prints a warning is a script whose warnings you eventually stop reading. Make it fail loudly and you can't proceed by accident.
When reachability fails, find out who owns the port.
# macOS / Linux — identify the process listening on port 3333lsof -nP -iTCP:3333 -sTCP:LISTEN# Terminate it only if it is a leftover from a previous runkill "$(lsof -t -nP -iTCP:3333 -sTCP:LISTEN)"
In my case the answer was nearly always a previous MCP server process that never fully exited. That is usually what "restart the Cowork app and it works again" is actually fixing. For a worked example of chasing a backend error from the browser side, see how we fixed Stripe webhook HTTP 500 errors using Claude in Chrome.
Measure Completion Rate in Your Own Setup
The 62% and the 95% belong to two screens I happen to open every week: the AdMob console and the App Store Connect sales view. A different target has a different starting point and a different ceiling. Borrow the shape of the result by all means, but adopting the numbers as your own is how you end up fixing the wrong thing.
So I append one line per run and let the arithmetic happen later. Nothing elaborate — an append and a summary.
Median rather than mean, because one run that fought on until the very end will drag an average somewhere unhelpful. The median stays close to what a normal run actually feels like.
The part that repays the effort is refusing to leave the failure note blank. I watch how many distinct notes accumulate more closely than I watch the percentage. A column of "success message never confirmed" points at the prompt. Notes that keep scattering into new shapes usually mean the problem is the choice of target, not the wording — that is my working rule, at least.
Ten runs is enough for the shape to show. Folding the record step into the same routine as the preflight check from the previous section is what made me keep doing it.
Which Fix to Try First
To spend less time guessing, here is the order I work down for each symptom. In my setup, isolation usually finishes within two attempts.
Symptom
Try first
Try next
If still broken
Clicks do nothing
Add a 5-second wait before the action
Switch to Tab + Enter keyboard navigation
Screenshot to confirm the element is visible
Content unreadable
Extend the wait to 6 seconds
"Read only the text visible on screen"
Read through a screenshot instead
Stuck at login
Log in manually beforehand
Add a session check as step one
If 2FA is required, drop it from automation
Stops midway
Split the task into batches of ten
Add an explicit retry instruction
Reproduce by hand and suspect the service
Wrong result
State the post-action success condition
Require a count in the report
Define the exit condition and rerun
MCP connection error
Run the preflight script
Kill the process holding the port
Start from a terminal and read stderr
When a fix doesn't land, go back to the leftmost column. Starting to fix a symptom you can't state in one sentence is how an afternoon disappears.
Claude in Chrome is an automation tool, but what actually made it dependable wasn't the automation. It was arranging things so a failure tells me where it stopped. A named wait duration and a verification step. Those two additions turned my weekly report pull from something I watched into something I only touch when it complains.
If you do one thing after reading this, pick the task that fails most often and append a single sentence after its final action: "confirm the success condition visually, and stop and report if it isn't met." Highest return, one line of typing.
Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.