MCP Web Fetch Server
The MCP Web Fetch Server is an all-in-one web research and file management server for LLM agents. Here's what you can do with it:
Web Fetching
Fetch web pages (
fetch_url) — retrieves content as markdown, with chunked reading viastart_indexandmax_lengthfor long pagesGet HTTP metadata (
fetch_metadata_tool) — performs a HEAD request to retrieve status code, headers, etc. without downloading full contentBatch-fetch multiple URLs (
batch_fetch) — concurrently fetches up to 10 URLs with per-URL error isolation and progress reportingExtract links and images (
extract_links) — scrapes and returns all links and images from a page as a structured list
Web Search
Search the web (
web_search) — queries DuckDuckGo (no API key needed), returning titles, URLs, and snippets; automatically falls back to a local SearXNG instance if DuckDuckGo fails
AI Summarization
Summarize a URL (
summarize_url) — fetches a page and uses the connected client's LLM (via MCP sampling) to generate a summary, with an optionalfocusparameter
Local File Management (opt-in, sandboxed, disabled by default)
Read files (
read_file), list directories (list_dir), and write files (write_file) within a configured allowed directory; prompts for confirmation before overwriting existing files
Monitoring & Security
Admin web dashboard for monitoring server status, configuration, fetch history, cache, and registered tools
Security features: SSRF protection, robots.txt compliance, domain allowlisting, Bearer token auth, and rate limiting
MCP Protocol Extras: Resources, Prompts, Completions, Elicitation, Roots, and Progress notifications
Provides web search capability using DuckDuckGo, with no API key required. Used for fetching search results via the web_search tool.
Provides a fallback search engine via a local SearXNG instance, used automatically when DuckDuckGo scraping fails. Allows self-hosted metasearch integration.
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., "@MCP Web Fetch Serversearch for latest AI news"
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.
MCP Web Fetch Server
An all-in-one Python MCP server for web research: fetch pages, search the web, batch-fetch, extract links, summarize via client-side sampling, and (optionally) read/write local files — all for LLM agents like Cursor. Supports local stdio and Streamable HTTP for remote access, and exercises essentially every MCP protocol capability (Tools, Resources, Prompts, Completions, Sampling, Elicitation, Roots, Progress, Logging).
Documentation:
Document | What's inside |
Full end-user guide: install (Docker/Linux/Windows), Cursor setup, all tools, admin GUI, config, troubleshooting | |
Full technical reference: architecture, modules, MCP APIs, admin API, security, Docker stack, testing |
Features
Tools
fetch_url— page content as markdown, with chunked reading (start_index,max_length)fetch_metadata_tool— HEAD request metadatabatch_fetch— fetch multiple URLs concurrently, with per-URL error isolation and progressweb_search— DuckDuckGo web search (no API key), with automatic fallback to a local SearXNG instance if DuckDuckGo's scrape failsextract_links— structured link/image extraction from a pagesummarize_url— asks the connected client's LLM to summarize a page (MCP sampling)read_file/write_file/list_dir— sandboxed local file access (opt-in, disabled by default)
Other MCP capabilities
Resources:
config://settings,history://recent,fetch-cache://{encoded_url}Prompts:
fetch,research_topic,summarize_page,extract_key_facts,compare_sourcesCompletions: URL/depth autocomplete for prompt and resource arguments
Elicitation:
write_fileconfirms before overwriting an existing fileRoots: local file tools honor client-exposed directories in addition to
FETCH_LOCAL_FILES_ROOTProgress notifications:
batch_fetchandsummarize_urlreport progress as they runManagement GUI: web dashboard at
/adminfor status, config, history, cache, and tools
Security
SSRF protection with resolve-then-check and redirect re-validation
robots.txtcompliance (override withignore_robots_txt=true)Optional domain allowlist
Local file tools sandboxed to one configured directory, path-traversal safe
Bearer token auth + rate limiting for HTTP mode
/healthendpointWindows
.exebuild (no Python required for end users)
Related MCP server: myscrape
Quick Start
Option A: Docker — full stack (recommended for server deployment)
Runs the MCP server, admin GUI, and SearXNG together.
Linux / macOS:
cd mcp-fetch-server
cp .env.docker.example .env # edit MCP_AUTH_TOKEN
chmod +x scripts/docker-up.sh
./scripts/docker-up.sh
# or: docker compose up -d --buildWindows (PowerShell):
cd "E:\my python projects\MCP\mcp-fetch-server"
copy .env.docker.example .env
.\scripts\docker-up.ps1Service | URL |
MCP protocol |
|
Admin GUI |
|
Health |
|
SearXNG (search fallback) |
|
Connect Cursor over HTTP (Bearer token required):
{
"mcpServers": {
"web-fetch": {
"url": "http://127.0.0.1:8000/mcp",
"headers": { "Authorization": "Bearer your-token-from-env" }
}
}
}Local files for read_file/write_file map to the ./workspace folder on your host.
Option B: Windows executable (local / Cursor stdio)
cd "E:\my python projects\MCP\mcp-fetch-server"
.\dist\mcp-fetch-server.exe --transport stdioBuild the exe yourself: .\scripts\build_exe.ps1 → outputs dist\mcp-fetch-server.exe
Option C: Python + uv (development)
cd "E:\my python projects\MCP\mcp-fetch-server"
uv sync --dev
copy .env.example .env
uv run mcp-fetch-server --transport stdioConnect to Cursor
See the User Manual — Connect to Cursor for step-by-step instructions.
Minimal .cursor/mcp.json using the executable:
{
"mcpServers": {
"web-fetch": {
"command": "E:/my python projects/MCP/mcp-fetch-server/dist/mcp-fetch-server.exe",
"args": ["--transport", "stdio"],
"env": { "PYTHONIOENCODING": "utf-8" }
}
}
}Management GUI
A built-in web dashboard lets you monitor and manage the server without using Cursor:
Mode | URL |
stdio (Cursor default) |
|
streamable-http |
|
The dashboard shows uptime, registered tools, redacted configuration, recent fetch history, cached page previews, and a button to clear history/cache. It auto-refreshes every 30 seconds.
If MCP_AUTH_TOKEN is set, enter it in the dashboard's auth bar (stored in your
browser session only). Disable the GUI with FETCH_ADMIN_ENABLED=false.
Optional: SearXNG search fallback
web_search uses DuckDuckGo by default and falls back to SearXNG when that scrape fails.
When you use Docker (docker compose up), SearXNG is started automatically and the MCP
container is preconfigured to reach it at http://searxng:8080.
For local (non-Docker) use, you can still run only SearXNG:
docker compose up -d searxngSet FETCH_SEARXNG_URL=http://localhost:8080 in .env. See searxng/settings.yml.
Remote HTTP Mode (without full Docker stack)
$env:MCP_AUTH_TOKEN = "your-long-random-token"
.\dist\mcp-fetch-server.exe --transport streamable-http --host 127.0.0.1 --port 8000MCP endpoint:
http://127.0.0.1:8000/mcpHealth check:
http://127.0.0.1:8000/health
Project Structure
mcp-fetch-server/
├── dist/mcp-fetch-server.exe # Windows executable
├── src/mcp_fetch_server/ # Source code (tools, resources, prompts, security, ...)
├── tests/ # 84 pytest tests
├── docs/ # User manual + technical docs
├── scripts/docker-up.sh # Linux/macOS stack startup
├── scripts/docker-up.ps1 # Windows stack startup
├── docker-compose.yml # Full stack: MCP server + SearXNG
├── .env.docker.example # Environment template for Docker Compose
├── Dockerfile # MCP server image
├── workspace/ # Host folder mounted for local file tools (Docker)
├── searxng/settings.yml # SearXNG config (JSON API enabled)
├── src/mcp_fetch_server/admin.py # Management web GUI
└── .cursor/mcp.json # Cursor configDevelopment
uv run pytest
uv run ruff check .
./scripts/docker-up.sh # Linux / macOS
docker compose downWindows only:
.\scripts\build_exe.ps1
.\scripts\docker-up.ps1License
MIT
Available Tools
9 toolsbatch_fetchARead-only
Fetch up to 10 public URLs concurrently and return each page's content (or error) in one response.
| Name | Required | Description | Default |
|---|---|---|---|
| urls | Yes | ||
| max_length | No | ||
| ignore_robots_txt | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses concurrent execution, 10 URL limit, and read-only behavior (consistent with readOnlyHint annotation). It also mentions error handling per URL. Missing details on max_length truncation and robots.txt respect, but overall provides useful 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?
Single sentence of 15 words, front-loaded with key constraints. Every word is necessary and clear. No waste.
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 core function and constraints but omits parameter effects (max_length, ignore_robots_txt). Given the output schema may define return format, the description is adequate for basic tool selection but not fully complete for invocation without parameter explanation.
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 0% schema description coverage, the description should explain parameter meaning, but it only mentions 'public URLs'. It does not describe max_length (content size limit) or ignore_robots_txt (robots.txt bypass). The agent cannot infer parameter semantics from the description.
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 tool fetches up to 10 public URLs concurrently and returns content or error per URL. This specifies verb, resource, limit, concurrency, and return type, differentiating it from siblings like fetch_url (single).
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 use for batch fetching multiple public URLs, contrasting with single fetch. However, it lacks explicit when-to-use guidance, exclusions (e.g., private URLs), or alternatives like web_search or fetch_metadata_tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_linksBRead-only
Fetch a URL and extract all links and images from the page as a list.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| max_links | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation 'readOnlyHint: true' already indicates this is a safe read-only operation. The description adds that it extracts specific content (links and images), but does not disclose further behavioral traits like rate limits, authentication needs, or the potential for large payloads.
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 a single, succinct sentence that conveys the essential action and output. There is no extraneous text, and every word contributes to understanding.
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 low complexity (2 parameters, no nested objects, output schema exists), the description covers the core purpose but lacks usage guidance and parameter details. The presence of an output schema reduces the need to describe return values, so the description is minimally complete for a straightforward 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?
With 0% schema description coverage, the description must compensate, but it fails to explain the two parameters. It does not clarify that 'url' is the target page and 'max_links' limits the number of extracted links, nor any constraints or formats. The parameter semantics are entirely absent.
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 explicitly states the action (fetch and extract), the resource (a URL page), and the output (links and images as a list). This clearly distinguishes it from sibling tools like 'fetch_url' (likely raw content) or 'batch_fetch' (multiple URLs).
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?
No guidance is provided on when to use this tool versus alternatives such as 'batch_fetch' for multiple URLs or 'fetch_metadata_tool' for metadata. The description does not mention preconditions, alternatives, or when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_metadata_toolARead-only
Return HTTP metadata for a URL using a HEAD request.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description adds limited behavioral context beyond specifying the HEAD request method. No mention of potential errors or HTTP status handling.
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?
Single sentence, front-loaded with the action ('Return'), no wasted words. Highly efficient.
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 simple tool with an output schema, the description is arguably sufficient. However, it lacks guidance on prerequisites (e.g., valid URL) and edge cases.
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 0% schema description coverage, the description fails to add any meaning to the 'url' parameter, such as format, constraints, or example. It only loosely mentions 'URL' in the description.
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 specifically that it returns HTTP metadata using a HEAD request, clearly distinguishing it from sibling tools like fetch_url (full content) or summarize_url.
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 using this tool when only metadata is needed without downloading the body, but it does not explicitly state when to use or not use it, nor mention alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_urlARead-only
Fetch a public HTTP/HTTPS URL and return page content as markdown. Use start_index to read long pages in chunks.
| Name | Required | Description | Default |
|---|---|---|---|
| raw | No | ||
| url | Yes | ||
| max_length | No | ||
| start_index | No | ||
| ignore_robots_txt | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the agent knows this is safe. The description adds that it returns markdown and can handle pagination with start_index. It does not contradict annotations. Some behavioral details like ignore_robots_txt implications are not explained, but overall adequate.
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, front-loaded with the core function, and contains no fluff. Every sentence 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?
With 5 parameters, an output schema, and 0% schema description coverage, the description is too brief. It fails to explain most parameters (raw, max_length, ignore_robots_txt) and does not mention output format or behavior beyond chunking. The agent would need to infer or experiment.
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%, so the description must compensate. Only start_index is mentioned (for chunking). Other parameters (raw, max_length, ignore_robots_txt) are not explained, leaving the agent uncertain about their effects. This is a significant gap for a 5-parameter tool.
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 (Fetch), the resource (public HTTP/HTTPS URL), and the output (page content as markdown). It also mentions chunking with start_index, distinguishing it from siblings like summarize_url or batch_fetch.
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 provides guidance on using start_index for long pages. However, it does not explicitly tell when not to use this tool versus alternatives like batch_fetch or summarize_url, nor does it mention any prerequisites or limitations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_dirARead-only
List the contents of a directory within an allowed local directory. Leave path empty to list the root itself.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, indicating no side effects. The description adds value by clarifying the tool operates within allowed local directories and that an empty path lists the root. This provides behavioral context beyond the annotation.
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 purpose, then parameter detail. No redundant information. 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?
Given a simple tool with one parameter, an output schema, and read-only annotation, the description covers the essential: purpose, scope, and parameter behavior. It does not elaborate on error handling or return format, but the output schema covers the latter.
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 has 0% coverage, so the description must compensate. It explains the single parameter 'path' meaning and behavior (empty defaults to root). This adds meaning beyond the schema's type and default values.
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 tool lists directory contents and specifies it operates within allowed local directories. The 'Leave path empty to list the root itself' adds further precision. This distinguishes it from siblings like read_file (file content) and fetch_url (remote URLs).
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?
No guidance is given on when to use this tool versus alternatives (e.g., read_file, write_file). The description does not mention prerequisites or contexts where the tool should or should not be used.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_fileARead-only
Read a text file from an allowed local directory (configured via FETCH_LOCAL_FILES_ROOT, plus any directories the client exposes as roots). Path is relative to the allowed directory.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. Description adds that path is relative and directories are allowed, but doesn't disclose file size limits, encoding, or error behavior. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no wasted words. Purpose and key constraint are 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?
Tool has simple input and output schema. Description covers purpose and path constraint. With output schema existing, return type is handled there. Minor omission: no mention of allowed file types or size limits.
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 has 0% description coverage; description adds critical meaning: 'Path is relative to the allowed directory.' This compensates well, though lacks examples.
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?
Clearly states verb 'Read' and resource 'text file from allowed local directory'. Distinguishes from siblings like fetch_url and write_file by specifying local file reading.
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?
Describes when to use (reading text files from allowed directories) and context about configuration (FETCH_LOCAL_FILES_ROOT, client roots). Lacks explicit when-not-to-use or alternatives, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
summarize_urlA
Fetch a URL and ask the connected client's LLM (via MCP sampling) to summarize it. Requires a client that supports the sampling capability; otherwise use fetch_url and summarize the content yourself.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| focus | No | ||
| max_length | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses the dependency on MCP sampling for summarization, which is a key behavioral trait. However, it omits details about error handling, authentication, or side effects beyond fetching.
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 action and purpose. No redundant or tangential 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?
Despite having an output schema, the description does not leverage it to explain return values. It also lacks details on how optional parameters affect behavior, leaving users guessing about their function.
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 0% with no parameter descriptions. The description only mentions 'url' implicitly but does not explain 'focus' or 'max_length'. For a tool with 3 parameters, the description should compensate but fails to do so.
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 'fetch' and 'summarize' with the resource 'URL'. It distinguishes from sibling tools like fetch_url and extract_links by specifying the summarization action via client sampling.
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 directive: requires client with sampling capability, and suggests fallback using fetch_url and manual summarization. This clearly differentiates from alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
web_searchARead-only
Search the web via DuckDuckGo (no API key required) and return titles, URLs, and snippets for the top matches. Automatically falls back to a local SearXNG instance (FETCH_SEARXNG_URL) if DuckDuckGo's scrape fails.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals that the tool uses DuckDuckGo (no API key required) with an automatic fallback to a local SearXNG instance, which adds behavioral context beyond the readOnlyHint annotation. It does not mention rate limits or result freshness, but the core behavior is well disclosed.
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 long, front-loading the primary function in the first sentence and adding a crucial fallback detail in the second. Every word serves a purpose, making it highly efficient and easy to process.
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 the core action, output components (titles, URLs, snippets), and fallback behavior. However, it omits mention of result count limit, caching, or error handling. Given the presence of an output schema, the description is fairly complete but could optionally address these points.
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 0% description coverage, meaning the description adds no meaning to parameters beyond the schema. It does not explain what 'query' or 'max_results' entail, nor their expected format. The description mentions 'top matches' but does not link it to the max_results 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 clearly states the tool 'Search the web' via DuckDuckGo and returns titles, URLs, and snippets. It uniquely identifies the resource (web) and action (search), distinguishing it from sibling tools like fetch_url or batch_fetch that handle individual URLs or file 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 description implies usage for general web search queries and mentions a fallback mechanism, but does not explicitly specify when not to use it or provide direct comparisons to siblings. The context from sibling names helps, but the guideline is not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_fileADestructiveIdempotent
Write text content to a file within an allowed local directory. If the file already exists and overwrite=false, the user will be asked to confirm before it is replaced.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| content | Yes | ||
| overwrite | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructive and idempotent behavior. The description adds that if overwrite=false and the file exists, the user will be asked to confirm, which is useful context beyond the annotation flags.
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 purpose, no wasted words.
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 the basic operation and overwrite behavior, but lacks details on path format, content encoding, or error handling. Since an output schema exists, return values are not required, but more context on input constraints would be helpful.
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%, so the description must compensate but only explains the overwrite parameter behavior. Path and content parameters lack any description of format, constraints, or examples.
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 tool writes text content to a file within an allowed local directory, using a specific verb and resource. This distinguishes it from siblings like read_file and list_dir.
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 explains when overwrite=false triggers user confirmation, but does not explicitly state when to use this tool versus alternatives like batch_fetch (which fetches from URLs). However, the context of writing local files is clear enough.
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.
9 tool updates
v0.1.0- First observed
batch_fetch - First observed
extract_links - First observed
fetch_metadata_tool - First observed
fetch_url - First observed
list_dir - First observed
read_file - First observed
summarize_url - First observed
web_search - First observed
write_file
TDQS
Scored across 9 tools
Each tool has a distinct purpose: fetching URLs (single, batch, metadata, links, search, summarize) and local file operations (list, read, write). No overlap between tools.
Most tools follow a verb_noun pattern in snake_case. The one minor inconsistency is 'fetch_metadata_tool' which includes an unnecessary 'tool' suffix, but otherwise naming is consistent.
9 tools is appropriate for a web fetch server that also includes local file capabilities. Not too many, not too few.
Web fetching covers single, batch, metadata, links, search, and summarize. Local file ops cover list, read, write but lack a delete tool. Minor gap.
Maintenance
Related MCP Connectors
Docs: https://docs.keenable.ai/mcp-server Keenable is a free, remote MCP server that gives agents access to the web index. Search the web with ranked results and date/site filters, then fetch any indexed page as clean markdown. Works out of the box with no account or API key.
Free remote MCP server for fetching public web pages through a rotating proxy pool.
Scrape, crawl and search the web for AI agents via MCP.
Related MCP Servers
- FlicenseAqualityCmaintenanceAn MCP server providing tools for web research, code review, and concept explanation, callable by any MCP-compatible client.3-
- AlicenseNot gradedqualityAmaintenanceA self-contained web-research MCP server that lets local LLM agents search, fetch, and synthesize web content using tools like web_search, web_fetch, and web_research.1MIT
- AlicenseAqualityBmaintenanceAn MCP server that fetches web pages and extracts clean, AI-usable context from them, enabling tools for link discovery, content search, and integrated fetch-and-search operations.5151MIT
- AlicenseAqualityCmaintenanceThis MCP server enables free web search and page content extraction using real browsers, with support for multiple search engines and stealth browser backends. It provides tools for searching, fetching pages, and setting up the Camoufox stealth browser.3MIT