web-search-plus-mcp
This server exposes two stable, source-only MCP tools for web search and page extraction across multiple providers.
web_search: Search the web withautorouting or a forced provider, returning source results, links, snippets, and optional routing diagnostics.Control searches with result count, country/language, recency filters, news/search type, include/exclude domains, Exa depth, caching options, and research mode with a time budget.
Use automatic fallback across configured search providers when one fails or returns poor results.
web_extract: Extract clean page content from one or more URLs using 9 extraction providers.Control extraction with markdown/HTML format, JavaScript rendering, image metadata, raw HTML inclusion, semantic spans, and span ranking by query.
Return one result per requested URL in request order, including per-URL errors, truncation warnings, and stored full-text references when available.
Choose compact responses by default or opt into full v3 evidence, provider attempts, routing receipts, and quality reports via
detail: "full".
Integrated via Serper to provide search results for facts, news, shopping, and local businesses.
Integrated to provide AI-synthesized answers with citations as one of the search provider options.
Integrated as a privacy-first, self-hosted search provider for retrieving web search results.
π web-search-plus-mcp
Give your AI app better web search and clean page reading. web-search-plus-mcp works with Claude Desktop, Cursor, NanoBot, Hermes, and other MCP apps. It searches across the services you choose, returns the original sources, and can try another service when one fails.
web-search-plus-mcp 5.1.6 (released 2026-10-30) says why a page could not be extracted (page not found, site refused, unreachable, provider does not support the site), stops paying for fallbacks when a page does not exist, and no longer blocks Firecrawl after a site it does not support. 5.1.5 fixed DonSeTch with DonSeTch 4.7.1 and newer; 5.1.4 brought compact responses by default; see the changelog.
What's new in 5.1.3
Search and page reading now return compact JSON by default, saving context by removing repeated evidence and execution diagnostics. Source titles, URLs, snippets and bounded page text stay intact. Clients that parse the full v3 contract (including observations and routing receipts) must pass detail: "full" or set the server default below. See docs/RELEASE_5_1_3.md.
Google /goto source wrappers are dropped without contacting Google by default; classic /url?q= links decode locally. Opt in to the bounded resolver with {"serper": {"resolve_redirects": true}} in config.json. SerpBase defaults to device: "mobile" (configurable as mobile or desktop under serpbase) and prefers canonical URLs. Every search provider shares a conservative corrupt-URL filter. Compact output includes positive redirects_wrapped, redirects_resolved, redirects_dropped and invalid_urls_dropped counts; full output retains their complete receipts. DonSeTch 4.10.3 is the tested version.
Earlier: 5.1.2
5.1.1 was never released, so this covers everything since 5.0.1. No provider request starts after the request deadline, web_extract returns exactly one result per requested URL in request order, and each result now carries requested_url, the URL you passed in (url is where the page was fetched). A rate limit, out-of-credit or auth error partway through a batch keeps the pages already fetched and marks the rest not tried: β¦ instead of failing the whole batch, and URLs past the per-call limit of 10 get their own not tried row instead of disappearing. The per-request budget no longer depends on SQLite, half-open circuit probes release their lease, and the search cache is keyed by the credentials that produced a result. Brave accepts queries up to its documented 600 characters and 75 words. Hermes-only changes (profile-scoped keys, native backend, hermes commands) are not part of this package. See docs/RELEASE_5_1_2.md.
Earlier: 5.0.1
Bug fixes for 5.0.0: everyday words like "synthesizer" no longer trip the source-only filter, one bad URL no longer sinks a web_extract batch (each failed URL gets its own error), empty pages fall back to the next provider, rate-limit waits are capped at 30 s, long queries are shortened for Brave, and auto routing off or a private SearXNG URL no longer break every search. See docs/RELEASE_5_0_1.md.
Earlier: 5.0.0
Automatic routing picks providers by query type (Brave for most queries including security and shopping, Exa for docs and academic; Serper remains a later fallback), clearly detected query languages reach the provider, research mode fuses provider results, and automatic search falls back faster on errors, empty answers and slow providers. This changes which API quota is used; see CHANGELOG.md for breaking changes.
Earlier: 4.3.5
Missing-key hints now reach the MCP client, failed calls set isError: true, locale settings are applied to Brave, You.com, Firecrawl, SerpBase and SearXNG, dedup keeps ?v=-style pages apart, and web_extract stays within its size limit. See docs/RELEASE_4_3_5.md.
Earlier: 4.3.4
Missing-key errors point to web-search-plus-mcp setup, the .env file or the MCP client env block instead of an inline key in config.json, and DonSeTch no longer loses its stderr excerpt when a session closes. See docs/RELEASE_4_3_4.md.
Earlier: 4.3.3
web_extract converts internationalized hostnames such as mΓΌller.de to punycode instead of rejecting them. See docs/RELEASE_4_3_3.md.
Earlier: 4.3.2
Security hardening, matching Hermes Web Search Plus 4.3.2: stricter extract URL validation, same-origin-only redirects, response size limits, no provider error text passed on, option-like domain and URL values refused before any run, and an allowlisted DonSeTch environment. Redirects across host, port or scheme now fail and provider errors are less detailed; see docs/RELEASE_4_3_2.md.
Earlier: 4.3.1
Faster: searches run inside the MCP server instead of one Python process per call, and provider connections are reused (auto routing 1.70 s β 0.99 s in live tests). Restart the server after adding a key to .env. See 4.3.1 notes.
What's new in 4.3.0
Adaptive routing learns again: since the 3.0 engine, provider calls no longer recorded samples. provider_stats.json writes are now locked across processes, and web_search honours defaults.max_results when count is omitted. See the 4.3.0 release notes.
What's new in 4.2.1
web_search now accepts no_cache and cache_ttl, matching the CLI. The optional DonSeTch 4.2.9 adapter stays separately installed. See the 4.2.1 release notes.
What's new in 4.2.0
Optional Jev is off by default. Enable with setup --jev --jev-key-file PATH. Jev can confirm a news search type, score extract bodies, and fill language when inference returned none. It is not a search provider. Keep the key in TYPESAFE_API_KEY_FILE, never in config.json.
Existing MCP tools and setup stay the same. The matching Hermes plugin adds an optional native backend; this MCP package does not include that adapter. The Windows fcntl import fix from Hermes #129 is not ported here. See the 4.2.0 release notes.
π Quick Start
# Run it without installing anything
uvx web-search-plus-mcp
# Or install it normally
pip install web-search-plus-mcp
web-search-plus-mcpAdd at least one search provider. You can start with one and add more later.
Related MCP server: OneSearch MCP Server
β¨ What it does
15 search providers β use one service or let Web Search Plus choose
9 page-reading providers β turn web pages into clean text
Automatic fallback β try another provider when the first one fails
Real sources β keep the links and text the result came from
Research mode β search several providers for broader questions
Optional details β see which provider ran and how the result was found
Simple setup tools β check your config and create a starter setup
Optional local search β connect a separately installed DonSeTch executable through the WSP provider adapter
Version 4.0.3 tests DonSeTch 3.2.1. Version 4.0.2 adds Parallel Search modes (default fast). Version 4.0.1 hardens DonSeTch process reuse and diagnostics. Version 4.0.0 removed the optional Hound provider and added the separately installed DonSeTch 2.1.0 stdio adapter. See the 4.0.0 release notes and DonSeTch guide for migration, licensing, and runtime boundaries.
π§ Easier onboarding
Check configured providers:
web-search-plus-mcp statusList providers or presets:
web-search-plus-mcp list providers
web-search-plus-mcp list presetsWrite a starter .env template and print a canonical MCP stdio snippet:
web-search-plus-mcp setup --preset starterThe recommended starter preset is You.com + Serper + Linkup. It gives a practical source-only baseline for fast current search, Google-style discovery, and extraction workflows without wiring every provider on day one.
π§© Agent Plugins package
This repository also contains a portable Agent Plugins 1.0 package for clients that support the standard. The root plugin.json describes the plugin and mcp.json connects the MCP server through the published PyPI package.
The portable configuration uses uvx with an exact web-search-plus-mcp version pin. Install uv first, then load this repository as an Agent Plugin in a compatible client such as VS Code, Cursor, GitHub Copilot, ChatGPT/Codex, or Kiro. Provider credentials are deliberately not stored in the plugin manifest; provide the required environment variables through the client or process environment.
The Agent Plugins format defines packaging and loading, not a central marketplace. Client-specific discovery and distribution remain outside the portable package contract.
status returns a non-zero exit code when no search provider is configured, which makes it usable as a config check in scripts.
Persistent routing preferences live in config.json rather than .env:
web-search-plus-mcp config show
web-search-plus-mcp config set-default you # strict fixed-provider mode
web-search-plus-mcp config set-routing on # restore auto-routing
web-search-plus-mcp config set-priority you,serper,exa,firecrawl,tavily,linkup,parallel,brave,keenable
web-search-plus-mcp config set-extract-priority serper,tavily,exa,linkup,parallel,firecrawl,you,keenable
web-search-plus-mcp config set-fallback serper
web-search-plus-mcp config disable parallel
web-search-plus-mcp config enable parallel
web-search-plus-mcp config set-auto-allow parallel on
web-search-plus-mcp config set-threshold 0.45
web-search-plus-mcp config reset --yesUse --config-path /path/to/config.json or WEB_SEARCH_PLUS_CONFIG=/path/to/config.json for isolated MCP host installs. Provider secrets stay in environment variables; routing behavior stays in config.json. Search and extraction priorities are independent. If an extraction priority lists only selected providers, the remaining extract-capable providers are appended in the public registry order.
Other presets:
minimalβ You.com onlyleanβ You.com + Linkupstarterβ You.com + Serper + Linkupallβ every supported provider env var
π€ Grok Build plugin
This repository is also a Grok Build plugin. Grok reads .mcp.json (the same pinned uvx server as above), skills/web-search-plus/SKILL.md (when and how to use web_search and web_extract), and .grok-plugin/plugin.json (metadata).
Install directly from the repository:
grok plugin install robbyczgw-cla/web-search-plus-mcpOr pick web-search-plus from the marketplace (/plugin inside Grok Build). uv must be installed; provider keys come from your environment, the plugin ships none. Check with grok mcp doctor.
βοΈ MCP host config
Canonical stdio snippet for Claude Desktop, Cursor, NanoBot, or Hermes native MCP:
{
"mcpServers": {
"web-search-plus": {
"command": "uvx",
"args": ["web-search-plus-mcp"],
"env": {
"YOU_API_KEY": "your_you_key",
"SERPER_API_KEY": "your_serper_key",
"LINKUP_API_KEY": "your_linkup_key"
}
}
}
}Common places to paste this snippet:
Claude Desktop macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonClaude Desktop Windows:
%APPDATA%\\Claude\\claude_desktop_config.jsonClaude Desktop Linux:
~/.config/Claude/claude_desktop_config.jsonCursor: project/user MCP config using the same
mcpServersshapeHermes native MCP:
~/.hermes/config.yamlundermcp_serverswith equivalent command/env fields
You can also place a .env file next to the package/project with the same variables.
π MCP protocol compatibility
The server uses MCP Python SDK v2 and keeps the stdio boundary dual-era compatible:
modern clients negotiate the stateless MCP
2026-07-28protocol throughserver/discoverlegacy handshake clients continue to negotiate MCP
2025-11-25
The package exposes stdio only; the specification's Streamable HTTP session removal, subscriptions, OAuth changes, tasks, and multi-round-trip requests do not alter the two-tool Web Search Plus surface. Both protocol paths are covered by real subprocess tests.
π Search Providers
You.com β fast source-result provider for current and multilingual search
Serper β Google-style facts, news, shopping, local queries
Exa β semantic discovery, GitHub/docs, arXiv/academic, and OSS discovery
Firecrawl β web search plus scrape-ready content
Parallel β LLM-ready web search with long excerpts; joins automatic routing when a key is configured (
PARALLEL_API_KEY)Tavily β research and analysis
Linkup β source-backed grounding/citations
Brave β explicit-only independent web index by default (
BRAVE_API_KEY,auto_allow=false)SearXNG β privacy-first self-hosted meta-search
SerpBase β explicit-only Google SERP API (
SERPBASE_API_KEY,auto_allow=false)Querit β explicit-only multilingual, real-time AI search (
QUERIT_API_KEY,auto_allow=false)Keenable β independent web index with search and extraction (
KEENABLE_API_KEY, or opt-in keyless public tier; off by default)DonSeTch β explicit-only local Search/Fetch provider through a separately installed stdio executable (
DONSETCH_BIN)Octen via Monid β explicit-only source-result web search with native recency and domain filters (
MONID_API_KEY,auto_allow=false)TinyFish β explicit-only BYOK source-result search (
TINYFISH_API_KEY,auto_allow=false)
Octen source search via Monid
The adapter executes Octen's /search endpoint through Monid's documented HTTP API for ranked links and highlights. It explicitly disables full-content retrieval and does not call Octen's answer or Broad Search APIs. Configure MONID_API_KEY from Monid, then select provider="octen"; automatic routing remains unchanged unless you deliberately enable auto_allow. Access and billing use Monid's prepaid wallet; see Monid for current pricing and terms.
TinyFish source search
Configure your own TINYFISH_API_KEY and select provider="tinyfish"; TinyFish remains outside automatic routing and fallback. Web Search Plus MCP does not provide, pool, proxy, or share TinyFish credentials. Review the TinyFish Search API reference and TinyFish Terms before use: the published Terms grant broad rights over Customer Data, including queries, for analysis, training, fine-tuning, evaluation, and model improvement. This integration therefore treats TinyFish as high risk and makes no no-training claim.
π Extract Providers
Tavily β public default first choice; fastest reliable extraction in the v2.1 benchmark
Exa β fast contents API, strong for docs/academic pages
Linkup β clean markdown and source-grounded fetches
Parallel β docs-focused fallback with full-content defaults of 60k characters per result / 120k total
Firecrawl β robust scrape fallback, useful for JS-heavy/blocked pages
You.com β LLM-ready snippets/content where available
Keenable β keyed or explicitly opted-in public extraction
Serper β fast webpage scraper extraction
DonSeTch β explicit-only local Markdown fetch through a separately installed stdio executable
auto_routing.extract_provider_priority can override the auto-extraction order without changing search routing. Explicit provider calls still try the requested provider first.
Keenable keyless public access
Keenable exposes authenticated endpoints via KEENABLE_API_KEY. It also has keyless /public endpoints, but those are opt-in and disabled by default. Without a key, Keenable is treated as unconfigured unless you explicitly enable public egress:
{ "keenable": { "allow_public": true } }or set:
KEENABLE_ALLOW_PUBLIC=1Use an API key for private or production use. The public endpoint sends queries and fetched URLs to a shared unauthenticated service and remains near the tail of the public default fallback order unless the operator configures a different extraction priority.
DonSeTch local provider
DonSeTch 4.2.9 is an independent
AGPL-3.0-only project. It is not bundled with this package. Web Search Plus
starts the separately installed executable as a stdio MCP process using
DONSETCH_BIN and projects its web_search and web_fetch results into the
normal source-only envelopes.
DonSeTch remains explicit-only unless the operator enables auto_allow. The
adapter was tested for stdio initialization, Search, Fetch, and structured
errors; browser-based retrieval depends on the host environment and is not
guaranteed.
See the DonSeTch setup and security guide for installation, configuration, licensing, migration, and tested boundaries.
Private/internal extraction target guard
web_extract blocks user-supplied target URLs that point at private or internal networks before any provider is called. This covers loopback, RFC1918, CGNAT/shared-address ranges, IPv6 local/mapped-private ranges, multicast, cloud metadata hosts, and hostnames resolving to private/internal IPs.
Operator-configured provider endpoints are separate: local Firecrawl-compatible backends can still run on 127.0.0.1 through provider config. If you intentionally need to extract trusted intranet URLs, opt in explicitly:
{ "extract": { "allow_private_urls": true } }Leave this off for public/agent-controlled URL extraction.
GroktoCrawl / local Firecrawl-compatible backends
The Firecrawl provider can target a local Firecrawl-v2-compatible backend by overriding its search and scrape URLs in config.json. For example, a local GroktoCrawl instance listening on 127.0.0.1:8080 can be used without adding a separate provider:
{
"firecrawl": {
"api_url": "http://127.0.0.1:8080/v2/search",
"scrape_url": "http://127.0.0.1:8080/v2/scrape"
}
}Keep FIRECRAWL_API_KEY configured if your backend enforces bearer authentication; local development instances may ignore the header. This does not make GroktoCrawl the default and does not claim coverage for every Firecrawl endpoint.
π MCP Tool Reference
This MCP server exposes exactly two stable, source-only tools: web_search and web_extract. Use web_search for source discovery and let the MCP host synthesize from those sources when needed; the server itself does not generate answers or truth claims.
The Hermes plugin exposes the same stable capability as web_search_plus and web_extract_plus; the names differ because MCP and Hermes use different tool surfaces.
Response detail (both tools)
Both tools return one JSON TextContent. The new optional detail argument accepts "compact" or "full". Selection order is argument > WEB_SEARCH_PLUS_MCP_DETAIL environment variable > mcp.detail in config.json > "compact". Only these two values are accepted. The tool schema deliberately has no fixed default, so clients can omit the argument and inherit the server setting.
For clients that cannot pass detail, put WEB_SEARCH_PLUS_MCP_DETAIL=full in the server process environment or the MCP client's env block, or add this to the existing config file (selected by WEB_SEARCH_PLUS_CONFIG):
{"mcp": {"detail": "full"}}full preserves the 5.1.2 response structure, including contract_version, observations, provider attempts, routing receipts, policy actions, dedup clusters, source diversity and requested quality reports. Clients that parse those fields must opt in to full. Routing, provider calls, caching and extraction limits are unchanged.
compact includes detail: "compact" and a hint for requesting the full contract. Search keeps titles, URLs, snippets, publication dates when available, and small source-type and fetch-priority labels. It also includes a short routing summary (failed or empty providers before the serving provider, excluding cancelled hedges), cache hits/age, short warning strings, and research providers merged. Research page counts are included only when extraction receipts provide a count; today's canonical search response may omit them. quality_report: true requires detail: "full" to return the detailed report. Failures keep status: "failed", a short error, provider reasons, setup instructions and environment-variable names; MCP isError remains true.
Compact extraction keeps one result per requested URL, in request order, with url, requested_url, title, bounded content, per-URL errors, requested spans and full_text storage references when present. A truncated page reports whether storing its full text succeeded; successful storage retains its reference, character count and checksum. Compact mode does not expose unbounded observation text.
web_search
Use for source discovery, current events, prices, weather, sports lineups, schedules, and whenever you want the raw search landscape first.
Parameters:
detailβcompact(server default) orfull; overrides env/configqueryβ required search queryproviderβauto,serper,serpbase,brave,tavily,querit,linkup,exa,firecrawl,parallel,you,searxng,keenable,donsetch,octen,tinyfishcountβ results to return, default5, max20depthβ Exa depth:normal,deep,deep-reasoningtime_rangeβhour,day,week,month,yearfreshnessβ unifiedday,week,month, oryearrecency requestsearch_typeβsearchor Serper-nativenewscountry/languageβ explicit locale overridesinclude_domains/exclude_domainsβ domain allow/deny listsmodeβnormalorresearchquality_reportβ include routing/result diagnostics withdetail: "full"research_time_budgetβ best-effort wall-clock budget for research modeno_cacheβ bypass the search cache and fetch live resultscache_ttlβ search-cache TTL in seconds (default 3600)
Example MCP arguments:
{
"query": "latest AI hardware news",
"provider": "auto",
"count": 5,
"quality_report": true,
"detail": "full"
}web_extract
Parameters:
detailβcompact(server default) orfull; overrides env/configurlsβ required list of URLsproviderβauto,tavily,exa,linkup,parallel,firecrawl,you,keenable,serper,donsetchformatβmarkdownorhtmlinclude_imagesβ include image metadata when supportedinclude_raw_htmlβ include raw HTML when supportedrender_jsβ render JavaScript before extraction when supportedspansβ select deterministic semantic spans from extracted textspans_queryβ optional query used to rank semantic spans
Example MCP arguments:
{
"urls": ["https://example.com"],
"provider": "auto",
"format": "markdown"
}Result shape: results holds one entry per requested URL, in request order. Each entry has url (where the page was actually fetched, after redirects and normalization), requested_url (the URL you passed in, so you can match results to inputs without relying on order), content, and error when the URL failed. URLs past the per-call limit (default 10) and URLs a provider never reached after a rate-limit, credit or auth error come back as their own entries with error: "not tried: β¦"; pages fetched before such an error are kept. requested_url is additive: url is unchanged.
π§ Classic Routing v2 examples
ζ±δΊ¬ AI γγ₯γΌγΉ δ»ζ₯β You.com multilingual/current searcharXiv 2024 LLM scaling lawsβ Exa academic discoveryCVE-2025 openssl advisoryβ Brave security/current searchbest bookshelf speakers under 1000 EUR Austriaβ Brave shopping/local search, with Serper as a later fallbackopen source alternatives to Linearβ Exa/Firecrawl OSS discoveryrecent RAG vs fine-tuning benchmark sourcesβ source-result discovery; the MCP host may synthesize from returned sources
Guarded providers can still be called explicitly. To let one participate in provider="auto", opt in:
web-search-plus-mcp config set-auto-allow parallel on
web-search-plus-mcp config set-auto-allow parallel off
web-search-plus-mcp config set-auto-allow donsetch on
web-search-plus-mcp config set-auto-allow donsetch offDevelopment
See CONTRIBUTING.md for project boundaries, portable-engine sync rules, provider requirements, security constraints, and pull-request expectations.
Run the same gates as CI:
python -m pip install --upgrade pip build
python -m pip install -e ".[test]"
python -m pytest tests/ -q -p no:cacheprovider
ruff check --config pyproject.toml .
python -m compileall -q web_search_plus_mcp tests
python scripts/gen_contract_v3_schemas.py --check
python -m buildThe GitHub Actions workflow runs the test suite on Python 3.10, 3.11, and 3.12, then verifies Ruff, byte-compilation, wheel creation, source-distribution creation, and wheel/sdist parity.
Credits
Thanks to LugMuad for the native Hermes integration proposal and testing in #125. That opt-in adapter ships in the Hermes plugin, not this MCP package.
Built on the Web Search Plus routing engine and packaged as a standalone MCP server.
License
MIT Β© 2026 robbyczgw-cla
Available Tools
2 toolsweb_extractB
Source-only URL extraction through 9 Web Search Plus v3 providers. Returns bounded page text, truncation warnings and stored-content references. Compact by default; detail='full' includes the complete v3 contract.
| Name | Required | Description | Default |
|---|---|---|---|
| urls | Yes | URLs to extract | |
| spans | No | Select deterministic semantic spans from extracted text. | |
| detail | No | Response detail: compact by default; full returns the complete v3 contract. Overrides the server default. | |
| format | No | markdown | |
| provider | No | auto | |
| render_js | No | ||
| spans_query | No | Optional query used to rank semantic spans. | |
| include_images | No | ||
| include_raw_html | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose real behavior: bounded page text, truncation warnings, stored-content references, and a compact-by-default response. It says nothing about provider fallback/rate limits, JS-rendering requirements, failure modes, or what 'source-only' excludes, which matters for a 9-param fetch 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?
Three short sentences, front-loaded with purpose then return behavior then the detail toggle. No padding, though the 'complete v3 contract' phrasing is vendor jargon that spends words without adding actionable meaning.
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?
No output schema exists, so the description's sketch of return values (bounded text, truncation warnings, stored-content references) is genuinely load-bearing. Against nine parameters, no annotations, and low schema coverage, however, the definition still leaves too much behavior and parameter meaning unstated to be called 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 only 44%, and the description only elaborates on 'detail' (already documented in the schema) plus the provider count. It leaves format, spans, spans_query, render_js, include_images and include_raw_html unexplained, so it does not compensate for the coverage 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?
Names a specific verb and resource: 'Source-only URL extraction through 9 Web Search Plus v3 providers.' An agent can distinguish it from web_search because it extracts from given URLs rather than discovering them, though the phrase 'source-only' is somewhat opaque and the sibling is never named.
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?
There is no explicit when-to-use or when-not-to-use statement and no mention of web_search as the alternative for discovery. The only signal is the implication that the tool operates on a caller-supplied URLs list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
web_searchB
Source-only web search through the Web Search Plus v3 runtime. Routes across configured source-result providers. Returns compact sources by default; detail='full' includes the complete v3 evidence and routing contract.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | normal fast path or opt-in research mode. | normal |
| count | No | Number of results | |
| depth | No | Exa depth: normal, deep multi-source search, or deep-reasoning. | normal |
| query | Yes | Search query | |
| detail | No | Response detail: compact by default; full returns the complete v3 contract. Overrides the server default. | |
| country | No | ISO 3166-1 alpha-2 country override (e.g. at, fr). | |
| language | No | ISO 639-1 language override (e.g. de), or auto via config defaults. | |
| no_cache | No | Bypass the search cache and fetch live results. Use for recency queries when a cached hit would be stale. | |
| provider | No | Force a specific provider, or use auto-routing. | auto |
| cache_ttl | No | Search-cache TTL in seconds. Default is 3600 if omitted. | |
| freshness | No | Unified recency filter alias for providers that support freshness. | |
| time_range | No | Recency filter. | |
| search_type | No | Search vertical. Serper and TinyFish serve news natively; other providers report unsupported metadata. | search |
| quality_report | No | Attach routing/result diagnostics. | |
| exclude_domains | No | Exclude these domains. | |
| include_domains | No | Restrict to these domains. | |
| research_time_budget | No | Best-effort budget for research mode. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose genuinely useful behavior beyond the schema: results are 'source-only', requests are routed across configured providers, and detail='full' expands the payload. However, it omits operationally significant traits an agent needs β that research mode is a long-running (up to 75s) best-effort call, that some providers silently don't support news/freshness, and that caching is on by default with a 3600s TTL.
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 short sentences, front-loaded with what the tool is and how output size is controlled. It loses a point because phrases like 'Web Search Plus v3 runtime' and 'v3 evidence and routing contract' are internal jargon that conveys little to a calling agent.
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?
This is a high-complexity tool: 17 parameters, 7 enums, multiple providers, two search modes and no output schema. The description does not describe the shape of a returned 'source', does not explain how provider auto-routing fails over or degrades, and does not address the research-mode latency tradeoff β substantial gaps given there are no annotations to lean on.
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 17 parameters including enums, defaults and ranges; the description is not required to compensate. Its only parameter reference ('detail=full includes the complete v3 evidence') merely restates the schema text, adding no new semantics.
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 ('web search') plus a meaningful qualifier ('source-only') that signals it returns raw sources rather than a synthesized answer. It never mentions the sibling web_extract or contrasts itself with it, so sibling differentiation is left implicit β the definition of a 4 rather than 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?
There is no when-to-use / when-not guidance: nothing says when to prefer web_search over web_extract, when to pick mode='research' versus the default fast path, or when forcing a specific provider is warranted. The only usage-adjacent sentence describes routing rather than decision criteria.
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.
2 tool updates
v5.1.6- Changed
web_extract1 field changed- added
Input schema / properties / detailAdded value: +{ + "description": "Response detail: compact by default; full returns the complete v3 contract. Overrides the server default.", + "enum": [ + "compact", + "full" + ], + "type": "string" +}
- Changed
web_search1 field changed- added
Input schema / properties / detailAdded value: +{ + "description": "Response detail: compact by default; full returns the complete v3 contract. Overrides the server default.", + "enum": [ + "compact", + "full" + ], + "type": "string" +}
1 tool update
v4.3.1- Changed
web_search2 fields changed- added
Input schema / properties / cache_ttlAdded value: +{ + "description": "Search-cache TTL in seconds. Default is 3600 if omitted.", + "maximum": 86400, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / no_cacheAdded value: +{ + "default": false, + "description": "Bypass the search cache and fetch live results. Use for recency queries when a cached hit would be stale.", + "type": "boolean" +}
2 tool updates
v4.0.2- Changed
web_extract1 field changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "tavily", - "exa", - "linkup", - "parallel", - "firecrawl", - "you", - "keenable", - "serper", - "hound" -]New value: +[ + "auto", + "tavily", + "exa", + "linkup", + "parallel", + "firecrawl", + "you", + "keenable", + "serper", + "donsetch" +]
- Changed
web_search1 field changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "serper", - "serpbase", - "brave", - "tavily", - "querit", - "linkup", - "exa", - "firecrawl", - "parallel", - "you", - "searxng", - "keenable", - "hound", - "octen", - "tinyfish" -]New value: +[ + "auto", + "serper", + "serpbase", + "brave", + "tavily", + "querit", + "linkup", + "exa", + "firecrawl", + "parallel", + "you", + "searxng", + "keenable", + "donsetch", + "octen", + "tinyfish" +]
1 tool update
v3.6.0- Changed
web_search2 fields changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "serper", - "serpbase", - "brave", - "tavily", - "querit", - "linkup", - "exa", - "firecrawl", - "parallel", - "you", - "searxng", - "keenable", - "hound", - "octen" -]New value: +[ + "auto", + "serper", + "serpbase", + "brave", + "tavily", + "querit", + "linkup", + "exa", + "firecrawl", + "parallel", + "you", + "searxng", + "keenable", + "hound", + "octen", + "tinyfish" +] - changed
Input schema / properties / search_type / descriptionPrevious value: -"Search vertical. Serper serves news natively; other providers report unsupported metadata."New value: +"Search vertical. Serper and TinyFish serve news natively; other providers report unsupported metadata."
2 tool updates
v3.3.1- Changed
web_extract3 fields changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "tavily", - "exa", - "linkup", - "parallel", - "firecrawl", - "you", - "keenable", - "serper" -]New value: +[ + "auto", + "tavily", + "exa", + "linkup", + "parallel", + "firecrawl", + "you", + "keenable", + "serper", + "hound" +] - added
Input schema / properties / spansAdded value: +{ + "default": false, + "description": "Select deterministic semantic spans from extracted text.", + "type": "boolean" +} - added
Input schema / properties / spans_queryAdded value: +{ + "description": "Optional query used to rank semantic spans.", + "type": "string" +}
- Changed
web_search1 field changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "serper", - "serpbase", - "brave", - "tavily", - "querit", - "linkup", - "exa", - "firecrawl", - "parallel", - "you", - "searxng", - "keenable" -]New value: +[ + "auto", + "serper", + "serpbase", + "brave", + "tavily", + "querit", + "linkup", + "exa", + "firecrawl", + "parallel", + "you", + "searxng", + "keenable", + "hound", + "octen" +]
1 tool update
- Changed
web_search2 fields changed- changed
Input schema / properties / depth / descriptionPrevious value: -"Exa depth: normal, deep synthesis, or deep-reasoning."New value: +"Exa depth: normal, deep multi-source search, or deep-reasoning." - changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "serper", - "serpbase", - "brave", - "tavily", - "querit", - "linkup", - "exa", - "firecrawl", - "parallel", - "perplexity", - "kilo-perplexity", - "you", - "searxng", - "keenable" -]New value: +[ + "auto", + "serper", + "serpbase", + "brave", + "tavily", + "querit", + "linkup", + "exa", + "firecrawl", + "parallel", + "you", + "searxng", + "keenable" +]
2 tool updates
v0.16.0- Changed
web_extract1 field changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "tavily", - "exa", - "linkup", - "parallel", - "firecrawl", - "you", - "keenable" -]New value: +[ + "auto", + "tavily", + "exa", + "linkup", + "parallel", + "firecrawl", + "you", + "keenable", + "serper" +]
- Changed
web_search4 fields changed- added
Input schema / properties / countryAdded value: +{ + "description": "ISO 3166-1 alpha-2 country override (e.g. at, fr).", + "type": "string" +} - added
Input schema / properties / freshnessAdded value: +{ + "description": "Unified recency filter alias for providers that support freshness.", + "enum": [ + "day", + "week", + "month", + "year" + ], + "type": "string" +} - added
Input schema / properties / languageAdded value: +{ + "description": "ISO 639-1 language override (e.g. de), or auto via config defaults.", + "type": "string" +} - added
Input schema / properties / search_typeAdded value: +{ + "default": "search", + "description": "Search vertical. Serper serves news natively; other providers report unsupported metadata.", + "enum": [ + "search", + "news" + ], + "type": "string" +}
2 tool updates
v0.13.0- Changed
web_extract1 field changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "tavily", - "exa", - "linkup", - "parallel", - "firecrawl", - "you" -]New value: +[ + "auto", + "tavily", + "exa", + "linkup", + "parallel", + "firecrawl", + "you", + "keenable" +]
- Changed
web_search1 field changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "serper", - "serpbase", - "brave", - "tavily", - "querit", - "linkup", - "exa", - "firecrawl", - "parallel", - "perplexity", - "kilo-perplexity", - "you", - "searxng" -]New value: +[ + "auto", + "serper", + "serpbase", + "brave", + "tavily", + "querit", + "linkup", + "exa", + "firecrawl", + "parallel", + "perplexity", + "kilo-perplexity", + "you", + "searxng", + "keenable" +]
1 tool update
v0.12.0- Changed
web_search1 field changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "serper", - "brave", - "tavily", - "exa", - "linkup", - "firecrawl", - "parallel", - "perplexity", - "kilo-perplexity", - "you", - "searxng", - "serpbase", - "querit" -]New value: +[ + "auto", + "serper", + "serpbase", + "brave", + "tavily", + "querit", + "linkup", + "exa", + "firecrawl", + "parallel", + "perplexity", + "kilo-perplexity", + "you", + "searxng" +]
2 tool updates
v0.9.0- Changed
web_extract1 field changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "tavily", - "exa", - "linkup", - "firecrawl", - "you" -]New value: +[ + "auto", + "tavily", + "exa", + "linkup", + "parallel", + "firecrawl", + "you" +]
- Changed
web_search1 field changed- changed
Input schema / properties / provider / enumPrevious value: -[ - "auto", - "serper", - "brave", - "tavily", - "exa", - "linkup", - "firecrawl", - "perplexity", - "kilo-perplexity", - "you", - "searxng", - "serpbase", - "querit" -]New value: +[ + "auto", + "serper", + "brave", + "tavily", + "exa", + "linkup", + "firecrawl", + "parallel", + "perplexity", + "kilo-perplexity", + "you", + "searxng", + "serpbase", + "querit" +]
2 tool updates
v0.8.0- Added
web_extract - Added
web_search
2 tool updates
v0.7.0- Removed
web_extract - Removed
web_search
TDQS
Scored across 2 tools
The two tools have clearly distinct purposes: web_search finds sources via providers, while web_extract pulls content from a specific URL. There is no meaningful overlap in intent or expected inputs.
Both names follow a consistent web_<verb> snake_case pattern that directly reflects their actions. The convention is predictable and easy for an agent to infer.
Two tools is thin for a server that also exposes provider routing and detail modes, even if the core surface is intentionally focused. It is borderline rather than clearly over- or under-scoped.
Search and extraction cover the primary web-research workflow without dead ends. Minor gaps exist around batch operations or provider introspection, but agents can work around them.
Maintenance
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yoβ¦
Free web search for AI agents. No API key required. Hosted MCP in active development.
Multi-engine search for AI agents. Trust scoring, local corpus, MCP-native. Self-hostable, BYOK.
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.
Related MCP Servers
- AlicenseAqualityAmaintenanceπ A Model Context Protocol (MCP) server providing unified access to multiple search engines (Tavily, Brave, Kagi), AI tools (Perplexity, FastGPT), and content processing services (Jina AI, Kagi). Combines search, AI responses, content processing, and enhancement features through a single interface.3256 npm358MIT
- AlicenseAqualityDmaintenanceA Model Context Protocol server that enables web search, scraping, crawling, and content extraction through multiple engines including SearXNG, Firecrawl, and Tavily.4187 npm147MIT
- AlicenseBqualityDmaintenanceA Model Context Protocol server that enables AI assistants to perform web searches using SearXNG, a privacy-respecting metasearch engine.143MIT
- AlicenseNot gradedqualityCmaintenanceA production-ready Model Context Protocol server that brings AI-powered web search directly into development environments, providing intelligent search results with proper citations in Claude Desktop, Cursor, or any MCP-compatible client.131 npm22MIT