fetch-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fetch-mcpfetch the fully rendered content of https://example.com"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
fetch-mcp
An MCP server that fetches a URL, fully renders it in a headless Chromium browser (so JavaScript-heavy single-page apps built with Angular, React, Vue, etc. actually populate their DOM), and returns clean, scrapeable content. Plain-HTTP "fetch" MCP servers return pre-render HTML — often just an empty <div id="root"> shell for a SPA. This server renders first, then scrapes.
Install and build
npm install
npm run buildRelated MCP server: web-to-markdown-mcp
Run a standalone sanity check
npm run build
npx @modelcontextprotocol/inspector node dist/index.jsThis opens the MCP Inspector, where you can call fetch_page interactively against a real URL.
Claude Desktop configuration
Add to claude_desktop_config.json:
{
"mcpServers": {
"fetch-mcp": {
"command": "node",
"args": ["/absolute/path/to/fetch-mcp/dist/index.js"]
}
}
}Claude Code configuration
Add to .mcp.json:
{
"mcpServers": {
"fetch-mcp": {
"command": "node",
"args": ["/absolute/path/to/fetch-mcp/dist/index.js"]
}
}
}fetch_page tool reference
Input:
Field | Type | Default | Description |
| string (required) | — | URL to fetch and render |
| string (optional) | — | CSS selector to wait for before extracting content |
| number |
| Total time budget in milliseconds (max |
| boolean |
| Return raw rendered HTML instead of Markdown |
| number |
| Maximum characters of returned content |
Output:
Field | Type | Description |
| string | The URL that was requested |
| string | The URL after any redirects |
| number | HTTP status of the final response |
| string | null | Page title |
|
| How content was derived |
|
| Which wait strategy was used |
| boolean | Whether the wait phase timed out (content is still returned, best-effort) |
| boolean | Whether |
| string | Extracted Markdown, or raw HTML if |
Example call:
{
"url": "https://example.com/dashboard",
"waitForSelector": "#app-loaded",
"timeoutMs": 20000
}Security model
Every request URL — the initial navigation, and every subresource, redirect, or XHR/fetch the page's own JavaScript issues — is checked against a DNS-based SSRF guard before it's allowed through. A hostname is resolved via dns.lookup for all its addresses, and the request is blocked unless every resolved address falls in the unicast (i.e. public, globally-routable) range — this rejects loopback, RFC1918 private ranges, link-local addresses (including the 169.254.169.254 cloud metadata address), carrier-grade NAT, and other non-routable ranges.
Known limitation: this guard has a DNS-rebinding TOCTOU gap — the DNS check and the actual TCP connection are not atomically pinned to the same resolved IP, so a hostname could theoretically re-resolve to an unsafe address between the check and the connection. Closing this fully would require pinning the connection to the checked IP, which breaks TLS/SNI for HTTPS targets, so it isn't done for v1.
Known limitations
If Readability can't find article-like content (common for dashboard-style SPA shells), the full page body is converted to Markdown instead — this fallback is best-effort and may include navigation chrome or other non-content markup.
contentis truncated atmaxContentLengthcharacters; a[content truncated]marker andtruncated: trueare included when this happens.At most 3 pages render concurrently; additional concurrent
fetch_pagecalls queue rather than fail.
Development
npm run dev # run directly with tsx, no build step
npm run typecheck # tsc --noEmit
npm test # vitest
npm run build # tsc, then chmod +x dist/index.jsThis server cannot be installed
Maintenance
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/cmaurer/fetch-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server