Skip to main content
Glama

free-search-mcp

License Python MCP

这是一个本地优先、无需 API 密钥的 Model Context Protocol (MCP) 服务器,它赋予任何 LLM(Claude、GPT、本地 Ollama 等)搜索网络、抓取并清理页面以及阅读文档的能力——无需您注册任何搜索 API。

它将多个开源 MCP 的最佳理念整合到一个 Python 包中,并增加了它们所缺失的 LLM 人机工程学和可靠性功能。

research("how does reciprocal rank fusion work", depth=3)
   ↓
# Research brief: how does reciprocal rank fusion work
_engines: duckduckgo, mojeek, startpage · sources: 3 · ~3,400 tokens_

## Sources
- [1] Reciprocal rank fusion | Elasticsearch Reference — <https://…>
- [2] Hybrid Search Scoring (RRF) | Microsoft Learn — <https://…>
- [3] RRF explained in 4 mins — Medium — <https://…>

## Documents
…full Markdown bodies of each page, ready for the LLM to read…

一次工具调用。三个来源。无需 API 密钥。没有类似 OPENAI_API_KEY 的搜索服务收费陷阱。


为什么存在这个项目

现有的搜索 MCP 各有千秋,但你通常需要它们的所有功能:

多引擎

无需 API 密钥

智能回退

PDF/DOCX

FTS5 缓存

过滤器

Trafilatura

LLM 调优

nickclyde/duckduckgo-mcp-server

~

mrkrsl/web-search-mcp

~

Aas-ee/open-webSearch

~

~

VincentKaufmann/noapi-google-search-mcp

~

free-search-mcp

此处的“LLM 调优”意味着:以 Markdown 为先的输出、Token 估算、段落边界处的智能截断、模型用于选择正确工具的“适用场景/不适用场景/返回内容/常见错误”文档字符串、可操作的错误提示、MCP 提示词和资源模板,以及将搜索→抓取→抓取→抓取合并为单次交互的 research() 工具。

“Trafilatura”意味着我们使用 trafilatura 提取主要内容——它是 Bevendorff 2023 ROUGE 基准测试的获胜者(约 0.85,而简单的样板剥离约为 0.55)。每个抓取的页面还会免费返回 author(作者)、published_date(发布日期)和 sitename(站点名称)。

“过滤器”意味着搜索/研究功能接受 freshness(新鲜度)、include_domains(包含域名)、exclude_domains(排除域名)、category(类别,如 news/pdf/github/paper/forum/blog)、include_text(包含文本)、exclude_text(排除文本)。


Related MCP server: uvxwebsearchmcp

工具

工具

描述

search(query, engines?, max_results?, use_cache?, max_age_hours?, freshness?, include_domains?, exclude_domains?, category?, include_text?, exclude_text?, format?)

通过倒数排名融合 (RRF) 合并的并行多引擎搜索

research(question, depth?, engines?, fetch?, use_cache?, max_age_hours?, freshness?, include_domains?, exclude_domains?, category?, include_text?, exclude_text?, format?)

一次性:搜索 + 抓取前 N 个结果 + 返回 Markdown 简报

fetch(url, render?, force_refresh?, max_age_hours?, format?)

抓取页面,返回阅读模式的 Markdown(经 trafilatura 提取,包含作者/日期/站点名)

fetch_batch(urls, render?, format?)

并发多 URL 抓取

read_doc(source, start?, length?, format?)

解析带分页的 PDF / DOCX / HTML / TXT / MD

cache_search(query, limit?, format?)

对之前抓取的页面进行 FTS5 搜索

engines()

列出 search 可用的引擎名称

此外还有 2 个 MCP 提示词Research thoroughlyFact-check claim)和一个 资源模板 (cache://page/{url}),用于将缓存页面拖回上下文而无需重新抓取。

过滤器 (search / research)

参数

效果

freshness

day / week / month / year

仅限最近 N 时间内的结果

include_domains

["python.org", "djangoproject.com"]

限制在这些域名内

exclude_domains

["pinterest.com"]

排除这些域名

category

news / pdf / github / paper / forum / blog

内容类型快捷方式(paper = arxiv/acm/ieee/…,forum = reddit/HN/SE 等)

include_text

"async"

标题/摘要中必须包含的子字符串

exclude_text

"beginner"

禁止包含的子字符串

max_age_hours

24

覆盖此调用中 7 天的默认缓存 TTL

所有工具默认使用 format="markdown" —— 可读性强,比 JSON 少约 40% 的 Token,并带有来源和 Token 预算头信息。传入 format="json" 可进行结构化访问。

工具注解

每个工具都附带正确的 readOnlyHintidempotentHintopenWorldHint 注解,以便 MCP 客户端可以标记它们并控制高权限操作。

引擎

默认集合(全部可靠,重复调用时无验证码): duckduckgo, mojeek, startpage

可选(对无头客户端有间歇性挑战): brave, bing, baidu

Brave/Bing/Baidu 在多次调用后都会拦截无头浏览器(PoW 验证码、“出错了”页面、重定向包装器)。仅在默认引擎无法找到所需内容时才传入 engines=["brave"] 等。


安装

git clone https://github.com/ymylive/free-search-mcp.git
cd free-search-mcp
uv sync
uv run playwright install chromium

作为独立服务器运行(stdio 传输):

uv run search-mcp

运行实时测试(访问真实网络——设置环境变量):

SEARCH_MCP_TEST_NETWORK=1 uv run pytest -v

离线测试默认运行,不触及网络。


连接到 Claude Desktop

将其添加到 ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) 或您平台上的等效位置:

