Skip to the content
Agent Tools

How to fetch web pages as clean Markdown and extract grounded JSON in Claude, Cursor or any MCP agent

When an AI coding agent needs to read a documentation page or RFC, raw HTML wastes context tokens on navigation menus and inline scripts, while local stdio fetch servers add 10 to 20 seconds of cold startup time. On 2026-10-20 we benchmarked Page Fetch (https://pagefetch.openkrill.app/mcp) on https://peps.python.org/pep-0020/ against Jina Reader, the reference mcp-server-fetch package and Firecrawl. In 1,265 ms, fetch_page returned 1,591 characters (225 words) of clean Markdown with the # PEP 20 - The Zen of Python heading intact, all 19 aphorisms inside a fenced code block and 1 deduplicated external link, while extract_page_json extracted 6 of 6 structured JSON fields with exact character-offset grounding.

What Page Fetch does on each URL

Page Fetch runs as a remote MCP server at https://pagefetch.openkrill.app/mcp with no account and no API key. It provides two read-only tools:

  • fetch_page fetches any public http:// or https:// URL (up to 2 MB, following up to 5 public redirects while blocking localhost and private IP ranges), strips <script>, <style>, <nav>, <header>, <footer> and <aside> chrome, prefers <main> or <article> when present, and converts the content to clean Markdown (default cap 20,000 characters, configurable up to 100,000). It also extracts page metadata (title, description, canonical, lang, content_type) and up to 100 deduplicated http(s) links resolved against the final URL.
  • extract_page_json converts the page to Markdown, takes the first 12,000 characters, and extracts a caller-supplied JSON Schema (type: "object" with required and properties) or natural-language prompt using claude-haiku-5-5. Every extracted value is checked against the source Markdown and returned with its found flag and exact character start and end offsets in the sources array.

Step 1: Fetch PEP 20 as Markdown and compare 3 rivals

We ran the same fetch of https://peps.python.org/pep-0020/ across Page Fetch and three web-reading rivals on 2026-10-20. Here is the JSON-RPC call to fetch_page:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "fetch_page",
    "arguments": {
      "url": "https://peps.python.org/pep-0020/"
    }
  }
}

Here is how the four tools compared on speed, structure preservation and setup requirements:

Tool or service Wall time Score Output size Structure and link quality on PEP 20
Page Fetch (fetch_page) 1,265 ms 10.0 / 10 1,591 chars (225 words) Keeps # PEP 20 - The Zen of Python H1, all 5 sections, fenced code block for the 19 aphorisms, and 1 deduplicated external link (https://groups.google.com/d/msg/comp.lang.python/B_VxeTBClM0/L8W9KlsiriUJ)
Jina Reader (https://r.jina.ai/https://peps.python.org/pep-0020/) 2,394 ms 8.0 / 10 2,340 chars Drops the H1 into a plain Title: header, keeps the ## Python Enhancement Proposals navigation heading from page chrome, and leaves the 19 aphorisms unfenced
mcp-server-fetch (uvx --python 3.12 mcp-server-fetch) 22,718 ms 7.4 / 10 1,895 chars 11,760 ms cold environment startup plus 10,958 ms tool call; drops H1, keeps ## Python Enhancement Proposals chrome and leaves internal #anchor links unresolved
Firecrawl (firecrawl.dev) not run not run requires key Hosted API and MCP server require account registration and a bearer API key before the first call

Step 2: Extract grounded JSON with character-offset verification

When your workflow needs typed fields rather than prose, call extract_page_json with a JSON Schema object:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "extract_page_json",
    "arguments": {
      "url": "https://peps.python.org/pep-0020/",
      "schema": {
        "type": "object",
        "required": ["pep_number", "title", "author", "status", "aphorism_count", "first_aphorism"],
        "properties": {
          "pep_number": { "type": "number" },
          "title": { "type": "string" },
          "author": { "type": "string" },
          "status": { "type": "string" },
          "aphorism_count": { "type": "number" },
          "first_aphorism": { "type": "string" }
        }
      }
    }
  }
}

The response returns both the extracted json object and a sources array proving where each value sits in the page's Markdown (grounded: { "found": 6, "total": 6 }):

{
  "status": "ok",
  "final_url": "https://peps.python.org/pep-0020/",
  "json": {
    "pep_number": 20,
    "title": "The Zen of Python",
    "author": "Tim Peters <tim.peters at gmail.com>",
    "status": "Active",
    "aphorism_count": 20,
    "first_aphorism": "Beautiful is better than ugly."
  },
  "grounded": {
    "found": 6,
    "total": 6
  },
  "sources": [
    { "path": "/pep_number", "found": true, "start": 6, "end": 8, "text": "20" },
    { "path": "/title", "found": true, "start": 11, "end": 28, "text": "The Zen of Python" },
    { "path": "/author", "found": true, "start": 39, "end": 75, "text": "Tim Peters <tim.peters at gmail.com>" },
    { "path": "/status", "found": true, "start": 86, "end": 92, "text": "Active" },
    { "path": "/aphorism_count", "found": true, "start": 6, "end": 8, "text": "20" },
    { "path": "/first_aphorism", "found": true, "start": 462, "end": 492, "text": "Beautiful is better than ugly." }
  ]
}

Connect Page Fetch to your AI client

Point your MCP client at https://pagefetch.openkrill.app/mcp or follow the setup guide for your editor:

Sources

Frequently asked questions

What is the best free MCP server to fetch a web page as clean Markdown for Claude or Cursor?
OpenKrill's Page Fetch MCP server (https://pagefetch.openkrill.app/mcp) is free, needs no API key or local Python setup, and returns clean Markdown, page metadata (title, description, canonical URL, language) and up to 100 deduplicated HTTP links in about 1.3 seconds.
How can I extract structured JSON from a web page URL without writing a scraper?
Call extract_page_json on https://pagefetch.openkrill.app/mcp with the page url and a JSON Schema object (type: "object" with required and properties). The tool converts the page to Markdown, extracts the requested fields with claude-haiku-5-5, and verifies each value against its exact character start and end offset in the source text.
What is a free alternative to Firecrawl or Jina Reader for fetching web pages in an AI agent?
Page Fetch (https://pagefetch.openkrill.app/mcp) provides both clean Markdown reading (fetch_page) and schema-guided JSON extraction (extract_page_json) over streamable HTTP MCP with no API key, within 60 calls a minute per network.
Does Page Fetch execute JavaScript or bypass paywalls and bot challenges?
No. Page Fetch reads the initial HTTP response up to 2 MB over HTTP or HTTPS, strips scripts, styles and navigation chrome, and converts the main article or body to Markdown. It refuses private IP ranges and returns a structured status when a host blocks automated requests.