Skip to main content
Glama
Kamisorara

online-search-mcp

by Kamisorara

online-search-mcp

本地联网搜索 MCP(Model Context Protocol)服务,供智能体使用:

  • search_web — DuckDuckGo 联网搜索(免费、无需 API Key),支持时效性过滤和地区偏好;可加 fetch_top=N 顺带抓取前几条结果的正文摘要,一步拿到答案

  • search_github — GitHub 仓库搜索(官方 API),支持 language: / stars: / topic: / pushed: 等限定符,找开源项目和案例用

  • fetch_url_content — 抓取网页正文并转为 Markdown(自动去导航/广告、处理中文编码,正文前附带标题与发布日期);GitHub/PyPI/Stack Overflow/Wikipedia 自动走官方数据源,JS 渲染/反爬页面自动降级到无头浏览器渲染

基于 Python + 官方 mcp SDK 2.x(MCPServer),stdio 传输,兼容所有标准 MCP 客户端。

安装

方式一:uv(推荐,已配好国内镜像)

镜像源直接写在 pyproject.toml 里(清华 TUNA,[[tool.uv.index]]),并禁用了 uv 从 GitHub 下载托管 Python(国内会超时,自动改用系统 Python),克隆即用:

cd D:\Data\Code\Projects\online_search_mcp
uv venv --python 3.14
uv sync --extra browser   # 不需要浏览器兜底则去掉 --extra browser

日常改动依赖后执行 uv sync --extra browser 即可,锁定文件 uv.lock 保证环境可复现。

方式二:pip

cd D:\Data\Code\Projects\online_search_mcp
python -m venv .venv
.venv\Scripts\pip install -e ".[browser]" -i https://pypi.tuna.tsinghua.edu.cn/simple

验证服务能启动(会挂住等待 stdio 输入,Ctrl+C 退出即为正常):

.venv\Scripts\python -m online_search_mcp

无头浏览器兜底(推荐)

默认安装只能读服务端渲染的页面(「查看网页源代码」里有正文的)。启用 Playwright 兜底后,JS 渲染的 SPA、部分反爬站点也能读:

# 已含在上面的 uv sync --extra browser / pip install ".[browser]" 中,还需下载 Chromium 内核(约 120MB,国内用 npmmirror 镜像)
PLAYWRIGHT_DOWNLOAD_HOST=https://cdn.npmmirror.com/binaries/playwright .venv\Scripts\python -m playwright install chromium

未安装 playwright 时服务照常工作(纯 HTTP),失败信息里会提示启用方法。

Related MCP server: Web Search MCP Server

代理配置(重要:自动跟随系统代理)

服务自动跟随 Windows 系统代理,语义与浏览器一致,零配置:

  • 打开 Clash/V2Ray 等工具的「系统代理」开关 → 搜索和抓取自动走代理(所有引擎可达,搜索稳定在 3-6s)

  • 关闭系统代理 → 直连(ddgs 多引擎容错,yahoo/mojeek 等可用引擎兜着,3-22s 波动)

  • 环境变量可强制指定(优先级高于系统代理):DDGS_PROXY(仅搜索)> HTTPS_PROXY / HTTP_PROXY / ALL_PROXY;socks5 写 socks5://127.0.0.1:1080

无头浏览器在启动时探测一次代理(会话期间跟随),HTTP 抓取和搜索则是每次调用时探测——中途开关系统代理,搜索和快路径抓取立即生效。

实测对比(同 query、8 条结果):直连 14.6s / 22.8s,走代理 5.7s / 3.1s。

接入 ZCode

编辑 C:\Users\<你>\.zcode\cli\config.json,在 mcp.servers 下添加(用户级,所有项目可用):

{
  "mcp": {
    "servers": {
      "online-search": {
        "command": "D:\\Data\\Code\\Projects\\online_search_mcp\\.venv\\Scripts\\python.exe",
        "args": ["-m", "online_search_mcp"],
        "env": {
          "HTTPS_PROXY": "http://127.0.0.1:7890"
        }
      }
    }
  }
}

