It obeys the site
The crawler reads robots.txt as RFC 9309 specifies. It obeys Retry-After, and it stops at a challenge, a 402 or a 403. Test a robots.txt.
npm install polite-crawlerclaude mcp add polite-crawler -- npx -y polite-crawler mcpen.wikipedia.org0 of 5 pagesdocs.example.org0 of 4 pagesmuseum.example0 of 2 pagesapi.busy.example0 of 3 pagesnews.example0 of 3 pagesshop.example0 of 3 pagesmembers.examplerobots.txt refuses: no requestblog.example0 of 3 pagesEach site gets one request at a time, and the sites run in parallel.
Research reads the same sources again and again. A plain web fetch goes back to the site each time, and nothing stays. This crawler fetches a page one time, keeps the response, and answers the next questions from a local index. Each site sees one request at a time, from a crawler that tells its name.
It obeys the site
The crawler reads robots.txt as RFC 9309 specifies. It obeys Retry-After, and it stops at a challenge, a 402 or a 403. Test a robots.txt.
It reads the cheap way
The crawler reads the JSON-LD, the visible text and the links with no browser. It opens a headless browser only for a page that needs JavaScript. See what it reads.
It answers from the disk
Each response goes into a capture log. A full-text index finds passages, and a quote check finds the exact text to cite. How it works.
One command gives Claude four tools. The tools fetch pages politely, search the store, read a range of a document and check a quote.
claude mcp add polite-crawler -- npx -y polite-crawler mcpThe same server works in Claude Desktop, Cursor and each MCP client. Set up the MCP server.
import { openCrawler } from "polite-crawler";
const crawler = openCrawler({ dir: "./crawl" });const page = await crawler.fetch("https://en.wikipedia.org/wiki/Web_crawler");
crawler.find("robots exclusion"); // ranked passages, with no requestcrawler.verify(page.doc!, "robots.txt protocol"); // the exact span and the capture to citeThese tools run the code of the package in your browser. Nothing goes to a server.