{
  "mcpServers": {
    "search": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/free-search-mcp", "run", "search-mcp"]
    }
  }
}

重启 Claude Desktop。上述七个工具将出现在工具抽屉中。

连接到其他客户端

该服务器通过 stdio 使用标准的 MCP 协议。任何支持 MCP 的客户端均可工作:

  • Claude Code (claude mcp add search uv --directory /…/free-search-mcp run search-mcp)

  • Cursor / Continue / Cline (使用上面的 JSON 片段)

  • 通过官方 MCP SDK 的自定义 Python / TypeScript 客户端


配置

所有设置都可以通过以 SEARCH_MCP_ 为前缀的环境变量覆盖:

变量

默认值

含义

SEARCH_MCP_DEFAULT_ENGINES

["duckduckgo","mojeek","startpage"]

JSON 列表

SEARCH_MCP_MAX_RESULTS_PER_ENGINE

10

SEARCH_MCP_RATE_LIMIT_PER_MINUTE

30

每个引擎

SEARCH_MCP_FETCH_RATE_LIMIT_PER_MINUTE

20

共享 fetch

SEARCH_MCP_CACHE_DIR

~/.cache/search-mcp

SEARCH_MCP_CACHE_TTL_SECONDS

604800

7 天

SEARCH_MCP_FETCH_STRATEGY

auto

auto / http / browser

SEARCH_MCP_BROWSER_HEADLESS

true

SEARCH_MCP_BROWSER_POOL_SIZE

2

并发页面

SEARCH_MCP_MAX_CONTENT_CHARS

50000

每个结果的截断长度


架构

   ┌─────────────────────────────────────────────────────┐
   │  FastMCP server (stdio)                             │
   │  tools: search / research / fetch / fetch_batch /   │
   │         read_doc / cache_search / engines           │
   └────────────┬────────────────────────────────────────┘
                │
   ┌────────────▼────────────┐  ┌────────────────────────┐
   │  aggregator             │  │  fetcher               │
   │  - parallel engines     │  │  - httpx fast path     │
   │  - reciprocal rank      │  │  - playwright fallback │
   │    fusion               │  │  - markdownify         │
   │  - search cache (FTS5)  │  │  - page cache (FTS5)   │
   └────┬────────────────────┘  └────────────┬───────────┘
        │                                    │
   ┌────▼─────────────────┐  ┌──────────────▼─────────────┐
   │  engines/            │  │  browser pool              │
   │   duckduckgo.py      │  │   - persistent context     │
   │   mojeek.py          │  │   - stealth init script    │
   │   startpage.py       │  │   - shared cookies         │
   │   brave.py     (opt) │  │   - semaphore-bounded pages│
   │   bing.py      (opt) │  └────────────────────────────┘
   │   baidu.py     (opt) │
   └──────────────────────┘

   ┌────────────────────────────┐    ┌──────────────────┐
   │  documents/                │    │  ratelimit       │
   │   pypdf, python-docx,      │    │   token bucket   │
   │   markdownify              │    │   per engine     │
   └────────────────────────────┘    └──────────────────┘

   ┌────────────────────────────┐    ┌──────────────────┐
   │  formatting                │    │  research        │
   │   token estimate           │    │   composed       │
   │   smart truncation         │    │   workflow       │
   │   markdown renderers       │    │                  │
   └────────────────────────────┘    └──────────────────┘

引擎适配器模式

src/search_mcp/engines/ 中的每个引擎都实现了:

class Engine:
    name: str
    needs_browser: bool          # Force Playwright?
    wait_selector: str | None    # CSS to wait for in browser mode

    def build_url(self, query: str, max_results: int) -> str: ...
    def parse(self, html: str) -> list[SearchResult]: ...

基类处理传输(httpx → Playwright 回退)、速率限制,以及 HTTP 返回验证码外壳而非结果的情况(通过浏览器自动重试)。


致谢

本项目站在巨人的肩膀上:


许可证

MIT — 见 LICENSE

Available Tools

10 tools
compareCompare URLs side-by-sideA
Read-onlyIdempotent

Fetch 2-5 URLs concurrently and return per-URL excerpts so the LLM can compare them against a single question in one round trip.

Best for:
- Side-by-side product/feature/article comparisons.
- "Compare X to Y" or "How does A differ from B" queries.
- Triangulating a fact across multiple sources.

Not recommended for:
- >5 URLs -> use `fetch_batch`.
- 1 URL -> use `fetch`.
- Don't have URLs yet -> use `search` or `research` first.

Returns:
- markdown (default): a comparison brief with per-URL sections, each
  containing title, sitename, published date, and a smart-truncated excerpt.
