Skip to main content
Glama
AIwithhassan

Documentation Retrieval & Web Scraping

by AIwithhassan

MCP Server: Documentation Retrieval & Web Scraping (uv + FastMCP)

This project provides a minimal, async MCP (Model Context Protocol) server that exposes a tool for retrieving and cleaning official documentation content for popular AI / Python ecosystem libraries. It uses:

  • fastmcp to define and run the MCP server over stdio.

  • httpx for async HTTP calls.

  • serper.dev for Google-like search (via API).

  • groq API (LLM) to clean raw HTML into readable text chunks.

  • python-dotenv for environment variable management.

  • uv as the package manager & runner (fast, lockfile-based, Python 3.11+).

Features

  • Search restricted to official docs domains (uv, langchain, openai, llama-index).

  • Tool: get_docs(query, library) returns concatenated cleaned sections with SOURCE: labels.

  • Streaming-safe async design (chunking large HTML pages before LLM cleaning).

  • Separate client.py demonstrating how to connect as an MCP client and call the tool, then post-process with an LLM.


Related MCP server: Library Docs MCP Server

Quick Start

Prerequisites:

1. Clone & Install

git clone <your-repo-url> mcp-server-python
cd mcp-server-python
uv sync

This will create/refresh a .venv based on pyproject.toml + uv.lock.

2. Environment Variables

Create a .env file in the project root:

SERPER_API_KEY=your_serper_api_key_here
GROQ_API_KEY=your_groq_api_key_here

Optional: add other model settings if you later extend functionality.

3. Run the MCP Server Directly

uv run mcp_server.py

The server will start and wait on stdio (no extra output unless you add logging). It registers the tool get_docs.

4. Use the Provided Client

uv run client.py

You should see something like:

Available tools: ['get_docs']
ANSWER: <model-produced answer referencing SOURCE lines>

If the list is empty, ensure the server started correctly and no exceptions were raised (add logging—see below).


Tool: get_docs

Signature:

get_docs(query: str, library: str) -> str

Supported libraries (keys): uv, langchain, openai, llama-index.

Flow:

  1. Build a site-restricted query: site:<docs-domain> <query>.

  2. Call Serper API for organic results.

  3. Fetch each result URL (async) via httpx.

  4. Split HTML into ~4000‑char chunks (memory safety & LLM limits).

  5. Clean each chunk using Groq LLM (openai/gpt-oss-20b) with a system prompt.

  6. Concatenate and label each block with SOURCE: <url> for traceability.

Returned value: A large text blob suitable for retrieval-augmented prompting, preserving source attribution lines.


Architecture

File overview:

File

Purpose

mcp_server.py

Defines FastMCP instance and implements search_web, fetch_url, and the get_docs tool.

client.py

Launches server via stdio, lists tools, calls get_docs, then feeds result to an LLM for a user-friendly answer.

utils.py

HTML cleaning helper (currently uses LLM + trafilatura for extraction and Groq for chunk transformation).

.env

Environment variables (excluded from VCS).

pyproject.toml

Declares dependencies and metadata.

uv.lock

Reproducible lockfile generated by uv.


Dependency Notes

Core runtime deps (from pyproject.toml):

  • fastmcp – MCP server helper.

  • httpx – async HTTP client.

  • groq – Groq API client.

  • python-dotenv – load variables from .env.

  • trafilatura – heuristic content extraction (currently partially used / can be extended).

Tip: If you add more scraping tools, reuse a single httpx.AsyncClient for performance.


Logging & Debugging

To see what the server is doing, you can temporarily add:

import logging, sys
logging.basicConfig(level=logging.INFO, stream=sys.stderr)

Place near the top of mcp_server.py after imports. Since protocol uses stdout for JSON-RPC, send logs to stderr only.

Common issues:

  • Empty tool list: The server exited early or crashed—add logging.

  • SERPER_API_KEY missing → 401 or empty search results.

  • GROQ_API_KEY missing → LLM cleaning fails (exception in get_response_from_llm).

  • Network timeouts: Adjust timeout in httpx.AsyncClient calls.


Extending

Ideas:

  • Add caching layer (e.g., sqlite or in-memory dict) to avoid re-fetching same URLs.

  • Parallelize URL fetch + clean with asyncio.gather() (mind rate limits / LLM cost).

  • Add another tool (e.g., summarize_diff, list_endpoints).

  • Provide structured JSON output (list of sources + cleaned text) instead of concatenated string.

  • Add tests using pytest + pytest-asyncio (mock Serper + LLM APIs).


Example Programmatic Use (Without Client Wrapper)

If you want to call the tool directly in a Python script using the client-side MCP library:

from mcp.client.stdio import stdio_client
from mcp import ClientSession, StdioServerParameters
import asyncio

