mcpField
F
FetchGate

FetchGate

Local
github.com/MoAz06Browser Automation3Updated 15w ago

About FetchGate

FetchGate is a deterministic fetch gate for agents that only releases page content when it confirms a real read. It is designed for agent developers who need refusals instead of answers based on failed or empty fetches.

Key features

  1. 01Verdicts for retrieved, failed, or uncertain reads
  2. 02Checks status, redirects, and extracted text
  3. 03Detects likely blocking and error pages
  4. 04Optional JavaScript rendering with Playwright
  5. 05Core works without models or API keys

Use cases

  1. 01Prevent answers based on empty fetch results
  2. 02Check whether a page was actually readable
  3. 03Retry thin JavaScript pages with browser rendering

MCP support

FetchGate provides the `fetch_url` tool to MCP clients. It returns content only for a confirmed read and otherwise returns a refusal.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

No install method listed yet

We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.

Repository

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

FetchGate

A 200 is not a read.

When an AI agent fetches a page and it quietly comes back empty (a JavaScript app, a 403, a Cloudflare wall), the agent often does not stop. It answers from memory and never tells you it did not actually read the page. FetchGate is a small gate at the fetch boundary that refuses to let that happen: the agent gets the content only when the page was really read, and an honest refusal otherwise.

It is deterministic (no model, no API keys), stdlib-only at its core, and free.

Quickstart

git clone https://github.com/MoAz06/FetchGate
cd FetchGate
python demo.py https://example.com https://httpbin.org/status/403
https://example.com
  verdict     : RETRIEVED  (clean)
  answerable  : ALLOW
  bytes       : raw 559 / extracted 127
  tiers       : static
  gate-confirmed content (127 chars): Example Domain This domain is for use ...

https://httpbin.org/status/403
  verdict     : FAILED  (transport.http_403)
  answerable  : STOP
  refused: the model gets no content and cannot answer as if it read this page.

Run the tests (no network, no model):

pip install -e .
python -m unittest discover -s tests

Easiest: one double-click (Claude Desktop)

Download fetchgate.mcpb from the Releases page and double-click it. Claude Desktop shows an Install button, no JSON editing. The bundle source is in bundle/; rebuild it with npx @anthropic-ai/mcpb pack bundle fetchgate.mcpb.

Vibecoders: add it from inside your editor

Cursor, one click (needs uv, which most setups have):

Add FetchGate to Cursor

Or just ask your AI. Paste this into Cursor, Claude Code, or Windsurf:

Add the fetchgate MCP server to this setup. Run pip install "fetchgate[mcp]" and register it as an MCP server named fetchgate with the command fetchgate-mcp. It stops an agent from answering as if it read a page it could not actually fetch.

Your assistant runs the install and wires up the config for you.

Use it in Claude Desktop or Cursor (manual)

pip install ".[mcp,http,extract]"    # the fetch tool, real redirect chain, better extraction
pip install ".[browser]"             # optional: render JavaScript pages
python -m playwright install chromium

Add to your MCP config (details in docs/mcp.md):

{ "mcpServers": { "fetchgate": { "command": "fetchgate-mcp" } } }

Your agent now has a fetch_url tool that returns content only for a confirmed read, and a refusal otherwise.

This repo is also a Claude Code plugin. After pip install "fetchgate[mcp]":

/plugin marketplace add MoAz06/FetchGate
/plugin install fetchgate@fetchgate

See docs/claude-code-plugin.md.

Use it in your own agent

from fetchgate import default_gate

gate = default_gate()   # renders JS pages if the [browser] extra is installed

def read_url(url: str) -> str:
    out = gate.guarded_fetch(url)
    content = gate.content_for(out.handle)
    if content is None:
        return f"NOT READ: {url} ({out.result.reason}). Do not answer as if you read it."
    return content

How it decides

Every fetch gets one verdict:

  • RETRIEVED: a real read. The agent may answer and cite it.
  • FAILED: a definite non-read (a 4xx or 5xx, a timeout, an https to http downgrade, an empty body). Stop.
  • UNKNOWN: fetched, but not enough readable content to confirm a read (often a JavaScript page). Stop, or render and try again.

Three layers feed the verdict, and the result is the strictest of them:

  • transport: status and redirect chain.
  • extraction: readable text kept separate from raw bytes. A 17 byte price JSON is a read, a 400 KB article at 2 percent text is a read, a JS shell with no text is not.
  • content-validity: a best-effort fingerprint for Cloudflare, consent, paywall, and soft-404 walls. It can only downgrade to UNKNOWN, never fake a read.

When a page looks thin or empty and the render tier is on, FetchGate escalates to a real headless browser and re-checks. It renders, it does not evade: a page still walled after an honest render stays a non-read.

Stated limits

  • content_sha256 is a receipt anchor, not tamper-evidence. A cloaked page hashes cleanly.
  • Provenance is not authenticity. The gate closes fail-silent-on-empty, not fetch-succeeds-on-wrong-content.
  • A read is not an answer. RETRIEVED means enough content arrived, not that it held the fact you need. Claim support is a downstream job.
  • Fail-closed has an availability cost. Anyone who can make your fetch fail can force a refusal. That is the trade for correctness.

What is built

The deterministic core, the offline evaluation with a signed manifest, the build-breaking cheat-test, the MCP server, and the Playwright render tier. Optional extras: [mcp], [http] (httpx redirect chain), [extract] (trafilatura), [browser] (Playwright), [sign] (Ed25519). When installed they are used automatically; the core stays stdlib-only.

MIT licensed.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.