- json: {question, urls, excerpts:[{url, title, excerpt, ...}],
  tokens_estimated}.

Common mistakes:
- Asking `compare` to actually answer the question — it returns material,
  the LLM does the comparison.
- Passing >5 URLs and expecting them all to fit in context — use
  `fetch_batch` for bulk reads.

Args:
    question: The comparison question the LLM will answer using the
        returned excerpts.
    urls: 2-5 absolute http(s) URLs.
    format: "markdown" (default) or "json".
ParametersJSON Schema
NameRequiredDescriptionDefault
urlsYes
formatNomarkdown
questionYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

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

Even with annotations declaring readOnlyHint and idempotentHint, the description adds valuable behavioral context: concurrent fetching, smart truncation, returned formats (markdown/json), tokens_estimated, and the common mistake that `compare` does not itself answer the question. No contradictions 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.

Conciseness5/5

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

The description is long but every sentence earns its place. It is structured with clear sections (Best for, Not recommended for, Returns, Common mistakes, Args), making it scannable and informative without redundancy.

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

Completeness5/5

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

For a tool with 3 parameters and an output schema, the description covers all necessary context: use cases, limits, return formats, and common pitfalls. It is fully self-contained and an agent can invoke it correctly without needing external information.

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

Parameters5/5

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

Schema description coverage is 0%, but the description fully compensates with an 'Args' section explaining each parameter, including the default for `format`, the 2-5 URL constraint, and that `question` is the comparison question. This adds meaning well beyond the bare schema.

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

Purpose5/5

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

The description leads with a specific verb+resource+scope: 'Fetch 2-5 URLs concurrently and return per-URL excerpts'. It clearly differentiates from siblings by explicitly naming use cases and not-recommended cases, such as using fetch_batch for >5 URLs and fetch for 1 URL.

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

Usage Guidelines5/5

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

Usage guidance is exemplary: it lists exact scenarios for use ('Compare X to Y', 'Triangulating a fact') and explicitly names alternatives (fetch_batch, fetch, search, research) with conditions. This leaves no ambiguity about when to invoke this tool.

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

downloadDownload a file to diskA
Idempotent

Save a file from a URL to a local, auto-expiring download directory.

Downloads are enabled by default and saved under
`SEARCH_MCP_CACHE_DIR/downloads`. Set `SEARCH_MCP_DOWNLOAD_ENABLED=false`
to disable them or `SEARCH_MCP_DOWNLOAD_DIR` to override the destination.

Best for:
- Keeping an actual file (installer, dataset, archive, image) rather than
  its text.
- Handing a path to another tool that needs a real file on disk.

Not recommended for:
- Reading a document's contents -> use `read_doc`, which parses it without
  touching the filesystem.
- Looking at a web page -> use `fetch`.
- Viewing an image -> use `fetch(inline=True)`.

Returns:
- markdown (default): where the file was saved, its size and type.
- json: {url, saved_path, media_type, bytes_size, sha256, expires_in_hours}.
  An expires_in_hours value of 0 means TTL cleanup is disabled.

Retention: files older than SEARCH_MCP_DOWNLOAD_TTL_HOURS (default 24) are
deleted before the next download and at startup. A value of 0 disables TTL
cleanup. Otherwise, treat the path as short-lived and copy it elsewhere if
you need to keep it.

Args:
    url: Absolute http(s) URL of the file to save.
    format: "markdown" or "json".
ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

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

The description discloses important behavioral details beyond annotations: auto-expiring directory, TTL cleanup, environment variable overrides, and the JSON return format including sha256 and expires_in_hours. It clearly states files are short-lived and advises copying if persistence is needed, which is valuable context for agents.

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

Conciseness5/5

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

The description is well-structured with a clear opening sentence, bullet-like 'Best for' and 'Not recommended for' sections, and a concise 'Args' list. Every section adds value without redundancy, and the most critical information is front-loaded.

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

Completeness5/5

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

The description covers purpose, configuration, retention behavior, return formats, and alternative tools. It also addresses the open-world aspect (external URLs) and idempotency implicitly. Given the output schema exists, the description still enriches context with environment variables and cleanup schedules, making it complete for an AI agent.

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

Parameters5/5

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

Although the schema has no descriptions for parameters, the description compensates fully by documenting 'url: Absolute http(s) URL' and 'format: markdown or json'. It also explains the default format and the different return structures for each, adding semantics beyond the schema.

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

Purpose5/5

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

The description clearly states the tool's function: 'Save a file from a URL to a local, auto-expiring download directory.' It distinguishes itself from siblings by listing alternatives like read_doc and fetch for other use cases.

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

Usage Guidelines5/5

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

The description provides explicit 'Best for' and 'Not recommended for' sections, naming specific alternatives (read_doc, fetch, fetch(inline=True)) and explaining when to use each. This leaves no ambiguity about when to select this tool.

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

enginesList available search enginesA
Read-onlyIdempotent

List engine names accepted by the engines= parameter of search / research.

Best for:
- Discovering what's installable before passing a non-default engine.
- Building user-facing UIs that let humans pick engines.

Not recommended for:
- Calling on every search — the list is static; cache it.

