mcp-web-tools-server
mcp-web-tools-server
Un servidor personalizado del Model Context Protocol (MCP) que proporciona a un agente de IA herramientas reales y funcionales para obtener páginas web y extraer contenido de ellas: texto de artículo limpio y legible, datos estructurados por selector CSS y una verificación de permisos de robots.txt.
¿Qué es MCP?
MCP es un protocolo abierto, publicado originalmente por Anthropic, que estandariza cómo las aplicaciones de IA (como Claude Desktop o Claude Code) se conectan a herramientas y fuentes de datos externas. En lugar de que cada aplicación de IA invente su propio formato de plugin, un servidor MCP expone un conjunto fijo de herramientas (y opcionalmente recursos y prompts) a través de una interfaz JSON-RPC simple, y cualquier cliente compatible con MCP puede descubrirlas y llamarlas de la misma manera. Este repositorio es uno de esos servidores: se ejecuta como un pequeño proceso local y habla MCP sobre stdio, por lo que cualquier cliente MCP puede listar sus herramientas y llamarlas sin saber nada sobre httpx, selectolax o trafilatura subyacentes.
Por qué esto es útil
De serie, un LLM no puede obtener una página web en vivo. Este servidor llena ese vacío con un conjunto de herramientas pequeño, probado y bien delimitado: un agente puede extraer el texto legible de un artículo, obtener campos específicos de una página mediante selector CSS (precio, título, etiquetas, lo que sea la estructura de la página) y verificar si el robots.txt del sitio permite la solicitud antes de realizarla. Es deliberadamente limitado en lugar de ser un framework de scraping de propósito general, bajo la teoría de que unas pocas herramientas que funcionan correctamente y fallan de manera predecible son más útiles para un agente que una gran superficie que a veces no funciona.
Herramientas
fetch_and_extract(url: str) -> str
Obtiene una URL y devuelve texto limpio y legible del contenido principal: scripts, estilos, navegación, anuncios y pies de página eliminados. Utiliza trafilatura para la extracción de artículos, con una heurística de densidad de párrafos (basada en selectolax) como alternativa para páginas que trafilatura no maneja con confianza.
extract_structured(url: str, css_selectors: dict) -> dict
Obtiene una URL y extrae campos por selector CSS, por ejemplo:
{"title": "h1", "price": ".price", "tags": ".tag-list a"}Devuelve:
{"title": "Trail Blazer 29 Mountain Bike", "price": "$1,249.00", "tags": ["mountain", "hardtail", "29er"]}Un selector que coincide con un elemento devuelve su texto, si coincide con varios devuelve una lista de sus textos, si no coincide con ninguno devuelve null. El análisis se realiza con selectolax.
check_robots_txt(url: str) -> dict
Obtiene el robots.txt del sitio objetivo e informa si el agente de usuario de este servidor tiene permiso para solicitar la URL dada, utilizando el urllib.robotparser estándar de Python. Si no se encuentra robots.txt, lo informa explícitamente (robots_txt_found: false) en lugar de asumir silenciosamente que el permiso fue realmente concedido.
Esto existe porque la etiqueta de scraping debería ser una preocupación de primera clase, no una ocurrencia tardía: un agente (o la persona que lo maneja) debería poder verificar el permiso antes de obtener, no solo cuando las cosas salen mal.
Principios de diseño
Identificación honesta. Las solicitudes utilizan una cadena User-Agent real que identifica esta herramienta y enlaza de vuelta a este repositorio, no un UA de navegador falsificado.
Solicitudes acotadas. Cada obtención tiene un tiempo de espera fijo (10 segundos por defecto) para que un servidor lento o colgado no pueda detener toda la sesión.
robots.txt es una herramienta, no se aplica silenciosamente.
check_robots_txtse proporciona para que un agente (o la persona que lo maneja) pueda verificar el permiso antes de hacer scraping, pero actualmente no bloqueafetch_and_extractoextract_structuredautomáticamente. Ver Limitaciones más abajo.Sin fallos por entrada incorrecta. Los fallos de red, tiempos de espera y URLs inválidas se capturan y devuelven como texto de error limpio o un diccionario
{"error": ...}, nunca una excepción no manejada que mate el proceso del servidor.
Estructura del proyecto
mcp_web_tools/
server.py MCP server definition and the three tool entry points
extractors.py Pure HTML-parsing logic (no network), used for readable-text and CSS-selector extraction
robots.py robots.txt fetching and permission checking
http_client.py Shared httpx fetch helper: user agent, timeout, error handling
tests/
test_extractors.py Unit tests against local HTML fixtures, no network
test_robots.py Unit tests with the network call mocked out
test_http_client.py Unit tests for URL validation
test_integration.py Integration tests against live public sites, marked and run separately
fixtures/ Static HTML used by the unit tests
scripts/
test_client.py Standalone script that launches the server and talks real MCP protocol to itEjecutar el servidor
python -m venv venv
# Windows
venv\Scripts\activate
# macOS/Linux
source venv/bin/activate
pip install -r requirements.txt
python -m mcp_web_tools.serverEl servidor se comunica a través de stdio usando el protocolo MCP; ejecutarlo directamente desde una terminal simplemente se quedará esperando a que un cliente se conecte. Úselo a través de un cliente MCP (ver más abajo) o el script de cliente de prueba incluido.
Configurarlo como servidor MCP en Claude Desktop o Claude Code
Agregue una entrada a la configuración del servidor de su cliente MCP, apuntando command al intérprete de Python del venv y args al módulo. Para Claude Desktop, esto va en claude_desktop_config.json:
{
"mcpServers": {
"web-tools": {
"command": "C:\\path\\to\\mcp-web-tools-server\\venv\\Scripts\\python.exe",
"args": ["-m", "mcp_web_tools.server"],
"cwd": "C:\\path\\to\\mcp-web-tools-server"
}
}
}En macOS/Linux, command sería /path/to/mcp-web-tools-server/venv/bin/python.
Para Claude Code, ejecute:
claude mcp add web-tools -- /path/to/mcp-web-tools-server/venv/bin/python -m mcp_web_tools.server(sustituya la ruta del venv de Windows si corresponde), o agregue la entrada equivalente al .mcp.json de su proyecto.
Ejecutar las pruebas
Las pruebas unitarias se ejecutan contra fixtures HTML locales y no tocan la red:
pytestLas pruebas de integración acceden a sitios de prueba públicos, reales y estables (example.com y books.toscrape.com, objetivos estándar de prueba/demo de scraping público) y están excluidas de la ejecución predeterminada. Ejecútelas explícitamente cuando tenga acceso a la red:
pytest -m integrationTambién hay un script independiente que lanza el servidor como un subproceso real y lo maneja a través del protocolo real cliente/servidor MCP, en lugar de llamar a las funciones de Python directamente:
python scripts/test_client.pyLimitaciones y qué añadiría a continuación
Sin renderizado de JavaScript. Este servidor obtiene HTML sin procesar con httpx. Las páginas que renderizan su contenido del lado del cliente (SPAs pesadas de React/Vue) devolverán poco o nada útil. Una cuarta herramienta que envuelva Playwright para una obtención con navegador sin cabeza sería la siguiente adición natural, a costa de ser mucho más pesada de ejecutar.
Sin limitación de velocidad. Cada llamada a herramienta realiza una solicitud cuando se llama. No hay limitación por dominio incorporada ni cola de solicitudes si un agente llama a las herramientas en un bucle cerrado contra el mismo host.
check_robots_txtsí muestracrawl_delay_secondscuando un sitio publica uno, pero nada lo aplica actualmente.robots.txt es consultivo, no se aplica.
fetch_and_extractyextract_structuredno consultan automáticamentecheck_robots_txtantes de obtener. Es una decisión de alcance deliberada para esta versión (un agente debería llamar acheck_robots_txtprimero), pero un modo más estricto que rechace automáticamente las obtenciones no permitidas sería una adición razonable.La heurística de legibilidad es básica. La alternativa de selectolax utilizada cuando trafilatura no produce un resultado confiable es un simple puntuador de densidad de párrafos. Es suficientemente buena para diseños típicos de artículos y blogs, pero funcionará peor en estructuras de página inusuales que una biblioteca de legibilidad creada específicamente.
Sin almacenamiento en caché. Cada llamada vuelve a obtener, incluso para la misma URL con momentos de diferencia. Está bien para un servidor de demostración/portafolio, no es ideal para un uso más intensivo.
Transporte único en la práctica. El servidor está configurado para stdio, que es lo que usan Claude Desktop y Claude Code. El SDK
mcptambién admite transportes SSE y HTTP transmisible; conectar uno de ellos sería necesario para ejecutar esto como un servicio alojado en lugar de un subproceso local.
This server cannot be installed
Maintenance
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
Driflyte MCP server which lets AI assistants query topic-specific knowledge from web and GitHub.
An MCP server that gives your AI access to the source code and docs of all public github repos
Pocket Agent (aipocketagent.com) MCP server — read tools for personas, apps, and product info.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ZephyraRR/mcp-web-tools-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server