npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fast-web-search-mcp

v0.1.0

Published

A fast, lightweight, local MCP server for free web search and webpage extraction.

Readme


Why fast-web-search-mcp?

Most MCP search servers require paid API keys, Docker containers, or headless browsers. fast-web-search-mcp provides free, fast, local web search with zero external dependencies beyond Node.js.

| Capability | fast-web-search-mcp | Paid APIs | Headless Browser | |------------|:-------------------:|:---------:|:----------------:| | Free to use | ✅ | ❌ | ✅ | | No API key | ✅ | ❌ | ✅ | | No Docker | ✅ | ✅ | ❌ | | Sub-second response | ✅ | ✅ | ❌ | | SSRF protection | ✅ | N/A | ❌ | | Result caching | ✅ | ❌ | ❌ | | Multiple providers | ✅ | ❌ | ❌ | | Works on Windows | ✅ | ✅ | ⚠️ |


Features

  • Web Search — DuckDuckGo primary with Bing fallback and Wikipedia reference lookup
  • News Search — Date-sensitive news results with publication metadata
  • Page Fetching — Readability extraction with Markdown or plain text output
  • Combined Research — Search, rank, and fetch top results in one call
  • Intelligent Caching — In-memory LRU cache with configurable TTL
  • Request Coalescing — Deduplicates concurrent identical searches
  • Rate Limiting — Per-provider throttling with exponential backoff
  • Result Deduplication — URL canonicalization and title similarity matching
  • SSRF Protection — Blocks private IPs, localhost, cloud metadata endpoints
  • Provider Fallback — Automatic failover when a provider is unavailable
  • Zero Runtime Dependencies — No Python, no Docker, no browser engine

Quick Start

Install

# Global install (recommended)
npm install -g fast-web-search-mcp

# Or run directly without installing
npx -y fast-web-search-mcp

Requirements

| Dependency | Version | |------------|---------| | Node.js | ≥ 22.0 | | npm | ≥ 10.0 |

Verify Installation

# Confirm the binary is available
fast-web-search-mcp --version

# Or run directly
npx fast-web-search-mcp --version

Integration

Add fast-web-search-mcp to your AI coding assistant. Select your platform below:

Project scope — add to .claude/settings.json in your project root:

{
  "mcpServers": {
    "fast-web-search": {
      "command": "fast-web-search-mcp",
      "env": {
        "FWSMCP_LOG_LEVEL": "warn",
        "FWSMCP_REDACT_QUERIES": "true"
      }
    }
  }
}

User scope — add to ~/.claude/settings.json for global availability:

{
  "mcpServers": {
    "fast-web-search": {
      "command": "fast-web-search-mcp",
      "env": {
        "FWSMCP_DEFAULT_REGION": "us-en",
        "FWSMCP_DEFAULT_LANGUAGE": "en",
        "FWSMCP_REDACT_QUERIES": "true"
      }
    }
  }
}

Or use the CLI:

claude mcp add fast-web-search -- fast-web-search-mcp

Windows users: Wrap the command with cmd /c:

claude mcp add fast-web-search -- cmd /c fast-web-search-mcp

Add to your configuration file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "fast-web-search": {
      "command": "fast-web-search-mcp",
      "env": {
        "FWSMCP_LOG_LEVEL": "warn",
        "FWSMCP_DEFAULT_REGION": "us-en",
        "FWSMCP_DEFAULT_LANGUAGE": "en"
      }
    }
  }
}

Restart Claude Desktop after saving.

Add to ~/.codex/config.toml (global) or .codex/config.toml (project):

[mcp_servers.fast-web-search]
command = "fast-web-search-mcp"
env = { FWSMCP_LOG_LEVEL = "warn", FWSMCP_REDACT_QUERIES = "true" }

Or use the CLI:

codex mcp add fast-web-search -- fast-web-search-mcp

Add to ~/.config/opencode/opencode.json:

