Skip to main content
Glama

@yawlabs/fetch-mcp

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.

Add to Yaw MCP

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

What it gives the model

Tool

What it does

http_get / http_head / http_options

Bare HTTP requests with headers, auth, timeout, size cap, retry

http_post / http_put / http_patch / http_delete

Write-method HTTP with JSON or raw body

fetch_html_to_markdown

GET a page and convert to clean markdown (3–8× smaller than raw HTML)

fetch_html_to_text

GET a page and convert to plain text with block structure preserved

fetch_reader

Reader-mode extraction — isolates the article body and returns title + markdown

fetch_meta

Extract <head> metadata: title, description, OpenGraph, Twitter cards, JSON-LD, feeds, icons

fetch_links

Extract every outbound link, resolved to absolute URLs, classified internal/external

fetch_sitemap

Parse sitemap.xml (including gzipped and sitemap-index chaining)

fetch_feed

Parse an RSS 2.0 or Atom 1.0 feed into entries

fetch_robots

Parse a site's robots.txt, return the verdict for a given path & user-agent

Related MCP server: cleanfetch

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 169.254.169.254

  • CGNAT (100.64/10)

  • Unique-local IPv6 (fc00::/7)

  • Multicast / broadcast

  • IPv4-mapped IPv6 (::ffff:0:0/96) re-checked against the IPv4 rules, and likewise the IPv4 embedded in IPv4-compatible (::/96), IPv4-translated (::ffff:0:0:0/96) and 6to4 (2002::/16) addresses

  • Teredo (2001::/32), NAT64 (64:ff9b::/96, 64:ff9b:1::/48), site-local (fec0::/10) and discard-only (100::/64) IPv6

  • Any other IPv6 outside global unicast (2000::/3), and the non-global blocks inside it (3fff::/20, 2001:2::/48, 2001:10::/28)

  • The Azure WireServer address 168.63.129.16

  • Non-http/https schemes (file://, gopher://, javascript:, …)

  • Hostname localhost and any *.localhost

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 or ftp://… is caught. For hostnames, DNS is resolved once per hop, every returned address is checked, and the verified IP is pinned into the HTTP dispatcher so the subsequent TCP connection dials that exact address — closing the DNS-rebinding TOCTOU window. Authorization, Cookie and Proxy-Authorization headers are stripped on cross-origin redirects.

Reaching private hosts (development)

The model chooses tool arguments, and the model is not trusted: a prompt injected through a fetched page can ask for anything. So the per-call allow_private_hosts: true opt-in is refused unless the operator enables it by launching the server with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 (true/yes/on also work; any unrecognised value is treated as off and named on stderr). With the variable set, a call still has to ask: requests without allow_private_hosts stay guarded.

{
  "mcpServers": {
    "fetch": {
      "command": "npx",
      "args": ["-y", "@yawlabs/fetch-mcp@latest"],
      "env": { "FETCH_MCP_ALLOW_PRIVATE_HOSTS": "1" }
    }
  }
}

Only set it where the model may legitimately reach your internal network -- a local dev box, not a cloud VM with a metadata endpoint.

Install & run

# One-off (auto-updates each spawn via @latest)
npx -y @yawlabs/fetch-mcp@latest

# Or globally
npm i -g @yawlabs/fetch-mcp
fetch-mcp

Requires Node 22.19 or newer when running on Node (the floor of its HTTP client, undici 8; the launcher refuses older Nodes with a clear message instead of crashing). Under oam, which the launcher prefers when installed, the Node version does not matter.

Configure in Claude Code / Claude Desktop

Add to your client's MCP config (usually claude_desktop_config.json or ~/.claude.json):

{
  "mcpServers": {
    "fetch": {
      "command": "npx",
      "args": ["-y", "@yawlabs/fetch-mcp@latest"]
    }
  }
}

Or via mcph:

mcph add fetch

Tool reference

http_get, http_post, http_put, http_patch, http_delete, http_head, http_options

Common parameters:

Field

Type

Default

Meaning

url

string

Absolute URL

headers

object

Custom request headers

timeout_ms

int

10000

Timeout for each attempt, covering DNS, every redirect hop and the body. Retries get a fresh budget; a whole call is capped at 5 minutes. Cancelling the tool call stops the request

max_bytes

int

5242880 (5 MiB)

Truncate body if larger

max_redirects

int

5

Redirect hops allowed

retries

int

0

Retry count on 408/425/429/5xx with backoff (honors Retry-After)

user_agent

string

@yawlabs/fetch-mcp/<v>

User-Agent override

basic_auth

{username,password}

Injects Authorization: Basic …

bearer_token

string

Injects Authorization: Bearer …

allow_private_hosts

bool

false

Opt this call into loopback / private / link-local targets. Refused unless the operator set FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 (details)

decode_text

bool

auto

When unset, auto-detects by response Content-Type (text for text/*, JSON, XML, JS, form-urlencoded; binary otherwise). Set explicitly true to force text decoding, false to force base64 in body_base64.

Body-capable tools (POST/PUT/PATCH/DELETE) also take:

Field

Type

Meaning

body

string

Raw request body

body_json

any

Structured body — encoded as JSON, Content-Type: application/json set automatically

content_type

string

Overrides Content-Type

Response shape:

{
  ok: boolean;
  status: number;
  statusText: string;
  url: string;              // final URL after redirects
  headers: Record<string,string>;
  body_text?: string;
  body_base64?: string;     // when decode_text=false
  json?: unknown;           // auto-parsed when response is application/json
  truncated?: boolean;      // set when max_bytes hit
  redirects?: string[];     // chain of intermediate URLs
  duration_ms: number;
  error?: string;
}

fetch_html_to_markdown

GET the URL, strip scripts/styles/iframes/svg/canvas plus <nav>, <footer>, <aside>, convert to atx-headed markdown with fenced code blocks and dash bullets. Intended for feeding pages into an LLM without blowing the context budget.

fetch_html_to_text

Same fetch, but emits plain text with block-level structure preserved as newlines. Useful when the model doesn't need markdown formatting.

fetch_reader

Isolates the main article body using, in order: <article>, <main>, itemprop="articleBody", common CMS class names (post-content, entry-content, etc.), then <body> as fallback. Returns:

{
  url: string;          // final URL after redirects
  title?: string;       // og:title, then <title>, then <h1>
  byline?: string;      // meta[name=author] / article:author
  wordCount: number;
  markdown: string;     // main content converted to markdown
}

fetch_meta

GET a URL and return its head metadata without downloading the full body (caps at 2 MiB by default):

{
  url: string;
  title?: string;
  description?: string;
  canonical?: string;
  language?: string;
  robots?: string;
  og:      Record<string, string>;       // first value per key (og:title, og:image, og:type, ...)
  twitter: Record<string, string>;       // first value per key
  article: Record<string, string>;       // first value per key
  ogAll:      Record<string, string[]>;  // only keys that appear > once (e.g. multiple og:image)
  twitterAll: Record<string, string[]>;
  articleAll: Record<string, string[]>;
  icons:   Array<{ rel: string; href: string; sizes?: string }>;
  feeds:   Array<{ href: string; title?: string; type?: string }>;   // RSS/Atom
  jsonLd:  unknown[];                    // parsed application/ld+json blocks
}

GET a page and return every <a href> with text, resolved to absolute URLs. Respects <base href>. Skips #, javascript:, mailto:, tel:, data:, file:. Each link is classified internal or external vs. the page host. Optional filter/dedupe/limit.

fetch_sitemap

Fetch a sitemap.xml or sitemap-index and return the URL list:

{
  sitemaps: string[];       // indexes followed, in order
  urlCount: number;
  truncated: boolean;       // hit max_urls
  childSitemaps: string[];  // listed but not fetched (past max_depth or max_sitemaps)
  warnings: Array<{ url: string; error: string }>;
  urls: Array<{
    loc: string;
    lastmod?: string;
    changefreq?: string;
    priority?: number;
  }>;
}

Gzipped .xml.gz sitemaps are auto-decompressed. max_depth controls how many levels of sitemap-index to follow (default 1). Setting max_depth: 0 on a sitemap-index returns the index's childSitemaps list without fetching any child (useful to discover structure cheaply). Partial failures — one child sitemap 500s while others succeed — are returned under warnings rather than aborting the whole call. max_sitemaps (default 50, max 1000) caps how many sitemap documents one call fetches, index included; children past it are listed under childSitemaps with a warning. The whole call is capped at 5 minutes. max_bytes (default 20 MiB) applies to each sitemap, and to the decompressed size of a gzipped one; a sitemap larger than that is an error (a warning for a child) rather than a silently partial URL list.

fetch_feed

Parse an RSS 2.0 or Atom 1.0 feed:

{
  kind: "rss" | "atom" | "unknown";
  title?: string;
  description?: string;
  link?: string;
  updated?: string;
  entryCount: number;
  truncated: boolean;       // hit limit
  entries: Array<{
    title?: string;
    link?: string;
    id?: string;
    published?: string;
    updated?: string;
    author?: string;
    summary?: string;
    content?: string;
    categories?: string[];
  }>;
}

fetch_robots

Fetches <origin>/robots.txt, parses it, and returns:

{
  robotsUrl: string;
  status: number;
  userAgent: string;
  path: string;
  allowed: boolean;
  matchedRule: string | null;  // the longest-match Allow/Disallow that decided it
  crawlDelay: number | null;   // from the matched group
  sitemaps: string[];          // top-level Sitemap: declarations
  rawRobotsText: string;       // first 512KB
  note?: string;               // only when robots.txt 404s
}

A /robots.txt that returns 404 means there are no rules, so the verdict is allowed: true. The response keeps the same shape: status: 404, matchedRule: null, crawlDelay: null, sitemaps: [], rawRobotsText: "", plus the note. Any other non-2xx status is returned as an error.

The parser follows Google's rules: longest match wins, * is a wildcard segment, $ anchors the end of the path, specific user-agent group beats the * wildcard group when the UA matches (comparison uses the length of the actually-matched agent token, not the group's first agent). Allow beats Disallow on equal-length ties.

Development

npm install
npm run build
npm test         # vitest
npm run lint     # biome
npm run typecheck

Tests spin up a local loopback HTTP server on 127.0.0.1:0 to exercise the real request/response path — no mocking of HTTP. SSRF tests verify that the default-deny still applies to that local server unless the operator gate is on and the request opts into allow_private_hosts.

License

MIT © Yaw Labs

Follow @TokenLimitNews on X

Available Tools

15 tools
fetch_feedA
Read-onlyIdempotent

Fetch 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
limitNoMax entries to return (default 50)
max_bytesNoMax bytes to read (default 10MiB)
timeout_msNo
user_agentNo
max_redirectsNo
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish this as a safe, read-only, idempotent operation. The description adds useful behavioral detail beyond that: it returns feed-level metadata plus structured entries and auto-detects RSS vs Atom. It does not discuss error or network edge cases, but the annotation safety profile lowers the burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two tight sentences with no filler. It front-loads the core action, then efficiently provides the return contract and the auto-detection behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description responsibly enumerates the returned metadata and entry fields. For a network tool with several optional tuning parameters, it leaves default/error behavior to the schema, but the core invocation trigger and return shape are sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only 43% schema description coverage and seven parameters, the description needed to compensate but does not. It says nothing about limit, max_bytes, timeout_ms, user_agent, max_redirects, or allow_private_hosts beyond what the schema already provides. The URL parameter is only implied by 'feed'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Fetch and parse') tied to a well-defined resource ('RSS 2.0 or Atom 1.0 feed') and enumerates the exact return shape. This clearly separates fetch_feed from the HTML, metadata, sitemap, and generic HTTP sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intended use case is implied by naming RSS/Atom feeds, but the description never explicitly says when to choose this over fetch_reader, http_get, or fetch_meta, nor does it state when not to use it. There's context, but no explicit routing or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_html_to_markdownA
Read-onlyIdempotent

GET a URL, decode the HTML, and convert to clean markdown (headings, lists, links, code fences). Scripts, styles, iframes, nav, footer, and aside elements are stripped. Intended for feeding web pages into an LLM cheaply -- markdown is usually 3-8x smaller than raw HTML. Follows redirects, respects size/timeout limits, and blocks private-host requests by default.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesURL to fetch
max_bytesNoMax response size in bytes (default 5MiB)
timeout_msNoTimeout in ms for the request, covering DNS, every redirect hop and the body (default 10000)
user_agentNoUser-Agent override
max_redirectsNoMax redirect hops (default 5)
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, and non-destructive behavior. The description adds valuable context beyond that: stripping of scripts/styles/nav/footer elements, redirect following, size/timeout limits, and default private-host blocking. It enriches the agent's mental model without contradicting annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no wasted words. The core action is front-loaded, followed by stripping behavior, use case, and safety characteristics. Every sentence contributes meaningful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 6 params and no output schema, the description covers the key behavior: input URL, output markdown, stripping rules, limits, and security. It doesn't detail error handling or edge cases, but the essential call semantics are clear. Slightly more on failure modes would push it to 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description's mention of 'size/timeout limits' and 'blocks private-host requests' aligns with parameters but adds no new syntax or format details beyond the schema. It does not compensate for anything missing, which is fine given full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'GET', the resource 'a URL', and the outcome 'convert to clean markdown', which distinguishes it from raw fetch tools. However, it does not explicitly differentiate from the sibling fetch_html_to_text, leaving the boundary between markdown and text extraction implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides a clear intended use ('feeding web pages into an LLM cheaply') and explains the size benefit, which signals when to use it. But it does not mention when NOT to use it or name alternatives like fetch_html_to_text, so the guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_html_to_textA
Read-onlyIdempotent

GET 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesURL to fetch
max_bytesNoMax response size in bytes (default 5MiB)
timeout_msNoTimeout in ms for the request, covering DNS, every redirect hop and the body (default 10000)
user_agentNoUser-Agent override
max_redirectsNoMax redirect hops (default 5)
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral detail: it strips scripts, styles, and comments, decodes HTML entities, and preserves block-level structure as newlines. This goes beyond annotations and informs the agent of processing specifics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler. The first sentence delivers the core action and output format, and the second provides a concise comparative note. All information earns its place and is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple: it fetches HTML and returns plain text. The description covers the output format and processing, and the schema covers all parameters. Annotations cover safety. It could mention error handling or redirect behavior, but those are implied by parameters and not essential for a read-only fetch tool. Overall, it is complete enough for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, meaning every parameter (url, max_bytes, timeout_ms, user_agent, max_redirects, allow_private_hosts) already has a clear description. The tool description adds no additional parameter-specific semantics, so it stays at the baseline of 3 for fully documented schemas.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear verb-resource pair ('GET a URL, decode the HTML, and return plain text') and specifies the output format precisely. It also distinguishes itself from a sibling by noting it is 'Lighter than markdown when you only need the reading content,' which helps an agent pick between this and fetch_html_to_markdown.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a usage hint by contrasting with markdown ('when you only need the reading content'), implying when to prefer this tool. However, it does not explicitly state when not to use it or name alternatives beyond markdown, leaving some inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_metaA
Read-onlyIdempotent

GET a URL and extract its head metadata: title, description, canonical, language, robots directive, Open Graph / Twitter Card / article: properties, icon links, RSS/Atom feed links, and any JSON-LD (schema.org) blocks. Keys that appear more than once (e.g. multiple og:image tags) are additionally returned via ogAll/twitterAll/articleAll arrays. Ideal for previewing a page before fully reading it.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesURL to extract metadata from
max_bytesNoDefault 2MiB — metadata lives in <head>
timeout_msNo
user_agentNo
max_redirectsNo
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds useful behavioral detail beyond that: it enumerates extracted metadata and the duplicate-key arrays (ogAll/twitterAll/articleAll), which are non-obvious and help the agent anticipate output shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each earning its place: the main action, the duplicate-key return behavior, and the use-case guidance. The enumerated metadata list is dense but directly relevant, and the description is not padded with filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by itemizing what will be returned, including feed links, social metadata, and JSON-LD blocks. It does not explain error cases or redirect behavior, but the optional network parameters have schema descriptions and the overall invocation requirements are clear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%, with url, max_bytes, and allow_private_hosts already documented in the schema. The tool description does not add parameter details beyond 'GET a URL', and the undocumented params (timeout_ms, user_agent, max_redirects) are left to name-based inference, making this minimally adequate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description states a specific verb and resource: 'GET a URL and extract its head metadata', then enumerates the exact metadata types returned. It clearly separates this tool from siblings like fetch_reader ('previewing… before fully reading it') and http_get, so an agent can distinguish it without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'Ideal for previewing a page before fully reading it' establishes a clear context for when fetch_meta should be chosen over full-content readers. It does not explicitly name alternatives or say when not to use it, so it falls short of the top score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_readerA
Read-onlyIdempotent

GET a URL, locate the main article body (prefers , , itemprop=articleBody, or known CMS class names; falls back to ), strip navigation/footer/aside chrome, and convert to clean markdown. Returns { title, byline, markdown, wordCount }. Optimized for feeding long-form articles into an LLM without header/footer/sidebar noise.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
max_bytesNo
timeout_msNo
user_agentNo
max_redirectsNo
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnly, idempotent, non-destructive), the description openly details the extraction strategy: preferred selectors, fallback to <body>, chrome stripping, and the exact return shape. This adds meaningful behavioral context that annotations alone do not provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences with no filler. The core behavior is front-loaded, the selector strategy and fallback are compactly summarized, and the use case is stated last without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the main purpose, return fields, and typical use case, which is substantial for a tool with no output schema. It omits edge-case behavior such as what happens when extraction fails or how optional limits like max_bytes interact with the returned markdown, but these are minor gaps given the complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 17%, with only allow_private_hosts explained in the schema. The tool description does not compensate: it mentions the URL target and output but adds no detail about max_bytes, timeout_ms, user_agent, or max_redirects behavior. The parameter names are suggestive, but the description itself contributes little semantic value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'GET a URL, locate the main article body... and convert to clean markdown.' It clearly differentiates itself from siblings like http_get and fetch_html_to_markdown by emphasizing article extraction, chrome-stripping, and LLM-oriented output.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: it is 'optimized for feeding long-form articles into an LLM without header/footer/sidebar noise,' which tells an agent when to prefer it. It does not explicitly name alternatives or state when not to use it, but the usage context is strong enough to guide selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_robotsA
Read-onlyIdempotent

Fetch and parse the robots.txt for a given origin, then tell the caller whether a target URL is crawlable by a given user-agent. Follows the Google-style longest-match rule with Allow-wins-on-tie. Returns the raw robots.txt, parsed groups, sitemap references, and the allow/deny verdict with the matching rule.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesTarget URL to check. We derive origin + path automatically.
timeout_msNo
user_agentNoUser-agent string to match against groups (default '*')
max_redirectsNo
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnly, openWorld, idempotent, non-destructive), the description adds the specific parsing rule (longest-match with Allow-wins-on-tie) and the returned data (raw robots.txt, parsed groups, sitemap references, and verdict). It does not conflict with annotations and adds meaningful behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose, then the matching rule, then the return contents. Every sentence adds necessary information with no filler. It is well-structured and appropriately sized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there is no output schema, the description appropriately covers the return values (raw robots.txt, parsed groups, sitemap references, verdict). It also explains the matching logic. It does not mention error handling or network behavior, but these are likely not critical for a read-only tool with annotations indicating no side effects. The description is sufficient for an agent to know what the tool does and what it returns.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already describes url, user_agent, and allow_private_hosts. The description only indirectly references url and user_agent without adding new meaning. The timeout_ms and max_redirects parameters lack descriptions in both schema and description, and the description does not compensate for this gap. With 60% schema coverage, the baseline is 3, and the description adds little parameter-specific value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it fetches and parses robots.txt and returns a crawlability verdict for a URL and user-agent. It uses specific verbs and resources, and the function is distinct from sibling fetch tools by focusing on robots.txt, not generic content or sitemaps.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the primary use case: checking crawlability for a given URL and user-agent. It provides clear context for when to use this tool, though it does not explicitly name alternatives or provide exclusions. Since no sibling handles robots.txt specifically, the implied usage is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_sitemapA
Read-onlyIdempotent

Fetch a sitemap.xml (or sitemap-index) and return the contained URLs with their lastmod / changefreq / priority. Follows sitemap-index chaining up to max_depth levels. Gzipped .xml.gz payloads are auto-decompressed. Partial failures (one child sitemap 500s while others work) are returned under 'warnings' without aborting the whole request. SSRF-protected by default.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesSitemap URL (sitemap.xml, sitemap.xml.gz, or a sitemap index)
max_urlsNoCap on total URLs returned (default 5000)
max_bytesNoMax bytes to read per sitemap response (default 20MiB)
max_depthNoHow many sitemap-index levels to follow (default 1). 0 keeps the top-level index flat and only returns its childSitemaps list.
timeout_msNo
user_agentNo
max_sitemapsNoCap on sitemap documents fetched -- the index plus every child (default 50, max 1000). Children past the cap are listed under childSitemaps, unfetched.
max_redirectsNo
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses substantial behavioral details beyond the annotations: it follows index chaining up to max_depth, auto-decompresses .gz payloads, returns partial failures as 'warnings' without aborting the request, and is SSRF-protected by default. This goes well beyond the readOnly/idempotent hints and gives the agent a clear model of what happens during execution.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured: the main purpose is front-loaded, followed by a few brief, high-value behavior notes (chaining, decompression, partial failures, SSRF). No redundant sentences or fluff; every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 9 parameters and no output schema, the description covers the core return data (URLs, lastmod, etc.), explains special behaviors like warnings and childSitemaps, and touches on SSRF safety. It does not fully describe the output JSON structure, but it gives enough context to understand what to expect, especially since 'warnings' is mentioned. The missing parameter details are partially covered by schema, so the overall picture is reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already covers 67% of parameters with descriptions. The tool description adds meaningful context for max_depth by explaining chaining behavior, and indirectly clarifies the url format (supports .gz). However, it does not add semantic value for the less-documented parameters (timeout_ms, user_agent, max_redirects), which remain self-explanatory but unaddressed. Overall the description adds some value but does not fully compensate for the missing schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Fetch', the resource ('sitemap.xml or sitemap-index'), and what is returned (URLs with lastmod/changefreq/priority). It also mentions distinguishing features like index chaining, which separates it from generic HTTP fetch tools and the other sitemap-adjacent tools (fetch_robots, fetch_meta) — it is obviously the sitemap-specific tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly compare to sibling tools or state when to prefer this over alternatives. It implies usage via its focus on sitemap parsing, but there is no direct 'use this when you need sitemap URLs' or a note about when not to use it (e.g., for non-sitemap XML). The guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

http_deleteA
DestructiveIdempotent

Perform an HTTP DELETE. Idempotent (per spec): a repeated DELETE on an already-deleted resource typically returns 404/410.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesTarget URL (http:// or https://)
bodyNoRaw request body as a string
headersNoExtra request headers as a key/value object
retriesNoRetries on 408/425/429/500/502/503/504 with exponential backoff (default 0)
body_jsonNoRequest body as a JSON value — sets content-type to application/json if none given
max_bytesNoMax response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB)
basic_authNoHTTP Basic auth credentials
timeout_msNoTimeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes.
user_agentNoUser-Agent override (default identifies as @yawlabs/fetch-mcp)
decode_textNoForce text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise.
bearer_tokenNoBearer token sent as Authorization: Bearer <token>
content_typeNoContent-Type header to send with the body (e.g. application/json, text/plain, application/x-www-form-urlencoded)
max_redirectsNoMax redirect hops to follow (default 5)
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true. The description adds the specific behavioral note that repeated DELETEs typically return 404/410, which is not covered by annotations. This is useful additional context beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, front-loaded with the core operation and a relevant behavioral note. No filler or redundancy. It earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is minimal, covering the core operation and idempotency, but does not mention return format, error handling, or response structure. However, since no output schema exists and the tool is an HTTP client, the expected behavior (status code, body) is standard. The description is adequate but could be enriched with a note about the response.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all 14 parameters. The description adds no parameter-specific meaning, which is acceptable given the high schema coverage. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the operation: 'Perform an HTTP DELETE.' This identifies the specific verb and resource (an HTTP endpoint), which differentiates it from sibling tools like http_get, http_put, etc. It also mentions idempotency, adding useful semantic context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use DELETE vs. other HTTP verbs or alternatives. The intent is implied by the method name and the general HTTP semantics, but the description does not state any conditions, exclusions, or alternatives. With many sibling HTTP tools, explicit routing would be helpful.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

http_getA
Read-onlyIdempotent

Perform an HTTP GET. Returns status, headers, and body. Automatically parses JSON when the server responds with application/json. Follows redirects (each hop re-validated against SSRF rules). Refuses URLs that resolve to private/loopback/link-local addresses unless the operator enabled FETCH_MCP_ALLOW_PRIVATE_HOSTS and the call sets allow_private_hosts.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesTarget URL (http:// or https://)
headersNoExtra request headers as a key/value object
retriesNoRetries on 408/425/429/500/502/503/504 with exponential backoff (default 0)
max_bytesNoMax response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB)
basic_authNoHTTP Basic auth credentials
timeout_msNoTimeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes.
user_agentNoUser-Agent override (default identifies as @yawlabs/fetch-mcp)
decode_textNoForce text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise.
bearer_tokenNoBearer token sent as Authorization: Bearer <token>
max_redirectsNoMax redirect hops to follow (default 5)
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal read-only, idempotent, non-destructive behavior, so the description adds valuable context on top: automatic JSON parsing, redirect-following with SSRF re-validation on every hop, and refusal of private/loopback/link-local addresses unless both operator-level and per-call opt-ins are set. This discloses non-obvious security and parsing behavior beyond what annotations or schema convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences deliver the core action, return payload, parsing behavior, redirect policy, and SSRF restrictions with zero filler. The most important operational facts are front-loaded before the safety caveat, making it easy for an agent to quickly decide and invoke.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having 11 parameters and no output schema, the description covers the returned shape, JSON parsing, redirect handling, and SSRF constraints, while the schema documents every parameter. The agent has enough to invoke the tool correctly and interpret its response; there are no material gaps requiring additional inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and every parameter including url, retries, timeout_ms, max_bytes, basic_auth, bearer_token, and allow_private_hosts already has a meaningful schema description. The description adds only a brief echo of the allow_private_hosts SSRF nuance, so the baseline of 3 is appropriate; it neither hurts nor substantially compensates for schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Perform an HTTP GET') and adds the return shape ('Returns status, headers, and body'), which makes the tool immediately identifiable among siblings like http_post, http_head, and fetch_html_to_markdown. The description goes beyond the tool name by specifying response contents and JSON parsing behavior.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to prefer http_get over the many sibling tools, such as fetch_reader or fetch_html_to_markdown, or when it should be avoided. The description implies use for raw HTTP GET retrieval, but it never states exclusions or alternatives, leaving the agent to infer selection from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

http_headA
Read-onlyIdempotent

Perform 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesTarget URL (http:// or https://)
headersNoExtra request headers as a key/value object
retriesNoRetries on 408/425/429/500/502/503/504 with exponential backoff (default 0)
max_bytesNoMax response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB)
basic_authNoHTTP Basic auth credentials
timeout_msNoTimeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes.
user_agentNoUser-Agent override (default identifies as @yawlabs/fetch-mcp)
decode_textNoForce text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise.
bearer_tokenNoBearer token sent as Authorization: Bearer <token>
max_redirectsNoMax redirect hops to follow (default 5)
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the bar is lower. The description adds meaningful behavioral context beyond annotations: the response includes status and headers with no body, and the operation is cheap because it avoids transferring content.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The core semantics (HTTP HEAD, no body, returns status/headers) are front-loaded, followed by practical use cases.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only HTTP HEAD tool, the description covers what it returns and why an agent would use it. There is no output schema, but 'status + headers with no body' adequately communicates the response shape, and the parameter schema covers invocation details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all 11 parameters are already documented structurally. The description does not repeat or add parameter-level meaning, but it does not need to; the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Perform an HTTP HEAD') and clearly distinguishes it from sibling methods by noting it returns status and headers with no body. This immediately differentiates it from http_get, http_post, and the fetch_* family.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete use cases: checking resource existence, reading Content-Length, and cheap polling. It does not explicitly name alternatives or state when not to use it, but the no-body distinction and listed use cases provide clear contextual guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

http_optionsA
Read-onlyIdempotent

Perform an HTTP OPTIONS. Returns the server's supported methods and CORS policy for a resource. Helpful for API discovery.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesTarget URL (http:// or https://)
headersNoExtra request headers as a key/value object
retriesNoRetries on 408/425/429/500/502/503/504 with exponential backoff (default 0)
max_bytesNoMax response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB)
basic_authNoHTTP Basic auth credentials
timeout_msNoTimeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes.
user_agentNoUser-Agent override (default identifies as @yawlabs/fetch-mcp)
decode_textNoForce text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise.
bearer_tokenNoBearer token sent as Authorization: Bearer <token>
max_redirectsNoMax redirect hops to follow (default 5)
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, covering the safety profile. The description adds the output behavior (supported methods and CORS policy) but does not disclose additional traits such as behavior when OPTIONS is unsupported or response variability. This is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler. The action is front-loaded, followed by return value and use case. Every sentence contributes useful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich schema and safety annotations, the description is mostly complete. It explains the return value in the absence of an output schema, though it could mention edge cases like servers that omit CORS headers. Overall it is sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all 11 parameters. The description adds no parameter-level meaning beyond the schema, which aligns with the baseline score of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource ('Perform an HTTP OPTIONS'), states the return value (supported methods and CORS policy), and names a clear use case (API discovery). This makes it readily distinguishable from sibling HTTP method tools like http_get or http_head.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use the tool ('Helpful for API discovery') and explains what it returns. It does not explicitly name alternatives or exclusions, but the use case is clear enough for an agent to select it over siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

http_patchA
Destructive

Perform an HTTP PATCH. Use for partial updates. Spec-wise NOT guaranteed idempotent — depends on the server's patch semantics.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesTarget URL (http:// or https://)
bodyNoRaw request body as a string
headersNoExtra request headers as a key/value object
retriesNoRetries on 408/425/429/500/502/503/504 with exponential backoff (default 0)
body_jsonNoRequest body as a JSON value — sets content-type to application/json if none given
max_bytesNoMax response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB)
basic_authNoHTTP Basic auth credentials
timeout_msNoTimeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes.
user_agentNoUser-Agent override (default identifies as @yawlabs/fetch-mcp)
decode_textNoForce text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise.
bearer_tokenNoBearer token sent as Authorization: Bearer <token>
content_typeNoContent-Type header to send with the body (e.g. application/json, text/plain, application/x-www-form-urlencoded)
max_redirectsNoMax redirect hops to follow (default 5)
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare idempotentHint=false and destructiveHint=true, so the bar is lower. The description adds genuine value by explaining WHY idempotency isn't guaranteed — "depends on the server's patch semantics" — which is beyond the bare annotation. But it contributes little else: no side-effect scope, auth requirements, or response-behavior disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Roughly three short clauses — action, usage context, and one critical caveat — with zero filler. The core purpose is front-loaded and every sentence earns its place. This is appropriately sized given that the schema carries all parameter detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a powerful open-world HTTP tool with 14 parameters, nested objects, and no output schema, the description is thin: it omits response-format hints, truncation/error behavior, and explicit when-not-to-use guidance. The unusually rich schema (defaults, bounds, per-param semantics) and annotations compensate substantially, keeping it adequate but not complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds nothing about parameters — all 14 (url, body, headers, retries, body_json, allow_private_hosts, etc.) are documented entirely in the schema with defaults and bounds. No bonus, no penalty beyond baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Perform an HTTP PATCH" states a specific verb and resource, and "Use for partial updates" pins down the exact use case that separates it from siblings like http_put (full replacement) and http_post (creation). The idempotency caveat further differentiates it from http_put, which is conventionally idempotent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Use for partial updates" is a direct, clear usage directive, and the idempotency warning functions as a caution against relying on safe retries. However, it never names alternatives (e.g., "use http_put for full replacement") or states explicit exclusions, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

http_postA
Destructive

Perform 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesTarget URL (http:// or https://)
bodyNoRaw request body as a string
headersNoExtra request headers as a key/value object
retriesNoRetries on 408/425/429/500/502/503/504 with exponential backoff (default 0)
body_jsonNoRequest body as a JSON value — sets content-type to application/json if none given
max_bytesNoMax response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB)
basic_authNoHTTP Basic auth credentials
timeout_msNoTimeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes.
user_agentNoUser-Agent override (default identifies as @yawlabs/fetch-mcp)
decode_textNoForce text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise.
bearer_tokenNoBearer token sent as Authorization: Bearer <token>
content_typeNoContent-Type header to send with the body (e.g. application/json, text/plain, application/x-www-form-urlencoded)
max_redirectsNoMax redirect hops to follow (default 5)
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, idempotentHint=false, and destructiveHint=true, so the safety profile is covered. The description reinforces this with 'NOT idempotent: calling twice submits twice,' which adds a concrete consequence, but it adds little beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler; the core action, the key body-format choice, and the idempotency warning are all front-loaded and every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 14-parameter tool this is concise, but the input schema is unusually thorough and the annotations carry the read/write and destructive profile. The description covers the main cross-parameter decision and the most important side-effect caveat; only explicit response/return behavior is left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents each parameter well. The description still adds value by framing body and body_json as the two mutually exclusive body-format options and highlighting that body_json auto-selects application/json.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear verb and resource: 'Perform an HTTP POST.' This unambiguously identifies the operation and, together with the tool name, separates it from the GET/PUT/PATCH/DELETE siblings. It lacks an explicit contrast with those siblings, so it stops just short of a top score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to choose POST over the sibling HTTP methods or the fetch_* helpers, and no exclusions or alternatives are mentioned. The non-idempotency warning is a behavioral caution, not a selection rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

http_putA
DestructiveIdempotent

Perform an HTTP PUT. Use for full-resource replacement. Idempotent: the same PUT applied twice leaves the resource in the same state.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesTarget URL (http:// or https://)
bodyNoRaw request body as a string
headersNoExtra request headers as a key/value object
retriesNoRetries on 408/425/429/500/502/503/504 with exponential backoff (default 0)
body_jsonNoRequest body as a JSON value — sets content-type to application/json if none given
max_bytesNoMax response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB)
basic_authNoHTTP Basic auth credentials
timeout_msNoTimeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes.
user_agentNoUser-Agent override (default identifies as @yawlabs/fetch-mcp)
decode_textNoForce text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise.
bearer_tokenNoBearer token sent as Authorization: Bearer <token>
content_typeNoContent-Type header to send with the body (e.g. application/json, text/plain, application/x-www-form-urlencoded)
max_redirectsNoMax redirect hops to follow (default 5)
allow_private_hostsNoAllow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare idempotentHint=true, destructiveHint=true, and readOnlyHint=false. The description restates idempotency ('the same PUT applied twice leaves the resource in the same state') and adds 'full-resource replacement' as semantic context, but does not disclose additional behaviors like error handling or response format. It does not contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences with no filler. The core action is front-loaded ('Perform an HTTP PUT'), followed by the key semantic reason to use it and a clarifying idempotency note.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The schema is rich and annotations cover safety and idempotency, making the tool callable correctly. However, there is no output schema and the description does not explain what the tool returns (e.g., response status, headers, body) or edge cases like SSRF blocking, leaving some contextual ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with thorough parameter descriptions including defaults, retries, SSRF protection, and timeout behavior. The description itself adds no parameter-level information, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Perform an HTTP PUT') plus its semantic role ('full-resource replacement'), which clearly distinguishes it from siblings like http_patch (partial update) and http_post (create/submit). The description is unambiguous about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a clear usage context: 'Use for full-resource replacement.' This tells the agent when to prefer this tool over sibling methods, though it does not explicitly name alternatives or state when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 15 tool updatesv0.8.0
    • Changedfetch_feed1 field changed
      • addedInput schema / properties / allow_private_hosts / description
        Added value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
    • Changedfetch_html_to_markdown2 fields changed
      • changedInput schema / properties / allow_private_hosts / description
        Previous value: -"Allow loopback / private / link-local addresses (default false)"New value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
      • changedInput schema / properties / timeout_ms / description
        Previous value: -"Request timeout in ms (default 10000)"New value: +"Timeout in ms for the request, covering DNS, every redirect hop and the body (default 10000)"
    • Changedfetch_html_to_text2 fields changed
      • changedInput schema / properties / allow_private_hosts / description
        Previous value: -"Allow loopback / private / link-local addresses (default false)"New value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
      • changedInput schema / properties / timeout_ms / description
        Previous value: -"Request timeout in ms (default 10000)"New value: +"Timeout in ms for the request, covering DNS, every redirect hop and the body (default 10000)"
    • Changedfetch_links1 field changed
      • addedInput schema / properties / allow_private_hosts / description
        Added value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
    • Changedfetch_meta1 field changed
      • addedInput schema / properties / allow_private_hosts / description
        Added value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
    • Changedfetch_reader1 field changed
      • addedInput schema / properties / allow_private_hosts / description
        Added value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
    • Changedfetch_robots1 field changed
      • addedInput schema / properties / allow_private_hosts / description
        Added value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
    • Changedfetch_sitemap2 fields changed
      • addedInput schema / properties / allow_private_hosts / description
        Added value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
      • addedInput schema / properties / max_sitemaps
        Added value: +{
        +  "description": "Cap on sitemap documents fetched -- the index plus every child (default 50, max 1000). Children past the cap are listed under childSitemaps, unfetched.",
        +  "maximum": 1000,
        +  "minimum": 1,
        +  "type": "integer"
        +}
    • Changedhttp_delete2 fields changed
      • changedInput schema / properties / allow_private_hosts / description
        Previous value: -"Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost."New value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
      • changedInput schema / properties / timeout_ms / description
        Previous value: -"Request timeout in ms (default 10000, max 120000)"New value: +"Timeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes."
    • Changedhttp_get2 fields changed
      • changedInput schema / properties / allow_private_hosts / description
        Previous value: -"Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost."New value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
      • changedInput schema / properties / timeout_ms / description
        Previous value: -"Request timeout in ms (default 10000, max 120000)"New value: +"Timeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes."
    • Changedhttp_head2 fields changed
      • changedInput schema / properties / allow_private_hosts / description
        Previous value: -"Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost."New value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
      • changedInput schema / properties / timeout_ms / description
        Previous value: -"Request timeout in ms (default 10000, max 120000)"New value: +"Timeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes."
    • Changedhttp_options2 fields changed
      • changedInput schema / properties / allow_private_hosts / description
        Previous value: -"Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost."New value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
      • changedInput schema / properties / timeout_ms / description
        Previous value: -"Request timeout in ms (default 10000, max 120000)"New value: +"Timeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes."
    • Changedhttp_patch2 fields changed
      • changedInput schema / properties / allow_private_hosts / description
        Previous value: -"Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost."New value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
      • changedInput schema / properties / timeout_ms / description
        Previous value: -"Request timeout in ms (default 10000, max 120000)"New value: +"Timeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes."
    • Changedhttp_post2 fields changed
      • changedInput schema / properties / allow_private_hosts / description
        Previous value: -"Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost."New value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
      • changedInput schema / properties / timeout_ms / description
        Previous value: -"Request timeout in ms (default 10000, max 120000)"New value: +"Timeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes."
    • Changedhttp_put2 fields changed
      • changedInput schema / properties / allow_private_hosts / description
        Previous value: -"Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost."New value: +"Allow loopback / private / link-local targets for this call (default false). Refused unless the server operator launched fetch-mcp with FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 -- SSRF protection stays on by default either way."
      • changedInput schema / properties / timeout_ms / description
        Previous value: -"Request timeout in ms (default 10000, max 120000)"New value: +"Timeout in ms for each attempt, covering DNS, every redirect hop and the body (default 10000, max 120000). Retries get a fresh budget; a whole call is capped at 5 minutes."
  2. 15 tool updatesv0.6.1
    • First observedfetch_feed
    • First observedfetch_html_to_markdown
    • First observedfetch_html_to_text
    • First observedfetch_links
    • First observedfetch_meta
    • First observedfetch_reader
    • First observedfetch_robots
    • First observedfetch_sitemap
    • First observedhttp_delete
    • First observedhttp_get
    • First observedhttp_head
    • First observedhttp_options
    • First observedhttp_patch
    • First observedhttp_post
    • First observedhttp_put

TDQS

A4/5.0

Scored across 15 tools

Disambiguation4/5

Most tools are clearly distinct (each HTTP method, and each fetch utility has a unique purpose). The three HTML conversion tools (fetch_reader, fetch_html_to_markdown, fetch_html_to_text) have overlapping goals but are differentiated by output format and focus (main article vs full page vs plain text). This slight ambiguity prevents a perfect score.

Naming Consistency4/5

Tools follow two clear prefixes: http_ for raw HTTP methods and fetch_ for high-level fetch operations. Within each group, naming is consistent (e.g., http_get, http_post; fetch_meta, fetch_links). The mixed prefixes are intentional and predictable, but not a single uniform convention, so a 4 is appropriate.

Tool Count5/5

15 tools is within the ideal range and each tool addresses a distinct need: seven HTTP methods and eight fetch utilities (reader, markdown, text, robots, sitemap, meta, links, feed). No tool feels redundant; the count is well-scoped for a comprehensive fetch/HTTP server.

Completeness5/5

The tool surface is complete for the domain: all standard HTTP methods are covered, and the fetch tools cover common web scraping needs (reading, converting, metadata, links, robots, sitemaps, feeds). There are no obvious gaps that would cause agent failures; http_get provides raw access when needed.

Maintenance

ActivityActive
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Enables fetching and converting web content to markdown with built-in prompt injection safeguards that detect and block malicious content attempting to manipulate the LLM.
    1
    2
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI agents to read web pages reliably, returning clean markdown content, hyperlinks, and metadata without navigation or ad noise.
    3
    6 npm
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to crawl and scrape websites, converting HTML to clean Markdown and structured metadata with support for JavaScript rendering, bot evasion, and SSRF protection.
    178
    MIT