Skip to content
Conduit

mcp server

free-web-search-mcp

Lightweight, cost-free web search MCP for AI assistants.

thejasmeetsingh/free-web-search-mcpcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 21, 2026

Free Web Search MCP

A lightweight Model Context Protocol (MCP) server written in Go that gives AI assistants two abilities, with no API keys and no paid third-party services:

  • web_search: search the web and get back titles, URLs and snippets
  • web_fetch: fetch a web page and get its main content back as clean Markdown

It ships as a single binary and supports both stdio and Streamable HTTP transports.

Features

  • No API keys, accounts or subscriptions
  • Search via DuckDuckGo's HTML endpoint
  • Readable-content extraction (strips navigation, ads and footers) converted to Markdown
  • In-memory caching with TTL expiry and LRU eviction
  • Works with any MCP client: Claude Code, Claude Desktop, Cursor, and others
  • Built-in SSRF protection on page fetching
  • Response size and output length limits
  • Single static binary, easy to deploy

Tools

web_search

Searches the web and returns a numbered list of results.

ParameterTypeRequiredDescription
querystringyesThe search query
max_resultsintegernoNumber of results to return (1-20, default 10)
no_cachebooleannoSkip the cache and fetch fresh results

web_fetch

Fetches a page and returns its main content as Markdown, prefixed with the title, source URL and author when available.

ParameterTypeRequiredDescription
urlstringyesThe http or https URL to extract
max_charsintegernoMaximum characters to return (default 20000)
no_cachebooleannoSkip the cache and fetch fresh results

Plain-text responses are returned as-is. Other content types (PDFs, images, etc.) are rejected.

Installation

macOS

brew tap thejasmeetsingh/free-web-search-mcp https://github.com/thejasmeetsingh/free-web-search-mcp
brew install --cask free-web-search-mcp

Linux

wget https://github.com/thejasmeetsingh/free-web-search-mcp/releases/download/v{tag}/free-web-search-mcp_{tag}_linux_x86_64.deb
sudo dpkg -i free-web-search-mcp_{tag}_linux_x86_64.deb

Replace {tag} with the specific version number from the releases page (e.g. 0.1.0).

Windows

scoop bucket add thejasmeetsingh https://github.com/thejasmeetsingh/free-web-search-mcp
scoop install thejasmeetsingh/free-web-search-mcp

Usage

stdio (default)

The client launches the server as a subprocess. This is the simplest option for local use.

./free-web-search-mcp

Streamable HTTP

Runs the server as a network service.

./free-web-search-mcp --transport http --addr 127.0.0.1:8080

The MCP endpoint is then available at http://127.0.0.1:8080/mcp.

FlagDefaultDescription
--transportstdioTransport to use: stdio or http
--addr127.0.0.1:8080Listen address (http only)
--search-cache-ttl10mHow long search results are cached
--fetch-cache-ttl30mHow long fetched pages are cached
--cache-size100Max entries per cache (0 disables caching)

Example prompts

  • "Search the web for the latest Go release notes and summarize the highlights."
  • "Find three articles about MCP servers, then fetch the most relevant one and give me the key points."
  • "Fetch https://example.com/blog/post and turn it into bullet-point notes."

How it works

Search. The server sends the query to DuckDuckGo's HTML endpoint, parses the result list with goquery, and unwraps DuckDuckGo's redirect links to return the real destination URLs.

Fetch. The server downloads the page (capped at 5 MB), extracts the main article content with go-readability, and converts it to Markdown with html-to-markdown. If readability finds nothing, the whole page is converted instead.

Caching

Search results and fetched pages are cached in memory to avoid repeat network requests and to reduce the chance of being rate-limited.

  • Search results are cached by normalized query (default TTL: 10 minutes).
  • Fetched pages are cached by URL (default TTL: 30 minutes).
  • Each cache holds up to --cache-size entries; the least recently used entry is evicted first. Set --cache-size 0 to disable caching.
  • Only successful responses are cached. Errors and empty search results are not.
  • Pass no_cache: true to either tool to bypass the cache and refresh the entry.
  • The cache lives in the process, so it is cleared on restart. With the stdio transport, each client session starts its own process and has its own cache.

Built on the official MCP Go SDK.

Security

web_fetch makes requests to URLs supplied by the model, which means untrusted input can influence where your machine connects. To limit the risk:

  • SSRF protection: connections to loopback, private (RFC 1918), link-local, multicast and unspecified addresses are blocked. The check runs on the resolved IP for every connection, including redirects.
  • Limits: only http/https, at most 5 redirects, a 5 MB body cap and request timeouts.
  • HTTP transport has no authentication. It binds to 127.0.0.1 by default. If you expose it beyond localhost, put it behind a reverse proxy that handles authentication.
  • Fetched page content is untrusted. A web page can contain text that tries to instruct the model (prompt injection). Treat tool output as data.

Limitations

  • Search relies on scraping DuckDuckGo. This is unofficial: heavy use may be rate-limited, and a change to DuckDuckGo's markup can break result parsing. The selectors live in search.go.
  • No JavaScript rendering. Pages that build their content client-side may return little or no content.
  • No proxy support for fetching, since the SSRF check needs to see the real destination address.
  • Only text-based pages are supported (no PDFs or binary files).

Troubleshooting

SymptomLikely cause / fix
duckduckgo returned status 202Rate-limited or bot-detected. Wait a while and retry, or reduce request frequency.
Search returns "No results found."Query returned nothing, or DuckDuckGo's HTML structure changed.
blocked non-public address ...The URL resolves to a private or local address, which is blocked by design.
Fetched content is empty or very shortThe page likely renders its content with JavaScript.
unsupported content typeThe URL points to a PDF, image or other non-text resource.
Client can't connect over stdioUse an absolute path to the binary and make sure it is executable.
Results or page content look outdatedThey may be served from cache. Use no_cache, lower the TTL flags, or restart the server.

Contributing

Issues and pull requests are welcome. Ideas for improvement:

  • Pluggable search backends (e.g. SearXNG)
  • Optional headless-browser fallback for JavaScript-rendered pages
  • PDF text extraction

License

MIT License. See LICENSE for details.

↑↓ navigate openesc close