fetch-mcp
Provides tools for fetching and parsing RSS 2.0 and Atom 1.0 feeds into structured entries, including titles, links, dates, authors, summaries, content, and categories.
Click on "Deploy 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 https://example.com/blog and convert to markdown"
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.
@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.
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 |
| Bare HTTP requests with headers, auth, timeout, size cap, retry |
| Write-method HTTP with JSON or raw body |
| GET a page and convert to clean markdown (3–8× smaller than raw HTML) |
| GET a page and convert to plain text with block structure preserved |
| Reader-mode extraction — isolates the article body and returns title + markdown |
| Extract |
| Extract every outbound link, resolved to absolute URLs, classified internal/external |
| Parse |
| Parse an RSS 2.0 or Atom 1.0 feed into entries |
| Parse a site's |
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 endpoint169.254.169.254CGNAT (
100.64/10)Unique-local IPv6 (
fc00::/7)Multicast / broadcast
IPv4-mapped IPv6 (
::ffff:0:0/96) re-checked against the IPv4 rulesNon-
http/httpsschemes (file://,gopher://,javascript:, …)Hostname
localhostand any*.localhost
DNS is resolved once per redirect 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 headers are stripped on cross-origin redirects. A 302 to http://127.0.0.1 through a public host gets caught. Set allow_private_hosts: true per-request when you really do need internal access (e.g. development).
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-mcpRequires Node ≥20.
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 fetchTool reference
http_get, http_post, http_put, http_patch, http_delete, http_head, http_options
Common parameters:
Field | Type | Default | Meaning |
| string | — | Absolute URL |
| object | — | Custom request headers |
| int |
| Request timeout |
| int |
| Truncate body if larger |
| int |
| Redirect hops allowed |
| int |
| Retry count on 408/425/429/5xx with backoff (honors |
| string |
|
|
|
| — | Injects |
| string | — | Injects |
| bool |
| Bypass SSRF block |
| bool | auto | When unset, auto-detects by response Content-Type (text for text/*, JSON, XML, JS, form-urlencoded; binary otherwise). Set explicitly |
Body-capable tools (POST/PUT/PATCH/DELETE) also take:
Field | Type | Meaning |
| string | Raw request body |
| any | Structured body — encoded as JSON, |
| string | Overrides |
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
}fetch_links
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
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.
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 typecheckTests 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 request opts into allow_private_hosts.
License
MIT © Yaw Labs
Links
Yaw Labs: https://yaw.sh
Available Tools
15 toolsfetch_feedARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| limit | No | Max entries to return (default 50) | |
| max_bytes | No | Max bytes to read (default 10MiB) | |
| timeout_ms | No | ||
| user_agent | No | ||
| max_redirects | No | ||
| allow_private_hosts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only, idempotent, and open-world. The description adds behavioral information: it performs in network fetch, parses both formats, auto-detects feed type, and returns structured metadata/entries. This is beyond what the structured annotation fields state, adding value without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, with the core action first, followed by output shape and the auto-detection note. Every sentence contributes; there is no filler or redundant restatement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description sketches the return structure and feed types, which is helpful for a tool with no output schema. However, it does not touch on network edge cases (e.g., malformed feeds, redirect semantics, use of allow_private_hosts), and parameter gaps remain, so it is not fully complete for a 7-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 29% (only limit and max_bytes have descriptions). The tool description does not mention any parameter, so it does little to compensate. The main input (`url`) is implicit, but helper parameters like timeout_ms, user_agent, allow_private_hosts are left without any guidance. This is a noticeable gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Fetch and parse') and resource ('RSS 2.0 or Atom 1.0 feed'), and enumerates the output fields, so an agent can tell it is a feed parser. It does not explicitly differentiate itself from sibling tools like fetch_reader, but the feed type and parse behavior make the purpose clear. Hence a 4, not a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: use this when you need a parsed RSS/Atom feed, and it lists what is returned. It does not explicitly call out siblings or mention 'when not to use' (e.g., raw XML or HTML fetching), but the intended use is apparent and free of ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_html_to_markdownARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL to fetch | |
| max_bytes | No | Max response size in bytes (default 5MiB) | |
| timeout_ms | No | Request timeout in ms (default 10000) | |
| user_agent | No | User-Agent override | |
| max_redirects | No | Max redirect hops (default 5) | |
| allow_private_hosts | No | Allow loopback / private / link-local addresses (default false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only/idempotent/non-destructive, and the description adds substantial behavioral context beyond them: which elements are stripped, that redirects are followed, that size/timeout limits are respected, and that private-host requests are blocked by default. These are exactly the runtime traits an agent needs to predict before calling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences with no filler: action first, then transformation specifics, then use case and runtime constraints. Every sentence earns its place and the most decision-relevant information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only fetch-and-convert tool with no output schema, the description sufficiently covers input, processing, output format, element stripping, redirect/limit behavior, and security defaults. An agent has everything needed to call it correctly without additional documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters. The description adds context about limits and private-host blocking, but doesn't need to elaborate further; baseline 3 is appropriate when the schema carries the parameter documentation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('GET a URL') and a concrete output ('convert to clean markdown'), with explicit transformations like stripping scripts, styles, iframes, nav, footer, and aside. This clearly differentiates it from raw-fetch siblings and from fetch_html_to_text, which would produce plain text rather than markdown.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear intended use case: 'feeding web pages into an LLM cheaply' with a concrete benefit ('3-8x smaller than raw HTML'). It doesn't explicitly name alternatives or state when not to use it, but the context is strong enough for an agent to select it appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_html_to_textARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL to fetch | |
| max_bytes | No | Max response size in bytes (default 5MiB) | |
| timeout_ms | No | Request timeout in ms (default 10000) | |
| user_agent | No | User-Agent override | |
| max_redirects | No | Max redirect hops (default 5) | |
| allow_private_hosts | No | Allow loopback / private / link-local addresses (default false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral details beyond that: HTML entities are decoded, scripts/styles/comments are stripped, and block-level structure becomes newlines. It does not go into edge cases like HTTP redirects or error handling, but outcomes behavior for a read-only tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no filler: first states the operation and return format, second gives processing details, and last gives the comparison use. It is front-loaded with the core action and output.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With only one required parameter, fully documented parameters, and no output schema, the description explains what to expect back: plain text with newlines, stripped scripts, and decoded entities. It also provides the comparison that helps with sibling decisions. No return-value schema means a description that adequately describes output is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage for all six parameters, including default values for max_bytes, timeout_ms, and max_redirects. The description does not add parameter-specific meaning, but the schema already carries the full burden. Baseline 3 is appropriate because the description does not compensate or conflict.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('GET'), resource (URL/HTML), and output behavior ('return plain text with block-level structure preserved as newlines'). It also differentiates from the markdown-based sibling by describing what is stripped and by saying it is 'lighter than markdown.' This lets an agent distinguish it from fetch_html_to_markdown and fetch_reader 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear condition for use: 'Lighter than markdown when you only need the reading content.' This implicitly points to an alternative tool type but does not name siblings like fetch_html_to_markdown or fetch_reader directly, nor does it state when not to use the tool beyond that condition. Clear context, but no explicit exclusion or alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_linksARead-onlyIdempotent
Extract every outbound link from an HTML page, resolved to absolute URLs. Each entry includes href, anchor text, optional rel/title, and an internal/external classification (bare-domain and www. treated as the same host). Anchors (#), javascript:, mailto:, tel:, data:, and file: URIs are skipped. Respects .
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| limit | No | Cap on returned links (default 1000) | |
| dedupe | No | Drop duplicate hrefs (default true) | |
| filter | No | Filter by type (default 'all') | |
| max_bytes | No | ||
| timeout_ms | No | ||
| user_agent | No | ||
| max_redirects | No | ||
| allow_private_hosts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds rich behavioral context beyond the readOnly/openWorld/idempotent annotations: absolute URL resolution, handling of <base href>, skipped URI schemes, and internal/external classification rules. This meaningfully tells the agent what the tool will and will not process.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: the first front-loads the core purpose, and the second packs essential behavioral details without fluff. Every clause adds useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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's enumeration of returned fields is valuable and mostly sufficient. It is not fully complete because it omits explicit guidance for advanced parameters and error/edge-case behavior, but for the common call path it is strong.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description clarifies that `url` should be an HTML page and explains output semantics relevant to `filter` and `dedupe`. However, schema coverage is only 33% and several parameters such as max_bytes, timeout_ms, user_agent, max_redirects, and allow_private_hosts are not addressed in the description, leaving gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Extract every outbound link from an HTML page' and details the output fields and classification. This makes it clearly distinguishable from sibling tools like fetch_meta or 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is implied through the link-extraction focus, but the description does not explicitly say when to choose this over sibling tools such as http_get or fetch_html_to_text. No exclusions or alternative recommendations are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_metaARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL to extract metadata from | |
| max_bytes | No | Default 2MiB — metadata lives in <head> | |
| timeout_ms | No | ||
| user_agent | No | ||
| max_redirects | No | ||
| allow_private_hosts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds behavioral value by disclosing that duplicate metadata keys are rolled up into ogAll/twitterAll/articleAll arrays and that metadata lives in the <head>, beyond what annotations state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact for the amount of behavior it covers: one dense sentence states the output, one explains duplicate-key handling, and one gives the usage intent. Every sentence contributes distinct information without padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The absence of an output schema raises the description's burden, and it does provide a strong account of the return shape, which is good. However, it remains incomplete for a 6-parameter tool because several parameters (timeout_ms, user_agent, max_redirects, allow_private_hosts) have no description-level semantics, even though their names are self-explanatory.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only 33% schema description coverage, the description needed to clarify the four undocumented parameters, but it only adds context for url and max_bytes (via the schema note about the 2MiB default). timeout_ms, user_agent, max_redirects, and allow_private_hosts are left to be inferred from their names, and the security-relevant allow_private_hosts gets no explanation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'extract' applied to a URL's head metadata and enumerates the exact fields returned (title, description, canonical, Open Graph, Twitter Card, JSON-LD, RSS/ATOM feeds), making its scope unmistakable. It also contrasts with 'fully reading' a page, which separates it from sibling fetch_reader/http_get even without naming them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Ideal for previewing a page before fully reading it' gives a clear when-to-use signal and implies that full-content extraction is the alternative. It does not name sibling tools or provide an explicit when-not-to-use statement, so it falls just 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.
fetch_readerARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| max_bytes | No | ||
| timeout_ms | No | ||
| user_agent | No | ||
| max_redirects | No | ||
| allow_private_hosts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only, idempotent, non-destructive annotations, the description discloses the DOM preference order, the fallback to <body>, the removal of navigation/footer/aside chrome, and the exact return shape. This gives the agent a solid model of what happens when the tool runs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences front-load the primary action and extraction strategy, then give the output shape and intended use case. There is no filler or repetition of schema/annotation information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for selection and general invocation, including return fields and article-extraction strategy. However, given six parameters with no parameter descriptionsable, the absence of any guidance on network controls and limits leaves a modest completeness gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description does not compensate by explaining max_bytes, timeout_ms, user_agent, max_redirects, or allow_private_hosts. While some parameter names are self-explanatory, the lack of defaults, units, or behavioral caveats leaves meaningful ambiguity for correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific operation ('GET a URL'), a clear resource (main article body), and an exact output (markdown with title, byline, wordCount). It differentiates itself from siblings like fetch_html_to_markdown and http_get by emphasizing article-body extraction and noise removal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly narrows use to long-form articles for LLM consumption and explains the extraction behavior, implying this is for reader-mode fetching rather than raw HTTP access. It does not name sibling alternatives or state explicit when-not-to-use conditions, so it falls 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.
fetch_robotsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Target URL to check. We derive origin + path automatically. | |
| timeout_ms | No | ||
| user_agent | No | User-agent string to match against groups (default '*') | |
| max_redirects | No | ||
| allow_private_hosts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive. The description goes beyond by detailing the matching rule ('Google-style longest-match with Allow-wins-on-tie') and listing what it returns (raw robots.txt, parsed groups, sitemap refs, verdict). This adds useful behavioral context beyond the annotation tags, with no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences: the first states the core action and output, the second details the matching rule and return payload. No filler, and the most important information is front-loaded. Excellent structure for an agent to quickly grasp.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 5 parameters and no output schema, the description is reasonably complete: it names the input (origin URL, user-agent), explains the algorithm, and enumerates the return components. The optional parameters are not covered, but their roles are inferable from names (timeout, redirects, private hosts). The core functionality is fully specified, and the safety profile is covered by annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 40% (url and user_agent have descriptions). The description clarifies that 'url' is derived origin+path automatically and ties 'user_agent' to matching groups. However, it does not explain timeout_ms, max_redirects, or allow_private_hosts, leaving those unexplained despite low schema coverage. Partial compensation, not complete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Fetch and parse') a clear resource ('robots.txt') and an outcome (determine whether a target URL is crawlable). It distinguishes itself from siblings like fetch_sitemap or http_get by focusing on robots.txt semantics, making the tool's role unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies its use case — checking crawlability via robots.txt — but it does not explicitly contrast with alternatives like http_get or fetch_sitemap, nor does it state conditions when this tool should not be used (e.g., if only sitemap data is needed). The guidance is implicit 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_sitemapARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Sitemap URL (sitemap.xml, sitemap.xml.gz, or a sitemap index) | |
| max_urls | No | Cap on total URLs returned (default 5000) | |
| max_bytes | No | Max bytes to read per sitemap response (default 20MiB) | |
| max_depth | No | How many sitemap-index levels to follow (default 1). 0 keeps the top-level index flat and only returns its childSitemaps list. | |
| timeout_ms | No | ||
| user_agent | No | ||
| max_redirects | No | ||
| allow_private_hosts | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive behavior. The description adds significant behavioral detail beyond that: sitemap-index chaining up to max_depth, gzip auto-decompression, partial failures returned under 'warnings' without aborting, and SSRF protection. These are valuable edge-case disclosures not present in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four sentences, front-loaded with the core purpose and followed by concise behavioral notes. Every sentence adds value—chaining, gzip, partial failures, SSRF protection—with no filler or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description does indicate return content (URLs with metadata) and mentions a 'warnings' field for partial failures. It covers main behaviors and error handling, but omits details on complete-failure responses, default values for undocumented parameters, and pagination behavior. Still, for a read-only tool with 8 parameters, it is reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 50% (4 of 8 parameters described). The description itself does not elaborate on parameters; it only references max_depth indirectly via chaining. It adds no new meaning for timeout, user_agent, max_redirects, or allow_private_hosts, which remain undocumented in both schema and description. This falls at the baseline for mid-coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Fetch') and resource ('sitemap.xml or sitemap-index') and clearly distinguishes the tool from siblings like fetch_robots or fetch_feed. It also details what it returns (URLs with lastmod/changefreq/priority), making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose is so specific that an agent can infer when to use it (whenever a sitemap is needed), and the description mentions partial failures and SSRF protection, which convey reliability context. However, it does not explicitly contrast with alternatives or state when not to use it, so it lacks exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
http_deleteADestructiveIdempotent
Perform an HTTP DELETE. Idempotent (per spec): a repeated DELETE on an already-deleted resource typically returns 404/410.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Target URL (http:// or https://) | |
| body | No | Raw request body as a string | |
| headers | No | Extra request headers as a key/value object | |
| retries | No | Retries on 408/425/429/500/502/503/504 with exponential backoff (default 0) | |
| body_json | No | Request body as a JSON value — sets content-type to application/json if none given | |
| max_bytes | No | Max response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB) | |
| basic_auth | No | HTTP Basic auth credentials | |
| timeout_ms | No | Request timeout in ms (default 10000, max 120000) | |
| user_agent | No | User-Agent override (default identifies as @yawlabs/fetch-mcp) | |
| decode_text | No | Force text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise. | |
| bearer_token | No | Bearer token sent as Authorization: Bearer <token> | |
| content_type | No | Content-Type header to send with the body (e.g. application/json, text/plain, application/x-www-form-urlencoded) | |
| max_redirects | No | Max redirect hops to follow (default 5) | |
| allow_private_hosts | No | Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and destructiveHint=true, and the description adds a concrete behavioral detail (repeated DELETE typically returns 404/410). This goes beyond the annotations by explaining the outcome of a specific edge case, providing useful context without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero redundancy: the main purpose is front-loaded, and the idempotency note is concise and informative. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 14 parameters and no output schema, the description is minimal. It covers the core operation and idempotency, but omits any guidance on response handling, error cases, or when to choose DELETE over alternatives. The schema carries most of the burden, so this is adequate but not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 beyond the schema's own descriptions, which sets the baseline at 3 as expected.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Perform') and resource ('HTTP DELETE'), clearly distinguishing it from sibling methods like http_get or http_post. It also adds a key semantic detail about idempotency, so an agent knows exactly what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly state when to use DELETE vs other HTTP methods, relying on the method name to convey intent. It lacks contrast with siblings or any scenario guidance, so an agent must infer usage from HTTP semantics alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
http_getARead-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 allow_private_hosts is set.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Target URL (http:// or https://) | |
| headers | No | Extra request headers as a key/value object | |
| retries | No | Retries on 408/425/429/500/502/503/504 with exponential backoff (default 0) | |
| max_bytes | No | Max response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB) | |
| basic_auth | No | HTTP Basic auth credentials | |
| timeout_ms | No | Request timeout in ms (default 10000, max 120000) | |
| user_agent | No | User-Agent override (default identifies as @yawlabs/fetch-mcp) | |
| decode_text | No | Force text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise. | |
| bearer_token | No | Bearer token sent as Authorization: Bearer <token> | |
| max_redirects | No | Max redirect hops to follow (default 5) | |
| allow_private_hosts | No | Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint, idempotentHint, destructiveHint), the description discloses important behaviors: automatic JSON parsing for application/json responses, redirect following with per-hop SSRF re-validation, and refusal of private/loopback/link-local addresses unless allow_private_hosts is set. These are non-obvious and genuinely useful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: the action and return value, the JSON parsing behavior, and the redirect/SSRF behavior. Front-loaded, no filler, and appropriately sized for an 11-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers what the tool returns, how it parses responses, how it handles redirects, and the key SSRF safety constraint. Given the detailed input schema and the absence of an output schema, this is complete enough for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline of 3 applies. The description does add one parameter-related detail (allow_private_hosts disables SSRF blocking), but it does not systematically enrich the parameter documentation beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 GET. Returns status, headers, and body.' This clearly distinguishes it from HTTP sibling methods (post/put/patch/delete/head/options) and from the specialized fetch_* tools, which are not raw HTTP GET operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context is clear: use this tool for raw HTTP GET requests. However, it never explicitly mentions when to prefer a sibling like fetch_reader or fetch_html_to_markdown, nor does it state when not to use it. Usage is implied by the name and description rather than explicitly contrasted with alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
http_headARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Target URL (http:// or https://) | |
| headers | No | Extra request headers as a key/value object | |
| retries | No | Retries on 408/425/429/500/502/503/504 with exponential backoff (default 0) | |
| max_bytes | No | Max response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB) | |
| basic_auth | No | HTTP Basic auth credentials | |
| timeout_ms | No | Request timeout in ms (default 10000, max 120000) | |
| user_agent | No | User-Agent override (default identifies as @yawlabs/fetch-mcp) | |
| decode_text | No | Force text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise. | |
| bearer_token | No | Bearer token sent as Authorization: Bearer <token> | |
| max_redirects | No | Max redirect hops to follow (default 5) | |
| allow_private_hosts | No | Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds the key behavioral detail that it returns status and headers with no body, going beyond the annotations, and notes the operation is 'cheap,' reinforcing its read-only nature. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core action and outcome, followed by the main use cases. Every word is purposeful; there is no fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a network tool with 11 parameters, the description covers the essential outcome and typical use cases. The schema fully documents parameters, and annotations cover safety, so nothing critical is missing. It could mention SSRF protection, but the schema already covers that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 11 parameters individually. The description adds no parameter-specific guidance beyond that, meeting the baseline of 3 without exceeding it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Perform an HTTP HEAD') with a clear resource and outcome (status + headers, no body). It lists concrete use cases (checking existence, Content-Length, cheap polling) that distinguish it from siblings like http_get which return a body.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit use cases: checking existence, getting Content-Length, and polling for changes. It implies preferring this over http_get when the body is not needed, but it does not explicitly name alternative tools or state when not to use it. The context is clear enough for an agent to select it appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
http_optionsARead-onlyIdempotent
Perform an HTTP OPTIONS. Returns the server's supported methods and CORS policy for a resource. Helpful for API discovery.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Target URL (http:// or https://) | |
| headers | No | Extra request headers as a key/value object | |
| retries | No | Retries on 408/425/429/500/502/503/504 with exponential backoff (default 0) | |
| max_bytes | No | Max response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB) | |
| basic_auth | No | HTTP Basic auth credentials | |
| timeout_ms | No | Request timeout in ms (default 10000, max 120000) | |
| user_agent | No | User-Agent override (default identifies as @yawlabs/fetch-mcp) | |
| decode_text | No | Force text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise. | |
| bearer_token | No | Bearer token sent as Authorization: Bearer <token> | |
| max_redirects | No | Max redirect hops to follow (default 5) | |
| allow_private_hosts | No | Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, which fully cover the safety profile. The description adds the behavioral outcome (returns supported methods and CORS policy) beyond what annotations state, which is useful. However, it doesn't disclose network-related behaviors like potential timeouts or SSRF protection, though these are mentioned in parameter descriptions. Given the strong annotation coverage, the description adds modest value but not a rich 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with zero fluff. The primary action and return value are front-loaded, and the 'Helpful for API discovery' note is appended as a secondary signal. Every word earns its place, and the structure is ideal for quick agent scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (11 parameters, nested objects) and lack of an output schema, the description is reasonably complete: it covers the purpose, the return value, and hints at use cases. The schema and annotations handle the rest (parameter meanings, safety, idempotency). No critical behavioral aspect an agent needs to safely invoke it is missing, though it could mention that it's read-only (already covered by annotations) or note SSRF protections (already in parameter description).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with detailed descriptions for all 11 parameters, including defaults, bounds, and types. The description itself does not explain any parameters beyond implying the URL via 'for a resource.' Since the schema already documents every parameter thoroughly, the baseline of 3 is appropriate; the description adds no semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb (Perform an HTTP OPTIONS) and the resource (the target URL) and what it returns (supported methods and CORS policy). It distinguishes itself from sibling HTTP verbs like http_get or http_post by naming the specific HTTP method, though it doesn't explicitly contrast with siblings. The mention of 'API discovery' adds helpful context for when an agent would choose this tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for API discovery but does not explicitly state when to use this tool versus alternatives like http_get or http_head, nor when not to use it. It provides some context ('Helpful for API discovery') but lacks explicit exclusion criteria or guidance on selecting between the many HTTP siblings. There is no mention of prerequisites or scenarios where OPTIONS would be inappropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
http_patchADestructive
Perform an HTTP PATCH. Use for partial updates. Spec-wise NOT guaranteed idempotent — depends on the server's patch semantics.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Target URL (http:// or https://) | |
| body | No | Raw request body as a string | |
| headers | No | Extra request headers as a key/value object | |
| retries | No | Retries on 408/425/429/500/502/503/504 with exponential backoff (default 0) | |
| body_json | No | Request body as a JSON value — sets content-type to application/json if none given | |
| max_bytes | No | Max response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB) | |
| basic_auth | No | HTTP Basic auth credentials | |
| timeout_ms | No | Request timeout in ms (default 10000, max 120000) | |
| user_agent | No | User-Agent override (default identifies as @yawlabs/fetch-mcp) | |
| decode_text | No | Force text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise. | |
| bearer_token | No | Bearer token sent as Authorization: Bearer <token> | |
| content_type | No | Content-Type header to send with the body (e.g. application/json, text/plain, application/x-www-form-urlencoded) | |
| max_redirects | No | Max redirect hops to follow (default 5) | |
| allow_private_hosts | No | Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnlyHint=false and destructiveHint=true, so the agent knows it mutates and may be destructive. The description adds a valuable behavioral note: it is not guaranteed idempotent and depends on server patch semantics, which is not in annotations. This adds context beyond the structured fields without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no wasted words. The primary action and use case are front-loaded, and the idempotency warning is appended efficiently. Every sentence earns its place, and it is appropriately short for a simple HTTP tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a generic HTTP tool with a rich schema and no output schema, the description covers the core purpose, usage context, and a key caveat (idempotency). It does not describe response format or side effects beyond what annotations indicate, but given the simplicity and the presence of annotations, it is adequate. Could add a note about authentication but that is not essential.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed descriptions for all 14 parameters. The description does not add any parameter-level meaning beyond what the schema already provides, so it meets the baseline for high schema coverage. No need to compensate for undocumented parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Perform an HTTP PATCH') and the resource (HTTP PATCH), and adds the distinguishing use case 'partial updates', which differentiates it from siblings like http_put (full updates) and http_post (create). It is specific and actionable, with no ambiguity 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'Use for partial updates', providing a clear context for when to call it. It does not name alternatives explicitly, but the 'partial updates' phrasing implicitly contrasts with full-update (PUT) and create (POST) tools. It also adds an idempotency caveat that guides the agent on suitability. Lacks an explicit 'do not use when' but is sufficient for most cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
http_postADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Target URL (http:// or https://) | |
| body | No | Raw request body as a string | |
| headers | No | Extra request headers as a key/value object | |
| retries | No | Retries on 408/425/429/500/502/503/504 with exponential backoff (default 0) | |
| body_json | No | Request body as a JSON value — sets content-type to application/json if none given | |
| max_bytes | No | Max response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB) | |
| basic_auth | No | HTTP Basic auth credentials | |
| timeout_ms | No | Request timeout in ms (default 10000, max 120000) | |
| user_agent | No | User-Agent override (default identifies as @yawlabs/fetch-mcp) | |
| decode_text | No | Force text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise. | |
| bearer_token | No | Bearer token sent as Authorization: Bearer <token> | |
| content_type | No | Content-Type header to send with the body (e.g. application/json, text/plain, application/x-www-form-urlencoded) | |
| max_redirects | No | Max redirect hops to follow (default 5) | |
| allow_private_hosts | No | Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (which already indicate non-idempotent, destructive, non-read-only), the description clarifies the practical consequence: 'calling twice submits twice.' It also discloses that body_json auto-sets the content-type, which is useful behavioral detail not present in 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with no filler. The core operation is front-loaded, followed by the most decision-relevant parameter distinction and the critical non-idempotence warning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is adequate given rich schema annotations, but there is no output schema and the description never states what the tool returns (status, headers, body, base64 behavior, etc.). For a 14-parameter HTTP client, a brief note on the response shape would make it more complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds meaning beyond the schema by contrasting raw string body versus JSON value body_json and explaining the automatic content-type behavior, which helps agents choose the right parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Perform an HTTP POST') and immediately distinguishes itself from the sibling HTTP verbs through the non-idempotence warning. It also names the two body modes, so there is no ambiguity 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description conveys that this tool is for HTTP POST requests, which is clear context, but it never explicitly says when to choose POST over a sibling like http_put or http_get. Usage is implied by the verb rather than stated as guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
http_putADestructiveIdempotent
Perform an HTTP PUT. Use for full-resource replacement. Idempotent: the same PUT applied twice leaves the resource in the same state.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Target URL (http:// or https://) | |
| body | No | Raw request body as a string | |
| headers | No | Extra request headers as a key/value object | |
| retries | No | Retries on 408/425/429/500/502/503/504 with exponential backoff (default 0) | |
| body_json | No | Request body as a JSON value — sets content-type to application/json if none given | |
| max_bytes | No | Max response body size in bytes before the body is truncated (default 5MiB, ceiling 100MiB) | |
| basic_auth | No | HTTP Basic auth credentials | |
| timeout_ms | No | Request timeout in ms (default 10000, max 120000) | |
| user_agent | No | User-Agent override (default identifies as @yawlabs/fetch-mcp) | |
| decode_text | No | Force text decoding (true) or binary base64 (false). Defaults to auto — text for text/*, json, xml, etc; binary otherwise. | |
| bearer_token | No | Bearer token sent as Authorization: Bearer <token> | |
| content_type | No | Content-Type header to send with the body (e.g. application/json, text/plain, application/x-www-form-urlencoded) | |
| max_redirects | No | Max redirect hops to follow (default 5) | |
| allow_private_hosts | No | Allow requests to loopback / private / link-local addresses. SSRF protection is on by default — only flip this when intentionally talking to localhost. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate idempotentHint=true, destructiveHint=true, and readOnlyHint=false. The description adds value by explaining idempotence in plain terms ('the same PUT applied twice leaves the resource in the same state') and clarifying the replacement semantics. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two tight sentences with no filler. The purpose is front-loaded, and the idempotency clarification is useful, not redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a generic HTTP client with 14 parameters and no output schema, the description covers the essential selection criteria: that it is a full-resource replacement and idempotent. The rich parameter schema and annotations carry the remaining burden, though response format and explicit exclusions are left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All 14 parameters are already documented in the input schema with individual descriptions, giving 100% schema description coverage. The tool description adds no parameter-level information, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Perform an HTTP PUT' and adds 'Use for full-resource replacement', which gives a specific semantic meaning beyond the tool name. This also clearly distinguishes it from siblings like http_patch, which would handle partial updates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Use for full-resource replacement' provides a clear, explicit condition for when to invoke this tool. It does not explicitly name alternatives or say 'do not use for partial updates', so it falls just short of full when/when-not guidance.
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.
15 tool updates
v0.6.1- First observed
fetch_feed - First observed
fetch_html_to_markdown - First observed
fetch_html_to_text - First observed
fetch_links - First observed
fetch_meta - First observed
fetch_reader - First observed
fetch_robots - First observed
fetch_sitemap - First observed
http_delete - First observed
http_get - First observed
http_head - First observed
http_options - First observed
http_patch - First observed
http_post - First observed
http_put
TDQS
Scored across 15 tools
Most tools have clear, distinct purposes: raw HTTP verbs vs. content transforms vs. site metadata. The only possible confusion is fetch_reader and fetch_html_to_markdown, since both return markdown from a URL, though their article-focused vs. document-focused intent is described well.
The HTTP verbs are consistently named http_get/http_post/etc., and most fetch tools follow a fetch_ resource pattern. But fetch_reader does not match fetch_html_to_markdown or fetch_html_to_text, and the file uses two overlapping prefixes, making the overall naming scheme feel mixed rather than fully consistent.
15 tools is within the upper edge of a well-scoped server, and each tool addresses a meaningful fetch or extraction task: HTTP methods, markdown/text conversion, metadata, links, robots, sitemaps, and feeds. No tool feels redundant or gratuitous.
The server covers the full lifecycle of fetching and interpreting web resources: all standard HTTP methods, article extraction, general HTML conversion, raw text, metadata, links, robots.txt, sitemaps, and feed parsing. The surface is comprehensive for its stated purpose.
Maintenance
Related MCP Connectors
Read any web page as clean Markdown for AI agents: fetch, search, metadata, links. SSRF-safe.
Read a URL as clean markdown, screenshot a website, url to PDF. Web access for agents, no signup.
Web scraping for AI agents. Converts URLs to clean, LLM-ready Markdown with anti-bot bypass.
Fetch pages as markdown, search web and news, extract structured data. For AI agents.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables fetching and converting web content to markdown with built-in prompt injection safeguards that detect and block malicious content attempting to manipulate the LLM.12MIT
- AlicenseAqualityCmaintenanceEnables AI agents to read web pages reliably, returning clean markdown content, hyperlinks, and metadata without navigation or ad noise.36 npmMIT
- AlicenseAqualityCmaintenanceEnables AI agents to fetch any web page as clean markdown or screenshot it, turning URLs into LLM-ready context.26 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables 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.171MIT