trackmcp
Back to directory
gabrimatic

mcp-web-search-tool

View on GitHub

An MCP server providing real-time web search capabilities to any AI model.

16 stars TypeScriptOthers Updated Aug 15, 2026
agentclaudeclaude-aimcpmcp-servermodel-context-protocolsearch-agentwebsearch-agent

Documentation

MCP Web Search Tool

An MCP server that gives an assistant live web search, full-page reading, and source citations. Stdio transport, pluggable providers, no scraper dependencies.

Claude Desktop Example
CI
License: MIT
Node

Quick start · Tools · Configuration · Clients · Security · Changelog


Overview

Five tools: `web_search`, `news_search`, `image_search`, `fetch_url`, `list_providers`. Search returns ranked summaries with stable ids; `fetch_url` reads the page behind any id. Brave Search is the primary provider; DuckDuckGo runs without a key as a fallback.

Requirements

Node.js`>= 20.18` (uses native `fetch`)
npm`>= 10`
Brave Search API keyoptional. Without it, DuckDuckGo handles `web_search`. `news_search` and `image_search` require a key.

Quick start

bash
git clone https://github.com/gabrimatic/mcp-web-search-tool.git
cd mcp-web-search-tool
npm install
cp .env.example .env   # edit BRAVE_API_KEY if you have one
npm run build
npm start

Run with Docker:

bash
docker build -t mcp-web-search .
docker run --rm -i -e BRAVE_API_KEY mcp-web-search

For Claude Desktop, Claude Code, Codex, VS Code, Cursor, or Windsurf integration, see `MCP_CLIENTS.md`.


Tools

Each tool returns two content blocks: a Markdown rendering for the model and a fenced JSON block with the structured payload. Errors come back as `isError: true` content with an actionable message; only unknown-tool calls throw a protocol error.

Live web search. Use first for current, source-backed answers.

ParameterTypeDescription
`search_term`string, requiredQuery string.
`provider`enum`"brave search"` or `"duckduckgo"`. Defaults to Brave when a key is set, otherwise DuckDuckGo.
`count`int (1–20)Number of results. Default 10.
`offset`intPagination offset (web only).
`cursor`stringOpaque cursor from a previous response.
`freshness`string`pd` (24h), `pw` (week), `pm` (month), `py` (year), or `YYYY-MM-DDtoYYYY-MM-DD`.
`country`stringISO country code.
`search_lang`stringUI language, e.g. `en`.
`safesearch`enum`off`, `moderate`, `strict`.
`include_domains`string[]Restrict results to these hosts.
`exclude_domains`string[]Drop results from these hosts (hostname-suffix match).

Recent news with source name and publish date. Brave only.

Image results with thumbnails. Brave only.

`fetch_url`

Reads a search result or arbitrary `http(s)` URL. Pass a result id from a previous search (preferred) or a full URL.

ParameterTypeDescription
`id_or_url`stringA result id (e.g. `r_a1b2c3d4e5f6`) or a full `http(s)` URL.
`url`stringDeprecated alias for `id_or_url`.
`max_chars`int (200–200 000)Soft cap on returned characters. Default 8000.
`cursor`stringCursor from a previous response to continue reading.

Returns the page title, readable text (scripts, styles, nav, footer, and aside stripped), the first 25 outbound links, HTTP status, content-type, byte length, and a `nextCursor` when truncated.

Refuses non-`http(s)` schemes and any host that resolves to a private, loopback, link-local, multicast, or IPv4-mapped IPv6 private address. Details: `SECURITY.md`.

`list_providers`

Returns the registered providers and the current default. Call this once if you are unsure whether `news_search` or `image_search` are available in this session.


Configuration

All configuration is environment-driven. Reference: `.env.example`.

VariableDefaultPurpose
`BRAVE_API_KEY`emptyBrave Search API key. When unset, DuckDuckGo is used.
`MAX_RESULTS``10`Default result count (clamped 1–50).
`REQUEST_TIMEOUT``10000`Per-request timeout in ms (1 000–60 000).
`DEFAULT_PROVIDER`autoForce a specific provider (e.g. `duckduckgo`).
`ALLOW_KEYLESS``true`When `false`, the server refuses to start without `BRAVE_API_KEY`.
`CACHE_MAX_ENTRIES` / `CACHE_TTL_MS``256` / `300000`Search cache.
`FETCH_CACHE_MAX` / `FETCH_CACHE_TTL_MS``128` / `600000`URL-fetch cache.
`FETCH_TIMEOUT_MS` / `FETCH_MAX_BYTES``15000` / `2000000`Per-request budget for `fetch_url`.

Project layout

code
src/
├── index.ts                    MCP server: tool registry, dispatch, rendering
├── config.ts                   env loader, validation, defaults
├── providers/
│   ├── SearchProvider.ts       abstract contract and shared types
│   ├── SearchProviderFactory   registry and default selection
│   ├── BraveSearchProvider     web/news/images via Brave API
│   └── DuckDuckGoProvider      keyless HTML-lite fallback
├── services/
│   ├── SearchService.ts        provider dispatch, LRU+TTL cache
│   └── FetchService.ts         safe URL fetch, readable extraction
└── utils/
    ├── http.ts                 native fetch, retry/backoff/timeout
    ├── html.ts                 zero-dep HTML to text + links
    ├── cache.ts                LRU+TTL cache
    └── ids.ts                  stable result-id minting and resolution
tests/                          vitest suite

Add a provider

ts
import { SearchProvider, SearchResponse, SearchOptions } from './SearchProvider.js';

export class MyProvider extends SearchProvider {
  getName() { return 'My Provider'; }
  override requiresApiKey() { return true; }
  async search(query: string, _opts: SearchOptions = {}): Promise {
    const out = this.emptyResponse(query, 'web');
    out.results = mapped; // shape: SearchResult[]
    return out;
  }
}

Register it in `SearchProviderFactory.setupDefaults`. Result ids are minted automatically when you call `mintResultId(url)` on each entry.


Development

bash
npm run dev          # tsx watch mode
npm test             # vitest (23 tests)
npm run lint
npm run format
npm run build

CI runs on Node 20, 22, and 24, plus a Docker image build. Tests cover the LRU+TTL cache, HTML extractor, DuckDuckGo parser, search-service caching, HTTP retry/backoff, SSRF guard, domain match, and the result-id resolver.


Example prompts

  • _"What are analysts saying about the MVP race after tonight's NBA games?"_
  • _"Summarise the top three results for `RAG benchmarks 2025` and pull the abstract from the first paper."_
  • _"Find images of the Webb telescope's latest deep field, then open the NASA page and quote the caption."_
  • _"What's the weather in Berlin right now?"_

License

MIT License

Developer

By Soroush Yousefpour

© All rights reserved.

YouTube Video

A short demo of MCP Web Search Tool with Claude:

Claude + MCP Web Search – Live Demo

Medium Article

Background on the project and how it works:

Deep Dive into MCP Web Search Tool

Support

Frequently asked questions

What is mcp-web-search-tool?

mcp-web-search-tool is An MCP server providing real-time web search capabilities to any AI model.

How do I install mcp-web-search-tool?

Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.

Is mcp-web-search-tool open source?

Yes — it is hosted on GitHub at https://github.com/gabrimatic/mcp-web-search-tool and has 16 stars.

Related MCP tools

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP