<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Web-Scraping on RockB</title><link>https://baeseokjae.github.io/tags/web-scraping/</link><description>Recent content in Web-Scraping on RockB</description><image><title>RockB</title><url>https://baeseokjae.github.io/images/og-default.png</url><link>https://baeseokjae.github.io/images/og-default.png</link></image><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 06 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://baeseokjae.github.io/tags/web-scraping/index.xml" rel="self" type="application/rss+xml"/><item><title>Cloudflare Browser Rendering MCP Server Guide 2026: Screenshots, Crawls, and Web Data for Agents</title><link>https://baeseokjae.github.io/posts/cloudflare-browser-rendering-mcp-server-guide-2026/</link><pubDate>Mon, 06 Jul 2026 00:00:00 +0000</pubDate><guid>https://baeseokjae.github.io/posts/cloudflare-browser-rendering-mcp-server-guide-2026/</guid><description>Practical guide to Cloudflare&amp;#39;s Browser Rendering MCP server — setup for Claude Code, Cursor, and OpenCode, with real workflows for screenshots, Markdown, crawls, and structured data extraction.</description><content:encoded><![CDATA[<p>If your AI coding agent needs to read a web page, take a screenshot, or crawl a site, you have two options: run a local browser stack (Playwright, Puppeteer) or call a hosted browser API. Cloudflare&rsquo;s Browser Rendering MCP server splits the difference — it gives you a managed browser in the cloud, exposed as MCP tools your agent can call directly.</p>
<p>I&rsquo;ve been testing all three Cloudflare browser paths — the official Browser Rendering MCP server, the <code>@cloudflare/playwright-mcp</code> Worker, and the CDP-based <code>chrome-devtools-mcp</code> setup — across Claude Code, Cursor, and OpenCode. Here&rsquo;s what works, what doesn&rsquo;t, and how to pick the right path.</p>
<h2 id="what-the-browser-rendering-mcp-server-actually-does">What the Browser Rendering MCP Server Actually Does</h2>
<p>Cloudflare announced 13 remote MCP servers on May 1, 2025, and the Browser Rendering server is the one that handles web page interaction. It wraps Cloudflare&rsquo;s <a href="https://developers.cloudflare.com/browser-run/">Browser Run</a> REST API into MCP tools your agent can call without writing HTTP requests.</p>
<p>The tool surface covers the jobs you&rsquo;d expect:</p>
<ul>
<li><strong>Screenshots</strong> — full-page or viewport captures of any URL</li>
<li><strong>Markdown conversion</strong> — rendered page content as clean Markdown</li>
<li><strong>HTML extraction</strong> — raw rendered HTML</li>
<li><strong>JSON extraction</strong> — AI-assisted structured data from pages</li>
<li><strong>Link discovery</strong> — all links on a page</li>
<li><strong>PDF rendering</strong> — page as PDF</li>
<li><strong>Element scraping</strong> — specific CSS selector targets</li>
<li><strong>Snapshots</strong> — accessibility-tree snapshots for LLM consumption</li>
<li><strong>Crawl</strong> — multi-page crawl jobs</li>
</ul>
<p>The key difference from running Playwright locally: you don&rsquo;t manage browser binaries, session state, or network egress. Cloudflare handles the Chromium instance in their edge network. Your agent just calls <code>take_screenshot</code> or <code>crawl</code> and gets back the result.</p>
<h2 id="three-paths-one-browser-run">Three Paths, One Browser Run</h2>
<p>Cloudflare offers three ways to connect your agent to Browser Run. They&rsquo;re not interchangeable — each serves a different workflow.</p>
<h3 id="path-1-official-browser-rendering-mcp-server">Path 1: Official Browser Rendering MCP Server</h3>
<p>This is the simplest path. Cloudflare hosts the MCP server, you configure your MCP client with your API token, and you&rsquo;re done. The server exposes tools like <code>browser_render_content</code>, <code>browser_take_screenshot</code>, and <code>browser_crawl</code>.</p>
<p><strong>Best for:</strong> Quick setup, standard web data workflows, teams that don&rsquo;t want to maintain a custom Worker.</p>
<h3 id="path-2-cloudflareplaywright-mcp-worker">Path 2: <code>@cloudflare/playwright-mcp</code> Worker</h3>
<p>This deploys a Playwright-based MCP server as a Cloudflare Worker with Browser Run and Durable Object bindings. You get 23 tools instead of the official server&rsquo;s subset — full Playwright control including click, type, navigation, and accessibility-tree snapshots.</p>
<p>The Worker exposes both <code>/sse</code> and <code>/mcp</code> endpoints. After deployment, you can test it in Cloudflare AI Playground before wiring it to your agent.</p>
<p><strong>Best for:</strong> Teams that need full browser automation (click, type, form fill) rather than just extraction. The accessibility-tree snapshots are faster and more deterministic than screenshot-only loops for many LLM workflows.</p>
<h3 id="path-3-cdp-via-chrome-devtools-mcp">Path 3: CDP via <code>chrome-devtools-mcp</code></h3>
<p>This connects <code>chrome-devtools-mcp</code> directly to Cloudflare&rsquo;s CDP WebSocket endpoint at <code>wss://api.cloudflare.com/client/v4/accounts/&lt;ACCOUNT_ID&gt;/browser-rendering/devtools/browser</code>. You get raw Chrome DevTools Protocol access — the same protocol Chrome DevTools uses.</p>
<p><strong>Best for:</strong> Debugging, persistent browser sessions, and workflows where you need to inspect network requests, console output, or DOM state over time.</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>All three paths share the same prerequisites:</p>
<ul>
<li>A Cloudflare account with <strong>Browser Run</strong> enabled</li>
<li>A <strong>Browser Rendering API token</strong> with at least <code>browser_rendering:edit</code> permission</li>
<li>Node.js v20.19 or newer (for the Playwright MCP and CDP paths)</li>
<li>An MCP-compatible client (Claude Desktop, Claude Code, Cursor, OpenCode)</li>
</ul>
<p>The API token scope matters. If your token only has <code>read</code> permissions, screenshot and crawl tools will fail silently. I spent 20 minutes debugging a 403 before realizing I&rsquo;d generated the wrong token type.</p>
<h2 id="quick-setup-for-claude-code-cursor-and-opencode">Quick Setup for Claude Code, Cursor, and OpenCode</h2>
<p>Here&rsquo;s the configuration for each client using the official Browser Rendering MCP server:</p>
<h3 id="claude-code">Claude Code</h3>
<p>Add to your <code>~/.claude/settings.json</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;mcpServers&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;cloudflare-browser&#34;</span>: {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;npx&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;args&#34;</span>: [<span style="color:#e6db74">&#34;@cloudflare/mcp-server-browser-rendering&#34;</span>],
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;env&#34;</span>: {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;CLOUDFLARE_API_TOKEN&#34;</span>: <span style="color:#e6db74">&#34;your-token-here&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;CLOUDFLARE_ACCOUNT_ID&#34;</span>: <span style="color:#e6db74">&#34;your-account-id&#34;</span>
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="cursor">Cursor</h3>
<p>In Cursor settings → MCP Servers, add:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;cloudflare-browser&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;command&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;npx @cloudflare/mcp-server-browser-rendering&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;env&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;CLOUDFLARE_API_TOKEN&#34;</span>: <span style="color:#e6db74">&#34;your-token-here&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;CLOUDFLARE_ACCOUNT_ID&#34;</span>: <span style="color:#e6db74">&#34;your-account-id&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="opencode">OpenCode</h3>
<p>In <code>~/.opencode/config.yaml</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">mcpServers</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">cloudflare-browser</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">command</span>: <span style="color:#ae81ff">npx</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">args</span>: [<span style="color:#e6db74">&#34;@cloudflare/mcp-server-browser-rendering&#34;</span>]
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">env</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">CLOUDFLARE_API_TOKEN</span>: <span style="color:#ae81ff">your-token-here</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">CLOUDFLARE_ACCOUNT_ID</span>: <span style="color:#ae81ff">your-account-id</span>
</span></span></code></pre></div><p>For the Playwright MCP path, you deploy a Worker first, then point your client at the Worker&rsquo;s <code>/sse</code> endpoint. The <a href="https://developers.cloudflare.com/browser-run/playwright/playwright-mcp/">Cloudflare docs</a> have the full Wrangler config and deploy command.</p>
<h2 id="core-tools-and-workflows">Core Tools and Workflows</h2>
<h3 id="screenshots">Screenshots</h3>
<p>The most straightforward use case. Your agent calls <code>browser_take_screenshot</code> with a URL and gets back a screenshot URL valid for a limited time. I use this for:</p>
<ul>
<li><strong>QA workflows</strong> — my agent deploys a preview, takes a screenshot, and checks visual regressions</li>
<li><strong>Documentation capture</strong> — snapshot docs pages before and after changes</li>
<li><strong>Competitor monitoring</strong> — periodic screenshot capture of competitor landing pages</li>
</ul>
<p>The screenshot tool accepts viewport dimensions, full-page vs viewport-only, and optional wait-for-selector timing. Without a wait, you&rsquo;ll get blank screenshots on slow-loading SPAs.</p>
<h3 id="markdown-conversion">Markdown Conversion</h3>
<p><code>browser_render_content</code> with format <code>markdown</code> returns the page as clean Markdown. This is my most-used tool. It strips navigation, ads, and boilerplate better than most standalone Markdown converters I&rsquo;ve tried.</p>
<p>The output is good enough to feed directly into an LLM context window. I&rsquo;ve used it to:</p>
<ul>
<li>Feed documentation pages into Claude Code for code generation</li>
<li>Extract blog post content for analysis</li>
<li>Convert API docs into structured reference material</li>
</ul>
<h3 id="crawl-jobs">Crawl Jobs</h3>
<p>The <code>browser_crawl</code> tool accepts a starting URL and optional depth/max-pages parameters. It returns an array of crawled pages with their content. This is useful for:</p>
<ul>
<li><strong>Site mapping</strong> — discover all pages under a path</li>
<li><strong>Bulk content extraction</strong> — grab all documentation pages at once</li>
<li><strong>Link auditing</strong> — find broken links across a site</li>
</ul>
<p>The crawl respects <code>robots.txt</code> and has a configurable rate limit. I&rsquo;ve found depth-1 crawls on medium-sized docs sites (50-100 pages) complete in 30-60 seconds.</p>
<h3 id="json-extraction">JSON Extraction</h3>
<p>This is the hidden gem. <code>browser_extract_json</code> takes a URL and a JSON schema, and returns structured data extracted from the page using AI. For example, you can pass a schema for product listings and get back an array of product objects.</p>
<p>It&rsquo;s not perfect — complex schemas with nested arrays sometimes return partial results — but for simple extraction jobs it saves writing a custom parser.</p>
<h2 id="example-research-agent-workflow">Example: Research Agent Workflow</h2>
<p>Here&rsquo;s a real workflow I run regularly. My agent needs to research a competitor&rsquo;s pricing page, extract the plan tiers, and compare them against our pricing:</p>
<ol>
<li>Call <code>browser_take_screenshot</code> on the pricing page for visual reference</li>
<li>Call <code>browser_render_content</code> with format <code>markdown</code> to get the text</li>
<li>Call <code>browser_extract_json</code> with a schema for plan name, price, features</li>
<li>Feed the results into a comparison table generation prompt</li>
</ol>
<p>The whole pipeline takes about 15 seconds and produces a draft I can review. Without the MCP server, I&rsquo;d be writing a Playwright script, running it, parsing the output, and formatting it — 15 minutes instead of 15 seconds.</p>
<h2 id="security-and-operational-considerations">Security and Operational Considerations</h2>
<p><strong>Token permissions.</strong> Your API token needs <code>browser_rendering:edit</code> for most tools. The <code>read</code> scope only covers status checks. Store tokens in your MCP client&rsquo;s env config, not in shared config files.</p>
<p><strong>Session lifetime.</strong> Browser Run sessions have a timeout. The official MCP server handles session creation and teardown automatically, but the Playwright MCP Worker&rsquo;s Durable Object sessions can persist longer. If you&rsquo;re running long crawl jobs, the Playwright MCP path is more reliable.</p>
<p><strong>Pricing.</strong> Browser Run charges per rendering request. Screenshots and Markdown conversion count as one request each. Crawl jobs count each page as a separate request. At scale, the costs add up — check the <a href="https://developers.cloudflare.com/browser-run/pricing/">pricing page</a> before building a high-volume pipeline.</p>
<p><strong>Rate limits.</strong> The free tier has a per-account rate limit. If you&rsquo;re running multiple agents concurrently, you&rsquo;ll hit 429 responses. The official MCP server doesn&rsquo;t retry automatically — your agent needs to handle rate-limit errors and back off.</p>
<h2 id="when-to-use-cloudflare-browser-run-vs-local-playwright">When to Use Cloudflare Browser Run vs Local Playwright</h2>
<p>Cloudflare&rsquo;s hosted browser is great when:</p>
<ul>
<li>You don&rsquo;t want to manage browser binaries and dependencies</li>
<li>Your agent runs in a serverless or containerized environment without a display server</li>
<li>You need occasional screenshots or page reads, not continuous browser sessions</li>
<li>You want accessibility-tree snapshots without running a full browser locally</li>
</ul>
<p>Local Playwright or Puppeteer is better when:</p>
<ul>
<li>You need persistent browser sessions (logged-in state, WebSocket connections)</li>
<li>You&rsquo;re doing high-volume scraping (Cloudflare costs exceed local compute)</li>
<li>You need to test against specific browser versions or device emulations</li>
<li>Your workflow involves complex user interactions (multi-step forms, drag-and-drop)</li>
</ul>
<p>For most AI coding agent workflows — reading docs, capturing screenshots, extracting structured data — the Cloudflare MCP server is the faster path. For anything that needs a real user session or runs at scale, go local.</p>
<h2 id="troubleshooting-common-issues">Troubleshooting Common Issues</h2>
<p><strong>&ldquo;Tool not found&rdquo;</strong> — Your MCP client version might not support the tool. Update to the latest version of Claude Code or Cursor. The official server requires MCP v2.1 or newer.</p>
<p><strong>Blank screenshots</strong> — The page didn&rsquo;t finish loading before the screenshot was taken. Add a <code>wait_until</code> parameter or increase the timeout. SPAs are the most common culprit.</p>
<p><strong>403 on all requests</strong> — Your API token has the wrong permissions. Regenerate it with <code>browser_rendering:edit</code> scope. The <code>read</code> scope looks like it works (no auth error) but returns empty results.</p>
<p><strong>Crawl returns one page</strong> — The crawl depth parameter defaults to 0 (current page only). Set <code>max_depth: 1</code> or higher for multi-page crawls.</p>
<p><strong>WebSocket disconnects</strong> — The CDP path has a session timeout. Set the <code>keep_alive</code> parameter or re-establish the connection. The Playwright MCP Worker&rsquo;s Durable Object handles reconnection better than the raw CDP path.</p>
<h2 id="the-bottom-line">The Bottom Line</h2>
<p>Cloudflare&rsquo;s Browser Rendering MCP server is the fastest way to give your AI coding agent web access without running a browser stack. The official server covers 80% of use cases with zero infrastructure. The Playwright MCP Worker covers the remaining 20% with full browser automation. The CDP path is for debugging and specialized workflows.</p>
<p>For a broader look at the MCP server ecosystem, check out my <a href="/posts/best-mcp-servers-for-developers-2026/">best MCP servers for developers</a> guide. If you&rsquo;re evaluating browser automation tools more broadly, the <a href="/posts/ai-browser-agents-comparison-2026/">AI browser agents comparison</a> covers alternatives like Browser Use, Stagehand, and Playwright MCP. And for the full Cloudflare agent infrastructure picture, <a href="/posts/cloudflare-agents-week-2026/">Cloudflare Agents Week 2026</a> covers Dynamic Workers, sandboxes, and Project Think.</p>
<p>Start with the official MCP server. If you hit its limits, deploy the Playwright MCP Worker. You&rsquo;ll have a working browser agent in under 30 minutes either way.</p>
]]></content:encoded></item></channel></rss>