My Agent Failed the Same LinkedIn Click 30 Times. Camoufox Got It on the First.

When Chrome MCP Hits Its Limits and You Need Real Browser Control: Chrome MCP vs Camoufox for AI Agents

7 min read

Sometimes the AI just does something dumb. Doesn't matter how you prompt it.

Split-screen office cubicle illustration comparing frustrated developer with failed automation attempts versus confident developer with successful browser automation result
30 failed attempts vs. first-try success. Wrong tool, buddy.

The Same Click, 30 Times

My agent failed the same LinkedIn click 30 times, hitting the same button on the same page in an infinite retry loop. LinkedIn profiles show "Follow" as the primary action and "Connect" tucked inside a "More" overflow menu (the 3 dots). You tap the overflow, the menu appears, you click "Connect," the connection dialog opens. Straightforward.

The Chrome MCP takes a screenshot to read the element's position, then sends the click. That sequence has a delay. Short, but incompressible. By the time the click event fires, the animated overflow menu has already dismissed itself. The agent doesn't detect this. It takes another screenshot, sees no "Connect" dialog, loops back. By attempt 14 the logs are showing the exact same sequence. Attempt 20 is just noise.

At some point I'm sitting there reading the logs thinking this thing is going to get me banned. (Dark Souls energy: you died, you tried, you died again. Except getting banned from LinkedIn is not a respawn situation.)

The Chrome MCP is not a bad tool. I want to be exact about that before going further, because it's easy to spiral into "the tool sucks" after a session like this. For 80% of browser automation tasks it's the right default. The problem was that the LinkedIn overflow menu case wasn't in that 80%, and the signal to switch was already there at attempt 2.

What Chrome MCP Actually Does Well (The 80%)

Reusing an existing session is where Chrome MCP is hard to beat. The browser is already authenticated, cookies loaded, 2FA cleared. The agent drops into that context without touching login or verification flows.

Navigation and text extraction are reliable. Reading DOM content, scraping structured pages, pulling text from stable layouts: solid.

Standard HTML forms work cleanly. Text fields, dropdowns, checkboxes: the MCP fills them without ceremony, no JavaScript gymnastics required.

Frontend debugging is the underrated case. The agent can read console errors, network waterfall, and live page state. Useful when you're building something and want the agent to verify its own output in the browser without spinning up a separate test harness. Think of it as pair programming where 1 partner only communicates through screenshots. Inefficient for most conversations, surprisingly fine for code review.

These 4 cases cover the majority of what any browser automation workflow needs day to day. The edge cases surface when the action requires tight timing or native event handling.

The 4 Ways It Breaks

The LinkedIn case produced 4 distinct failure modes on the same action. Each plays out differently.

The menu closes before the click lands. The overhead between taking a screenshot and dispatching the click is incompressible. For a CSS transition that dismisses in 150ms, that overhead is enough. The menu is gone before the click arrives.

Synthetic clicks are silently ignored. LinkedIn's artdeco component library listens for trusted pointer events, the kind generated through actual hardware input. A programmatically dispatched click doesn't carry the isTrusted flag. The component doesn't respond. No error, no feedback, nothing.

The element is hidden by the sticky header. LinkedIn's navbar stays fixed at the top of the viewport. If the overflow menu opens near the top of the page, the navbar intercepts the click. Chrome MCP performs no hit-test to detect this.

The tab drifts. After enough parasitic clicks, something activates: a card, a profile link, a sidebar panel. The agent loses the target page and starts confidently automating whatever it landed on. (Sponsored networking event accepted. Thanks, agent.)

Each of these is workable in isolation. All 4 together on the same action is a structural wall.