async def demo():
	params = StdioServerParameters(command="uv", args=["run", "mcp_server.py"])
	async with stdio_client(params) as (r, w):
		async with ClientSession(r, w) as session:
			await session.initialize()
			tools = await session.list_tools()
			print([t.name for t in tools.tools])
			docs = await session.call_tool("get_docs", {"query": "install", "library": "uv"})
			print(docs.content[:500])

asyncio.run(demo())

Running With Active Virtualenv

If you have an already activated virtual environment and want to use that instead of the project’s pinned environment, you can force uv to target it:

uv run --active client.py

Otherwise, uv will warn that your active $VIRTUAL_ENV differs from the project .venv but continue using the project environment.


License

Add a license section here (e.g., MIT) if you intend to distribute.


Troubleshooting Cheat Sheet

Symptom

Cause

Fix

No tools listed

Server not running / crashed

Add stderr logging; run uv run mcp_server.py manually

AttributeError on .text

Cleaner returned None

Ensure you return actual string from fetch_url / LLM call

401 from Serper

Bad/missing API key

Check .env and reload shell

Empty search results

Narrow query

Simplify query or verify domain key

High latency

Many sequential LLM chunk calls

Batch or reduce chunk size


Contributing

  1. Fork & branch.

  2. Run uv sync.

  3. Add tests for new tools (if added).

  4. Open PR with clear description.


Roadmap (Optional)

  • [] Add JSON schema metadata for tool params.

  • [] Structured response format (list of {source, text}).

  • [] Add caching layer.

  • [] Add rate limiting/backoff.

  • [] Add CI workflow (lint + tests).


Acknowledgments

  • Serper.dev for search API

  • Groq for fast OSS model serving

  • Astral for uv

  • MCP ecosystem for protocol foundation

Available Tools

1 tool
get_docsA

Search the latest docs for a given query and library. Supports langchain, openai, llama-index and uv.

Args: query: The query to search for (e.g. "Publish a package with UV") library: The library to search in (e.g. "uv")

Returns: Summarized text from the docs with source links.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes
libraryYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses that the tool searches 'latest docs' and returns 'summarized text with source links,' which adds some behavioral context beyond basic functionality. However, it lacks details on rate limits, authentication needs, error handling, or pagination, leaving gaps in transparency for a search operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded: the first sentence states the core purpose, followed by supported libraries, then clearly labeled 'Args' and 'Returns' sections. Every sentence adds value without redundancy, making it efficient and easy to parse for an AI agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations, 0% schema coverage, and no output schema, the description provides basic purpose, parameter semantics, and return format. However, it lacks details on behavioral aspects like error cases, rate limits, or authentication, and the output is only vaguely described ('summarized text with source links'). For a search tool with two parameters, this is adequate but has clear gaps in completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explicitly defines both parameters in the 'Args' section: 'query' as 'The query to search for' with an example, and 'library' as 'The library to search in' with an example and list of supported values. This adds significant meaning beyond the schema, though it doesn't fully detail constraints like library validation or query formatting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Search the latest docs for a given query and library.' It specifies the verb ('search'), resource ('docs'), and scope ('latest docs for a given query and library'), with examples of supported libraries. However, without sibling tools, it cannot demonstrate differentiation from alternatives, preventing a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by listing supported libraries (langchain, openai, llama-index, uv) and providing examples, suggesting it should be used for searching documentation within these specific libraries. However, it lacks explicit guidance on when to use this tool versus alternatives (e.g., other search methods or tools), and there are no sibling tools to compare against, so the guidance is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 1 tool update
    • First observedget_docs

TDQS

A3.6/5.0
Disambiguation5/5

With only one tool, there is no possibility of ambiguity or overlap between tools. The tool 'get_docs' has a clear and singular purpose, so agents cannot misselect between multiple options.

Naming Consistency5/5

Since there is only one tool, it inherently has perfect naming consistency. The name 'get_docs' follows a verb_noun pattern, and there are no other tools to compare it against for inconsistency.

Tool Count2/5

The server's name 'Documentation Retrieval & Web Scraping' suggests a broader scope than what is covered by a single tool. One tool is insufficient for comprehensive documentation retrieval and web scraping, as it lacks operations like scraping web pages, updating or deleting scraped data, or handling different document types beyond the specified libraries.

Completeness2/5

The tool set is severely incomplete for the server's stated purpose. While 'get_docs' handles searching docs for specific libraries, it does not cover web scraping, CRUD operations for scraped data, or broader documentation management, leaving significant gaps that will likely cause agent failures in tasks beyond basic searches.

Maintenance

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AIwithhassan/mcp-server-python'

If you have feedback or need assistance with the MCP directory API, please join our Discord server