{
  "mcp": {
    "fast-web-search": {
      "type": "local",
      "command": ["fast-web-search-mcp"],
      "enabled": true,
      "environment": {
        "FWSMCP_DEFAULT_REGION": "us-en",
        "FWSMCP_DEFAULT_LANGUAGE": "en",
        "FWSMCP_REDACT_QUERIES": "true",
        "FWSMCP_SAFE_SEARCH": "moderate"
      }
    }
  }
}

Antigravity IDE:

  1. Click ... in the agent side panel → MCP ServersManage MCP ServersView raw config
  2. Add the server to the opened mcp_config.json file

Antigravity CLI:

Type /mcp in the prompt panel to open the interactive MCP Manager.

Configuration file:

  • Global: ~/.gemini/config/mcp_config.json
  • Project: .agents/mcp_config.json
{
  "mcpServers": {
    "fast-web-search": {
      "command": "fast-web-search-mcp",
      "args": [],
      "env": {
        "FWSMCP_LOG_LEVEL": "warn",
        "FWSMCP_REDACT_QUERIES": "true"
      }
    }
  }
}

Add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "fast-web-search": {
      "command": "fast-web-search-mcp",
      "env": {
        "FWSMCP_LOG_LEVEL": "warn"
      }
    }
  }
}

Add to .vscode/mcp.json in your workspace:

{
  "servers": {
    "fast-web-search": {
      "command": "fast-web-search-mcp",
      "env": {
        "FWSMCP_LOG_LEVEL": "warn"
      }
    }
  }
}

MCP Tools

| Tool | Description | Use Case | |------|-------------|----------| | web_search | Search the general web via DuckDuckGo + Bing fallback | General research, fact-finding | | news_search | Search for recent news articles with publication dates | Current events, monitoring | | fetch_url | Fetch a URL and extract clean Markdown or plain text | Article reading, documentation | | search_and_fetch | Combined search + fetch workflow with character budget | Deep research, analysis | | diagnostics | Return non-sensitive server diagnostics | Troubleshooting (disabled by default) |

Tool Parameters

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | query | string | required | Search query (1-500 characters) | | max_results | integer | 10 | Maximum results to return (1-25) | | strategy | string | "fallback" | Provider strategy: fallback or merge | | region | string | "us-en" | Region code for localized results | | language | string | "en" | Language code | | time_range | string | "any" | Time filter: day, week, month, year, any | | safe_search | string | "moderate" | Content filter: off, moderate, strict | | include_domains | array | — | Restrict results to these domains | | exclude_domains | array | — | Exclude results from these domains | | deduplicate | boolean | true | Remove duplicate results by URL | | timeout_ms | integer | — | Operation timeout (1000-60000 ms) |

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | query | string | required | News search query (1-500 characters) | | max_results | integer | 10 | Maximum results (1-25) | | time_range | string | "week" | Time filter: day, week, month | | region | string | "us-en" | Region code | | language | string | "en" | Language code | | include_domains | array | — | Restrict to these domains | | exclude_domains | array | — | Exclude these domains |

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | url | string | required | HTTP/HTTPS URL to fetch | | output | string | "markdown" | Output format: markdown or text | | max_characters | integer | 20000 | Maximum characters (100-100000) | | include_metadata | boolean | true | Include page metadata | | include_links | boolean | false | Include extracted links | | timeout_ms | integer | — | Fetch timeout (1000-60000 ms) |

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | query | string | required | Search query (1-500 characters) | | search_results | integer | 8 | Number of results to consider (1-20) | | fetch_results | integer | 3 | Number of pages to fetch (1-5) | | max_characters_per_page | integer | 20000 | Character limit per page | | total_character_budget | integer | 100000 | Total character budget | | timeout_ms | integer | — | Total timeout (5000-120000 ms) |


Configuration

All configuration is environment-based. No config files required.

| Variable | Default | Description | |----------|---------|-------------| | FWSMCP_LOG_LEVEL | warn | Log verbosity: debug, info, warn, error | | FWSMCP_LOG_FORMAT | text | Log format: text or json | | FWSMCP_REDACT_QUERIES | true | Redact search queries in logs | | FWSMCP_DEFAULT_REGION | us-en | Default region for searches | | FWSMCP_DEFAULT_LANGUAGE | en | Default language for searches | | FWSMCP_SAFE_SEARCH | moderate | Safe search level: off, moderate, strict | | FWSMCP_PROVIDERS | duckduckgo,bing,wikipedia | Comma-separated provider list | | FWSMCP_PROVIDER_STRATEGY | fallback | Strategy: fallback (sequential) or merge (parallel) | | FWSMCP_SEARCH_TIMEOUT_MS | 20000 | Search operation timeout (ms) | | FWSMCP_PROVIDER_TIMEOUT_MS | 10000 | Per-provider timeout (ms) | | FWSMCP_FETCH_TIMEOUT_MS | 15000 | Page fetch timeout (ms) | | FWSMCP_RESEARCH_TIMEOUT_MS | 45000 | search_and_fetch total timeout (ms) | | FWSMCP_MAX_SEARCH_RESULTS | 25 | Maximum results per search | | FWSMCP_MAX_FETCH_CHARACTERS | 100000 | Maximum characters per fetch | | FWSMCP_CACHE_ENABLED | true | Enable in-memory result cache | | FWSMCP_CACHE_MAX_ENTRIES | 250 | Maximum cache entries | | FWSMCP_SEARCH_CACHE_TTL_MS | 900000 | Search cache TTL (15 min) | | FWSMCP_NEWS_CACHE_TTL_MS | 300000 | News cache TTL (5 min) | | FWSMCP_PAGE_CACHE_TTL_MS | 1800000 | Page cache TTL (30 min) | | FWSMCP_SEARXNG_URL | — | Optional SearXNG instance URL | | FWSMCP_DIAGNOSTICS_ENABLED | false | Enable diagnostics tool | | FWSMCP_GLOBAL_EXCLUDE_DOMAINS | — | Comma-separated domains to always exclude | | FWSMCP_CONFIG_FILE | — | Path to optional JSON config file |

Optional JSON Configuration

For complex setups, point FWSMCP_CONFIG_FILE to a JSON file:

{
  "defaults": {
    "region": "us-en",
    "language": "en",
    "safeSearch": "moderate"
  },
  "providers": {
    "order": ["duckduckgo", "bing", "wikipedia"],
    "strategy": "fallback"
  },
  "cache": {
    "enabled": true,
    "maxEntries": 250,
    "searchTtlMs": 900000
  },
  "limits": {
    "maxSearchResults": 25,
    "maxFetchCharacters": 100000
  },
  "privacy": {
    "redactQueriesInLogs": true
  }
}

Priority: Environment variables > JSON config file > defaults.


Architecture

┌─────────────────────────────────────────────────────────┐
│                    MCP Client                            │
│            (Claude Code / Codex / OpenCode)              │
└─────────────────────┬───────────────────────────────────┘
                      │ stdio (JSON-RPC)
                      ▼
┌─────────────────────────────────────────────────────────┐
│               fast-web-search-mcp                        │
│                                                         │
│  ┌─────────┐  ┌──────────┐  ┌───────────┐  ┌────────┐ │
│  │  Tools   │  │  Cache   │  │ Coalescer │  │ Limiter│ │
│  │ 5 tools  │  │ LRU+TTL  │  │ Dedup     │  │ Per-   │ │
│  │          │  │          │  │ inflight  │  │ provider│ │
│  └────┬─────┘  └──────────┘  └───────────┘  └────────┘ │
│       │                                                  │
│       ▼                                                  │
│  ┌─────────────────────────────────────────────────┐    │
│  │              Orchestrator Pipeline                │    │
│  │  Validate → Cache → Coalesce → Select → Execute  │    │
│  │  → Normalize → Filter → Dedup → Rank → Return    │    │
│  └─────────────────────┬───────────────────────────┘    │
│                        │                                 │
│       ┌────────────────┼────────────────┐               │
│       ▼                ▼                ▼               │
│  ┌─────────┐    ┌──────────┐    ┌────────────┐         │
│  │ DuckDuck │    │   Bing   │    │ Wikipedia  │         │
│  │   Go     │    │          │    │ REST API   │         │
│  │ (HTML)   │    │ (HTML)   │    │            │         │
│  └─────────┘    └──────────┘    └────────────┘         │
│       │                │                                 │
│       ▼                ▼                                 │
│  ┌─────────────────────────────────────────────────┐    │
│  │            HTTP Client (Node fetch)               │    │
│  │   Timeout · Body Limit · Redirect · SSRF Block   │    │
│  └─────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────┘

Security

Protections

| Threat | Mitigation | |--------|------------| | SSRF / private network access | Blocks localhost, RFC1918, link-local, cloud metadata IPs | | Credential leakage | Rejects URLs with embedded username/password | | Query exposure | Logs redact queries by default (FWSMCP_REDACT_QUERIES=true) | | Prompt injection via fetched content | Includes untrusted content warning in all fetch results | | Uncontrolled resource consumption | Body size limits, timeout enforcement, character budgets | | Process isolation | stdio transport only — no network listener, no HTTP endpoint |

Disabled by Default

  • Diagnostics tool — must be explicitly enabled via FWSMCP_DIAGNOSTICS_ENABLED=true
  • SearXNG integration — requires explicit FWSMCP_SEARXNG_URL configuration

See docs/SECURITY.md for the full threat model.


Development

git clone https://github.com/your-org/fast-web-search-mcp.git
cd fast-web-search-mcp
npm ci
npm run build
npm test

Available Scripts

| Script | Description | |--------|-------------| | npm run build | Production build with tsup | | npm run dev | Development mode with tsx | | npm test | Run full test suite (177 tests) | | npm run test:unit | Unit tests only | | npm run test:security | Security tests only | | npm run typecheck | TypeScript type checking | | npm run lint | ESLint | | npm run format | Prettier formatting |

Project Structure

fast-web-search-mcp/
├── src/
│   ├── cache/              # LRU cache, cache key generation
│   ├── config/             # Defaults, env parsing, config loader
│   ├── fetch/              # URL validation, content extraction, Markdown
│   ├── http/               # HTTP client, errors, headers
│   ├── observability/      # Structured stderr logger
│   ├── providers/          # DuckDuckGo, Bing, Wikipedia, SearXNG
│   ├── schemas/            # Zod validation schemas
│   ├── search/             # Orchestrator, coalescer, rate limiter, dedup
│   ├── server/             # MCP server factory, tool registration
│   ├── tools/              # 5 MCP tool implementations
│   ├── utils/              # Domain, text, date, async utilities
│   └── index.ts            # Entry point
├── test/
│   ├── fixtures/           # HTML fixtures for parser tests
│   └── unit/               # Unit tests (177 tests)
├── docs/                   # Documentation and ADRs
└── examples/               # Config examples

Documentation

| Document | Description | |----------|-------------| | Configuration Reference | All environment variables and options | | Provider Guide | Provider details, strategy, and SearXNG setup | | Security Model | Threat model and protections | | Troubleshooting | Common issues and debugging | | OpenCode Integration | OpenCode-specific setup guide | | Changelog | Version history |


Roadmap

  • [ ] SQLite persistent cache
  • [ ] Brave Search provider
  • [ ] Image search support
  • [ ] Streamable HTTP transport
  • [ ] Result scoring customization

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing)
  3. Commit changes (git commit -m 'feat: add amazing feature')
  4. Push to branch (git push origin feature/amazing)
  5. Open a Pull Request

License

MIT License. See LICENSE for details.