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_pagefetches any publichttp://orhttps://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 cap20,000characters, configurable up to100,000). It also extracts page metadata (title,description,canonical,lang,content_type) and up to 100 deduplicatedhttp(s)links resolved against the final URL.extract_page_jsonconverts the page to Markdown, takes the first12,000characters, and extracts a caller-supplied JSON Schema (type: "object"withrequiredandproperties) or natural-language prompt usingclaude-haiku-5-5. Every extracted value is checked against the source Markdown and returned with itsfoundflag and exact characterstartandendoffsets in thesourcesarray.
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:
- Page Fetch tool reference and parameter schema
- Install Page Fetch in ChatGPT
- Install Page Fetch in Claude Desktop and Claude Code
- Install Page Fetch in Cursor
- Install Page Fetch in VS Code and GitHub Copilot
- Install Page Fetch in Pi
- Page Fetch Agent Skill (SKILL.md) for web research and grounded JSON extraction
Sources
- PEP 20 - The Zen of Python (peps.python.org) used as the benchmark target on 2026-10-20
- Jina Reader (r.jina.ai) (checked 2026-10-20)
- mcp-server-fetch on PyPI (checked 2026-10-20)
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.