Atlas / MCP servers / yawlabs / fetch-mcp

fetch-mcpCAUTION

mcp/yawlabs/fetch-mcp

Comprehensive HTTP fetch MCP server with SSRF protection, HTML-to-markdown, and robots.txt awareness

Verdict
CAUTION
Grade
C
Trust score
80 /100
Exposed tools
15 11r · 3w · 1d
Transport
stdio
License
MIT
Stars
2
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

[](https://yaw.sh/mcp/install?name=Fetch&command=npx&args=-y%2C%40yawlabs%2Ffetch-mcp&description=HTTP%20fetch%20for%20AI%20agents%20-%20HTML-to-markdown%2C%20reader%20mode%2C%20metadata%2C%20RSS%2C%20sitemaps&source=https%3A%2F%2Fgithub.com%2FYawLabs%2Ffetch-mcp)

One click adds this to your local Yaw MCP config so it's available in every Yaw Terminal session. Or install manually below.

A comprehensive HTTP fetch MCP server for AI assistants. Bring-your-own client: runs as a stdio MCP server so any MCP-compatible client (Claude Code, Claude Desktop, Cursor, mcph, ...) can fetch web content safely.

What it gives the model

Safety

SSRF protection is on by default. The server refuses requests to:

  • Loopback (127.0.0.0/8, ::1)
  • RFC1918 private ranges (10/8, 172.16/12, 192.168/16)
  • Link-local (169.254/16, fe80::/10) — including the cloud metadata endpoint `
Read from source at commit 13bb7c181b47OBSERVED · 2026-10-11
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (npm)
claude mcp add fetch-mcp -- npx -y @yawlabs/[email protected]
03

Exposed tools (15)

11 read · 3 write · 1 destructive. Blast radius: 1 tool can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
fetch_feedreadFetch and parse an RSS 2.0 or Atom 1.0 feed. Returns feed-level metadata (title, description, link, updated) plus a list of entries (title, link, id, published, updated, author, summary, content, contentType, categories). Auto-detects RSS vs Atom.
fetch_html_to_markdownread
fetch_html_to_textreadGET a URL, decode the HTML, and return plain text with block-level structure preserved as newlines. Scripts, styles, and comments stripped; HTML entities decoded. Lighter than markdown when you only need the reading content.
fetch_linksread
fetch_metaread
fetch_readerread
fetch_robotsread
fetch_sitemapread
http_deletedestructivePerform an HTTP DELETE. Idempotent (per spec): a repeated DELETE on an already-deleted resource typically returns 404/410.
http_getread
http_headreadPerform an HTTP HEAD. Returns status + headers with no body. Useful for checking a resource exists, getting its size (Content-Length), or polling for changes cheaply.
http_optionsreadPerform an HTTP OPTIONS. Returns the server
http_patchwritePerform an HTTP PATCH. Use for partial updates. Spec-wise NOT guaranteed idempotent — depends on the server
http_postwritePerform an HTTP POST. Body can be given as a raw string (body) or as a JSON value (body_json — auto-sets content-type to application/json). NOT idempotent: calling twice submits twice.
http_putwritePerform an HTTP PUT. Use for full-resource replacement. Idempotent: the same PUT applied twice leaves the resource in the same state.
04

Trust audit

CAUTIONgrade C · trust 80/100 Install with care. The audit found things worth knowing before you trust its output.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (2 observation(s))
Network
declared (5 observation(s))
Shell
declared (4 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (21)

HIGHFilesystem / path · fs.credential_store · CWE-22, CWE-59
scripts/update-manifests.mjs:221
const SSH = 'ssh -i ~/.ssh/gh_woods -o IdentitiesOnly=yes';
Why it matters. touches a credential store
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
http_delete
Why it matters. 1 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/tests/launcher.test.ts:63
return new Function(`${pieces}\nreturn runtimePlan;`)() as RuntimePlan;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/tests/launcher.test.ts:68
return new Function(`${pieces}\nreturn { pickNewest, floor: OAM_MIN };`)() as {
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/tests/launcher.test.ts:81
return new Function(`${pieces}\nreturn fallbackInProcess;`)() as (hostOam: string | undefined) => boolean;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/tests/launcher.test.ts:200
const parse = new Function(
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/tests/launcher.test.ts:228
const parse = new Function(
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
CHANGELOG.md:117
- **SSRF: a redirect to a literal blocked IP, or to a non-http(s) scheme, is now refused. Every redirect hop runs the pre-flight URL validator.** `validateUrl()` -- scheme allow-list, literal-IP block
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
CHANGELOG.md:118
- **`allow_private_hosts` now needs the operator's opt-in: `FETCH_MCP_ALLOW_PRIVATE_HOSTS=1`. Breaking for anyone who relied on the per-call flag alone.** The flag is a tool argument on all 15 tools,
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
CHANGELOG.md:330
- **SSRF protection on by default** — blocks loopback, RFC1918 private ranges, link-local (incl. `169.254.169.254` cloud metadata), CGNAT, unique-local IPv6, multicast, IPv4-mapped IPv6 (re-checked),
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
CLAUDE.md:29
2. **Per-hop redirect re-validation.** `sendHop()` in `src/http.ts` MUST run `validateUrl()` on every URL it dials (scheme allow-list, literal-IP block list, `localhost*`) AND resolve DNS + re-run `ch
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
README.md:30
- Link-local (`169.254/16`, `fe80::/10`) — including the cloud metadata endpoint `169.254.169.254`
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
CHANGELOG.md:117
- **SSRF: a redirect to a literal blocked IP, or to a non-http(s) scheme, is now refused. Every redirect hop runs the pre-flight URL validator.** `validateUrl()` -- scheme allow-list, literal-IP block
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
CHANGELOG.md:118
- **`allow_private_hosts` now needs the operator's opt-in: `FETCH_MCP_ALLOW_PRIVATE_HOSTS=1`. Breaking for anyone who relied on the per-call flag alone.** The flag is a tool argument on all 15 tools,
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
CHANGELOG.md:330
- **SSRF protection on by default** — blocks loopback, RFC1918 private ranges, link-local (incl. `169.254.169.254` cloud metadata), CGNAT, unique-local IPv6, multicast, IPv4-mapped IPv6 (re-checked),
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
CLAUDE.md:29
2. **Per-hop redirect re-validation.** `sendHop()` in `src/http.ts` MUST run `validateUrl()` on every URL it dials (scheme allow-list, literal-IP block list, `localhost*`) AND resolve DNS + re-run `ch
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:41
Every redirect hop is re-validated against all of the above -- scheme, literal IP and `localhost*` -- before it is dialed, so a 302 from a public host to `http://127.0.0.1`, `http://169.254.169.254` o
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@modelcontextprotocol/sdk, fast-xml-parser, undici, zod, @biomejs/biome, @types/node, @yawlabs/mcp-compliance, esbuild
Why it matters. 12 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
CHANGELOG.md:74
- **The MCP SDK moves from 1.30.0 to 1.32.1** (GHSA-6qxp-vccf-f47h, high: the SDK's OAuth client could send credentials to an authorization server chosen by the MCP server; this server does not import
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
CHANGELOG.md:124
- **The launcher refuses to serve on a Node older than 22.19.0 with a clear message, instead of crashing.** undici 8's floor is Node 22.19.0. Below it the failure was never clean: Node 20 died at impo
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
SECURITY.md:39
The MCP host (your editor, your agent) runs this server. An LLM talks to the server over stdio and can call tools with arguments the LLM itself chose. The LLM is **not trusted** -- a malicious prompt
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine

Gates applied: no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha 13bb7c181b47full audit observations/trust-audit/mcp-server/yawlabs__fetch-mcp.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-1113bb7c181b47CAUTIONC80first audit
06

Questions

What is the fetch-mcp MCP server?

Comprehensive HTTP fetch MCP server with SSRF protection, HTML-to-markdown, and robots.txt awareness

What tools does fetch-mcp expose?

15 in total: 11 read-only, 3 that write, and 1 that can delete or overwrite (http_delete). Every one is listed on this page with its risk.

Is fetch-mcp safe to connect to an agent?

With care. The audit graded it C (80/100) and found 21 things worth knowing before you trust this server, listed below with the exact line each was found on. Separately from the audit: 1 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does fetch-mcp need?

It reads GH_TOKEN and GITHUB_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does fetch-mcp run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as @yawlabs/fetch-mcp at 0.8.4.

How current is this page?

The grade is for one exact copy of the source (13bb7c181b47), read on 2026-10-11. The repository is watched and re-audited when it changes.

Advertisement