A newer version of the Gradio SDK is available:
5.49.1
title: Web MCP
emoji: 🔎
colorFrom: blue
colorTo: green
sdk: gradio
sdk_version: 5.36.2
app_file: app.py
pinned: false
short_description: Search & fetch the web with per-tool analytics
thumbnail: >-
https://cdn-uploads.huggingface.co/production/uploads/5f17f0a0925b9863e28ad517/tfYtTMw9FgiWdyyIYz6A6.png
Web MCP Server
A Model Context Protocol (MCP) server that exposes two composable tools—search (Serper metadata) and fetch (single-page extraction)—alongside a live analytics dashboard that tracks daily usage for each tool. The UI runs on Gradio and can be reached directly or via MCP-compatible clients like Claude Desktop and Cursor.
Highlights
- Dual MCP tools with shared rate limiting (
360 requests/hour) and structured JSON responses. - Daily analytics split by tool: the Analytics tab renders "Daily Search" (left) and "Daily Fetch" (right) bar charts covering the last 14 days.
- Persistent request counters keyed by UTC date and tool:
{"YYYY-MM-DD": {"search": n, "fetch": m}}, with automatic migration from legacy totals. - Pluggable storage: respects
ANALYTICS_DATA_DIR, otherwise falls back to/data(if writable) or./datafor local development. - Ready-to-serve Gradio app with MCP endpoints exposed via
gr.apifor direct client consumption.
Requirements
- Python 3.8 or newer.
- Serper API key (
SERPER_API_KEY) with access to the Search and News endpoints. - Dependencies listed in
requirements.txt, includingfilelockandpandasfor analytics storage.
Install everything with:
pip install -r requirements.txt
Configuration
Export your Serper API key:
export SERPER_API_KEY="your-api-key"(Optional) Override the analytics storage path:
export ANALYTICS_DATA_DIR="/path/to/persistent/storage"If unset, the app automatically prefers
/datawhen available, otherwise./data.(Optional) Control private/local address policy for
fetch:FETCH_ALLOW_PRIVATE— set to1/trueto disable the SSRF guard entirely (not recommended except for trusted, local testing).FETCH_PRIVATE_ALLOWLIST— comma/space separated host patterns allowed even if they resolve to private/local IPs, e.g.:export FETCH_PRIVATE_ALLOWLIST="*.corp.local, my-proxy.internal"
If neither is set, the fetcher refuses URLs whose host resolves to private, loopback, link‑local, multicast, reserved, or unspecified addresses. It also re-checks the final redirect target.
The request counters live in <DATA_DIR>/request_counts.json, guarded by a file lock to support concurrent MCP calls.
Running Locally
Launch the Gradio server (with MCP support enabled) via:
python app.py
This starts a local UI at http://localhost:7860 and exposes the MCP SSE endpoint at http://localhost:7860/gradio_api/mcp/sse.
Connecting From MCP Clients
- Claude Desktop – update
claude_desktop_config.json:{ "mcpServers": { "web-search": { "command": "python", "args": ["/absolute/path/to/app.py"], "env": { "SERPER_API_KEY": "your-api-key" } } } } - URL-based MCP clients – run
python app.py, then point the client tohttp://localhost:7860/gradio_api/mcp/sse.
Tool Reference
search
- Purpose: Retrieve metadata-only results from Serper (general web or news).
- Inputs:
query(str, required) – search terms.search_type("search" | "news", default "search") – switch tonewsfor recency-focused results.num_results(int, default 4, range 1–20) – number of hits to return.
- Output: JSON containing the query echo, result count, timing, and an array of entries with
position,title,link,domain, and optionalsource/datefor news.
fetch
- Purpose: Download a single URL and extract the readable article text via Trafilatura.
- Inputs:
url(str, required) – must start withhttp://orhttps://.timeout(int, default 20 seconds) – client timeout for the HTTP request.
- Output: JSON with the original and final URL, domain, HTTP status, title, ISO timestamp of the fetch, word count, cleaned
content, and duration.
Both tools increment their respective analytics buckets on every invocation, including validation failures and rate-limit denials, ensuring the dashboard mirrors real traffic.
Analytics Dashboard
Open the Analytics tab in the Gradio UI to inspect daily activity:
- Daily Search Count (left column) – bar chart for the past 14 days of
searchtool requests. - Daily Fetch Count (right column) – bar chart for the past 14 days of
fetchtool requests. - Tooltips reveal the display label (e.g.,
Sep 17), raw count, and ISO date key.
Data is stored in JSON and can be safely externalized for long-term tracking. Existing totals in the legacy integer-only format are automatically migrated during the first write.
Rate Limiting & Error Handling
- Global moving-window limit of
360requests per hour shared across both tools (powered bylimits). - Standardized error payloads for missing parameters, invalid URLs, Serper issues, HTTP failures, and rate-limit hits, each preserving analytics increments.
Troubleshooting
SERPER_API_KEY is not set– export the key in the environment where the server runs.Rate limit exceeded– pause requests or reduce client concurrency.- Empty extraction – some sites block bots; try another URL.
- Storage permissions – ensure the chosen data directory is writable; adjust
ANALYTICS_DATA_DIRif necessary.
Licensing & Contributions
Feel free to fork and adapt for your MCP workflows. Contributions are welcome—open a PR or issue with proposed analytics enhancements, additional tooling, or documentation tweaks.