Why It Breaks (It's Not the Prompt)

The Chrome MCP operates from above the browser. It sits as an extension, observes through screenshots, dispatches 1 action per cycle, and waits. This model has a real advantage: it doesn't require installing anything inside the rendering engine, it reuses your existing Chrome session without modification, and you can point it at any running Chrome instance with no setup. The tradeoff is that every action involves a round-trip with enough latency to drop time-sensitive UI states, and the clicks it dispatches don't originate from within the trusted event pipeline.

Modern JavaScript frameworks check the isTrusted property on incoming pointer events, and React, Vue, and component libraries like LinkedIn's artdeco all make this check. A Chrome MCP click lands in the DOM but fails the component's internal validation. The failure is silent, no error surfaces, and you'd have to read the component source to even know the check exists.

I spent 3 weeks trying to fix the timing side specifically: wait_for_element, increasing retry gaps, different delay values between screenshot and click. The menu kept dismissing. The isTrusted problem was completely separate and I only figured that out after reading the artdeco source. That was a fun Thursday.

Why CLIs often beat MCP for agent work covers the token cost side of this tradeoff, but the trusted event side is what actually bites in production.

A Chrome MCP click is technically a click. The component treats it like a polite email nobody asked for.

The Switch Signal: 2 to 3 Failures

The rule is 1 line: after 2 to 3 failures on the same specific action, stop and switch tools. Adding another retry loop doesn't change the outcome when the failure is structural.

After the 3rd failed attempt on the same gesture, you're not debugging the approach. You're leveling up your log file.

The situations that trigger the switch:

  • A menu or overlay closes before the click lands
  • 2 gestures need to chain inside a tight time window (open menu, then click item)
  • The element doesn't respond to clicks and shows no error
  • A React or Vue button stays grayed out despite the form appearing valid
  • The same action needs to run dozens of times in headless mode

I think this 2-to-3 threshold holds for most standard web UIs. Less confident it applies the same way to fully custom frameworks where failure modes look different.

What Camoufox Changes (And What It Costs)

Camoufox is a Firefox browser hardened against bot detection, driven by Playwright. Where Chrome MCP operates from above the browser, Playwright injects events from inside the rendering engine, through the same path real user input takes.

On the LinkedIn overflow case:

Real trusted events. Playwright dispatches the full pointer event chain with isTrusted: true. The overflow menu opens. The "Connect" item registers the click. First profile done.

ARIA-based locators. Instead of screenshot pixel coordinates: page.getByRole('menuitem', { name: 'Connect' }). Deterministic, readable, and doesn't break when LinkedIn tweaks their padding by 2 pixels in a Monday maintenance window. Every team's had that deploy 😅

No round-trip between actions. Open the menu and click the item in the same script execution. No screenshot cycle between the 2 steps. No race condition.

React state validation. For a submit button that stays grayed out until the input has a value: Playwright emits both the input and change events to wake the component's state, then clicks the unlocked button. Chrome MCP clicks the grayed button. Nothing happens.

Caveats right away. The session doesn't transfer: first launch requires a manual login, since Camoufox doesn't inherit Chrome's cookies. A new browser fingerprint triggers LinkedIn's "new device" verification. The Playwright script is production code that needs to be maintained. And LinkedIn's rate limiting doesn't care which browser you're using if the action cadence looks automated.

The switch has a real setup cost. It pays off when Chrome MCP has already shown 2 to 3 failures on a specific action. Not before. Playwright is built on Chrome DevTools Protocol, which is part of why the event model ends up much closer to real user input than anything operating from above the browser.

When to Use What

TITLE "Chrome MCP vs Camoufox: When to Switch" + subtitle "8 scenarios, 1 decision rule". Metaphor: 2-column control room panel, left side labeled CHROME MCP (green), right side labeled CAMOUFOX (orange), with 4 situation cards on each side. Style: engineer blueprint on graph paper, clean grid lines, technical annotation style, no decorative elements. Palette: slate gray #334155, terminal green #22c55e, warning orange #f97316, off-white #f8fafc, black #0f172a. Content: Green column cards: NAVIGATE AND EXTRACT, FILL STANDARD FORM, REUSE EXISTING SESSION, FRONTEND DEBUGGING. Orange column cards: MENU OR OVERLAY, 2 CHAINED GESTURES, SYNTHETIC CLICK IGNORED, HEADLESS VOLUME. Highlight: full-width bottom banner in orange with bold white text: SWITCH RULE: 2 TO 3 FAILURES ON THE SAME ACTION. Legend: green card = Chrome MCP territory, orange card = Camoufox territory. Footer: copyright rentierdigital.xyz bottom-right, small. NOT flat corporate dashboard, NOT generic side-by-side comparison template.
Chrome MCP vs Camoufox Decision Guide

Chrome MCP for:

  • Quick one-off tasks on sites you're already logged into
  • Reading content from stable pages
  • Form filling on standard HTML inputs
  • Debugging frontend issues in an existing session

Camoufox + Playwright for:

  • Repeated actions that need to be reliable
  • Interactive elements that require trusted events
  • Tight timing sequences (menus, dropdowns, modals)
  • Production automation that can't afford retry loops

The switch trigger: 2-3 failures on the same specific action. Not 30.


The 30-attempt session cost 40 minutes and a Playwright script rewrite. Camoufox got the first profile in 12 seconds. The 29 after that ran at the same pace.

The signal was there at attempt 2. I just needed 28 more attempts to read it. 🤦‍♂️

Sources

This post may contain affiliate links. If you click them, I might earn a small commission. Costs you nothing, and helps me keep shipping quality articles every day for your reading pleasure.


When the agent keeps retrying the same click 30 times, it's usually not a prompt problem—it's a tool mismatch. The CLI blueprint in the welcome kit shows how to structure browser tools so they fail fast and signal when to switch, instead of looping into oblivion.

Get the welcome kit