Skip to content

ChHsiching/agent-web-fetch

Repository files navigation

agent-web-fetch

English | 简体中文

A free, uncapped web reader for MCP-capable agents (Claude Code, ZCode, and any client that speaks the Model Context Protocol). It takes a URL the agent already holds and returns the page's main content as clean, model-friendly markdown — a drop-in replacement for the paid, rate-limited fetch tools built into many agent clients.

  • Free and uncapped — runs on your machine over plain HTTP. No API key, no quota, no monthly limit, no 429s.
  • Reliable launch — ships as a single statically-linked binary. No npx, no runtime to install, no network at startup. It connects the first time, every time.
  • Near-zero maintenance — static HTTP fetch + the Readability extraction algorithm (the same engine Firefox Reader View uses). No headless browser treadmill, no anti-detection arms race to keep up with.

What it does

Give it a URL, get back the page's main article as markdown:

fetch({ "url": "https://example.com" })
  → "# Example Domain\n\nThis domain is for use in documentation examples..."

It runs Readability-style extraction to isolate the main article and strip boilerplate (nav, footer, scripts). When a page has no clear main article (list pages, dashboards), it falls back to the full document so you never get empty output. Image URLs are preserved in the markdown.

Tool parameters

Parameter Required Default Description
url yes The URL to fetch. Must be an absolute http/https URL.
timeout no 30s Per-request timeout, as a Go duration string (e.g. 45s).
return_format no markdown markdown or text.
no_cache no false Bypass the in-memory cache and force a fresh fetch.

What it does not do

  • No web search / discovery — it fetches URLs you give it; it doesn't find pages.
  • No JavaScript rendering — pages that need JS to produce content return sparse results. (This is a deliberate v1 trade-off for near-zero maintenance.)
  • No summarization / translation / image description — it returns content, it doesn't process it. No paid model calls.
  • No authenticated content — it fetches anonymously; login-walled pages are out of scope.

Install

1. Download the binary for your platform

Grab the right file from the latest release:

Platform File
Windows agent-web-fetch-windows-amd64.exe
macOS (Apple Silicon) agent-web-fetch-darwin-arm64
macOS (Intel) agent-web-fetch-darwin-amd64
Linux agent-web-fetch-linux-amd64

No installer, no runtime to install (no Node, Python, or Go required).

Where to put the file: a recommended per-user location exists on each platform — it needs no admin rights and is the conventional spot for user-installed programs:

Platform Recommended location
Windows %LOCALAPPDATA%\Programs\agent-web-fetch\agent-web-fetch.exe
macOS / Linux ~/.local/bin/agent-web-fetch

That said, MCP doesn't actually care where the file lives — it launches the binary via the absolute path in your config, so you can put it anywhere you have read/execute permission (no need to add it to PATH). Just don't drop it into other users' directories or system folders that need admin rights. The examples below use the recommended locations; replace the path if you put it elsewhere.

2. Register it with your MCP client

This is a standard stdio MCP server: it has no arguments and no environment requirements. In every MCP client the config entry is the same idea — point command at the binary's absolute path, leave args empty:

"chhsich-web-fetch": {
  "type": "stdio",
  "command": "/absolute/path/to/agent-web-fetch",
  "args": []
}

What differs between clients is only where this entry goes and the exact key names. Concrete examples for the common ones:

ZCode — add the entry to its MCP servers config (a flat object keyed by server name, no outer wrapper):

{
  "chhsich-web-fetch": {
    "type": "stdio",
    "command": "C:/Users/<username>/AppData/Local/Programs/agent-web-fetch/agent-web-fetch.exe",
    "args": []
  }
}

Claude Code~/.claude.json (or %USERPROFILE%\.claude.json on Windows), where servers live under a mcpServers key:

{
  "mcpServers": {
    "chhsich-web-fetch": {
      "type": "stdio",
      "command": "C:/Users/<username>/AppData/Local/Programs/agent-web-fetch/agent-web-fetch.exe",
      "args": []
    }
  }
}

Or via the CLI (does the same thing): claude mcp add chhsich-web-fetch "C:/Users/<username>/AppData/Local/Programs/agent-web-fetch/agent-web-fetch.exe"

Any other stdio MCP client — find where it keeps its MCP server list (a JSON/YAML config, a settings UI, etc.) and add one entry: type stdio, command = absolute path to the binary, args = []. That's the whole contract — there are no other parameters to set.

Replace the path: the examples above use the recommended install location with <username> as a placeholder — swap in your actual username (or use %LOCALAPPDATA% if your client expands env vars). Adjust the path if you put the binary somewhere else.

Naming: the key (chhsich-web-fetch above) is your client-side label for the server — call it whatever you want. The tool it exposes is named fetch, so the model calls fetch(...). Two servers exposing a tool both named fetch don't conflict as long as the server keys differ (the server name is the namespace).

Path tip (Windows): use the full absolute path including .exe. Forward slashes work in JSON and avoid backslash escaping.

Windows SmartScreen note: the release binary is unsigned, so Windows may show a "Windows protected your PC" prompt the first time it runs. Click More info → Run anyway. This is expected for unsigned binaries and only happens once.

Restart your client after editing the config. The fetch tool now appears alongside the built-in tools and the model can call it like any other.

3. Verify it works

After restarting your client, ask the model to fetch any public page, e.g.:

Use the fetch tool to read https://example.com

You should get back the page's content as markdown. If nothing comes back or the tool is missing, set WEB_FETCH_LOG (below) and check the log file.

4. (Optional) Enable file logging

By default the server is silent (stdout is the MCP transport and must stay clean). To write diagnostics to a file for troubleshooting:

Set the WEB_FETCH_LOG environment variable to a file path. Logs append there and never touch stdout.

Build from source

Requires Go 1.22+.

# Build all four platform binaries into dist/
./build.sh          # any bash (Git Bash, WSL, Linux, macOS)
# or, on unix with make:
make release

Each binary is statically linked (CGO_ENABLED=0) with no external runtime dependency. Run the test suite with go test ./....

How it works

URL → validate (http/https, absolute) → HTTP GET (realistic browser headers)
   → Readability extraction → markdown → in-memory cache (1h TTL)
                                     ↘ full-document fallback (never empty)

The fetch pipeline is a single deep module (internal/fetch), exposed over stdio as one MCP tool (internal/mcpserver). Every failure (timeout, non-2xx, bad content type, even a recovered panic) comes back as a structured error the model can read — the server process never crashes.

See CONTEXT.md for the project glossary and docs/adr/ for the architectural decisions (MCP + binary distribution, anonymous fetching, static extraction, Go, launch reliability).

About

MCP server that fetches a URL and returns its content as markdown. Free, uncapped, no API key — for Claude Code, ZCode, and any MCP client.

Topics

Resources

Stars

Watchers

Forks

Releases

Contributors

Languages