web-speed-oss
Web Speed
Web Speed löst das Signal-Rausch-Problem für KI-Agenten. Während das moderne Web für menschliche Augen optimiert ist (unübersichtliches HTML, komplexe Layouts, JS-lastige Oberflächen), übersetzt Web Speed dieses Chaos in eine deterministische, Token-effiziente strukturelle Karte, die für Agenten-Flotten mit hohem Durchsatz konzipiert ist.
Keine KI enthalten. Kein anthropic, kein openai, keinerlei LLM-Abhängigkeit. Die gesamte Interpretation findet im aufrufenden Agenten statt.
Warum es existiert
Problem | Web Speed Lösung |
Rohes HTML besteht aus über 150.000 Zeichen an Skripten, Styles und SVG-Rauschen | Entfernt alles Nicht-Strukturelle → bis zu 97 % Token-Reduzierung |
LLMs halluzinieren Element-IDs und übersehen Interaktionspunkte im rohen DOM | Gibt eine eingefrorene strukturelle Karte zurück — was da ist, ist da, nichts wird erfunden |
Benutzerdefinierte Scraper gehen pro Website kaputt | Deterministisches Protokoll — dieselbe JSON-Struktur für jede Website im Web |
Agent muss Seiten einzeln nacheinander neu entdecken |
|
Related MCP server: Delta-MCP
Tools
Tool | Beschreibung |
| Vollständige strukturierte Karte: Überschriften, Navigation, Inhaltslinks, Formulare, Tabellen, Text, Metadaten |
| Formular absenden (GET oder POST), Karte der resultierenden Seite zurückerhalten |
| Von einer Root-URL aus crawlen, eine kombinierte Karte aller Seiten zurückgeben |
| Tiefe strukturelle Daten für Knoten, die einem CSS-Selektor entsprechen |
| Sofortige Seitenklassifizierung — |
| Einen zwischengespeicherten Map-Eintrag löschen, damit der nächste Aufruf frische Daten abruft |
Installation
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.txtAusführen
Für die lokale Entwicklung mit dem MCP-Inspektor:
mcp dev server.pyUm direkt über stdio auszuführen (wie MCP-Clients es starten):
python server.pyRegistrierung bei Claude / Cowork
Fügen Sie dies zu ~/Library/Application Support/Claude/claude_desktop_config.json (Mac) oder dem Äquivalent unter Windows hinzu:
{
"mcpServers": {
"web-speed": {
"command": "/absolute/path/to/web-interpreter/venv/bin/python",
"args": ["/absolute/path/to/web-interpreter/server.py"]
}
}
}Starten Sie dann Claude Desktop / Cowork neu. Die sechs Tools erscheinen unter dem web-speed MCP-Server.
Ausgabeschemata
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": "" }
}
}Wichtige Felder:
navigation— Links innerhalb semantischer Navigations-, Header- oder Footer-Elemente (Site-Chrome, Menüs). Auf 60 begrenzt.content_links— Links innerhalb des Seitenkörpers (Artikel, Suchergebnisse, Auflistungen). Enthält immertotal, damit Sie die tatsächliche Anzahl kennen, auch wenn bei 60 abgeschnitten wird.forms— Jedes Formular mit jedem Feld, CSRF-Token werden wortgetreu imvaluedes versteckten Feldes beibehalten.page_type— Abgeleitet aus der Struktur: Passwortfeld →login, viele Elemente/Links →listing,<article>mit Absätzen →article, Formulare →form, hauptsächlich Links →navigation.
page_type
Leichtgewichtig — gibt nur die Klassifizierung zurück. Sofort verfügbar, wenn die Seite zwischengespeichert ist.
{
"url": "https://example.com/login",
"fetched_at": "2025-01-01T12:00:00Z",
"page_type": "login",
"title": "Sign In"
}submit_form
Gleiche Ausgabeform wie interpret_page, für die Seite, auf der der Server nach dem Absenden landet.
{
"url": "https://example.com/login",
"method": "POST",
"fields": {
"email": "user@example.com",
"password": "hunter2",
"_csrf": "abc123"
}
}CSRF-Token kommen wortgetreu in fields — übernehmen Sie diese aus den versteckten Feldern im forms-Array des vorherigen interpret_page-Aufrufs.
inspect_element
Tiefe strukturelle Daten für Knoten, die einem CSS-Selektor entsprechen. Auf 25 Elemente begrenzt.
{
"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" }
]
}
]
}Beispiel-Selektoren: #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 }Fehler
Tools lösen niemals Fehler aus. Bei einem Fehler:
{
"error": true,
"code": "FETCH_FAILED | PARSE_FAILED | TIMEOUT | NOT_HTML",
"message": "human-readable explanation",
"url": "https://example.com/broken"
}Wie ein Agent die Ausgabe verwenden sollte
Eine Website navigieren:
Lesen Sie navigation für das Site-Chrome (Menüs, Header, Footer) und content_links für Links im Seitenkörper. content_links.total verrät Ihnen, wie viele existieren, auch wenn die Liste gekürzt ist. Wählen Sie den Link, der Ihrem Ziel entspricht, und rufen Sie interpret_page auf.
Ein Formular absenden:
Lesen Sie forms. Jedes Feld hat name (was gesendet werden soll), type (welche Daten erwartet werden), label/placeholder (wofür es ist), required und value. Versteckte Felder (type: "hidden") enthalten CSRF-Token — übergeben Sie deren value wortgetreu zurück. Erstellen Sie ein flaches name → value-Wörterbuch und rufen Sie submit_form auf.
Klassifizieren vor dem Handeln:
Rufen Sie zuerst page_type auf, wenn Sie Logik verzweigen müssen (z. B. ist dies eine Login-Seite oder ein Dashboard?), ohne für ein vollständiges interpret_page zu bezahlen.
In eine Komponente hineinbohren:
Sie haben eine Tabelle in der Karte gesehen, möchten aber die einzelnen Zeilen? Eine Produktauflistung, aber Sie möchten den Link und Preis jeder Karte? Rufen Sie inspect_element mit einem CSS-Selektor auf, um strukturierte Details zu diesen spezifischen Knoten zu erhalten, ohne die gesamte Seite neu zu laden.
Einen mehrstufigen Workflow vorplanen:
Rufen Sie site_map auf, bevor Sie beginnen. Sie erhalten den Titel, Typ, die Tiefe und ausgehende Links jeder Seite sowie jedes Formular auf der gesamten Website — Sie können den gesamten Workflow planen (Login-Formular finden, Dateneingabeseite finden, Submit-Endpunkt finden), ohne einen einzigen Round-Trip.
page_type ist ein Signal, keine Garantie:
Die Klassifizierung ist heuristisch. JS-gerenderte SPAs, die leere HTML-Hüllen ausliefern, werden oft als other eingestuft — das Passwortfeld ist erst im HTML, nachdem JavaScript ausgeführt wurde. Betrachten Sie page_type als schnellen Filter und verifizieren Sie ihn dann anhand der tatsächlichen forms und headings.
Gemeinsame Registry-Synchronisierung
Standardmäßig wird jede neue Seitenkarte, die Ihr OSS-Server erstellt, asynchron an die Web Speed Shared Registry unter api.getwebspeed.io übermittelt. Dies ist das Crowdsourcing-Schwungrad — jeder Agent, der eine URL abruft, fügt sie dem globalen Cache hinzu, sodass der nächste Agent überall eine sofortige Antwort erhält.
Dies ist ein Opt-out, kein Opt-in. Die Standardeinstellung ist aktiviert, da je mehr Mitwirkende es gibt, desto schneller laufen die Agenten aller Beteiligten.
Was geteilt wird
Nur strukturelle Seitendaten:
Seitentyp, Titel, Beschreibung
Überschriften, Navigationslinks, Inhaltslinks
Formularfeldnamen, Typen und Labels (keine Werte)
Tabellen, Textblöcke
Open Graph Metadaten
Niemals geteilt: Cookies, Session-Token, Formularwerte, JS-gerenderte Karten (die sitzungsspezifische Login-Zustände enthalten könnten).
Synchronisierung deaktivieren
Setzen Sie die Umgebungsvariable, bevor Sie den Server starten:
WEB_SPEED_REGISTRY_SYNC=false python server.pyOder in Ihrer MCP-Client-Konfiguration:
{
"mcpServers": {
"web-speed": {
"command": "/path/to/venv/bin/python",
"args": ["/path/to/server.py"],
"env": {
"WEB_SPEED_REGISTRY_SYNC": "false"
}
}
}
}Auf eine selbst gehostete Registry verweisen
Wenn Sie Ihre eigene gehostete Instanz betreiben, verweisen Sie die Synchronisierung dorthin:
WEB_SPEED_REGISTRY_URL=https://your-instance.example.com python server.pySynchronisierungsverhalten
Fire-and-Forget: Der Beitrag wird im Hintergrund gesendet. Die Anfrage Ihres Agenten wird mit voller Geschwindigkeit abgeschlossen, unabhängig davon, ob der Ping erfolgreich ist.
Nur bei Cache-MISS: Karten, die bereits in Ihrem lokalen 24-Stunden-Festplatten-Cache vorhanden sind, werden nicht erneut gesendet.
Fehler sind lautlos: Netzwerkfehler, Timeouts und Server-Ablehnungen werden nur auf DEBUG-Ebene protokolliert und gelangen niemals zum Agenten.
Architektur
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)Keine KI. Keine Interpretation. Der Agent ist das Gehirn.
Bekannte Einschränkungen
JS-gerenderte SPAs: Seiten, die Inhalte über JavaScript (React, Vue, Angular) laden, geben nur die Pre-Render-HTML-Hülle zurück. Passwortfelder, Suchergebnisse und Navigation, die durch JS injiziert werden, fehlen. Verwenden Sie
inspect_elementauf dem, was sichtbar ist, und kombinieren Sie es mit einem Browser-Automatisierungstool für SPA-lastige Ziele.page_typeHeuristiken: Die Klassifizierung ist strukturell und schnell, aber nicht unfehlbar. Eine Marketingseite mit vielen internen Links könnte alslistingeingestuft werden; eine Seite mit einem E-Mail-Feld und ohne Passwort wird nicht alsloginerkannt.Cache ist lokale Festplatte: Das Verzeichnis
./cache/ist lokal. In einer Multi-Prozess- oder verteilten Bereitstellung werden Cache-Einträge nicht über Instanzen hinweg geteilt. Für gemeinsames Caching ersetzen Siecache.pydurch ein Redis- oder Memcached-Backend.Ratenbegrenzungen nicht durchgesetzt: Web Speed drosselt keine ausgehenden Anfragen. Für Agenten-Flotten mit hohem Volumen setzen Sie einen Ratenbegrenzungs-Proxy (z. B. Cloudflare, nginx) vor den Server.
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