Brave Search MCP Server: web results, images, videos, rich results, AI summaries, and more.
Websearch is installed from its publisher's own source and answers where it runs, so this marketplace is not in the path of a single call. There is no address here to send one to, and a panel that pretended otherwise would be showing you an answer we made up. Install it and call it from your own client — the Installation tab has the entry for each one.
What it does
Multi-engine web search, fetch, browser control. 11 tools, keyless lanes.
Quickstart
# 1 — add it to Claude Code
claude mcp add --scope user sk-dev-ai-websearch-mcp '--' uvx --from skdev-websearch-mcp websearch-mcp
# 2 — ask your agent for something these tools do
# doctor, ping, search and 17 more
Websearch costs nothing on mcprush: there is no plan to choose here, no cap to set and nothing mcprush can bill you for.
Collected from a public index. Nobody has claimed this account, so nothing here was written by its author — claim it if it is yours.
Where are you running it?
Every route below installs the same thing and ends at the same approval screen. This one runs on your machine: your client starts Websearch as a process under your own user, with your files and your network, so the tool surface below is what it can do to your computer rather than to a server somewhere else. Its scan result is on the Security tab — read the surface before you approve it.
This is a public server: you run it yourself and this marketplace is not in the path. You need uv (docs.astral.sh/uv): uvx comes with it. Claude Code registers it in one command; --scope user makes it available in every project. The '--' is in quotes so that PowerShell passes it on.
claude mcp add --scope user sk-dev-ai-websearch-mcp '--' uvx --from skdev-websearch-mcp websearch-mcpReconnect, or start a new session, and the tools appear in the model’s tool list.
Nothing is required, but it can take GROQ_API_KEYS (Optional. Groq keys for synthesis and query rewriting.), TAVILY_KEYS (Optional. Tavily search lane.), NV_KEY (Optional. NVIDIA embeddings for ranking.), SE_KEY (Optional. Stack Exchange key (10k/day instead of 300).), S2_KEY (Optional. Semantic Scholar key (1 RPS).) if you want to set them.
One config entry your client uses to start the process locally. A local server runs with your file system and your network, which is why it is priced without metering.
20 tools, with what each one reads, writes and reaches shown before you agree — the same list on every route above. Read the tool surface.
Tool surface
What the model actually sees. Descriptions are diffed on every release — see version history.
Read from its source code. A server that builds its tool list when it starts can list more tools than this.
Preflight: report which lanes are usable RIGHT NOW and the exact command to enable the rest. Run this first, and whenever a feature returns empty results. Distinguishes 'broken' from 'needs optional setup' — the browser lanes (Google AI Mode, browser_action, bot-wall bypass) require a…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| probe_network | boolean | no | Run an outbound HTTPS check (adds ~1s) |
Lightweight connectivity check — verifies internet and key search endpoints are reachable. Use before expensive calls when connectivity is uncertain. No params needed. e.g. ping()
No parameter schema on file.
Multi-engine web search with dedup, reranking, and synthesis. Use for open research questions; for a known URL use fetch, for papers use arxiv, for encyclopedic facts use wikipedia. depth=1 returns snippets with relevance_score+fetch_relevance per result. depth>=2 fetches full pages + re-ranks.…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| query | string | yes | — |
| count | integer | no | — |
| depth | integer | no | Effort: 1=snippets only, 2+=fetch the top pages and rerank on full text. Defaults to 3 when a model lane is available (GROQ_API_KEYS or the in-tool model) and 1 otherwise; WEBSEARCH_DEFAULT_DEPTH pins |
| search_type | string | no | — |
| timelimit | string | no | Time filter: d/w/m/y |
| safesearch | string | no | — |
| language | string | no | Content language for Wikipedia/summaries |
| upload_urls | array | no | GAI file upload: supported formats .avif .bmp .heic .heif .jpeg .pdf .png .webp. 10MB max. Only one file per call (GAI drops all but the last). Local: file:///path or remote URL. |
| start_date | string | no | Tavily date filter start (YYYY-MM-DD) |
| end_date | string | no | Tavily date filter end (YYYY-MM-DD) |
| include_domains | array | no | Tavily domain include filter |
| exclude_domains | array | no | Tavily domain exclude filter |
| synthesize | boolean | no | Synthesize a cited answer from the top results. The answer is deliberately short and says so when it is truncated. |
| synthesize_length | string | no | short = at most 6 sentences; long = up to 12, for genuinely multi-part questions |
| follow_up | boolean | no | Allow ONE extra retrieval round when the first answer admits a gap (rests on a single source, a claim could not be tied to its source, or it says part of the question is unanswered). Adds 20-40s when |
| domain | string | no | AnySearch vertical: finance, code, academic, health, travel, legal, security. Guessed from query via simple heuristic — may be wrong, omit for general search. |
| anysearch_tag | string | no | AnySearch precise sub-domain tag in {domain}.{sub_domain} format (e.g. code.doc, finance.us_stock). Overrides domain. |
| anysearch_zone | string | no | AnySearch geo zone (cn or intl) |
| anysearch_language | string | no | AnySearch content language (e.g. en, zh-CN) |
| google_ai_only | boolean | no | Skip all other search engines and answer only via Google AI Mode. Requires a signed-in Chromium session reachable over CDP (WEBSEARCH_CDP_URL); on a headless server or without a browser this returns a |
URL to markdown/text. Auto-fallback: direct fetch → CDP for blocked/JS pages. Supports PDF, EPUB, DOCX. SSRF-protected. Use focus="query" to filter content by relevance. Paginated via offset (response: next_offset). Results cached 1h; cache_ttl=0 fresh. For structured JSON extraction use extract…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| url | string | yes | — |
| max_chars | integer | no | Chars to return per call (for pagination) |
| offset | integer | no | Char offset for paginated reads (0 = start). Response includes is_truncated, next_offset, total_extracted_chars (full page size). |
| focus | string | no | BM25 relevance filter — extract only content blocks relevant to this query. Use ONLY to pull specific sections from a large page (e.g. focus='pricing'). On crucial pages INSTEAD omit focus and fetch t |
| cache_ttl | integer | no | Cache TTL in seconds (0 = force fresh fetch). Cache keyed by URL+extraction_type+css_selector, not focus/offset. |
| cache_bust | boolean | no | Ignore a fresh cache entry and re-fetch. The response carries cache with hit/age_s/ttl_remaining_s either way, so 'is this stale?' is answerable without guessing. |
| css_selector | string | no | CSS selector — extract only the matching element's text (CDP tier only; ignored on the direct-fetch tier) |
| extraction_type | string | no | — |
| target_language | string | no | — |
| output_format | string | no | — |
| fast | boolean | no | — |
| raw | boolean | no | Skip CDP/trafilatura, return raw text directly (use for GitHub raw files, pastebin, etc.) |
| network_idle | boolean | no | Wait for network idle before extracting (slower but captures JS-rendered content; CDP tier only) |
| include_images | boolean | no | Include image captions/alt text |
| include_links | boolean | no | Include hyperlinks in output |
| include_formatting | boolean | no | Preserve text formatting (bold, italic, etc) |
| include_tables | boolean | no | Extract tables from HTML |
| start_line | integer | no | 1-based start line for reading a range (slices content by newline) |
| end_line | integer | no | 1-based end line (inclusive). Use with start_line for targeted reading. |
| quality_floor | number | no | Min acceptable extraction quality 0-1 (length+density+structure score); below it the result is flagged low_quality |
ARIA accessibility snapshot (LLM-readable page text). Use to see a page's interactive structure and what is actually visible; for readable article content use fetch. e.g. screenshot(url='https://example.com')
| Parameter | Type | Required | Notes |
|---|---|---|---|
| url | string | yes | — |
| max_chars | integer | no | — |
| depth | integer | no | ARIA snapshot tree depth limit |
| verbose | boolean | no | Show all ARIA roles (not just interactive) |
| start_line | integer | no | 1-based start line for snapshot text range |
| end_line | integer | no | 1-based end line (inclusive) for snapshot text range |
Drive a real browser page (needs a Chromium-based browser with --remote-debugging-port on this host, e.g. chromium/google-chrome/brave/Helium, set via WEBSEARCH_CDP_URL; run doctor() to check): navigate, click, type, press a key, evaluate JS, read page HTML/text, get the accessibility tree, or…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| action | string | no | navigate=go to url, click=mouse click on selector, type=insert text (focuses selector first if given), key=press a key (Enter/Escape/Tab), evaluate=run JS and return its value, html=page HTML, text=in |
| url | string | no | URL to act on (required for action=navigate; optional for other actions — the tab navigates there first). SSRF-validated. |
| selector | string | no | CSS selector — required for action=click, optional focus target for action=type, element for action=text |
| text | string | no | Text to type (action=type) |
| key | string | no | DOM key value to press (action=key), e.g. Enter, Escape, Tab, ArrowDown |
| expression | string | no | JavaScript expression to evaluate in the page (action=evaluate). Arrow functions are auto-invoked. |
| wait_state | string | no | Load milestone to wait for after navigating (and for action=wait) |
| steps | array | no | Ordered multi-step flow executed in ONE tab (max 25). Each step is an object with the same fields as the top-level params (action, url, selector, text, key, expression, wait_state). Use for flows like |
| session_id | string | no | Reuse a persistent tab from browser_session(action='create') instead of opening a throwaway one. Required for anything stateful across calls: logins, cookies, multi-page flows, forms. Without it, each |
| timeout | number | no | Per-step timeout in seconds (1-120) |
| max_chars | integer | no | Max chars returned for html/text/aria (200-200000) |
| full_page | boolean | no | action=screenshot: capture beyond the viewport |
| image_type | string | no | action=screenshot: image format |
| quality | integer | no | action=screenshot: JPEG quality 0-100 |
| depth | integer | no | action=aria: accessibility tree depth (1-100) |
Persistent browser tab you can reuse across calls (needs a Chromium with --remote-debugging-port; run doctor()). Without a session every browser_action call gets a fresh tab that is closed immediately, so logins, cookies and multi-step flows cannot survive. Create a session, then pass session_id…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| action | string | no | — |
| session_id | string | no | Required for action=info/close; omitted from action=close closes every session |
| label | string | no | Human label folded into the generated id, e.g. 'login' |
| url | string | no | Optional page to open in the new session |
Fetch several URLs in one call. Replaces a loop of fetch calls or a throwaway requests script: dedups URLs, caps concurrency, honours robots.txt, shares the cache, and returns per-URL success/status/content plus counts. Reports truncated when the batch cap (50) is hit so you know to call again…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| urls | array | yes | — |
| max_concurrent | integer | no | Parallel fetches (1-8) |
| max_chars | integer | no | — |
| cache_ttl | integer | no | Shared cache TTL in seconds; 0 forces a refetch of every URL. |
| focus | string | no | Keep only content relevant to this query |
| respect_robots | boolean | no | — |
Breadth-first crawl of a site with hard caps. Replaces a bespoke scraper and makes politeness non-optional: per-page cap, depth cap, robots.txt, dedup, concurrency limit. Returns each page's title and trimmed content plus a stop_reason so you know whether the site was exhausted or a cap stopped…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| start_url | string | yes | — |
| max_depth | integer | no | Link hops from start (0-5) |
| max_urls | integer | no | Hard page cap (1-100) |
| same_domain | boolean | no | — |
| include_patterns | array | no | Only URLs containing one of these substrings |
| exclude_patterns | array | no | — |
| concurrency | integer | no | — |
| respect_robots | boolean | no | — |
| max_chars | integer | no | Content kept per page |
Every link on a page with its anchor text, title and rel. Replaces hand-parsing HTML before crawling or finding a 'next' button. Resolves relative hrefs, drops javascript:/mailto:, dedups, and can stay on one domain. Use before crawl or to locate a specific navigation target.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| url | string | yes | — |
| same_domain | boolean | no | — |
| max_links | integer | no | — |
| include_text | boolean | no | — |
Pull HTML tables into json, csv or markdown. Replaces a pandas/lxml script every time a page has a pricing or stats table. Reports tables_found so you can pick one by index, and marks truncated when max_rows is hit. Use extract(css) for non-tabular structure instead.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| url | string | yes | — |
| selector | string | no | CSS selector to narrow which tables are considered |
| fmt | string | no | — |
| index | integer | no | 0-based index among matched tables |
| max_rows | integer | no | — |
Save a URL to disk and return the local path, byte count, sha256 and content type. Replaces curl/requests plus a filename guess. Writes only inside dest_dir (default ~/.cache/websearch/downloads) and refuses path traversal. Marks truncated if the byte cap stopped the transfer, so you know the file…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| url | string | yes | — |
| dest_dir | string | no | — |
| filename | string | no | — |
| max_bytes | integer | no | — |
Has this page changed since the last time it was fetched? Compares the live page against the cached snapshot and returns changed/old_hash/new_hash plus the added and removed lines. Replaces a hand-rolled polling and hashing script. Returns had_previous=false on the first call for a URL: fetch it,…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| url | string | yes | — |
| extraction_type | string | no | — |
Fill several form fields, click submit, and optionally read the result - in one call. Replaces a multi-step browser_action program full of fragile selectors. Works on a session so the submitted state is real; without session_id it creates a temporary session and closes it afterwards. fields[] is…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| fields | array | yes | [{selector: '#email', value: 'a@b.c'}, {selector: '#tos', action: 'click'}] |
| session_id | string | no | Reuse a persistent tab; omit to use a temporary one |
| url | string | no | Page to open first |
| submit_selector | string | no | Submit button; omit to fill without submitting |
| wait_state | string | no | — |
| read_selector | string | no | CSS selector to read after submitting; empty reads the whole page |
| timeout | number | no | — |
Click a 'next' control repeatedly and collect a value from each page. Replaces a pagination loop script. Stops at max_pages, when the next control is not clickable, or when the collected value stops changing (which usually means the last page). Always returns stop_reason and marks truncated, so…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| next_selector | string | yes | CSS selector for the next-page control |
| session_id | string | no | — |
| url | string | no | Page to open first |
| max_pages | integer | no | Hard page cap (1-25) |
| read_selector | string | no | What to collect from each page; empty reads the whole page |
| wait_state | string | no | — |
| wait_ms | integer | no | Pause after each navigation |
| stop_when_unchanged | boolean | no | — |
| timeout | number | no | — |
Full Wikipedia API client: articles, summaries, categories, links, pageviews, revisions, backlinks, geosearch, recent changes, random pages. Use for encyclopedic facts; for open research use search. e.g. wikipedia(query='Python', action='summary')
| Parameter | Type | Required | Notes |
|---|---|---|---|
| action | string | no | search=find articles, summary=REST fast extract, summary_action=Action API+images, categories=list page cats, links=page links, pageviews=traffic stats |
| query | string | no | — |
| count | integer | no | — |
| language | string | no | — |
| lat | number | no | — |
| lon | number | no | — |
| category | string | no | Category name for categorymembers action (without Category: prefix) |
| namespace | integer | no | Namespace filter (0=articles, 14=categories). Applies to search/links/allpages/random actions. |
| days | integer | no | Days of pageview history (pageviews action) |
| type_filter | string | no | Change type filter for recentchanges: edit/new/move/log/categorize |
| include_images | boolean | no | Include thumbnail images in summary_action |
| distance | integer | no | Search radius in meters for geosearch |
Search arXiv academic papers (single-source; for multi-source paper search use codesearch papers). Use raw_query for boolean operators (AND, OR, ANDNOT), phrase search (ti:"exact phrase"), wildcards (au:smith*). e.g. arxiv(query='cs.AI transformer', count=5)
| Parameter | Type | Required | Notes |
|---|---|---|---|
| query | string | yes | — |
| count | integer | no | — |
| search_field | string | no | — |
| sort_by | string | no | — |
| sort_order | string | no | — |
| start | integer | no | — |
| id_list | string | no | Comma-delimited arXiv IDs |
| category | string | no | arXiv category filter (e.g. cs.AI, math.CO) |
| raw_query | string | no | Raw arXiv search_query syntax with boolean operators (AND/OR/ANDNOT), phrase, wildcards. Overrides query+search_field. |
Discover all pages on a website via sitemap XML (primary) and HTML link extraction (fallback). Use to survey a site's pages before fetching individually. Returns the base domain, source type, total count, and an array of discovered URLs with metadata (last_modified, priority, changefreq when…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| url | string | yes | Full URL of the site to map (e.g. https://example.com) |
| max_urls | integer | no | Cap on returned URLs |
| max_depth | integer | no | Recursive link extraction depth (0=homepage only). Only used when no sitemap exists. |
| include_sitemap | boolean | no | Try sitemap discovery first |
| include_links | boolean | no | Fall back to HTML link extraction when no sitemap |
| same_domain | boolean | no | Only include URLs from the same domain |
| exclude_patterns | array | no | Regex patterns to exclude matching URLs |
| rank | boolean | no | Score each URL by fetch quality + sitemap priority and return important-first with rank_score (costs one scored pass; use before deep-fetching a site) |
Extract structured JSON from a webpage using LLM, CSS, or regex strategies. Persistent cache — repeat calls free. For LLM strategy, describe what you want and get clean JSON back. For CSS strategy, provide field names (fastest, free). For raw page content, use fetch instead. Examples:…
| Parameter | Type | Required | Notes |
|---|---|---|---|
| url | string | yes | Target URL to extract data from |
| instruction | string | no | Natural language extraction instruction (used with strategy=llm). Example: 'extract all product names, prices, and ratings from this page' |
| strategy | string | no | css=CSS-selector-based extraction (fast, free), llm=AI-powered (costs quota), regex=pattern-based (emails, phones, URLs) |
| fields | array | no | List of field names for extraction (e.g. ['name', 'price', 'rating']). Used with strategy=css or strategy=llm |
| chunk_threshold | integer | no | Max tokens per chunk for LLM extraction (lower = cheaper, higher = more context) |
| css_selector | string | no | CSS selector for the container element (used with strategy=css). Defaults to 'body' |
| provider | string | no | LLM provider string in LiteLLM format (e.g. groq/openai/gpt-oss-120b, openai/gpt-4o, ollama/llama2) |
PDF extraction: PyMuPDF fast text-layer path, Docling+OCR fallback for scanned/image-only PDFs (CPU). Formats: markdown (default), json, html, or comma combos like 'markdown,json'. e.g. pdf_extract(input_path='/path/to/doc.pdf', format='markdown')
| Parameter | Type | Required | Notes |
|---|---|---|---|
| input_path | array | yes | PDF file paths or URLs (local files, http/https, file://) |
| format | string | no | — |
| password | string | no | PDF password for protected files |
| pages | string | no | Page range e.g. 1-5,8,10-12 |
| hybrid | string | no | Force the Docling OCR fallback regardless of text layer (upper bound: CPU cost only) |
| hybrid_mode | string | no | Alias for hybrid (same values) |
| force_ocr | boolean | no | Shortcut: force the Docling OCR fallback even when a text layer exists |
- Every tool, no call limit
- No card, and mcprush charges nothing for it
- Source published under MIT
- Runs on your machine — nothing of it reaches our gateway
- Nothing to cap, because mcprush bills nothing
What counts against your monthly calls
| Tool | Unit | Calls used | Out of the allowance |
|---|
Nothing here is billable: mcprush charges nothing to install Websearch or to call it, at any volume.
Two independent axes, because powerful and malicious are different questions. The grade is threat only. The capability level is blast radius, and it is never a penalty on the grade — it is priced as one subtract-only term in the score, where you can see it.
| Term | Level | What it prices | Points |
|---|---|---|---|
| capability-exposure | high | capability blast radius (high) — client exposure if the model is manipulated | −6 |
| verification-discount | repo | publisher verification (public source) — no provenance, but the source is public and inspectable | −1 |
| coverage-honesty | source | inspection depth (source) — how much of the target the scan could see | −0 |
What the scan could actually read
A grade is only as meaningful as its coverage, so the scanner publishes its own depth before it publishes its result.
Tools were statically extracted from the published source (18 recovered), not enumerated from a running server. Tool-poisoning, Unicode-smuggling, capability and toxic-flow analysis ran on this inferred surface, but a mis-parsed registration could be missed or mis-attributed, so tool-derived findings are capped below “confirmed”. To grade the real runtime surface, scan the running server: --command "npx -y <package>".
Capability — what it could do if the model were manipulated
Tags derived from each tool’s schema and the implementation, not from what the tool calls itself. high is the level these add up to.
| Tool | Capability tags | Why the tag was assigned |
|---|---|---|
| doctor | no tags | |
| ping | no tags | |
| search | untrusted-input | untrusted-input: keyword "web_search" |
| fetch | untrusted-input | untrusted-input: keyword "fetch" |
| screenshot | untrusted-input | untrusted-input: keyword "fetch" |
| browser_action | no tags | |
| browser_session | no tags | |
| fetch_many | untrusted-input | untrusted-input: keyword "fetch" |
| crawl | untrusted-input | untrusted-input: keyword "crawl" |
| extract_links | untrusted-input | untrusted-input: keyword "crawl" |
| extract_table | no tags | |
| download | untrusted-input | untrusted-input: keyword "download" |
| diff_page | untrusted-input | untrusted-input: keyword "fetch" |
| wikipedia | no tags | |
| arxiv | no tags | |
| map_site | no tags | |
| extract | no tags | |
| pdf_extract | no tags |
Toxic-flow graph
The lethal trifecta, checked as a graph rather than as a checklist: untrusted input, a sensitive source and an external sink have to meet before there is a path worth worrying about.
The public result for this release does not print the flow graph, so there is nothing to show here. That is not the same as "no paths were found": what the scan did read is above, under coverage.
Supply chain and provenance
This is the first scan of this surface here, so there is nothing yet to compare it against.
Every result on this tab comes from one deterministic pass over the published package — offline, rule by rule, and auditable line by line above. Same methodology version, same bytes, same score.
Release history
Always latest — the install command names no version, so it installs the newest release when it runs; the current release on file is 1.10.0. Pin a release below and the command asks for exactly that one.
No release note was published with this version.
One review per account, from a signed-in account that does not publish this listing. Nothing else is asked — you can say what you think before you install it. Publishers can reply once per review, and a review can be edited or deleted by whoever wrote it.
Any signed-in account that does not publish Websearch can review it, once — before installing it or after. A review from an account that has installed it is marked as one.
Nobody has reviewed this listing. The rating on the card is the mean of the reviews written here and nothing else, so there is no rating until somebody writes the first — which takes a signed-in account that does not publish it, and nothing else.