mcp-human-search
Runs Baidu searches through a real browser on a persistent profile as part of the fallback chain, handling Baidu's redirect links (kept as-is since they resolve for the reader) and supporting headed CAPTCHA solving plus Baidu passport sign-in so cookies persist for future headless searches.
Runs DuckDuckGo searches in a persistent server-private browser profile as one stop in the ordered engine fallback chain, returning cleaned organic results with provenance about which engine served them and why others were skipped. Supports CAPTCHA handoff via a headed sign-in window and a 10-minute cooldown for blocked engines.
Drives a real Google search through a persistent browser profile: types the query with human-like jitter, verifies and submits it, extracts organic results, unwraps /url?q= redirect links, and fails over to other engines when Google shows a CAPTCHA or bot wall. Includes a sign-in tool that opens a headed window on Google's profile so you can solve a challenge or sign in to a Google account, after which cookies persist and Google rejoins the fallback chain.
Runs Sogou searches via a real browser on a persistent profile in the engine fallback chain, extracting organic results while keeping Sogou's redirect links intact, with CAPTCHA/login handoff through a headed sign-in window.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-human-searchsearch for the latest AI breakthroughs"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-human-search
Human-like web search as a Model Context Protocol server — a cross-harness port of dsh-human-search. A real browser drives real search engines, with an ordered fallback chain across Google, DuckDuckGo, Bing, Baidu, and Sogou, CAPTCHA/account-login handoff to you, and cookies that persist per engine — owned by this server only.
Any MCP-capable harness can use it: DeepSeek Harness, pi.dev, Claude Code, Cursor, VS Code, and anything else that speaks MCP over stdio.
No harness installation is modified. Everything the server writes lives under one state root — $HUMAN_SEARCH_HOME or ~/.human-search/ (profiles, cookies, optional server-managed Chromium). Remove that directory and the machine is exactly as it was.
How it works
The harness launches the server over stdio and gets three tools:
human_search,human_search_sign_in,human_search_status.Each search launches (or reuses) a persistent, server-private Chromium profile per engine, opens the engine's home page, types the query like a person (per-character jitter, small pauses), and reads the organic results.
The typed submit is verified, not assumed: the search box's value is read back (a page whose JavaScript has not hydrated yet silently swallows keystrokes), the autosuggest panel is dismissed before Enter (with it open, Enter submits a trending suggestion instead of your query), and the settled page is checked — a SERP for a different query, a "Loading…" bot-check stub, or results sharing no word with the query (a decoy SERP under IP-reputation pressure) is never trusted. Anything unusable retries once through the engine's results URL, then fails over.
Engines are tried strictly in your configured order. Any failure — CAPTCHA or bot wall, timeout, parse failure, zero results, an engine busy with your sign-in window — fails over to the next engine. The returned result notes which engine served it and why others were skipped.
When an engine blocks with a CAPTCHA:
the search fails over immediately (the other engines keep answering), and
the server opens a headed browser window on the machine running the server with that engine's profile, so you can solve the CAPTCHA and optionally sign in to your account (Google account for Google, Microsoft account for Bing, Baidu passport, …). An MCP logging notification is emitted for harnesses that surface them (pi.dev appends them to
~/.pi/agent/mcp.log).once the block clears, cookies are persisted (in the profile and as a portable
storageStatesnapshot) and the engine rejoins the chain automatically.
A blocked engine is skipped for a 10-minute cooldown after a failed sign-in attempt so the chain's budget isn't burned on it; call
human_search_sign_inany time to re-open the window.
Related MCP server: ddgs-mcp
Install
Prerequisites: Node ≥ 20.
# run directly with npx (no install step)
npx -y mcp-human-search
# or from a local checkout (development)
pnpm install && pnpm build
node lib/cli.jsBrowser setup
The server uses, in order:
an explicit browser executable path (
executablePathin the config file, orHUMAN_SEARCH_BROWSER),your system Google Chrome / Microsoft Edge / Chromium,
a server-managed Chromium under
<state root>/browsers/.
For 3, install once per machine:
npx -y mcp-human-search install-browser # or: node lib/cli.js install-browserHeadless searches prefer the server-managed full Chromium (new-headless mode — a far less bot-flagged fingerprint than the dedicated headless shell; Google serves the shell a CAPTCHA wall even signed in), with the lighter headless shell as fallback. Whichever binary wins, a HeadlessChrome user-agent marker — an instant bot signal — is probed once and rewritten to the headful-equivalent string automatically.
Check what the server sees without connecting a harness:
npx -y mcp-human-search statusFirst-run warm-up (recommended)
Fresh machines and datacenter/VPN IPs start with no engine reputation, which means CAPTCHAs or decoy results. Warm the profiles once, as a human, from a desktop session (WSLg/X11 on Windows counts):
npx -y mcp-human-search warm google duckduckgo bing # any subset / orderOne headed window per engine opens on the server's shared profile: run one search, solve any challenge that appears, optionally sign in (Google/Microsoft/Baidu accounts all raise the trust floor), then close the window to advance. Cookies persist in the profile the headless chain reuses for every future search. Set HUMAN_SEARCH_BROWSER=/path/to/chrome to warm with a specific binary.
Harness configuration
DeepSeek Harness (DSH)
Add one row via dsh-mcp-client to your composition:
- id: mcp-human-search
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: human-search
transport: stdio
command: npx
args: ['-y', 'mcp-human-search']The tools appear as mcp__human-search__human_search etc. Note this adds a tool alongside the stock web_search — steer the model with prompting (or disable the stock tool) if you want human search preferred. The default 50 s chain budget fits DSH's 60 s toolCallTimeoutMs. If you want the stock web_search tool itself backed by this engine chain, use the native dsh-human-search plugin instead.
pi.dev
pi mcp add human-search -- npx -y mcp-human-searchor edit ~/.pi/agent/mcp.json (project-level: .pi/mcp.json):
{
"mcpServers": {
"human-search": {
"command": "npx",
"args": ["-y", "mcp-human-search"],
"exposure": "direct",
"timeout": 90,
"description": "Human-like web search via a real browser with engine fallback (Google, DuckDuckGo, Bing, Baidu, Sogou)"
}
}
}exposure: "direct" declares the three tools like built-ins — the default codemode exposure would hide them behind script discovery, which rarely pays off for a three-tool server. timeout (seconds, default 60) gives headroom over the 50 s chain budget. Run /mcp in a session (or pi mcp list in a shell) to inspect the connection.
Claude Code
claude mcp add human-search -- npx -y mcp-human-searchCursor / VS Code
Standard mcpServers entry:
{
"mcpServers": {
"human-search": { "command": "npx", "args": ["-y", "mcp-human-search"] }
}
}Tools
human_search
Input: { query: string, maxResults?: number (1–50, default 15) }.
Runs the ordered fallback chain. Success returns a provenance note ("Human web search served by Google. Skipped: DuckDuckGo: blocked (…).") followed by a numbered result list, plus structuredContent (servedBy, sources, truncated, attempts) for clients that consume it. When every engine fails, the tool returns an error with the per-engine trail and a fix hint.
human_search_sign_in
Input: { engine: "google" | "duckduckgo" | "bing" | "baidu" | "sogou" }.
Opens a headed browser window on the machine running this server, on that engine's persistent profile, so you can solve a CAPTCHA and/or sign in. You type credentials into the engine's own pages; the server never sees them. Returns immediately: window opened / already open / cannot open (with headless-host guidance). While the window is open, searches on that engine fail over instantly instead of queueing; the episode times out after 10 minutes.
human_search_status
No input. Reports — without any network calls — whether a usable browser was found, per-engine health (ok / blocked / signing-in, with reasons), sign-in windows currently open, the state root, and the resolved configuration.
Configuration
Configuration is resolved once at server start (restart to reload): defaults → <state root>/config.json → environment variables.
<state root>/config.json (all keys optional):
{
"engines": [{ "id": "google", "enabled": true }, { "id": "bing", "enabled": true }],
"headless": true,
"locale": "",
"executablePath": "",
"perEngineTimeoutMs": 15000,
"chainBudgetMs": 50000,
"idleCloseMs": 300000
}engines — the array order is the fallback order; engines not listed are appended (enabled) in the default order, so the chain never silently loses one. Set
"enabled": falseto exclude one.headless —
falseshows every search in a visible window (debugging).locale — overrides every engine's default locale.
executablePath — explicit Chrome/Edge/Chromium binary.
perEngineTimeoutMs — per-engine budget (1 000–60 000).
chainBudgetMs — whole-chain budget (10 000–120 000); keep it below your harness's tool-call timeout (DSH and pi.dev default to 60 s).
idleCloseMs — close idle engine browsers after this long;
0keeps them alive.
Environment overrides (win over the file):
Variable | Meaning |
| State root (default |
| Comma list: the enabled set and its order ( |
| Explicit browser executable path |
|
|
| Locale override |
| Per-engine budget |
| Whole-chain budget |
| Idle browser close delay ( |
A malformed config.json is a stderr warning and defaults — never a crash.
Engine notes, learned from live validation:
Result links wrapped in engine redirects (Google
/url?q=, Bing/ck/abase64 payloads) are unwrapped to their targets; Baidu and Sogou redirect links are kept as-is (they resolve for the reader).Extracted results must share at least one word with the query (for Latin-script queries). An engine under IP-reputation pressure sometimes serves a perfectly formed SERP whose results are unrelated decoys; those are treated as "no results" and the chain fails over instead of citing junk.
Baidu and Sogou are Chinese engines and can be slow outside China; raise
perEngineTimeoutMsif they time out on your network.If an engine keeps failing on your IP, run the warm-up once — a minute of real usage builds more trust than any amount of headless retrying.
CAPTCHA and account login
The interactive window appears on the machine running the server. When that's your desktop or laptop, it's your screen. On a headless server there is no display — the server logs why, keeps failing over, and you can warm the profiles on a desktop with
mcp-human-search warmagainst the sameHUMAN_SEARCH_HOME, then copy the state root over (or pointHUMAN_SEARCH_HOMEat a shared location). SSH with X forwarding also works.You never have to give the server credentials: you type them into the engine's own pages, in a real browser profile owned by this server. Cookies persist only there.
While a sign-in window is open, that engine's searches fail over instantly instead of queueing.
Migrating from dsh-human-search
The profiles are interchangeable. To reuse your warmed cookies, copy the DSH plugin's state over the new root before first use:
cp -a ~/.dsh/web-human-search/. ~/.human-search/Uninstall
Remove the MCP server entry from your harness configuration, then delete the state root:
rm -rf ~/.human-searchPrivacy & footprint
Cookies, local storage, and exported
storageStatesnapshots live in the state root (mode 0700) and are never sent anywhere except the engines they belong to. The model sees search results only — never cookies or credentials.The server performs searches exactly as rendered to a human in a browser; it does not use scraper endpoints or APIs.
PLAYWRIGHT_BROWSERS_PATHis pointed at the server's own browsers directory inside the server process; a server-managed Chromium never touches other tooling's caches.
Development
pnpm install
pnpm build # lib/server.js + lib/cli.js (committed; git installs don't run build scripts)
pnpm test # unit tests (chain logic, config, engine extraction, MCP tool surface)
pnpm typecheckLayout: src/engines/ per-engine adapters (pure markup descriptions), src/chain.ts the fallback chain and human-like driver, src/browser.ts the per-engine persistent-browser pool, src/login.ts the sign-in episode coordinator, src/search.ts the search tool logic, src/server.ts the MCP server, src/config.ts/src/state.ts startup configuration and on-disk state, src/cli.ts the mcp-human-search binary. tests/ runs without a browser via scripted fake pages, and includes an in-memory-transport MCP client test of the full tool surface.
License
MIT
Available Tools
3 toolshuman_searchA
Search the web the way a person does: a real browser drives real search engines (Google, DuckDuckGo, Bing, Baidu, Sogou) in a persistent per-engine profile, trying them in a configured fallback order. CAPTCHAs and bot walls fail over to the next engine and open a headed sign-in window on the server machine for the user to solve (see human_search_sign_in); cookies persist across searches. Returns a provenance note (which engine served, which were skipped and why) followed by a numbered result list, plus structured sources for citation. Use human_search_status to inspect engine health.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | The search query, exactly as a person would type it | |
| maxResults | No | Cap on returned sources (default 15) |
Output Schema
| Name | Required | Description |
|---|---|---|
| sources | Yes | |
| attempts | Yes | Per-engine attempt trail in try order |
| servedBy | Yes | Engine that served these results |
| truncated | Yes | True when sources were cut to maxResults |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so richly: per-engine persistent profiles, configured fallback order, CAPTCHA/bot-wall failover, a headed sign-in window opened on the server machine, and cookie persistence across searches. These are non-obvious side effects and failure modes an agent could not infer from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and mechanism, and every sentence conveys operative detail (engines, failover, persistence, return shape, sibling routing). It is dense and the long middle sentence is heavy, but nothing is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a two-parameter tool with an output schema already present, the description supplies everything else an agent needs: engine set, fallback semantics, CAPTCHA handling path, state persistence, and a pointer to the status sibling. No material gap remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% – both 'query' and 'maxResults' (with its 1-50 range and default of 15) are already documented in the schema. The description adds no syntax or format guidance beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Search the web the way a person does') and immediately names the mechanism (real browser driving Google, DuckDuckGo, Bing, Baidu, Sogou in a persistent profile). It is clearly distinguishable from human_search_status and human_search_sign_in, which it names explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes to human_search_status for engine health and to human_search_sign_in for the CAPTCHA sign-in flow, and describes the fallback-order context that governs when this tool is used. It stops short of stating when *not* to use it (e.g., vs. a lightweight/headless search), so it is strong but not fully exclusionary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
human_search_sign_inA
Open a headed browser window on the machine running this MCP server, on the engine's own persistent profile, so the user can solve a CAPTCHA and/or sign in to their account (Google, Microsoft, Baidu, ...). The user types credentials into the engine page itself; this server never sees them. Cookies persist for all future searches. While the window is open, searches on that engine fail over to the others instantly. Requires a display on the server machine (SSH X forwarding counts); on a headless host, warm the profiles with the mcp-human-search warm CLI on a desktop instead.
| Name | Required | Description | Default |
|---|---|---|---|
| engine | Yes | Engine whose profile opens in the headed window |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers: credentials never reach the server, cookies persist across future searches, concurrent searches on that engine fail over to the others, and a display (or SSH X forwarding) is required. These side effects and prerequisites are exactly what an agent needs before invoking a headed-browser action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the action and keeps every sentence load-bearing (purpose, credential safety, cookie persistence, failover, display requirement, headless fallback). It is somewhat long and reads as one dense block, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema and no annotations, yet the description covers prerequisites, security posture, persistence, and concurrency behavior. An agent has everything needed to decide whether invoking it is safe and appropriate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single `engine` parameter is enumerated and documented, so the schema does the heavy lifting. The description adds only that the window opens on that engine's persistent profile, which is marginal beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: opening a headed browser window on the MCP server's own persistent profile so the user can solve a CAPTCHA or sign in. The CAPTCHA/credential purpose implicitly separates it from human_search and human_search_status, which cannot fill that role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear trigger (user must solve a CAPTCHA or sign in) and an explicit when-not with an alternative (on a headless host, use the `mcp-human-search warm` CLI on a desktop instead). It never names the sibling tools human_search or human_search_status, so routing between them is still left partly to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
human_search_statusA
Report the human-search server state without touching the network: whether a usable browser was found (and which), per-engine health (ok / blocked / signing-in, with reasons), sign-in windows currently open, the state root, and the resolved configuration.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it explicitly declares no network access (implying no side effects and safety to call), and enumerates the health states (ok / blocked / signing-in with reasons). It stops short of stating auth requirements or whether any state can change as a result of the call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence leading with the verb and resource, followed by a dense but informative enumeration of returned state. Slightly list-heavy, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description usefully compensates by enumerating the returned fields (browser resolution, per-engine health with reasons, open sign-in windows, state root, config). This is nearly complete for a zero-param diagnostic tool, lacking only auth/permission prerequisites.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the baseline this scores 4. The description correctly implies a no-argument status query and adds nothing misleading about inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Report') and resource ('human-search server state'), and the enumeration of what is reported (browser found, per-engine health, sign-in windows, state root, config) pins the scope precisely. This clearly distinguishes it from the diagnostic-vs-action split with siblings human_search and human_search_sign_in.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'without touching the network' implies this is a cheap, safe diagnostic call, which helps an agent choose it, but there is no explicit statement of when to use this versus human_search or human_search_sign_in. Usage is inferable but not spelled out.
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.
3 tool updates
v0.1.0- First observed
human_search - First observed
human_search_sign_in - First observed
human_search_status
TDQS
Scored across 3 tools
Each tool targets a distinct concern: human_search_status inspects server state without networking, human_search performs the actual search, and human_search_sign_in handles CAPTCHA/credential solving. The descriptions explicitly cross-reference each other (e.g. 'Use human_search_status to inspect engine health'), leaving no realistic misselection.
All three tools share the human_search_ prefix and snake_case, giving a clear family. The main action tool drops the suffix entirely (human_search instead of human_search_run/search), a minor deviation from the otherwise predictable prefix+qualifier pattern.
Three tools cleanly cover the server's narrow purpose of browser-driven human-like search: search, inspect status, and solve sign-in. Nothing is redundant and nothing feels missing by way of extra surface area.
The search/status/sign-in lifecycle is well covered, including failover and provenance reporting. Minor gaps exist—no tool to close a pending sign-in window, clear/logout cookies, or list warm profiles (some of this is only reachable via the documented CLI).
Maintenance
Related MCP Connectors
Stealth web browser for agents: search, fetch, click, download and type in persistent MCP sessions.
Hosted real Google Chrome MCP with per-user persistent state. Navigate, click, type, screenshot.
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
Scrape, crawl and search the web for AI agents via MCP.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to perform web searches with full content retrieval and multi-engine provenance, including trust scoring and local corpus persistence, via MCP integration.1 npm2Apache 2.0
- AlicenseAqualityCmaintenanceEnables keyless multi-engine web, news, image, and video metasearch plus full-page markdown extraction for AI agents over MCP, with resilient fallback across DuckDuckGo, Bing, Brave, Google, and other backends.6MIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to perform keyless web searches, extract fully rendered pages into clean Markdown, and automate a shared Chrome browser through page navigation, clicking, typing, reading, screenshots, and backtracking—all without API keys.MIT
- AlicenseBqualityBmaintenanceEnables MCP clients to run live web searches, fetch and navigate readable web pages, search images, capture PDF screenshots, and retrieve finance, weather, sports, and world-time data through a zero-configuration authenticated backend.1122 npmMIT