Returns:
- The live, complete list of engine name strings. The buckets below are
  illustrative; always trust the returned list over this doc.

Common mistakes:
- Passing one of these names as a query to `search` — they go in the
  `engines=` argument, not `query`.
- Passing a key-only engine (brave_api/serper/tavily/google_cse) with no key
  configured — it returns an actionable error, not results.

Defaults: duckduckgo + mojeek + googlenews + bing (reliable, all-HTTP,
          low-latency; googlenews is an RSS index with structured publish
          dates and its URLs resolve to the real publisher on
          fetch/research; bing's www4 edge answers in ~0.3s).
Keyless opt-in: google + serpsearch (Google SERP scrapers, HTTP-first),
          anysearch (JSON aggregator), startpage (browser-rendered, slower),
          brave (PoW captcha after a few calls), baidu
          (CN index), bilibili (CN video), zhihu (CN Q&A, often login-gated),
          sogou + so360 (CN indexes; sogou returns redirect URLs),
          wikipedia (encyclopedia, follows SEARCH_MCP_REGION language),
          openlibrary (books),
          searx (public-instance meta-search; set SEARCH_MCP_SEARX_INSTANCES
          if it returns nothing).
Vertical (auto-selected by `category`, see below): arxiv, openalex,
          crossref, pubmed (papers); github, stackexchange, hackernews
          (code and developer discussion); gdelt (worldwide news).
Key-required (configure via admin UI / SEARCH_MCP_*_API_KEY): brave_api,
          serper, tavily, google_cse, github_code (GitHub rejects anonymous
          code search).

You usually do NOT need to pass `engines=` for these. Passing `category=`
to `search`/`research` routes the query to the sources that natively index
it — `category="paper"` actually queries arXiv/OpenAlex/Crossref instead of
filtering general web results by hostname. Naming engines explicitly turns
that routing off.
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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

Building on the readOnly and idempotent annotations, the description adds substantial behavioral detail: the list is live and complete, buckets are illustrative, the tool may return an actionable error for key-only engines with no key, and engine results are static/cacheable. It also discloses operational nuances like HTTP-first behavior and captcha issues, which go far beyond the annotation hints.

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

Conciseness4/5

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

The description is long but well-structured with clear section labels ('Best for', 'Not recommended for', 'Returns', 'Common mistakes', and engine category groupings). The core purpose is front-loaded, and while the engine-by-engine details are extensive, they are substantive and directly useful for selecting the right engine. A minor deduction for slightly verbose enumeration that could be partly externalized.

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

Completeness5/5

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

For a simple listing tool, the description is remarkably complete: it explains the return type, provides defaults, keyless opt-ins, verticals, key-required engines, common mistakes, and sibling relationships. The output schema exists, but the description still covers behavior and integration context, making it fully self-sufficient.

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

Parameters4/5

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

The tool has zero parameters, so the input schema is empty and the description needs no parameter explanation. It earns the baseline 4 by clearly explaining the meaning and usage of the returned values (engine name strings) in the context of other tools, even though an output schema exists. It adds value by clarifying how these names are consumed by `search` and `research`.

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

Purpose5/5

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

The description opens with a crisp, specific statement: 'List engine names accepted by the `engines=` parameter of `search` / `research`.' This uses a clear verb+resource and immediately distinguishes this tool from sibling search/fetch tools by focusing on engine name discovery. It answers both what and why.

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

Usage Guidelines5/5

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

The description explicitly states when to use ('Best for: Discovering what's installable before passing a non-default engine', 'Building user-facing UIs') and when not (not for calling on every search, cache it). It also details the alternative of using `category=` with `search`/`research` instead of explicit engines, giving clear, actionable guidance.

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

extract_structuredExtract structured data from a URLA
Read-onlyIdempotent

Pull JSON-LD, OpenGraph, Twitter cards, and microdata from a web page.

Best for:
- Product pages (price, currency, availability, brand, rating).
- Article pages (author, publish date, image, headline).
- Recipe / event / video pages where rich metadata IS the answer.
- Cases where `fetch` returns prose but you need fields.

Not recommended for:
- Just reading a page -> use `fetch`.
- PDFs / DOCX -> use `read_doc`.
- Pages that don't publish schema.org metadata (most blogs) — you'll get
  empty lists; fall back to `fetch`.

Returns:
- json: {url, json_ld:[], microdata:[], opengraph:[], rdfa:[]}. Twitter
  card meta tags are surfaced inside the `opengraph` list.
- markdown (default): a flattened key/value view with each block printed
  as a JSON code block under its syntax heading.

Common mistakes:
- Calling on every URL "just in case" — most sites have no structured
  data, and `fetch` is what you actually want.

Args:
    url: Absolute http(s) URL.
    format: "markdown" (default) or "json".
ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

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

The description provides rich behavioral context beyond the annotations: it details the exact return shape (`json` and `markdown` views), notes that Twitter cards are surfaced inside the `opengraph` list, and warns that pages without schema.org metadata will yield empty lists. This is far more than the read-only/idempotent hints already convey.

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

Conciseness5/5

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

The description is well-structured with clear section headers, bullet lists, and a compact Args section. Every sentence earns its place — the length is justified by the need to convey use cases, return formats, and common pitfalls without redundancy.

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

Completeness5/5

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

Despite the moderate complexity, the description covers purpose, usage guidelines, return formats, behavior on empty results, and parameter semantics. It also cross-references sibling tools appropriately. With an output schema present, the description doesn't need to repeat return type details, but it still explains the two output formats clearly.

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

Parameters5/5

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

Schema description coverage is 0%, but the description fully compensates: it specifies that `url` must be an absolute http(s) URL, and explains `format` options (markdown default vs json) with context from the Returns section. This adds meaning that the raw schema (type + enum) does not provide.

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

Purpose5/5

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

The description starts with 'Pull JSON-LD, OpenGraph, Twitter cards, and microdata from a web page' — a specific verb and resource that clearly states what the tool does. It also explicitly contrasts with sibling tools, noting when to use `fetch` or `read_doc` instead, which fully distinguishes it from alternatives.

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

Usage Guidelines5/5

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

The 'Best for' and 'Not recommended for' sections give explicit use cases with concrete page types and explicit fallback alternatives. The 'Common mistakes' section further clarifies when not to use the tool, providing strong usage guidance beyond mere capability.

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

fetchFetch a URL: page text, document, or resourceA
Read-onlyIdempotent

Fetch one URL: page text, or a description of a non-text resource.

Handles any http(s) resource, not just HTML:
- HTML pages -> reader-mode Markdown (nav/footer/scripts stripped).
- PDF/DOCX/XLSX/PPTX/EPUB/CSV/code/archives -> parsed text (same engine as
  `read_doc`, which you should prefer when you need pagination).
- Images, video, audio, fonts, opaque binaries -> a description
  (media type, byte size, dimensions, sha256), NOT the bytes.

Best for:
- You already have a URL (from `search`, the user, or your own knowledge)
  and need the actual page text.
- Verifying a single claim by reading the source.
- Checking what a resource IS before deciding to spend tokens on it.

Not recommended for:
- Multiple URLs at once -> use `fetch_batch` (concurrent, one round-trip).
- "Search then read top N" -> use `research` (one call, not two).
- Long documents you need to page through -> use `read_doc` (start/length).
- You don't have a URL yet -> use `search` first.

Returns:
- markdown (default): a small header (URL, render method, token count)
  plus the cleaned page body.
- json: {url, title, content, method, truncated, tokens_estimated,
  author, published_date, sitename}, plus {media_type, bytes_size, sha256,
  width, height} for non-text resources.
- With `inline=True` on an image: the image itself, viewable by a
  vision-capable model.

Common mistakes:
- Passing a search query instead of a URL.
- Using `render="http"` on a JS-only SPA — it returns near-empty content;
  use "auto" (default) or "browser".
- Setting `inline=True` on a large image out of habit. A 1MB image costs
  well over a thousand tokens; fetch it plainly first and inline only if
  the description says it's worth looking at.
- Forgetting that results are cached 7 days — use `force_refresh=True`
  or `max_age_hours=0` for a fresh pull.

Args:
    url: Absolute http(s) URL.
    render: "auto" (try HTTP, fall back to stealth Chromium), "http"
        (fast, fails on JS), "browser" (slow, robust).
    force_refresh: Bypass the page cache entirely.
    max_age_hours: Treat cached pages older than this as a miss. 0 = same
        as force_refresh. None = server default TTL (7 days).
    inline: For images only — return the image itself instead of a
        description, so a vision-capable model can see it. Ignored for
        text resources.
    format: "markdown" or "json".
ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
formatNomarkdown
inlineNo
renderNoauto
force_refreshNo
max_age_hoursNo

TDQS

A5/5.0
Behavior5/5

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

Beyond the readOnlyHint annotations, the description discloses significant behavioral details: rendering modes (auto/http/browser) and their tradeoffs, parsing behavior for different file types, a 7-day cache with force_refresh/max_age_hours controls, token cost implications of inline images, and common mistakes like using render='http' on SPAs.

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

Conciseness5/5

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

The description is long but excellently structured with headers, bullet lists, and short paragraphs. Every sentence adds functional value—no filler—and the front-loaded summary plus examples make it easy to scan.

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

Completeness5/5

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

Despite lacking an output schema, the description fully specifies return formats (markdown/json), non-text resource details, error-prone scenarios, and parameter semantics. It covers all necessary context for correct invocation, making it complete for a complex tool.

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

Parameters5/5

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

Since the input schema has zero description coverage, the description fully compensates with an 'Args' section that explains each of the 6 parameters, including defaults, allowed values, and specific behavior (e.g., inline ignored for text resources, max_age_hours semantics). This goes far beyond the schema.

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

Purpose5/5

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

The description opens with 'Fetch one URL: page text, or a description of a non-text resource,' providing a specific verb and resource. It also distinguishes itself by covering multiple resource types and hinting at its relationship with siblings like fetch_batch and read_doc.

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

Usage Guidelines5/5

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

Explicit 'Best for' and 'Not recommended for' sections name direct alternatives (fetch_batch, research, read_doc, search) and outline precise scenarios, such as verifying a single claim versus searching and reading top N.

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

fetch_batchFetch many URLs concurrentlyA
Read-onlyIdempotent

Fetch a list of URLs in parallel. Per-URL failures do not raise.

Best for:
- 2+ URLs you want to read in one round-trip.
- Reading the top N results of a previous `search` call.

Not recommended for:
- A single URL -> `fetch` (no list-wrapping overhead).
- "Search and then read" -> `research` collapses both into one tool call.
- PDFs/DOCX -> `read_doc` per file.

Returns:
- markdown (default): each page rendered as a Markdown section, separated
  by horizontal rules; failed URLs become inline error notes.
- json: list[dict], one entry per URL, with `error` set on failures.

Common mistakes:
- Passing a single URL inside a 1-element list — use `fetch` directly.
- Assuming an exception means the whole batch failed; check each item's
  `error` field instead.

Args:
    urls: List of absolute http(s) URLs (max 20 per call).
    render: Same as `fetch`.
    format: "markdown" or "json".
ParametersJSON Schema
NameRequiredDescriptionDefault
urlsYes
formatNomarkdown
renderNoauto

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

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

Beyond annotations (readOnlyHint, idempotentHint), the description discloses key behaviors: per-URL failures do not raise, failed URLs appear as inline error notes in markdown or error fields in JSON, and the max batch size of 20. This enriches the agent's understanding of edge cases.

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

Conciseness5/5

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

Though moderately long, the description is well-structured with clear sections (Best for, Not recommended for, Returns, Common mistakes, Args). Every sentence provides actionable information, and there is no redundant repetition of schema or annotations.

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

Completeness5/5

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

This is a complex tool with multiple parameters, error semantics, and alternatives. The description covers batch limits, error handling, return formats, render behavior, and sibling distinctions. With an output schema already present, the extra return-value detail is a bonus, making the description complete for an AI agent.

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

Parameters5/5

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

The schema has 0% description coverage, but the description fully compensates with an Args section explaining each parameter: `urls` (absolute http(s), max 20), `render` (same as fetch), and `format` (markdown or json). It also clarifies the output behavior tied to format.

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

Purpose5/5

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

The description clearly states 'Fetch a list of URLs in parallel' with a specific verb and resource. It distinguishes itself from siblings by explicitly saying when to use `fetch` (single URL), `research` (search+read), and `read_doc` (PDFs/DOCX).

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

Usage Guidelines5/5

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

Provides explicit 'Best for' and 'Not recommended for' sections that name alternatives (`fetch`, `research`, `read_doc`). This gives the agent clear decision rules for tool selection.

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

read_docRead a remote (or sandboxed local) documentA
Read-onlyIdempotent

Read an http(s) document (or a sandboxed local file) into Markdown.

Best for:
- Remote PDFs and DOCX from an http(s) URL (parsed locally, no remote API).
- Local PDF/DOCX/text/Markdown files — ONLY when local reads are enabled
  (see Security below).
- Paginating through a long document via `start` / `length`.

Not recommended for:
- Arbitrary HTML web pages -> `fetch` does reader-mode cleanup that this
  tool does not.
- Pages discovered through search -> `fetch` or `research`.

Security (local files are sandboxed and OFF by default):
- Local-file reads are DISABLED unless the server operator sets the
  SEARCH_MCP_DOCUMENT_ROOT env var to a directory. With it unset, a local
  path raises a "local file reads are disabled" error — pass an http(s)
  URL instead, or ask the operator to enable the sandbox.
- When enabled, `source` must resolve INSIDE that root; relative paths
  resolve against the root (not the process CWD) and any `..` traversal
  that escapes the root is rejected. `file://` URLs are always rejected.
- Remote http(s) sources are unaffected by this setting.

Returns:
- markdown (default): rendered document text with a small header.
- json: {content, title, format, total_chars, start, returned_chars,
  truncated}. Use `total_chars` and `returned_chars` to drive pagination.

Common mistakes:
- Calling this on a normal article URL — you'll get raw HTML noise; use
  `fetch` instead.
- Forgetting to advance `start` when paginating: next call should pass
  `start = previous_start + returned_chars`.
- Passing a negative `length` (raises an error) or a `start` past the end
  (clamped to EOF: you'll get `returned_chars == 0`, `start == total_chars`,
  and `truncated == False` — that's the signal you've paged off the end).

Args:
    source: http(s) URL, or a local path UNDER SEARCH_MCP_DOCUMENT_ROOT when
        local reads are enabled (disabled by default — see Security).
    start: Character offset to begin reading from. Default 0. Clamped into
        [0, total_chars]; a negative value is treated as 0.
    length: Max characters to return; None = read to end (still capped by
        the per-call max content size). Must be >= 0 — a negative length
        is rejected with a ValueError.
    format: "markdown" or "json".
ParametersJSON Schema
NameRequiredDescriptionDefault
startNo
formatNomarkdown
lengthNo
sourceYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

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

Annotations already declare read-only, idempotent, and open-world hints, but the description adds substantial behavioral detail: local-file sandboxing, environment variable gating, file:// rejection, path traversal protection, clamping behavior for start/length, and the exact signals for paging off the end. 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.

Conciseness5/5

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

The description is long but every section earns its place: Best-for/Not-recommended, Security, Returns, Common mistakes, and Args. Information is front-loaded with the core verb+resource first, and the structure makes it easy to scan. No redundancy or filler.

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

Completeness5/5

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

Despite having an output schema, the description still explains the json format fields and pagination signals. It fully covers the tool's complexity: security sandbox, env var dependency, error conditions, sibling differentiation, and parameter semantics. Nothing important is left ambiguous for a tool with this many nuances.

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

Parameters5/5

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

Schema has 0% description coverage, so the description must fully explain parameters. The 'Args' section does this thoroughly: source (URL vs local path, security constraints), start (offset, clamping, negative handled as 0), length (None means to end, must be >= 0, ValueError on negative), and format (markdown vs json). Goes far beyond the schema's bare types and defaults.

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

Purpose5/5

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

The description clearly states the tool reads http(s) documents or sandboxed local files into Markdown. It distinguishes itself from siblings by explicitly noting it is not for arbitrary HTML pages (use fetch) or search-discovered pages (use fetch/research).

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

Usage Guidelines5/5

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

Provides explicit 'Best for' and 'Not recommended for' sections with named alternatives (fetch, research). Also includes critical usage context like when local reads are enabled and how pagination should work.

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

researchSearch and read in one callA
Read-only

One-shot research: search the web, fetch the top results, return both.

Best for:
- Open-ended questions that need finding sources AND reading them
  ("what's new with X", "summarize the controversy around Y").
- Replacing a `search` + N x `fetch` chain with one call.
- Producing a citable brief with [n]-style source references.

Not recommended for:
- You only need links -> `search` (cheaper, no fetching).
- You only need to read one URL you already have -> `fetch`.
- You want to query previously-fetched cached pages -> `cache_search`.

Returns:
- markdown (default): a "Research brief" with a Sources index then the
  full Markdown body of each fetched document, separated by horizontal
  rules; includes a token estimate.
- json: {question, engines, sources:[{rank,title,url,snippet,...}],
  documents:[...], tokens_estimated, errors}.

Common mistakes:
- Using `depth=8` for a quick lookup — that's 8 page fetches; 2-3 is
  almost always enough.
- Calling `research` for a known URL — that's `fetch` territory.
- Forgetting that `fetch=False` returns sources only (much cheaper if
  the LLM only needs to pick which one to read).

Args:
    question: What you want to know, in natural language.
    depth: How many top results to fetch (1-8). 3 is a good default.
    engines: Override the engine set (see `engines()` for names).
    fetch: If False, return source list without reading them.
    use_cache: Reuse cached search/page data within TTL.
    max_age_hours: Treat cached search results AND cached page bodies older
        than this as a read miss; fresh data is always written back. 0 =
        force-refresh both the engine search and every fetched page body;
        None = server default TTL (7 days). A non-zero value is honored for
        both halves (it used to be ignored for anything but 0).
    format: "markdown" or "json".
ParametersJSON Schema
NameRequiredDescriptionDefault
depthNo
fetchNo
formatNomarkdown
enginesNo
categoryNo
questionYes
freshnessNo
use_cacheNo
exclude_textNo
include_textNo
max_age_hoursNo
exclude_domainsNo
include_domainsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the spartan annotations, the description discloses cache write-back behavior, TTL semantics for `max_age_hours`, return format details, token estimation, and failure-prone usage patterns. It even notes a historically surprising behavior (non-zero `max_age_hours` now applies to both search and pages), adding real transparency.

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

Conciseness5/5

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

The description is long, but it is highly structured with scannable headings, bullets, and a clear linear flow. Every section adds distinct value: purpose, use cases, exclusions, return format, common mistakes, and parameter details. The length is justified by the tool's complexity and parameter count.

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

Completeness4/5

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

Given the tool's complexity, the description covers purpose, usage boundaries, output formats, and parameter behavior well, and the output schema exists to formalize return values. Still, the description omits several parameters (e.g., `category`, `freshness`, domain filters), which leaves some operational gaps for an agent trying to use the full feature set.

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

Parameters4/5

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

Schema description coverage is 0%, so the description carries the burden. It explains `question`, `depth`, `engines`, `fetch`, `use_cache`, `max_age_hours`, and `format` with actionable detail, but leaves `category`, `freshness`, `exclude_text`, `include_text`, `exclude_domains`, and `include_domains` unexplained. The covered parameters are handled very well, but the six omitted ones are a clear gap.

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

Purpose5/5

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

The description states a specific verb+resource: 'search the web, fetch the top results, return both.' It clearly distinguishes this tool from siblings by framing it as a combined search-and-fetch operation, with the title 'Search and read in one call' reinforcing the purpose.

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

Usage Guidelines5/5

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

The description provides explicit 'Best for' and 'Not recommended for' sections, naming concrete alternatives: `search`, `fetch`, and `cache_search`. It also includes common mistakes and specific scenarios, giving an agent clear decision criteria for when to use this tool versus siblings.

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

Tool Schema Changelog

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

  1. 4 tool updatesv0.9.1
    • Addeddownload
    • Changedfetch2 fields changed
      • addedInput schema / properties / inline
        Added value: +{
        +  "default": false,
        +  "title": "Inline",
        +  "type": "boolean"
        +}
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "anyOf": [
        -        {
        -          "type": "string"
        -        },
        -        {
        -          "additionalProperties": true,
        -          "type": "object"
        -        }
        -      ],
        -      "title": "Result"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "fetchOutput",
        -  "type": "object"
        -}New value: +null
    • Changedresearch1 field changed
      • changedInput schema / properties / category / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "news",
        -      "pdf",
        -      "github",
        -      "paper",
        -      "forum",
        -      "blog"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "news",
        +      "pdf",
        +      "github",
        +      "paper",
        +      "forum",
        +      "blog",
        +      "image",
        +      "dataset"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedsearch1 field changed
      • changedInput schema / properties / category / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "news",
        -      "pdf",
        -      "github",
        -      "paper",
        -      "forum",
        -      "blog"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "news",
        +      "pdf",
        +      "github",
        +      "paper",
        +      "forum",
        +      "blog",
        +      "image",
        +      "dataset"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
  2. 2 tool updatesv0.2.0
    • Addedcompare
    • Addedextract_structured
  3. 7 tool updatesv0.1.0
    • First observedcache_search
    • First observedengines
    • First observedfetch
    • First observedfetch_batch
    • First observedread_doc
    • First observedresearch
    • First observedsearch

TDQS

A4.7/5.0

Scored across 10 tools

Disambiguation4/5

Each tool has a distinct primary role: engines lists valid engine names, search discovers URLs, fetch and read_doc both retrieve single resources but are clearly separated (web pages vs. documents), and fetch_batch vs. compare both handle multiple URLs but compare is question-driven with per-URL excerpts. The 'Not recommended for' sections in the descriptions sharply delineate boundaries, though fetch vs. read_doc and fetch_batch vs. compare could still cause brief hesitation.

Naming Consistency3/5

Names mix single verbs (search, fetch, compare, download), verb_noun compounds (fetch_batch, read_doc, cache_search, extract_structured), and bare nouns (engines, research). All use snake_case, but the verb/noun ordering is inconsistent—e.g., fetch_batch vs. read_doc, and cache_search vs. search. The pattern is readable but not uniform.

Tool Count5/5

10 tools is well-scoped for a search/retrieval server: engines for discovery, search for web discovery, fetch/fetch_batch for reading, read_doc for documents, research for search-and-read, cache_search for local recall, compare for multi-source comparison, extract_structured for metadata, and download for files. Each tool earns its place without redundancy or bloat.

Completeness5/5

The tool surface covers the entire search-read-retrieve pipeline: discover engines, search the web, fetch single or multiple pages, read PDFs/DOCX with pagination, run a full research workflow, query the local cache, compare sources, extract structured metadata, and download files. There are no obvious dead ends or missing operations for the stated purpose of web search and content retrieval.

Maintenance

ActivityMaintained
ResponsivenessNo issues

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.

  • Multi-engine search for AI agents. Trust scoring, local corpus, MCP-native. Self-hostable, BYOK.

  • Public MCP server for the LLM Search Engine

  • Your agent needs the open web — searched by more than one engine, and read as clean markdown rather than raw HTML. **What you can ask for** • "Search this question with two providers and tell me where they disagree." • "Scrape these 40 URLs into markdown, in one batch." • "Crawl this documentation site and give me every page." • "Do deep research on this topic and cite the sources." • "Find the academic papers behind this claim." **How to use it** Point any MCP client at https://mcp.aisa.one/search/mcp and sign in with OAuth — there is no key to create or paste. 30 tools across several independent providers: Tavily and Exa search, answers, contents and agent runs; Firecrawl scrape, batch scrape, crawl, map and search; Perplexity Sonar, Sonar Pro, reasoning and deep research; Oxylabs AI search and LLM jobs; OpenAI and Anthropic web search; and scholarly search. **Why this rather than the source** Several independent indexes behind one account, because one engine's blind spot is not visible from inside it. **It is also a door to the rest** The same login reaches 26 sources and 580+ operations. Find the page here, then ask the same agent who links to it or how much traffic it gets — without adding a second server. **What it costs** Finding and inspecting an operation is free. Running one is billed per call at API prices, with no seat and no monthly minimum, and every call takes max_price_usd so an agent cannot overspend by accident. **Where else it reaches** https://mcp.aisa.one/seo-serp/mcp for the Google results page itself, https://mcp.aisa.one/seo-serp-other-engines/mcp for Bing, Baidu and Naver.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A lightweight MCP server that enables LLMs to search the web via DuckDuckGo, search GitHub code repositories, and extract clean content from web pages in LLM-friendly formats.
    8
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    A zero-config web search and fetch MCP server for LLM agents, featuring multi-backend metasearch, persistent rolling cache, and structured error envelopes for retry-friendly interactions.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server enabling local-first web search, fetch, extract, and caching with citeable excerpts, no API key required. Supports research workflows for agents and apps.
    16 npm
    MIT