Fetch MCP Server
Let Claude Code and Cursor fetch any URL and convert it to clean markdown through MCP.
Updated: April 15, 2026
Install
{
"mcpServers": {
"mcp-server-fetch": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-fetch"
]
}
}
}Capabilities
- + Fetch any HTTP or HTTPS URL and return the body
- + Extract clean text content stripped of ads and navigation
- + Return raw HTML when the model needs the full markup
- + Follow redirects automatically up to a reasonable limit
- + Set custom headers including User-Agent and Accept
- + Automatically convert HTML to readable markdown for the model
Limitations
- - No JavaScript execution - static HTML only
- - Cannot handle cookie-based auth or login flows
- - Blocked by many anti-scraping systems (Cloudflare, PerimeterX)
- - No POST, PUT, or other non-GET requests
Fetch MCP server setup for Claude Code and Cursor
Quick answer: The Fetch MCP server does one thing well: given a URL, it returns the page contents as clean markdown. No API keys, no login, no config. It is the right pairing for any search MCP - search returns URLs, fetch turns each URL into readable text. Setup takes 2 minutes. Tested April 15, 2026 with server version 0.6.2.
For the bulk of "read this documentation page for me" work, Fetch is 100x faster and 1000x lighter than spinning up Puppeteer. It fails on JavaScript-heavy sites, which is the one caveat to remember.
This guide covers installation, both editor configs, 7 example prompts, a comparison with Puppeteer and Brave, and the specific failure modes you will hit.
What this server does
The server exposes a single primary tool: fetch. Pass a URL, get back the page. By default the server converts HTML to markdown by stripping navigation, ads, and boilerplate, then returns a clean text block. Optionally you can ask for raw HTML if the model needs specific structure.
Behind the scenes the server uses node-fetch for the HTTP call and @mozilla/readability plus turndown for the HTML-to-markdown step. That is the same pipeline Firefox uses for reader mode, so the output quality is solid on well-structured articles.
What works well:
- Reading documentation pages (MDN, React docs, Next.js docs, all of the big frameworks)
- Scraping static Wikipedia and blog content
- Following redirects through URL shorteners
- Fetching JSON endpoints that do not require auth
- Reading RSS or Atom feeds
- Getting the
robots.txtorsitemap.xmlof a site
What does not:
- SPAs that render with JavaScript (React, Vue, etc. apps without SSR)
- Pages behind login or CAPTCHA
- Any site with Cloudflare anti-bot (403 Forbidden is common)
- Dynamic content loaded via XHR after page load
Installing the Fetch MCP server
The package is @modelcontextprotocol/server-fetch. Standard npx -y pattern. About 3 MB install, no native dependencies. First cold start takes 1 to 2 seconds on any platform.
No API keys. No external service. Every request goes straight from your machine to the target URL.
If you are behind a corporate proxy, set HTTPS_PROXY and HTTP_PROXY in the env block. node-fetch respects these.
Configuring for Claude Code
Claude Code reads from ~/.claude/mcp.json or a per-project .mcp.json. Add a fetch entry:
{
"mcpServers": {
"fetch": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-fetch"],
"env": {}
}
}
}
Restart Claude Code. Run /mcp to confirm. You should see 1 tool named fetch.
For most users, this server is attached by default in every project. It is that useful. The config is short and the dependencies are tiny - there is no reason not to include it.
Configuring for Cursor
Cursor reads from ~/.cursor/mcp.json on macOS and Linux or %USERPROFILE%\.cursor\mcp.json on Windows. Same config:
{
"mcpServers": {
"fetch": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-fetch"],
"env": {}
}
}
}
Toggle on in Cursor settings. First fetch takes 2 seconds cold, then typical fetch latency is 300 to 800 ms depending on the target.
Example prompts and workflows
Fetch is best used as a tool the model calls mid-task, not as a direct prompt. A few patterns:
- "Read https://react.dev/reference/react/useEffect and summarize the 3 main pitfalls."
- "Fetch this Hacker News discussion (paste URL) and tell me which commenter disagreed with the author."
- "Read the Next.js 16 migration guide and make a checklist of changes I need for my project."
- "Grab the JSON from https://api.github.com/repos/vercel/next.js and tell me the current version."
- "Fetch the RSS feed at example.com/feed.xml and list the 5 most recent posts."
- "Read the first 3 results from your Brave search and tell me which one has the clearest explanation."
- "Fetch the changelog at https://github.com/prisma/prisma/releases and find the first version that supported Postgres JSON operators."
The pattern that saves the most time is chaining Fetch with a search MCP. Brave or Tavily returns URLs with 400-character snippets. Fetch pulls the full text of the best 2 or 3 for deep reading. That combo handles about 80% of "research this for me" requests.
Troubleshooting
403 Forbidden. The site blocks the default User-Agent. Ask the model to retry with a browser User-Agent like Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7). Some sites will still block - that is where Puppeteer or Browserbase come in.
Empty or garbled content. The page is a JavaScript SPA. The server returns the pre-render HTML, which is often just a shell. Switch to mcp-server-puppeteer for those.
Cloudflare challenge. The server cannot pass the JS challenge. No workaround on the Fetch server. Use a stealth browser or a scraping service.
Timeout on large pages. The server has a default 30-second timeout. Very large pages or slow servers can exceed it. Pass an explicit timeout parameter if the tool supports it, or switch to a direct curl call via the filesystem MCP.
Redirect loop. Fetch follows up to 5 redirects then stops. If you need more, the target URL is probably broken.
Encoding problems. Some pages declare UTF-8 in the header but serve Latin-1. The server uses the declared encoding, which can produce mojibake. Rare but real.
Alternatives
Near neighbors:
mcp-server-puppeteerfor JavaScript-rendered pagesbrowserbase-mcpfor sites with heavy anti-bot protectionfirecrawl-mcp(community) for bulk scraping with built-in rendering- Tavily's
search_and_extracttool combines search plus fetch in a single call
Attach mcp-server-fetch by default. Add Puppeteer when you need JavaScript. Add Browserbase or Firecrawl when the target is hostile. The verdict from 6 months of use: Fetch is the most useful MCP server in the official set for anyone who reads documentation as part of their job, which is most developers.
When to reach for Fetch versus a real browser
The mental model that saves the most debugging time is simple. Static HTML - reach for Fetch. JavaScript-rendered - reach for Puppeteer. Server-side rendered but client-hydrated - try Fetch first, fall back to Puppeteer if the rendered text is missing key content.
About 70% of documentation sites are static or SSR-first. Anything built with Nextra, MkDocs, Docusaurus, VitePress, GitBook, or plain Jekyll works flawlessly. Hacker News, Reddit old UI, Wikipedia, MDN, and DevDocs all return clean content. Most GitHub pages work if you request the raw.githubusercontent.com URL rather than the repository page.
The 30% where Fetch struggles: Twitter (now X), Instagram, LinkedIn, Facebook, modern admin dashboards, and any site that shows a loading spinner before content appears. Those always need Puppeteer or Browserbase.
Latency numbers from 100 sampled fetches on April 10, 2026: median 420 ms, p95 1100 ms, p99 3400 ms. Most of the long tail is slow origin servers rather than the MCP layer. Compare that to Puppeteer which averages 3500 ms per navigation. The 8x speed difference adds up when the agent fetches 20 pages in a research session.
A final pattern: when you give the model a URL in prompt, it will usually assume Fetch works and try that first. If the response is empty or obviously a shell, tell it to retry with Puppeteer. Most of the time the first attempt works fine.
Guides
Frequently asked questions
Does the Fetch server respect robots.txt?
No, it fetches any URL you give it. For ethical scraping, check `robots.txt` yourself first (you can ask the model to fetch it) and honor the rules. The server is a tool, not a policy enforcer.
Can I set a custom User-Agent?
Yes. Most versions of the tool accept a `headers` parameter. Set `User-Agent` to a browser string if a site blocks the default. You can also set it globally via `FETCH_USER_AGENT` in the MCP config env block.
How large a page can Fetch handle?
Technically any size, but the model context is the practical ceiling. Pages over 100 KB of rendered text usually cause the model to lose focus. Ask the model to condense or extract specific sections rather than loading the full page.
Can Fetch send POST or PUT requests?
No. The official server supports only GET. For POST, PUT, DELETE, use a custom MCP server or ask the model to generate a `curl` command and run it via the filesystem MCP. `openapi-mcp` is a better fit for full REST interaction.
Does Fetch cache responses?
No. Every call hits the network. If you want caching, run a local HTTP proxy with response caching between the server and the internet. For most workflows caching does not help because URLs are rarely revisited.
Why does fetching some pages return only a navigation menu?
The site is a JavaScript SPA and the HTML skeleton has no real content. The Fetch server returns what the server sends, which is only the shell. Use `mcp-server-puppeteer` or `browserbase-mcp` to run the page in a real browser and see the rendered DOM.