webfetch-mcp
README.md
# webfetch-mcp
A minimal **read-only** MCP server that fetches hard-to-scrape web pages via an
anti-detection browser and returns clean, **token-efficient markdown**.
It exposes exactly **one tool** — `fetch(url) → markdown` — annotated
`readOnlyHint: true`, so MCP clients that gate writes behind approval prompts
(such as a Cloudflare OS MCP gatekeeper) run it **without asking**.
## Why
`camofox-mcp` exposes 47 browser-automation tools, none annotated read-only, so
every fetch queues for manual approval. For the common case — *just get me the
page text* — that friction is needless: a fetch reads a page and mutates nothing.
This server declares that honestly and returns the most token-efficient
representation available.
## Extraction strategy
camofox-browser has no markdown or readability endpoint — only Playwright ARIA
snapshots (a role/name tree, not prose) and arbitrary JS evaluation. This server
bundles `@mozilla/readability` + `turndown` (via esbuild into IIFE strings at
build time) and ships them into the page in a single `/evaluate` call:
1. **Readability** — clean main-article markdown (best; ~10× smaller than a snapshot)
2. **innerText** — real prose, falls back here for SPAs / dashboards Readability can't parse
3. **snapshot** — ARIA tree, last resort for canvas-heavy or empty-text pages
The output carries a `Strategy:` marker so the caller knows which ran.
## Usage
```bash
# Build
npm install
npm run build # bundles libs + compiles TS
# Run (defaults: port 8090, browser at localhost:9377, no auth)
node dist/src/index.js
```
### Configuration (env)
| Var | Default | Purpose |
|---|---|---|
| `CAMOFOX_URL` | `http://localhost:9377` | camofox-browser REST API base URL |
| `WEBFETCH_HTTP_PORT` | `8090` | MCP Streamable HTTP listen port |
| `WEBFETCH_API_KEY` | _(unset)_ | If set, clients must send `Authorization: Bearer <key>` |
### MCP protocol check
```bash
# initialize + tools/list (expect 1 tool, readOnlyHint=true)
curl -X POST localhost:8090/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"t","version":"0.0.0"}}}'
```
## Deployment
Built by a Komodo Build → `registry.zxcapp.de/docker/webfetch-mcp`, then deployed
as a sibling of `camoufox-mcp` in the `camoufox` stack. Shares netbird-client's
network namespace so it reaches camofox-browser at `localhost:9377`.
See `services/komodo/plans/webfetch-mcp/` in `home-infra` for the full deploy plan.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing