Closing the SSRF gap nobody's fetch server closes
Why I built Safe-Fetch, an MCP fetch server with SSRF defense as the entire point, not an afterthought.
The most-used reference MCP fetch server ships with no SSRF protection, by its own README’s admission. I read that line and couldn’t stop thinking about it. Any agent with fetch access is one crafted URL away from reaching your cloud metadata endpoint, an internal admin panel, or a service that never expected to be reachable from outside its network.
So I built Safe-Fetch: an MCP fetch server where SSRF defense isn’t a feature, it’s the entire point.
One pipeline, no exceptions
Every request, including every redirect the server follows, runs through the same four checks. There’s no separate, looser path for redirects, which is exactly where most fetch servers quietly lose their guarantees.
Pipeline
That last stage is the one worth sitting with. It’s common to validate the initial URL carefully and then follow redirects through a lighter, separate check, on the theory that the first check already proved the request was safe. It didn’t. The IP a hostname resolves to right now says nothing about what it’ll resolve to on the next lookup.
Where the naive version breaks
DNS rebinding is the attack this pipeline exists to close. The idea: an attacker points a domain at a normal, external IP long enough for your server to validate it, then swaps the DNS record to something internal before the actual connection happens.
Pinning the connection to a resolved IP, rather than re-resolving at connect time, closes the window entirely. It’s a small mechanical difference with an outsized effect on what the server can be tricked into doing.
What a blocked request actually looks like
The default threat matrix blocks cloud metadata addresses, RFC-1918 private ranges, loopback, and IPv4-mapped IPv6 loopback, along with non-HTTP(S) schemes and URLs carrying embedded credentials.
Successful responses are also explicitly framed as untrusted data before they reach the agent, so fetched content gets treated as data to reason about, not instructions to follow.
What I’d tell someone building the next one
Correct SSRF defense is genuinely hard to get right, and doing it right, and being able to prove it, was the whole point of this project. The pipeline design forced a discipline I wouldn’t have gotten from a checklist: if a request or a redirect can’t name which of the four stages it passed through, it doesn’t go out. Sixty-two unit tests cover the threat matrix, and the project has been checked against the OWASP MCP Top 10 via independent scanning.
If you’re wiring fetch access into an agent, read your fetch server’s SSRF section before you read anything else about it. If it doesn’t have one, that’s the answer.
Code’s on GitHub.