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.
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:
In Codex:
(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:
Claude Desktop, other clients, a source checkout and Docker are under
Install.
Why this exists
"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)
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:
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:
A source checkout with Chromium, a smoke test and client registration in one
step:
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.
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:
(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
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)
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
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:
Set a key as an environment variable or .env line, or on the local settings
page:
(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:
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:
Every setting is listed in docs/CONFIGURATION.md and
documented in .env.example.
Development
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.