Free Search

io.github.sweetcornna由 GitHub 帳號 sweetcornna 發布v0.18.0更新於 Oct 31, 2026

No-API-key web search, page fetching and document reading across many engines. Local-first.

概覽

AI 產生的概覽

免 API 金鑰、本機優先的網頁搜尋與閱讀工具:多引擎搜尋、抓取網頁、解析文件並查核引用。

可以做什麼
  • 跨多個免金鑰引擎搜尋網頁,可依時效、網域與類別篩選,並列出可用來源
  • 平行抓取一個或多個網址,回傳閱讀模式 Markdown、解析後的文件文字或非文字檔案的說明
  • 一次完成搜尋與閱讀,回傳附來源的調研簡報
  • 讀取並分頁解析 PDF、DOCX、XLSX、PPTX、EPUB、CSV 與程式碼檔案,擷取價格、日期等結構化中繼資料
  • 並排比較二到五個頁面,追蹤單篇論文的引用關係並檢查撤稿,在本地全文快取中檢索已抓取的頁面
  • 把網址存到本機會自動過期的下載目錄
適用情境
適合助理需要取得最新網頁資訊、閱讀來源或解析文件,又不想註冊搜尋 API 的情境。可用於調研簡報、多來源事實核對、文獻查核,以及閱讀遠端 PDF 或辦公室文件。
執行需求
以 stdio 在本機執行;README 表示只需 uv(uvx free-search-mcp),瀏覽器渲染引擎與 JavaScript 較重的頁面可選裝 Chromium。不需要 API 金鑰或帳號。選用設定包括 SEARCH_MCP_CACHE_DIR、SEARCH_MCP_REGION 與 SEARCH_MCP_PROXY;額外引擎可選配各自的 API 金鑰。
安裝前請注意
選用的 HTTP 傳輸沒有身分驗證,任何能連上它的人都能讓它抓取任意網址,應只綁定回環位址或放在具驗證的代理之後。選用登入引擎會消耗你自己的帳號與配額;README 警告 Google 的 Antigravity 條款禁止第三方登入,已有帳號因此被停用。SEARCH_MCP_PROXY 屬於機密資訊。download 會寫入本機檔案,本機檔案讀取預設關閉。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Free Search,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

free-search-mcp

https://github.com/user-attachments/assets/354b522a-ef6b-4547-bb07-c80c6268a5e8

Music: “Ethereal Space (cdk Mix)” by cdk, ccmixter.org/files/cdk/34151, licensed CC BY 3.0.

[License] [Python] [MCP]

free-search-mcp is a local-first Model Context Protocol server that needs no API key. It lets any LLM (Claude, GPT, a local Ollama model, …) search the web, fetch and clean up pages, and read documents, and you never sign up for a search API.

It combines ideas from several open-source MCP servers in one Python package, and adds the output shaping for LLMs and the reliability work that each of them lacked.

text
research("how does reciprocal rank fusion work", depth=3)   ↓# Research brief: how does reciprocal rank fusion work_engines: duckduckgo, bing, yahoojp, anysearch · 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…

That was one tool call. It returned three sources with their full text, and no API key was involved.

Quick start

You need uv and nothing else: no sign-up, no API key, no clone.

In Claude Code, inside a session:

text
/plugin marketplace add sweetcornna/free-search-mcp/plugin install free-search@free-search-mcp

In Codex:

bash
codex plugin marketplace add sweetcornna/free-search-mcpcodex plugin add free-search@free-search-mcp

(In Codex, a [mcp_servers.search] entry left in ~/.codex/config.toml by an earlier codex mcp add silently shadows the plugin's server. Remove it with codex mcp remove search.)

The plugin brings the 11 tools, the verified-research skill (how to check a snippet against its page and its date) and, in Claude Code, the free-search:quick-search agent, all pinned to one version. /plugin update free-search moves to the next release.

Optionally, install Chromium once for the browser-rendered engines (brave, zhihu, …) and JavaScript-heavy pages. Everything else works without it, and a call that needs it returns this command as its error:

bash
uvx --from free-search-mcp playwright install chromium

Claude Desktop, other clients, a source checkout and Docker are under Install.

Why this exists

Multi-engineNo API keySmart fallbackPDF/DOCXFTS5 cacheFiltersTrafilaturaLLM-tuned
nickclyde/duckduckgo-mcp-server✗✓✗✗✗✗✗~
mrkrsl/web-search-mcp✓✓✓✗✗✗✗~
Aas-ee/open-webSearch✓✓~✗✗✗✗~
VincentKaufmann/noapi-google-search-mcp✗✓✓✓✓✗✗~
free-search-mcp✓✓✓✓✓✓✓✓

"LLM-tuned" means Markdown-first output with token estimates, errors that name the next step, and a research() that turns a search and its fetches into one call. docs/HOW_IT_WORKS.md explains the less obvious columns.

Tools (11)

ToolDescription
search(query, ...filters)Parallel multi-engine search, RRF-merged, title-fuzzy + host-canonical deduped, with optional extractive lead_snippet
research(question, depth?, ...filters)One-shot: search + fetch top N + return Markdown brief
paper_graph(paper, direction?, limit?)Walk one paper's citation graph: references, citing works ranked by influence, and Crossref retraction/correction notices. Takes a DOI, an OpenAlex ID, an exact title, or an arXiv reference (arXiv:1706.03762, an arxiv.org/abs/… URL, a 10.48550/arXiv.… DOI, or a bare id such as 1706.03762, 2401.12345v3 or hep-th/9901001 when it is the whole input)
compare(question, urls=[2..5])Concurrent fetch of 2-5 URLs, side-by-side excerpts keyed by question
fetch(url, render?, inline?, ...)Fetch any resource: reader-mode Markdown for pages, parsed text for documents, or a description (type/size/dimensions/sha256) for images and binaries. inline=True returns the image itself for vision models
fetch_batch(urls, ...)Concurrent multi-URL fetch (max 20 per call)
read_doc(source, start?, length?, ...)Parse PDF / DOCX / XLSX / PPTX / EPUB / CSV / code / zip-tar / HTML / TXT / MD with pagination
extract_structured(url, ...)Pull JSON-LD / OpenGraph / Twitter cards / microdata via extruct. Long prose fields (articleBody and the like) are clipped, and the result says so in trimmed. This tool returns metadata; use fetch for the text
cache_search(query, limit?, ...)FTS5 search across previously fetched pages
engines(group?)The source tree (group, then sub-group, then engine), one line each. group is an enum of the groups that own engines, so a typo fails schema validation
download(url, ...)Save a file to ${SEARCH_MCP_CACHE_DIR}/downloads by default; files auto-delete after 24h. Set SEARCH_MCP_DOWNLOAD_ENABLED=false to disable it.

There are also 5 MCP prompts and 2 resource templates (cache://page/{url}, cache://search/{query_hash}). A twelfth tool, ask, appears only when an answer backend is configured (see Delegating a lookup).

search and research take these filters:

ParamValuesEffect
freshnessday / week / month / yearOnly results from the last N. Results with no date are kept, and freshness_note says when that is most of them. day / week also add googlenews
include_domains["python.org", "djangoproject.com"]Restrict to these domains
exclude_domains["pinterest.com"]Remove these
categorya group (paper, finance, news, software, security, weather, …) or a sub-group (paper.biomed, finance.filings, finance.fx, software.python, dataset.ml, …)Routes to the sources that natively index that kind of thing; the enum in the tool schema lists every value
include_text"async"Substring required in title/snippet
exclude_text"beginner"Substring forbidden
max_age_hours24Accept a cached answer only if it is younger than this. Default 7 days; the tightest of this, the freshness window's TTL, the 6-hour news cap and the category's own cap (weather, finance.fx 1 hour; software, security 6 hours) wins

Output is Markdown by default, with provenance and a token estimate in the header. format="json" returns structured data.

How a search runs

  • A search that names no engines asks a small keyless pool: duckduckgo, bing, yahoojp (Yahoo! JAPAN, the keyless route to Google's index) and anysearch. googlenews joins when recency is asked for, so360 and quark when the query is written in Chinese, naver when it is written in Korean. Sources that only served a CAPTCHA or an empty shell (mojeek, google, startpage, searx, sogou) were removed rather than left to fail on every fresh process.
  • category= routes to sources that index that kind of thing (papers, filings, datasets, packages, CVEs, …). Record sources such as pypi, nvd or openmeteo also join by themselves when the question is one they can answer directly.
  • An engine that serves a CAPTCHA, a login wall or an off-topic page is benched, a reserve takes its seat, and the response says what happened. A proxy (SEARCH_MCP_PROXY) is the fix for IP gating.
  • Once you have signed in to codex, it searches beside those engines on every such search and its results join the same ranking (the agent lane). The links never wait more than 6 s for it.
  • With an answer backend configured (SEARCH_MCP_AGENT_BACKEND=api, claude-code or codex), search also runs the answer agent beside the engines from the same result set and puts a short sourced answer above the links. SEARCH_MCP_AGENT_IN_SEARCH=false turns that off; ask stays available either way.
  • Every result says how old it is and where its date came from, so the agent can tell a lead from a checked fact.
  • engines() prints the whole source tree. engines=["so360", "baidu"] runs exactly the engines named.

No engine that a search reaches by itself needs a key. The details, with measurements, are in docs/HOW_IT_WORKS.md; walls and proxies in docs/PROXY_AND_GATES.md; a tour of the tools with examples in docs/USAGE.md.

Install

The plugin in Quick start is the recommended path, because the server is pinned to the plugin's version and updates with it. The other routes run the same server:

WhereHow
Claude Desktopopen free-search-mcp-<version>.mcpb from the latest release
MCP Registryio.github.sweetcornna/free-search-mcp
Claude Code, without the pluginclaude mcp add search -s user -- uvx free-search-mcp
Codex, without the plugincodex mcp add search -- uvx free-search-mcp
Hermes Agent (the plugin)hermes plugins install sweetcornna/free-search-mcp/plugins/free-search --enable
Any other MCP clientthe stdio command uvx free-search-mcp
Dockerdocker compose build, then docker compose run --rm search-mcp

A source checkout with Chromium, a smoke test and client registration in one step:

bash
curl -LsSf https://raw.githubusercontent.com/sweetcornna/free-search-mcp/main/scripts/install.sh | bash -s -- --client claude-code

Over HTTP, uvx free-search-mcp --transport streamable-http --port 8000 serves http://127.0.0.1:8000/mcp. That endpoint has no authentication and fetches any URL for whoever reaches it, so keep it on loopback or put an authenticating proxy in front.

The JSON for Claude Desktop, Cursor, Cline, Continue and Zed, the installer's options and the plugin's token cost are in docs/INSTALL.md. Operating rules for agents are in docs/AGENT_USAGE.md.

Search on your own account: codex and antigravity

Two opt-in engines search on an account you sign in with instead of an API key. Neither is in any pool or route, and nothing changes for anyone who never signs in. Once you sign in to codex, it searches beside the keyless engines on every automatic search (the agent lane); antigravity runs only when a call or SEARCH_MCP_AGENT_ENGINES names it.

codexantigravity
Searches withOpenAI's web search, the one Codex usesGoogle Search, run by a Gemini model
Accounta ChatGPT plan that includes Codexa Google account with Antigravity
Each search counts againstthe plan's Codex usagethe account's Antigravity quota
The provider allows ityesno, see the warning below
Opens a sign-in page by itselfon first use, over stdio on a desktopnever
Full guide, with 中文速览docs/CODEX_SEARCH.mddocs/ANTIGRAVITY_SEARCH.md

Warning: Google's Antigravity terms forbid using its sign-in from third-party tools and name suspension of the Antigravity and Gemini CLI accounts as the consequence, and Google has suspended accounts for it. Sign in to antigravity only with an account you accept that risk for.

1. Sign in once

Run the sign-in on the machine the server runs on:

bash
uvx --from free-search-mcp search-mcp-login codex         # the ChatGPT page `codex login` showsuvx --from free-search-mcp search-mcp-login antigravity   # prints the warning, then Google's consent pageuvx --from free-search-mcp search-mcp-login status        # account, plan, token expiry

(uv run search-mcp-login … in a source checkout.) The settings page, search-mcp-admin, has the same Sign in / 登录 buttons. Tokens are stored in ~/.config/search-mcp/oauth/ (0600) and refreshed automatically. The plugin, uvx and the Desktop bundle all read that directory, so a running server picks up a new sign-in without a restart.

  • codex can skip this step: the first search that names it opens the sign-in page and finishes once you approve (stdio on a desktop only; SEARCH_MCP_CODEX_AUTO_SIGNIN=false turns it off). A machine already signed in to the Codex CLI can reuse that sign-in read-only with search-mcp-login codex --use-codex-cli.
  • antigravity signs in with Antigravity's own OAuth client, which is not shipped in this package. The sign-in reads it from the Antigravity app installed on the machine (checked on macOS). Without Antigravity installed, set SEARCH_MCP_ANTIGRAVITY_CLIENT_ID and SEARCH_MCP_ANTIGRAVITY_CLIENT_SECRET; a machine that has signed in keeps both in ~/.config/search-mcp/oauth/antigravity.json.

2. Name the engine

python
search("rust 2024 edition changes", engines=["codex"])research("what changed in python 3.14 asyncio", engines=["antigravity"])search("rust 2024 edition changes", engines=["codex", "duckduckgo", "bing"])

In Claude Code or Codex, ask for it in words ("search this with the codex engine"). Filters apply as usual, and results are cached like any other search. Measured on 2026-09-26, a codex search took about 3 s and an antigravity search 10 to 20 s.

3. Settings (all optional)

VarDefaultMeaning
SEARCH_MCP_CODEX_MODEL, SEARCH_MCP_ANTIGRAVITY_MODELlatestlatest follows the account's model catalogue, so a new model is used once it is listed; a model name pins one
SEARCH_MCP_CODEX_TIMEOUT, SEARCH_MCP_ANTIGRAVITY_TIMEOUT60seconds for one search
SEARCH_MCP_CODEX_AUTO_SIGNINtrueopen the sign-in page on first use
SEARCH_MCP_AGENT_ENGINESautothe agent lane: auto seats a signed-in codex; off; or a list such as codex,antigravity
SEARCH_MCP_AGENT_LANE_WAIT_SECONDS6how long a search waits for the lane
SEARCH_MCP_AGENT_LANE_GRACE_SECONDS2how much longer than the keyless engines it waits, once they have results
SEARCH_MCP_ANTIGRAVITY_CLIENT_ID, SEARCH_MCP_ANTIGRAVITY_CLIENT_SECRETread from the Antigravity installfor a machine without Antigravity; set both or neither
SEARCH_MCP_PROXYemptythe sign-in and the searches go through it

The agent lane

A signed-in codex does not wait to be named. Every search that names no engines asks it at the same moment as the keyless pool, and its results are fused into the same ranking, so the agent search and the keyless search run in parallel and one answer comes back. The keyless pool keeps its breaker, reserves, routing and rescue, which naming engines=["codex", ...] would switch off.

  • The search waits for the lane at most 6 s from when the engines were asked (SEARCH_MCP_AGENT_LANE_WAIT_SECONDS), and at most 2 s past the keyless engines once they have results. A lane engine still searching then finishes in the background, and its results are merged into the cached result set, so the same search a little later returns them.
  • The lane never queues for a rate-limit token, a spent usage window benches it at once, and its problems are reported under agent_lane, never as a failed search.
  • SEARCH_MCP_AGENT_ENGINES=off turns it off; codex,antigravity adds antigravity to it.

On a server, over SSH, or in Docker

  • Sign in with --no-browser (search-mcp-login codex --no-browser, or antigravity --no-browser), open the printed address in any browser, and approve. The browser then fails to load a 127.0.0.1:1455 or localhost:51121 address; paste that whole address into the terminal.
  • Over streamable-http, codex never opens a sign-in page by itself, since it would open on the server. Sign in there with the command above first.
  • In Docker, point SEARCH_MCP_CONFIG_DIR at a mounted volume so the tokens outlive the container, and run the sign-in inside it with --no-browser. antigravity there needs the two client variables.

search-mcp-login logout codex or logout antigravity deletes the stored tokens. To revoke Antigravity's access itself, remove it under "Third-party apps and services" in the Google account.

When it does not work

The error saysDo this
codex not configured / antigravity not configuredno sign-in is stored on this machine; run the sign-in above
port 1455 and 1457 … are in use, or port 51121another sign-in (codex login, an open sign-in page) holds the port; close it and retry
the usage limit, quota or rate limit was reachedwait until the reset time the error gives; the keyless engines still work
needs Antigravity's OAuth clientinstall Antigravity, or set the two client variables
HTTP 403 no valid license from antigravityset SEARCH_MCP_ANTIGRAVITY_VERSION to the installed Antigravity release; it can also mean Google restricted the account
has expired or was revokedsign in again

Optional: your own API key

You do not need one, and agents should never ask for one. Six engines run only when a call names them and the operator has set their own key:

EngineProviderKey
brave_apiBrave Search APISEARCH_MCP_BRAVE_API_KEY
serperSerperSEARCH_MCP_SERPER_API_KEY
serpbaseSerpBaseSEARCH_MCP_SERPBASE_API_KEY
tavilyTavilySEARCH_MCP_TAVILY_API_KEY
google_cseGoogle Custom SearchSEARCH_MCP_GOOGLE_CSE_API_KEY + SEARCH_MCP_GOOGLE_CSE_CX
github_codeGitHubSEARCH_MCP_GITHUB_TOKEN

Set a key as an environment variable or .env line, or on the local settings page:

bash
uv run search-mcp-admin        # local settings / 本地设置 — http://127.0.0.1:8765

(uvx --from free-search-mcp search-mcp-admin for a plugin or uvx install.) The page is bilingual (中英双语), binds to 127.0.0.1 only, applies a saved key without a restart, and never shows a stored value again. The walkthrough per provider is docs/API_KEYS.md.

Delegating a lookup

Delegation keeps page text out of the caller's context and returns a short answer with dated sources. None of it is on by default:

You wantUseIt needs
The agent to search and read by itselfthe tools, as installednothing
Your host's own subagents to do the lookupthe quick-search agent definitiona host with subagents
The server to dispatch through Claude CodeSEARCH_MCP_AGENT_BACKEND=claude-codethe claude CLI, logged in
The server to dispatch through CodexSEARCH_MCP_AGENT_BACKEND=codexthe codex CLI, logged in
The server to call a model endpoint you chooseSEARCH_MCP_AGENT_BACKEND=apian OpenAI-compatible or Anthropic-compatible URL
Your own code to supply the modelask(question, answer_with=...) in Pythonnothing else

The settings, the agent files and measured timings are in docs/DELEGATION.md.

Configuration

Nothing is required. Settings are SEARCH_MCP_* variables, read from the environment first, then ./.env, then ~/.config/search-mcp/.env (SEARCH_MCP_CONFIG_DIR moves that directory). The ones people change most:

VarDefaultMeaning
SEARCH_MCP_PROXYemptyoutbound proxy (http, https or socks5) for the engines, the browser and fetch
SEARCH_MCP_PROXY_ENGINESemptyproxy only these engines
SEARCH_MCP_DEFAULT_ENGINES["duckduckgo","bing","yahoojp","anysearch"]the pool a search uses when it names no engines
SEARCH_MCP_REGIONus-enlocale for engines that take one
SEARCH_MCP_CACHE_DIR~/.cache/search-mcpsearch and page cache
SEARCH_MCP_TOOLSemptyregister only these tools

Every setting is listed in docs/CONFIGURATION.md and documented in .env.example.

Development

bash
git clone https://github.com/sweetcornna/free-search-mcp.git && cd free-search-mcpuv sync && uv run playwright install chromiumuv run pytest -q                              # offlineSEARCH_MCP_TEST_NETWORK=1 uv run pytest -v    # live, hits the real web

Running claude inside the checkout picks up the repo's .mcp.json, which starts the working tree's server. The architecture is in docs/HOW_IT_WORKS.md, and cutting a release in docs/RELEASING.md.

Credits

This project builds on:

License

MIT. See LICENSE.

來源:README.md,提交 2c7fee9

工具

11

fetch

Fetch a URL: page text, document, or resource

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. The header says `cached N days ago`

輸入參數url必填formatinlinerenderforce_refreshmax_age_hours

fetch_batch

Fetch many URLs concurrently

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".

輸入參數urls必填formatrender

read_doc

Read a remote (or sandboxed local) document

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`, which is 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 enabl

輸入參數startformatlengthsource必填

research

Search and read in one call

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`. - Checking or expanding one paper's citations -> `paper_graph`. 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, and 2-3 is almost always enough. - Calling `research` for a known URL: that is what `fetch` is for. - 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). Prefer `category=`. Naming engines turns category routing off. fetch: If False, return source list without reading them. freshness: "day"|"week"|"month"|"year". Restricts to recent results. Best-effort; undated results are kept rather than dropped. include_domains: Restrict to these domains (e.g. ["python.org"]). exclude_domains: Drop results from these domains. category: Which KIND of source to search; a bare group wid

輸入參數depthfetchformatenginescategoryquestion必填freshnessuse_cacheexclude_textinclude_textmax_age_hoursexclude_domains另有 1 個

paper_graph

Walk a paper's citation graph

Follow the citations of ONE paper, and check whether it still stands. `search` finds papers that MENTION your words. This follows the edges instead: what a specific paper built on, and what has built on it since. Best for: - Checking a citation before repeating it: is the DOI real, and has the paper been retracted or corrected? - "What happened after this result": citing works come back ordered by how much the field cited them, so a 2019 paper leads to the current state of the art rather than to the most recent preprint about it. - Building a reading list backwards from one good paper. Not recommended for: - Finding papers by topic -> `search(category="paper")`, or a sub-group like `"paper.biomed"` / `"paper.cs"` / `"paper.preprint"`. - Reading the paper itself -> `read_doc` on the returned URL. Returns: - markdown (default): the paper with its retraction/correction notices, then "References" and "Cited by" sections. - json: {paper, references, citations, notes}, where `paper.crossref` carries `registered` and every post-publication `notices` entry. Common mistakes: - Passing a topic instead of a paper. A title resolves to its single best match; a phrase that names no specific paper resolves to the wrong one. - Reading an empty `citations` list as "uncited" when `notes` says the lookup was truncated. Args: paper: DOI (`10.1145/1571941.1572114`, or a doi.org URL), an OpenAlex ID (`W2148972377`), or the paper's exact title. direction: "both", "references" (what it cites) or "citations" (what cites it). limit: Max neighbours per direction, 1-50. format: "markdown" or "json".

輸入參數limitpaper必填formatdirection

engines

List available search engines

List the available sources, grouped by what they index. Best for: - Choosing a source deliberately: which one indexes filings, or preprints, or Chinese-language pages. - Checking a name before passing it to `engines=` on `search` / `research`. Not recommended for: - Calling on every search: the list is static, so read it once. Returns (markdown): a `group -> sub-group -> engine` tree, one line of description per engine. `group="paper"` restricts it to that group. Returns (json): `{"engines": [...names...], "taxonomy": {...}, "descriptions": {...}}`. Prefer `category=` over `engines=`. `category="paper"` WIDENS: it routes to one specialist per sub-group. A dotted sub-group NARROWS: `"paper.biomed"` queries only the biomedical indexes. Naming engines explicitly turns that routing off entirely, so reach for it only to force a specific source. Common mistakes: - Passing one of these names as `query`: they belong in `engines=`. - Passing a key-only engine with no key configured; it returns an actionable error, not results.

輸入參數groupformat

compare

Compare URLs side-by-side

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".

輸入參數urls必填formatquestion必填

extract_structured

Extract structured data from a URL

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".

輸入參數url必填format

download

Download a file to disk

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".

輸入參數url必填format

版本歷史

7
  1. v0.18.0最新Oct 31, 2026
  2. v0.17.0Oct 29, 2026
  3. v0.16.0Oct 22, 2026
  4. v0.15.0Oct 21, 2026
  5. v0.14.1Oct 18, 2026
  6. v0.13.1Sep 26, 2026
  7. v0.12.0Sep 22, 2026

評分

已滿足適用檢查項的 90%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分
  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分