不需要代理就把 env 整段删掉。改完重启 ZCode 会话,在 Settings → MCP 里确认 online-search 已连接,工具名为 mcp__online-search__search_web 和 mcp__online-search__fetch_url_content。

只想在某个项目里启用的话,把同样的 online-search 条目写进该项目的 <repo>\.zcode\config.json 即可。

接入其他 MCP 客户端(Claude Desktop / Cherry Studio / Cursor 等)

标准 mcpServers 格式:

{
  "mcpServers": {
    "online-search": {
      "command": "D:\\Data\\Code\\Projects\\online_search_mcp\\.venv\\Scripts\\python.exe",
      "args": ["-m", "online_search_mcp"],
      "env": {
        "HTTPS_PROXY": "http://127.0.0.1:7890"
      }
    }
  }
}

引导智能体主动使用(重要)

挂上 MCP ≠ 智能体一定会用——模型默认倾向凭训练记忆回答。三层引导,从自动到手动:

  1. 工具描述(已内置,无需配置):每个工具的说明都写了适用场景与示例,服务级 instructions 会在 MCP 握手时注入客户端。任务里出现「最新的 / 查一下 / 找个开源项目」类字眼时,模型会自动匹配到对应工具。

  2. 指令文件(最有效,推荐配置):在 ZCode 的 ~/.zcode/AGENTS.md(全局生效)或项目根的 AGENTS.md 里立规矩,把「先搜索」变成默认行为;Claude Code 用 CLAUDE.md、Cursor 用 .cursorrules,内容可直接复用:

    ## 联网搜索规则
    - 版本号/发布日期、近期新闻、库的最新 API、开源选型、任何不确定的事实:
      必须先联网验证,禁止凭记忆直接回答
    - 通用检索用 search_web(新闻类加 timelimit="w";想直接拿答案加 fetch_top=2)
    - 找开源项目/示例代码用 search_github(支持 language:python stars:>500 等限定符)
    - 搜索摘要不够时用 fetch_url_content 抓原文;引用时附来源链接

    ZCode 中工具全名为 mcp__online-search__search_web 等(带服务器前缀),其它客户端一般是裸名 search_web。

  3. 提问方式(辅助):「搜一下最新版」比「你知道…吗」触发率高得多;客户端里挂的 MCP 越多、工具列表越长,选择精度越稀释,不常用的建议在设置里关掉。

工具说明

工具

参数

说明

search_web

query(必填)、max_results=8、timelimit=None(d/w/m/y)、region="wt-wt"(cn-zh 中文)、fetch_top=0(0-3)

返回带链接的 Markdown 结果列表;fetch_top>0 时并发抓取前 N 条正文摘要(各约 800 字);被限流/断网时返回友好错误说明而非崩溃

search_github

query(必填,支持限定符)、max_results=8、sort="best-match"(stars/forks/updated)

官方 API 免认证限 10 次/分钟;设 GITHUB_TOKEN 环境变量提升到 30 次/分钟

fetch_url_content

url(必填)、max_chars=20000、render_mode="auto"

trafilatura 提取正文转 Markdown(正文前带标题/发布日期),超长截断并标注;智能体高频站点自动走官方数据源

站点专用通道

fetch_url_content 对以下站点自动改走官方数据源(更快、更干净、无反爬),命中时结果开头带 [经站点专用通道读取(…)] 标注;通道失败自动回落通用抓取,不影响整体可用性:

站点

数据源

说明

github.com/{o}/{r} 及 /tree/…

GitHub API

仓库元信息(⭐/语言/更新)+ README 原文

github.com/…/blob/{ref}/{path}

raw.githubusercontent

源文件直读(文本类扩展名,代码自动包代码块)

pypi.org/project/{name}

PyPI JSON API

版本/摘要/作者/文档链接/顶级依赖

Stack Overflow 及 Stack Exchange 系问答

Stack Exchange API

问题 + 采纳回答排最前、其余按票数

{lang}.wikipedia.org/wiki/…

Wikipedia REST

词条全文(大陆网络需开系统代理)

fetch_url_content 的抓取策略(四级 + 缓存)

  1. 站点专用通道:上表站点走官方 API/raw 直读(0.3-1s,最快最干净)

  2. 快路径:纯 HTTP + trafilatura 抓取(0.1-1s),绝大多数网页走这条

  3. llms.txt 生态:正文不够时找站点提供的 Markdown 副本(HTML 里声明的 text/markdown 链接,或盲试 url+".md"),比浏览器渲染快一个量级

  4. 兜底:仍拿不到足够正文(正文 <500 字、被 403/429/5xx 拦截、或检测到人机验证页)时,自动用无头 Chromium 渲染后再提取(约 3-8s),结果带 [正文经无头浏览器渲染后提取] 标记

  5. 缓存:同一 URL 5 分钟内重复抓取直接命中缓存(快数百倍),结果带 [缓存命中] 标记;发生重定向时结尾标注最终 URL

render_mode 参数可显式控制:auto(默认)/ request(强制纯 HTTP,最快,跳过浏览器兜底)/ browser(强制渲染,已知 JS 页面用)。

search_web 的防线与缓存

  • 三层防线:ddgs 多引擎聚合(失败重试 3 次)→ 全部失败时无头浏览器搜百度兜底 → 仍失败返回友好错误

  • 自限流:默认 6 次/分钟(SEARCH_RPM 可调),防止频繁搜索触发引擎对整个 IP 的封锁

  • 搜索缓存:同参数查询 5 分钟内直接命中(不占限流配额,智能体重复搜索很常见),带 [搜索缓存命中] 标记

健康自检(doctor)

排查问题一键体检,输出各依赖版本、代理来源、浏览器兜底、GitHub/PyPI/ddgs 各通道连通性与配额:

.venv\Scripts\python -m online_search_mcp.doctor           # 全量检查(含真实网络探测)
.venv\Scripts\python -m online_search_mcp.doctor --offline # 只看配置,不联网

相关环境变量:FETCH_BROWSER=off 关闭浏览器兜底;FETCH_BROWSER_TIMEOUT=秒(默认 20);FETCH_CACHE_TTL=秒 / FETCH_CACHE_MAX=条(默认 300/64,设 0 禁用);SEARCH_RPM=次/分钟(默认 6);SEARCH_CACHE_TTL=秒 / SEARCH_CACHE_MAX=条(默认 300/32,设 0 禁用)。

开发

# 端到端冒烟测试(走 stdio 真实调用三个工具)
.venv\Scripts\python -X utf8 tests\smoke_test.py
# 性能基准(搜索/抓取/冷启动延迟测量)
.venv\Scripts\python -X utf8 tests\perf_test.py

致谢与参考实现

部分设计移植自以下开源项目(许可证均宽松,源码在 refs/ 供查阅,不入库):

  • duckduckgo-mcp-server(MIT)— TTL 缓存、滑动窗口限流

  • open-webSearch(Apache-2.0)— renderMode 三档、人机验证页检测

  • one-search-mcp(MIT)— 浏览器本地搜索引擎兜底思路

  • mcpsurfr(MIT)— 站点专用通道(GitHub/PyPI/Stack Exchange/Wikipedia)、llms.txt Markdown 副本、正文附带标题与日期、搜索缓存

  • agent-search-mcp(Apache-2.0)— doctor 自检命令形态

  • wigolo(AGPL-3.0,仅思路参考未搬代码)— doctor 命令、结果附正文的产品思路

已知限制

  • DuckDuckGo 免费接口有匿名限流,短时间大量搜索可能被暂时封禁(服务内置 3 次退避重试 + 自限流)

  • 登录墙绕不过:无头浏览器能过多数反爬(实测知乎的 403 可以),但需要登录才能看的内容依然拿不到(会返回登录提示原文)

  • 无头浏览器也过不了的强反爬(Cloudflare 五秒盾、验证码)依然失败,返回明确提示

  • 二进制内容(PDF/图片)不做解析,返回提示信息

  • 滚动才懒加载的内容可能缺失(只渲染首屏)

  • 连接层失败(域名不通/被墙)不做浏览器兜底,直接返回代理配置提示

  • 站点专用通道依赖对应官方 API 的可达性(大陆直连下 Wikipedia 可能不通),失败自动回落通用抓取

License

MIT

Available Tools

3 tools
fetch_url_contentA

抓取网页正文并转为 Markdown(自动去导航/广告,处理中文编码)。

5 分钟内重复抓取同一 URL 直接命中缓存。发生重定向时结尾标注最终 URL。

Args: url: 目标网址(http/https)。 max_chars: 返回正文最大字符数,默认 20000,超出截断并标注。 render_mode: "auto"(默认,HTTP 优先、失败时无头浏览器兜底)/ "request"(强制纯 HTTP,最快,不启动浏览器)/ "browser"(强制无头浏览器渲染,已知是 JS 页面时用,省一次无效 HTTP)。

NameRequiredDescriptionDefault
urlYes
max_charsNo
render_modeNoauto

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does solid work: it discloses a 5-minute per-URL cache, that redirects are marked with the final URL, that oversized bodies are truncated and flagged, and that auto mode falls back to a headless browser. It omits failure modes entirely — timeouts, non-HTML content, blocked/paywalled pages, or whether the browser fallback has a cost/latency penalty worth avoiding.

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?

Summary sentence is front-loaded and high-signal; the Args block is compact and each entry earns its place. Minor redundancy in restating defaults that also appear in the schema, but with 0% schema coverage that restatement is functional rather than wasteful.

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?

An output schema exists, so return values need not be re-explained; the description still adds the useful note that redirects append the final URL and that truncation is marked. For a 3-param fetch tool the remaining gap is error/edge behavior, which is the main thing an agent would still be guessing at.

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%, so the description must compensate and it does: all three parameters are explained with types, defaults, and behavior (max_chars default 20000 plus truncation-and-marking), and render_mode's three accepted string values are enumerated with tradeoffs despite the schema having no enum. This adds meaning the schema 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 opening sentence names a specific verb+resource pair (抓取网页正文, convert to Markdown) and adds differentiating scope: automatic stripping of navigation/ads and Chinese encoding handling. Against siblings search_web and search_github, which locate pages rather than return their content, the tool's role is unmistakable from the description alone.

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

Usage Guidelines4/5

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

render_mode guidance is explicit about when to pick each mode (browser for known JS pages to avoid a wasted HTTP round-trip, request for max speed), and the cache rule tells the agent repeat fetches within 5 minutes are cheap. It stops short of exclusions — nothing says when not to use this tool or what happens on non-HTML/auth-gated URLs.

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

search_githubA

搜索 GitHub 仓库(官方 API,找开源项目/案例/轮子用这个)。

支持限定符组合,示例: - "mcp server language:python stars:>1000"(Python 高星 MCP 服务) - "rimworld mod topic:rimworld-mod"(按主题) - "web crawler pushed:>2025-01-01 language:go"(近期活跃的 Go 爬虫) 常用限定符:language: / stars:>N / topic: / pushed:>YYYY-MM-DD / license: / in:name,description

Args: query: 搜索词,可含上面的限定符。 max_results: 返回条数上限,默认 8(1-20)。 sort: "best-match"(相关度)/ "stars" / "forks" / "updated"。

NameRequiredDescriptionDefault
sortNobest-match
queryYes
max_resultsNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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

No annotations exist, so the description carries the burden. It discloses the result cap range (1–20), the default (8), the sort vocabulary, and the supported qualifier set — real behavioral detail. It says nothing about GitHub API authentication/token requirements or unauthenticated rate limits, which are the main failure modes for this tool, and it doesn't characterize what a result entry contains beyond 'returns N results'.

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?

Purpose is front-loaded in the first line, followed by examples and then a per-argument block — good scan order. The qualifier list partially duplicates what the examples already demonstrate, so there is mild redundancy, but every line is actionable.

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?

An output schema exists, so return-value explanation is not needed, and the query grammar — the hardest part of this tool — is covered thoroughly. The remaining gap is operational: no mention of auth/token or rate limits for the official API, which matters for an agent that may call it repeatedly.

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 coverage is 0% (titles only), yet the description fully compensates: `query` is documented with combinable qualifiers (language:, stars:>N, topic:, pushed:>, license:, in:name,description) plus three concrete examples; `max_results` documents default 8 and the 1–20 bound; `sort` enumerates the four valid string values even though the schema declares none.

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

Purpose4/5

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

States a specific verb+resource (search GitHub repositories) and adds scope via the official API plus the 'find open-source projects/cases/libs' gloss, which separates it from the generic search_web sibling in spirit. It never names the siblings explicitly, so the differentiation is implied rather than stated.

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

Usage Guidelines4/5

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

The parenthetical '(official API, use this for finding open-source projects/cases/wheels)' gives a clear use context, and the three worked query examples show realistic invocation patterns. It lacks an explicit 'when not to use this / use search_web instead' clause, so it stops short of full routing guidance.

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

search_webA

联网搜索(DuckDuckGo),返回带链接的结果列表。

Args: query: 搜索关键词,支持中英文。 max_results: 返回条数上限,默认 8(1-20)。 timelimit: 时效性过滤:None 不限 / "d" 一天 / "w" 一周 / "m" 一月 / "y" 一年。新闻类查询建议 "w" 或 "d"。 region: 地区语言偏好:"wt-wt" 全球 / "cn-zh" 中文 / "us-en" 美国英文。 fetch_top: 同时抓取前 N 条(0-3)结果的正文摘要(各约 800 字,并发纯 HTTP)。 需要直接答案、不想再逐条 fetch 时设 2-3;默认 0 保持低延迟。

NameRequiredDescriptionDefault
queryYes
regionNowt-wt
fetch_topNo
timelimitNo
max_resultsNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral burden. It does disclose the latency tradeoff (default fetch_top 0 keeps latency low), that content fetching is concurrent plain HTTP with ~800 characters per snippet, and the numeric bounds (1-20 results, 0-3 fetches). It says nothing about rate limits, failure modes, or throttling, which matters for a scraping-backed search tool.

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?

Front-loaded one-line purpose followed by a compact parameter block; each parameter note earns its place with a default or a use case. Slightly verbose but no filler sentences.

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?

An output schema exists, so return values needn't be spelled out, and all five parameters are fully documented. The only gap is failure/rate-limit behavior, which is forgivable given the output schema and complete parameter coverage.

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%, so the description must compensate and it does: every one of the five parameters gets meaning, valid values, and defaults — region enumerations (wt-wt/cn-zh/us-en), timelimit codes (d/w/m/y), result caps, and the 0-3 fetch_top range. It explains far more than the bare schema.

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

Purpose4/5

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

The first line names a specific verb (联网搜索 / web search), the engine (DuckDuckGo), and the return shape (a result list with links). It implicitly separates itself from search_github and fetch_url_content by being a general web search, but never names those siblings explicitly.

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

Usage Guidelines4/5

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

It gives real selection guidance: use timelimit "w"/"d" for news queries, and set fetch_top to 2-3 when you want direct answers instead of fetching results one by one — which routes the agent away from the sibling fetch_url_content. It lacks explicit when-not-to-use or a direct comparison to search_github.

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. 3 tool updatesv0.2.0
    • First observedfetch_url_content
    • First observedsearch_github
    • First observedsearch_web

TDQS

A4.2/5.0

Scored across 3 tools

Disambiguation4/5

The three tools have clearly distinct targets: web search, single-URL content extraction, and GitHub repository search. The only mild overlap is that search_web's fetch_top option also retrieves page snippets, which could occasionally be confused with fetch_url_content, but the description frames it as a low-latency convenience rather than a replacement.

Naming Consistency5/5

All three names follow the same snake_case verb_object pattern (search_web, fetch_url_content, search_github). The verbs are predictable and the object noun clearly identifies the resource or action, so an agent can infer behavior from the name alone.

Tool Count5/5

Three tools is a tight, well-scoped surface for a search-and-retrieve server, with no redundant or filler entries. Each tool maps to a distinct step in the research workflow (discover, read, find code), so nothing feels missing or excessive within this scope.

Completeness4/5

The search-then-fetch loop is fully covered, including GitHub-specific discovery, so agents can complete most research tasks without dead ends. Minor gaps remain: no batch multi-URL fetch, no pagination beyond max_results, and no alternative search backends if DuckDuckGo fails.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers