Unrendered: AI Crawler Checker

io.github.missiongrowthPublished by GitHub account missiongrowthv0.1.4Updated Nov 4, 2026

AI crawler checker: shows which page content GPTBot and ClaudeBot can't read without JavaScript.

Overview

AI-generated overview

Local MCP server that loads a page in headless Chrome and reports what AI crawlers see without JavaScript, plus per-bot robots.txt and fetch verdicts.

What you can do
  • Analyze a page by loading it in headless Chrome and comparing the raw HTML with the rendered page: content coverage, words only added by JavaScript, and the largest text blocks missing from the raw HTML.
  • Inspect metadata differences between raw and rendered versions: title, meta description, canonical, hreflang, html lang, robots meta and JSON-LD.
  • List links that exist only after JavaScript and text in the raw HTML that JavaScript removes.
  • Report gate reasons when the raw request hits a challenge page, an HTTP error, a redirect or a failed fetch.
  • Check AI bots: robots.txt verdict per bot and what the server returns when requested with each bot's published user-agent.
When to use it
Useful when checking whether a site's content is readable by AI crawlers such as GPTBot or ClaudeBot without JavaScript, or when auditing robots.txt rules and server responses for those bots. Suited to SEO and AI-visibility reviews of public pages.
Requirements
Runs locally via npx (npm package unrendered-mcp) with Node 20 or later and an installed Google Chrome; no browser is downloaded. Optional environment variables UNRENDERED_CHROME_CHANNEL to pick another Chromium channel and UNRENDERED_ALLOW_PRIVATE_HOSTS=1 to allow local or private hosts. Network access to the site being analysed.
Before you install
The tools fetch the target URL and its resources, and check_ai_bots sends roughly 20 sequential requests to the site, which can look like bot traffic. Private, loopback and link-local hosts are refused by default; enabling UNRENDERED_ALLOW_PRIVATE_HOSTS widens what a model-supplied URL can reach. Pages are loaded without your logins or cookies, so results differ from a logged-in view.

Installation

In SourceWeft

  1. Open Unrendered: AI Crawler Checker in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

unrendered-mcp: AI Crawler Checker MCP Server

An MCP server that gives an AI assistant the analysis of the Unrendered Chrome extension: what a crawler that does not run JavaScript receives (the raw HTML) compared with the page a browser renders.

It does not reimplement the analysis. The extension's own snapshot code (src/content/snapshot.ts), analyze, robots.txt parser and bot classifier are bundled and run unchanged, inside your installed Google Chrome.

Install

Requires Node 20 or later and Google Chrome. No browser is downloaded.

sh
npx -y unrendered-mcp

Claude Code

sh
claude mcp add unrendered -- npx -y unrendered-mcp

Claude Desktop

Add to claude_desktop_config.json:

json
{  "mcpServers": {    "unrendered": {      "command": "npx",      "args": ["-y", "unrendered-mcp"]    }  }}

If Chrome is missing the tools answer with an error that says so. UNRENDERED_CHROME_CHANNEL selects another Chromium channel (default chrome).

By default the tools refuse URLs whose host is, or resolves to, a loopback, private, link-local or multicast address, because the URL comes from a model that may have read a hostile page. Set UNRENDERED_ALLOW_PRIVATE_HOSTS=1 to analyse a local dev server. Chrome runs with its sandbox on.

Tools

analyze_page({ url })

Loads the URL in a headless Chrome, takes the extension's snapshot in an isolated world of the page (as a content script does), runs analyze, and returns a compact JSON object:

  • coverage: share of the main content (and of all visible text) whose words are present in the raw HTML, with word counts and the basis used (main-landmark or outside-landmarks)
  • main_content_words: words found in the raw HTML, words found only in JSON-LD or hydration data, words only present after JavaScript
  • missing_from_raw_html: the largest text blocks that exist only after JavaScript (truncated, capped at 15)
  • fields: differences in title, meta description, canonical, hreflang, html lang, robots meta and JSON-LD (capped at 30 rows)
  • links_only_after_javascript, text_in_raw_html_removed_by_javascript
  • gate: when the raw request is a challenge page (Cloudflare, AWS WAF, DataDome), an HTTP error, a different URL or a failed fetch, no coverage is computed and the gate says why
  • not_checked: what this run did not verify

check_ai_bots({ url })

For every bot in the extension's list: the robots.txt verdict for the URL (with the matching rule and line), and what the server answers when requested with that bot's published user-agent (same, different, blocked, challenged, rate-limited, redirected-elsewhere, error), plus noindex. Bots with no verified user-agent string, Googlebot and Applebot (which the extension does not imitate) and control tokens such as Google-Extended get a robots.txt verdict only (http: "not_probed").

What runs where

  • Everything runs on your machine. Chrome starts headless for each call and is closed afterwards.
  • analyze_page loads the page in that Chrome. The page requests its own resources, and the raw HTML is requested three times from the page itself, as in the extension.
  • check_ai_bots requests /robots.txt and the URL about 20 times from Node, sequentially, with Chrome's user-agent and with each bot's.
  • The analysis code runs in a blank Chrome page, because it needs a browser DOM parser.

Privacy

Nothing is sent anywhere except requests to the site you analyse (and to addresses it redirects to or loads resources from). No analytics, no telemetry, no accounts, nothing stored. Each call uses a fresh temporary Chrome profile that is discarded when it ends.

Known differences from the extension

  • Closed shadow roots cannot be reached without the extension API, so their text counts as absent from the rendered side.
  • The browser is headless, 1280x720, en-US, without your logins or cookies; the user-agent is Chrome's without the Headless marker.
  • check_ai_bots sends its requests from Node, not from the browser: the TLS fingerprint and some headers differ from Chrome's, and no cookies are sent (the extension also sends none for bot probes). The character-set fallback is utf-8 because no rendered page is loaded to read document.characterSet from.

Development

sh
pnpm installpnpm build       # bundles the page scripts and the server into dist/pnpm typecheckpnpm parity      # compares this server with the extension's panel on 20 URLs (build the extension in the repo root first)

License

AGPL-3.0-only.

Source: mcp/README.md at commit dd7596a

Tools

2

analyze_page

Compare raw HTML with rendered DOM

Loads the URL in Chrome and compares what a crawler that does not run JavaScript receives (the raw HTML) with the rendered page, using the Unrendered extension's analysis. Returns the share of the main content present in the raw HTML, words only added by JavaScript, the text blocks missing from the raw HTML, head and JSON-LD field differences, challenge or error gates, and a not_checked list.

Parametersurlrequired

check_ai_bots

Check AI bot access

For each AI bot the extension knows (GPTBot, ClaudeBot, PerplexityBot and others), returns the robots.txt verdict for the URL and what the server answers when requested with that bot's published user-agent (same page, different page, blocked, challenged, redirected).

Parametersurlrequired

Version history

1
  1. v0.1.4LatestOct 21, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts