web-speed-oss
Web Speed
Web Speed resuelve el problema de señal-ruido para agentes de IA. Mientras que la web moderna está optimizada para ojos humanos (HTML desordenado, diseños complejos, interfaces cargadas de JS), Web Speed traduce ese caos en un mapa estructural determinista y eficiente en tokens, diseñado para flotas de agentes de alto rendimiento.
Sin IA integrada. Sin anthropic, sin openai, sin dependencia de LLM de ningún tipo. Toda la interpretación reside en el agente que realiza la llamada.
Por qué existe
Problema | Solución de Web Speed |
El HTML sin procesar tiene más de 150,000 caracteres de scripts, estilos y ruido SVG | Elimina todo lo que no sea estructural → hasta un 97% de reducción de tokens |
Los LLM alucinan IDs de elementos y pierden puntos de interacción en el DOM sin procesar | Devuelve un mapa estructural congelado — lo que está ahí, está ahí, no se inventa nada |
Los scrapers personalizados se rompen por sitio | Protocolo determinista — la misma forma JSON para cada sitio en la web |
El agente tiene que redescubrir páginas en un viaje de ida y vuelta a la vez |
|
Related MCP server: Delta-MCP
Herramientas
Herramienta | Descripción |
| Mapa estructurado completo: encabezados, navegación, enlaces de contenido, formularios, tablas, texto, metadatos |
| Envía un formulario (GET o POST), devuelve el mapa de la página resultante |
| Rastrea desde una URL raíz, devuelve un mapa combinado de todas las páginas |
| Datos estructurales profundos para nodos que coinciden con un selector CSS |
| Clasificación instantánea de página — |
| Elimina un mapa en caché para que la siguiente llamada obtenga uno nuevo |
Instalación
Mac / Linux
cd web-interpreter
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtWindows
cd web-interpreter
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txtEjecución
Para desarrollo local con el inspector MCP:
mcp dev server.pyPara ejecutar directamente sobre stdio (cómo lo lanzan los clientes MCP):
python server.pyRegistrar con Claude / Cowork
Agrégalo a ~/Library/Application Support/Claude/claude_desktop_config.json (Mac) o el equivalente en Windows:
{
"mcpServers": {
"web-speed": {
"command": "/absolute/path/to/web-interpreter/venv/bin/python",
"args": ["/absolute/path/to/web-interpreter/server.py"]
}
}
}Luego cierra y reinicia Claude Desktop / Cowork. Las seis herramientas aparecerán bajo el servidor MCP web-speed.
Esquemas de salida
interpret_page
{
"url": "https://example.com/",
"fetched_at": "2025-01-01T12:00:00Z",
"page_type": "other",
"title": "Example Domain",
"description": "",
"headings": [
{ "level": 1, "text": "Example Domain" }
],
"navigation": [
{ "label": "Home", "url": "https://example.com/", "location": "header" }
],
"content_links": {
"total": 47,
"truncated": false,
"items": [
{ "label": "More information...", "url": "https://www.iana.org/domains/example" }
]
},
"forms": [
{
"id": "search",
"action": "https://example.com/search",
"method": "GET",
"fields": [
{
"name": "q",
"type": "text",
"label": "Search",
"placeholder": "Search...",
"required": false,
"value": ""
},
{
"name": "_csrf",
"type": "hidden",
"label": "",
"placeholder": "",
"required": false,
"value": "abc123"
}
]
}
],
"tables": [
{
"id": "results",
"headers": ["Name", "Price", "Stock"],
"rows": [["Widget A", "$9.99", "In stock"]]
}
],
"text_blocks": [
{ "tag": "p", "text": "This domain is for use in illustrative examples." }
],
"metadata": {
"lang": "en",
"canonical": "",
"open_graph": { "title": "", "description": "", "image": "" }
}
}Campos clave:
navigation— enlaces dentro de elementos semánticos nav/header/footer (cromo del sitio, menús). Limitado a 60.content_links— enlaces dentro del cuerpo de la página (artículos, resultados de búsqueda, listados). Siempre incluyetotalpara que sepas el conteo real incluso cuando se trunca a 60.forms— cada formulario con cada campo, tokens CSRF preservados textualmente en elvaluedel campo oculto.page_type— inferido de la estructura: campo de contraseña →login, muchos elementos/enlaces →listing,<article>con párrafos →article, formularios →form, mayormente enlaces →navigation.
page_type
Ligero — devuelve solo la clasificación. Instantáneo cuando la página está en caché.
{
"url": "https://example.com/login",
"fetched_at": "2025-01-01T12:00:00Z",
"page_type": "login",
"title": "Sign In"
}submit_form
La misma forma de salida que interpret_page, para la página en la que aterriza el servidor después del envío.
{
"url": "https://example.com/login",
"method": "POST",
"fields": {
"email": "user@example.com",
"password": "hunter2",
"_csrf": "abc123"
}
}Los tokens CSRF van en fields textualmente — extráelos de los campos ocultos en el array forms de la llamada interpret_page anterior.
inspect_element
Datos estructurales profundos para nodos que coinciden con un selector CSS. Limitado a 25 elementos.
{
"url": "https://example.com/shop",
"selector": ".product-card",
"matched": 48,
"truncated": true,
"elements": [
{
"tag": "div",
"id": "product-42",
"classes": ["product-card", "featured"],
"text": "Widget Pro $49.99 Add to cart",
"attributes": { "id": "product-42" },
"links": [{ "label": "Add to cart", "url": "https://example.com/cart/add/42" }],
"fields": [],
"children": [
{ "tag": "h3", "text": "Widget Pro" },
{ "tag": "span", "text": "$49.99" },
{ "tag": "a", "text": "Add to cart", "href": "https://example.com/cart/add/42" }
]
}
]
}Selectores de ejemplo: #login-form, .product-card, table.results tbody tr, nav a, [data-testid="price"]
site_map
{
"root_url": "https://example.com",
"crawled_at": "2025-01-01T12:00:00Z",
"total_pages": 8,
"pages": [
{
"url": "https://example.com",
"title": "Home",
"page_type": "navigation",
"depth": 0,
"links_to": ["https://example.com/about", "https://example.com/contact"]
}
],
"all_forms": [
{
"found_on": "https://example.com/contact",
"id": "contact",
"action": "https://example.com/contact/submit",
"method": "POST",
"fields": [
{ "name": "email", "type": "email", "label": "Your email", "placeholder": "", "required": true, "value": "" },
{ "name": "message", "type": "textarea", "label": "Message", "placeholder": "", "required": true, "value": "" }
]
}
],
"all_navigation": [
{ "label": "About", "url": "https://example.com/about" },
{ "label": "Contact", "url": "https://example.com/contact" }
]
}invalidate_cache
{ "url": "https://example.com", "invalidated": true }Errores
Las herramientas nunca lanzan excepciones. En caso de fallo:
{
"error": true,
"code": "FETCH_FAILED | PARSE_FAILED | TIMEOUT | NOT_HTML",
"message": "human-readable explanation",
"url": "https://example.com/broken"
}Cómo debe usar el agente la salida
Navegar por un sitio:
Lee navigation para el cromo del sitio (menús, encabezado, pie de página) y content_links para los enlaces del cuerpo de la página. content_links.total te indica cuántos existen incluso si la lista está truncada. Elige el enlace que coincida con tu objetivo y llama a interpret_page.
Enviar un formulario:
Lee forms. Cada campo tiene name (qué enviar), type (qué datos espera), label/placeholder (para qué sirve), required y value. Los campos ocultos (type: "hidden") llevan tokens CSRF — pasa su value de vuelta textualmente. Construye un diccionario plano name → value y llama a submit_form.
Clasificar antes de comprometerse:
Llama a page_type primero cuando necesites ramificar la lógica (p. ej., ¿es esta una página de inicio de sesión o un panel de control?) sin pagar por un interpret_page completo.
Profundizar en un componente:
¿Viste una tabla en el mapa pero quieres las filas individuales? ¿Un listado de productos pero quieres el enlace y precio de cada tarjeta? Llama a inspect_element con un selector CSS para obtener detalles estructurados sobre esos nodos específicos sin recargar toda la página.
Planificar previamente un flujo de trabajo de varios pasos:
Llama a site_map antes de empezar. Obtienes el título, tipo, profundidad y enlaces salientes de cada página, además de cada formulario en todo el sitio — puedes planificar todo el flujo de trabajo (encontrar el formulario de inicio de sesión, encontrar la página de entrada de datos, encontrar el endpoint de envío) sin un solo viaje de ida y vuelta.
page_type es una señal, no una garantía:
La clasificación es heurística. Las SPA renderizadas por JS que sirven shells HTML vacíos a menudo serán other — el campo de contraseña no está en el HTML hasta que se ejecuta JavaScript. Trata page_type como un filtro rápido, luego verifica contra los forms y headings reales.
Sincronización de registro compartido
Por defecto, cada mapa de página nuevo que construye tu servidor OSS se aporta de forma asíncrona al registro compartido de Web Speed en api.getwebspeed.io. Este es el volante de crowdsourcing: cada agente que obtiene una URL la añade a la caché global, por lo que el siguiente agente en cualquier lugar obtiene una respuesta instantánea.
Esto es opt-out, no opt-in. El valor predeterminado está activado porque cuantos más colaboradores haya, más rápido funcionarán los agentes de todos.
Qué se comparte
Solo datos estructurales de la página:
Tipo de página, título, descripción
Encabezados, enlaces de navegación, enlaces de contenido
Nombres de campos de formulario, tipos y etiquetas (sin valores)
Tablas, bloques de texto
Metadatos Open Graph
Nunca se comparte: cookies, tokens de sesión, valores de formulario, mapas renderizados por JS (que pueden contener estado de inicio de sesión específico de la sesión).
Desactivar la sincronización
Establece la variable de entorno antes de iniciar el servidor:
WEB_SPEED_REGISTRY_SYNC=false python server.pyO en la configuración de tu cliente MCP:
{
"mcpServers": {
"web-speed": {
"command": "/path/to/venv/bin/python",
"args": ["/path/to/server.py"],
"env": {
"WEB_SPEED_REGISTRY_SYNC": "false"
}
}
}
}Apuntar a un registro autohospedado
Si estás ejecutando tu propia instancia alojada, apunta la sincronización allí:
WEB_SPEED_REGISTRY_URL=https://your-instance.example.com python server.pyComportamiento de sincronización
Fire-and-forget: la contribución se envía en segundo plano. La solicitud de tu agente se completa a toda velocidad independientemente de si el ping tiene éxito.
Solo en MISS de caché: los mapas que ya están en tu caché de disco local de 24 horas no se vuelven a enviar.
Los fallos son silenciosos: los errores de red, tiempos de espera y rechazos del servidor se registran solo en el nivel DEBUG y nunca aparecen ante el agente.
Arquitectura
URL ──▶ fetcher.py (httpx: 10s timeout, 5 redirects, Chrome UA
▼ OR Playwright headless Chromium for js=true)
cleaner.py (BeautifulSoup/lxml: strip noise, split nav vs content
▼ links, filter layout tables, deduplicate text blocks,
structured map infer page_type, detect auth_gated)
▼
cache.py (24h TTL, MD5 keyed JSON files in ./cache/)
▼
registry_sync.py (fire-and-forget POST to api.getwebspeed.io/v1/contribute)
▼
server.py (FastMCP: 8 tools over stdio)Sin IA. Sin interpretación. El agente es el cerebro.
Limitaciones conocidas
SPA renderizadas por JS: Las páginas que cargan contenido mediante JavaScript (React, Vue, Angular) devuelven solo el shell HTML de pre-renderizado. Los campos de contraseña, resultados de búsqueda y navegación que son inyectados por JS faltarán. Usa
inspect_elementen lo que sea visible y combínalo con una herramienta de automatización de navegador para objetivos con mucha carga de SPA.Heurísticas de
page_type: La clasificación es estructural y rápida, pero no infalible. Una página de marketing con muchos enlaces internos podría serlisting; una página con un campo de correo electrónico y sin contraseña no serálogin.La caché es disco local: El directorio
./cache/es local. En un despliegue multiproceso o distribuido, las entradas de caché no se compartirán entre instancias. Para el almacenamiento en caché compartido, reemplazacache.pycon un backend de Redis o Memcached.Límites de tasa no aplicados: Web Speed no limita las solicitudes salientes. Para flotas de agentes de alto volumen, coloca un proxy de limitación de tasa (p. ej., Cloudflare, nginx) frente al servidor.
This server cannot be deployed
Maintenance
Related MCP Connectors
Agentic identity trust: precision decisioning, cryptographic release tokens, hash-chained proof
Paid token risk and security intelligence for AI agents over MCP with x402 payments.
The MCP gateway with an EU-hosted, persistent memory layer that shrinks your token bill.
Zero-secret MCP gateway for AI agents: risk-scored, audited calls with human-in-the-loop approval.
Related MCP Servers
- AlicenseAqualityAmaintenanceThe MCP for the Web Speed Agent SDK that enables post-auth agents.1936 PyPI3GPL 3.0
- AlicenseNot gradedqualityCmaintenanceToken-efficient MCP reimplementation with progressive tool discovery, result handling, and compact wire encoding, reducing token usage by up to 89% on tool definitions.1MIT
- AlicenseBqualityBmaintenanceEnables AI agents to access design system tokens and component contracts through MCP, reducing token usage and ensuring consistency.29MIT
- AlicenseNot gradedqualityDmaintenanceConsolidates code understanding, documentation, browser automation, memory, and knowledge graph into a single MCP server with progressive discovery for up to 98% token reduction.Apache 2.0