web-speed-agent
web-speed-agent
Lokale Browser-Automatisierung + Web Speed API Integration für authentifizierte Web-Extraktion.
Setzen Sie einen KI-Agenten auf eine beliebige Website an – auch auf solche, die einen Login erfordern – und erhalten Sie saubere, strukturierte Daten zurück. Anmeldedaten bleiben auf Ihrem Rechner. Nur die extrahierte HTML wird an den Server gesendet.
pip install web-speed-agent
playwright install chromiumMöchten Sie dies mit Claude, Gemini oder anderen KI-Clients verwenden?
Schauen Sie sich das MCP Server Installationshandbuch an – es ist der einfachste Weg, KI-Agenten über natürliche Sprache einloggen und Daten extrahieren zu lassen.
Funktionsweise
Your machine Web Speed server
───────────────────────────────── ──────────────────────────
Playwright browser (local)
↓ navigates, logs in, clicks
↓ gets page HTML
↓ (no passwords sent)
agent.extract(html) ────────→ Advanced extraction engine
←──────── Structured JSONAnmeldedaten verlassen niemals Ihren Rechner. Der Server sieht nur HTML.
Related MCP server: Agent Identity MCP Server
Schnellstart
import asyncio
from web_speed_agent import Agent
async def main():
agent = Agent(api_key="wsp_...") # or set WEBSPEED_API_KEY env var
# Public pages — no browser needed
result = await agent.map("https://techcrunch.com/some-article/")
print(result["article"]["sections"])
# Authenticated pages — browser runs locally
agent.store_credential("mysite", "me@example.com", "mypassword")
async with agent.browser(session_name="mysite") as browser:
page = await browser.new_page()
await page.goto("https://mysite.com/login")
username, password = agent.get_credential("mysite")
await page.fill('[name="email"]', username)
await page.fill('[name="password"]', password)
await page.click('button[type="submit"]')
await page.wait_for_load_state("networkidle")
# Now on a logged-in page — extract it
html = await page.content()
result = await agent.extract(html, page_type="listing")
print(result["listing"]["items"])
asyncio.run(main())Holen Sie sich einen API-Schlüssel unter getwebspeed.io.
Installation
Voraussetzungen: Python 3.10+, ein Web Speed API-Schlüssel
pip install web-speed-agent
playwright install chromium
export WEBSPEED_API_KEY="wsp_..."Kernkonzepte
Agent
Die Hauptklasse. Verwaltet Anmeldedaten, Browsersitzungen und API-Aufrufe.
from web_speed_agent import Agent
# API key from argument
agent = Agent(api_key="wsp_...")
# API key from environment variable (recommended)
# export WEBSPEED_API_KEY="wsp_..."
agent = Agent()
# Use as async context manager (auto-closes HTTP client)
async with Agent() as agent:
...Extrahieren öffentlicher Seiten
Kein Browser erforderlich für Seiten, die keinen Login erfordern:
# Fetch + extract in one call
result = await agent.map("https://example.com/article")
# With JavaScript rendering (for heavy SPAs)
result = await agent.map("https://example.com/spa", js=True)Extrahieren authentifizierter Seiten
Verwenden Sie eine lokale Browsersitzung. Der Browser läuft auf Ihrem Rechner:
async with agent.browser(session_name="mysite") as browser:
page = await browser.new_page()
await page.goto("https://mysite.com/dashboard")
html = await page.content()
result = await agent.extract(html)Der session_name speichert Cookies dauerhaft unter ~/.webspeed/sessions/<name>/, sodass nachfolgende Ausführungen den Login-Schritt überspringen.
Verwaltung von Anmeldedaten
Anmeldedaten werden in Ihrem System-Schlüsselbund gespeichert (macOS Keychain, Windows Credential Manager, Linux secret-tool). Sie werden niemals an Web Speed-Server gesendet.
# Store once
agent.store_credential("mysite", "me@example.com", "mypassword")
# Retrieve anywhere
username, password = agent.get_credential("mysite")
# Remove
agent.delete_credential("mysite")Extraktionsergebnis
Der Server gibt seitentyp-bewusste strukturierte Daten zurück:
# Article
result = await agent.extract(html, page_type="article")
# result["page_type"] → "article"
# result["title"] → "Article Title"
# result["author"] → "Jane Smith"
# result["published_date"] → "2026-05-06"
# result["article"]["sections"] → [{"heading": "...", "paragraphs": [...]}]
# result["article"]["links"] → [{"text": "...", "url": "..."}]
# Product
result = await agent.extract(html, page_type="product")
# result["product"]["name"] → "Wireless Headphones"
# result["product"]["price"] → "$99.99"
# result["product"]["availability"] → "In Stock"
# result["product"]["rating"] → "4.5"
# result["product"]["specs"] → {"Battery": "30h", ...}
# Listing (search results, category pages)
result = await agent.extract(html, page_type="listing")
# result["listing"]["items"] → [{"title": "...", "url": "...", "price": "..."}]
# Auto-detect (default)
result = await agent.extract(html)
# result["page_type"] → "article" | "product" | "listing" | "other"Alle Ergebnisse enthalten engine: "advanced" – 60–85 % effizienter bei der Token-Nutzung als rohes HTML.
Beispiele
Preisüberwachung
import asyncio
from web_speed_agent import Agent
async def check_price(url: str, site_name: str) -> str:
async with Agent() as agent:
agent.store_credential(site_name, "me@example.com", "password", overwrite=True)
async with agent.browser(session_name=site_name) as browser:
page = await browser.new_page()
# Login
await page.goto(f"https://{site_name}.com/login")
user, pwd = agent.get_credential(site_name)
await page.fill('[name="email"]', user)
await page.fill('[name="password"]', pwd)
await page.click('button[type="submit"]')
await page.wait_for_load_state("networkidle")
# Check product
await page.goto(url)
await page.wait_for_load_state("networkidle")
html = await page.content()
result = await agent.extract(html, page_type="product")
return result.get("product", {}).get("price", "unknown")
price = asyncio.run(check_price("https://example.com/product/123", "example"))
print(f"Current price: {price}")Ein privates Dashboard lesen
import asyncio
from web_speed_agent import Agent
async def get_dashboard_data():
async with Agent() as agent:
async with agent.browser(session_name="analytics") as browser:
page = await browser.new_page()
# Login (first run only — session persists after)
creds = agent.get_credential("analytics")
if not creds:
agent.store_credential("analytics", "me@company.com", "password")
creds = agent.get_credential("analytics")
await page.goto("https://analytics.company.com/login")
await page.fill('[name="email"]', creds[0])
await page.fill('[name="password"]', creds[1])
await page.click('button[type="submit"]')
await page.wait_for_load_state("networkidle")
# Navigate to dashboard
await page.goto("https://analytics.company.com/dashboard")
await page.wait_for_selector(".metrics-table", timeout=10000)
html = await page.content()
result = await agent.extract(html)
return result
asyncio.run(get_dashboard_data())Mehrseitiges Scrapen während des Logins
import asyncio
from web_speed_agent import Agent
async def scrape_inbox():
async with Agent() as agent:
async with agent.browser(session_name="webmail") as browser:
page = await browser.new_page()
# Login
await page.goto("https://mail.example.com/login")
user, pwd = agent.get_credential("webmail")
await page.fill('[name="username"]', user)
await page.fill('[name="password"]', pwd)
await page.click('[type="submit"]')
await page.wait_for_load_state("networkidle")
# Scrape multiple pages
emails = []
for page_num in range(1, 4):
await page.goto(f"https://mail.example.com/inbox?page={page_num}")
await page.wait_for_load_state("networkidle")
html = await page.content()
result = await agent.extract(html, page_type="listing")
emails.extend(result.get("listing", {}).get("items", []))
return emails
asyncio.run(scrape_inbox())KI-Agenten-Integration (MCP)
Der enthaltene MCP-Server ermöglicht es Claude Desktop, Gemini CLI und jedem MCP-kompatiblen Agenten, das SDK direkt zu nutzen. Der Agent kann sich einloggen, navigieren, klicken und extrahieren – alles durch natürliche Sprache.
Starten Sie den MCP-Server:
WEBSPEED_API_KEY="wsp_..." python3 agent_mcp_server.pyZu Claude Desktop hinzufügen (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"web-speed-agent": {
"command": "python3",
"args": ["/path/to/agent_mcp_server.py"],
"env": {
"WEBSPEED_API_KEY": "wsp_..."
}
}
}
}Zu Gemini CLI hinzufügen (~/.gemini/settings.json):
{
"mcpServers": {
"web-speed-agent": {
"command": "python3.11",
"args": ["/path/to/agent_mcp_server.py"],
"env": {
"WEBSPEED_API_KEY": "wsp_...",
"PYTHONPATH": "/path/to/web-speed-agent"
}
}
}
}Sagen Sie dann dem Agenten:
"Speichere meine Anmeldedaten für united – Benutzername me@example.com, Passwort meinpasswort"
"Logge dich bei united.com ein und finde mir den günstigsten Flug von SFO nach JFK am nächsten Freitag"
Verfügbare MCP-Tools:
Tool | Beschreibung |
| Login im System-Schlüsselbund speichern |
| Browser öffnen + anmelden |
| URL in der aktiven Sitzung aufrufen |
| Strukturierte Daten von der aktuellen Seite abrufen |
| Auf eine Schaltfläche oder einen Link klicken |
| In ein Formularfeld schreiben |
| Ein Formular absenden |
| Browsersitzung beenden |
| API-Guthaben prüfen |
API-Referenz
Agent
Agent(
api_key: str | None = None,
server_url: str | None = None,
config_dir: str = "~/.webspeed",
headless: bool = True,
)Parameter | Beschreibung |
| Web Speed API-Schlüssel. Greift auf die Umgebungsvariable |
| API-Server-URL überschreiben. Standard: |
| Verzeichnis für Konfiguration, Sitzungen und Protokolle. Standard: |
| Browser im Headless-Modus ausführen. Standard: |
agent.browser()
agent.browser(
session_name: str | None = None,
headless: bool | None = None,
proxy: str | None = None,
) -> ManagedBrowserGibt einen asynchronen Kontext-Manager zurück. Rufen Sie innerhalb des Blocks .new_page() auf, um eine Playwright-Page zu erhalten.
Parameter | Beschreibung |
| Cookies unter |
| Instanz- |
| Proxy-URL, z. B. |
Sitzungsnamen müssen alphanumerisch sein + Bindestriche/Unterstriche, maximal 64 Zeichen.
agent.extract()
await agent.extract(
html: str,
page_type: str = "auto",
) -> dictSendet HTML an die Web Speed API. Kostet 1 Credit.
Parameter | Beschreibung |
| Roher HTML-String (z. B. von |
|
|
agent.map()
await agent.map(
url: str,
js: bool = False,
) -> dictRuft eine öffentliche URL über den Server ab und extrahiert sie. Kein lokaler Browser erforderlich. Kostet 1 Credit.
Parameter | Beschreibung |
| Seiten-URL. Muss |
| JavaScript vor der Extraktion rendern. |
agent.account()
await agent.account() -> dictGibt zurück: credits, tier, status, lifetime (gesamt/Treffer/Fehlschläge).
agent.store_credential()
agent.store_credential(
site: str,
username: str,
password: str,
overwrite: bool = False,
) -> NoneSpeichert im System-Schlüsselbund. Löst CredentialError aus, wenn Anmeldedaten existieren und overwrite=False.
agent.get_credential()
agent.get_credential(site: str) -> tuple[str, str] | NoneGibt (username, password) zurück oder None, falls nicht gefunden.
agent.delete_credential()
agent.delete_credential(site: str) -> NoneEntfernt Anmeldedaten aus dem Schlüsselbund.
Ausnahmen
from web_speed_agent import (
WebSpeedError, # Base exception
AuthenticationError, # Invalid/missing API key
InsufficientCreditsError, # No credits remaining
APIError, # API returned 4xx/5xx
RateLimitError, # 429 Too Many Requests
CredentialError, # Keychain error
BrowserError, # Playwright error
NetworkError, # Timeout or DNS failure
PlaywrightNotInstalledError, # Run: playwright install chromium
)from web_speed_agent import Agent, InsufficientCreditsError, NetworkError
try:
result = await agent.extract(html)
except InsufficientCreditsError:
print("Out of credits — top up at getwebspeed.io")
except NetworkError as e:
print(f"Connection failed: {e}")Konfiguration
Umgebungsvariablen
Variable | Beschreibung |
| API-Schlüssel (empfohlen gegenüber Konfigurationsdatei) |
| Server-URL überschreiben (muss |
Konfigurationsdatei
~/.webspeed/config.yaml – wird beim ersten Start automatisch erstellt. Berechtigungen auf 0o600 gesetzt (nur Besitzer).
api:
server_url: https://api.getwebspeed.io
timeout: 30
browser:
headless: trueSitzungsdateien
Persistente Browsersitzungen werden unter ~/.webspeed/sessions/<name>/storage.json gespeichert.
Berechtigungen:
0o600(nur Besitzer)Enthält: Cookies, localStorage, sessionStorage
Sicher zu löschen: Der Agent authentifiziert sich beim nächsten Lauf erneut
Sicherheit
Was Ihren Rechner verlässt
Wenn Sie agent.extract(html) aufrufen, wird das Seiten-HTML zur Verarbeitung an die Web Speed API gesendet. Alles andere bleibt lokal.
Daten | Wohin sie gehen |
Anmeldedaten | Verlassen niemals Ihren Rechner (nur System-Schlüsselbund) |
Browser-Cookies / Sitzung | Verlassen niemals Ihren Rechner (lokales Playwright) |
Seiten-HTML | Über HTTPS an Web Speed API zur Extraktion gesendet |
Extrahiertes JSON | An Sie zurückgegeben |
HTML-Bereinigung (standardmäßig aktiviert)
Bevor HTML übertragen wird, bereinigt das SDK es automatisch lokal:
Inline-
<script>- und<style>-Blöcke entferntVersteckte Formularfelder mit auth-bezogenen Namen (
csrf,token,nonce,sessionusw.) werden geleertSensible
<meta>-Inhaltsattribute gelöschtHTML-Kommentare entfernt
Sichtbare Inhalte – Text, Links, Tabellen, Überschriften, Produktdaten – bleiben unberührt.
# Default: scrubbing is on
result = await agent.extract(html)
# Turn off only if the page has no sensitive data
result = await agent.extract(html, scrub=False)
# Or scrub manually and inspect before sending
from web_speed_agent import scrub
clean_html = scrub(raw_html)
print(clean_html) # inspect what will be sent
result = await agent.extract(clean_html, scrub=False)Serverseitige Datenverarbeitung
HTML wird nur im Arbeitsspeicher verarbeitet – niemals auf die Festplatte geschrieben, niemals protokolliert, niemals zwischengespeichert
Auth-geschützte Seiten werden niemals zwischengespeichert – Seiten, die einen Login erfordern, sind explizit vom gemeinsamen Register ausgeschlossen
Nutzungsprotokolle speichern nur: einen Hash Ihres API-Schlüssels, einen Hash der URL (oder
"sdk-extract"), Zeitstempel und erkannten Seitentyp – keine InhalteKein rohes HTML in Fehlerantworten – Ausnahmen werden bereinigt, bevor ein Fehler zurückgegeben wird
Weitere Schutzmaßnahmen
Anmeldedaten werden im System-Schlüsselbund gespeichert, niemals in Dateien, niemals an Server gesendet
Sitzungsdateien werden mit
0o600-Berechtigungen geschrieben (nur Besitzer lesen/schreiben)Konfigurationsverzeichnis mit
0o700-Berechtigungen erstelltTLS immer verifiziert –
verify=Truebei allen HTTP-Aufrufen, kann nicht deaktiviert werdenHTTPS erzwungen –
server_urlmuss mithttps://beginnen, einfaches HTTP wird abgelehntPfad-Traversal-Prävention – Sitzungsnamen gegen
[a-zA-Z0-9_-]-Whitelist validiertKeine Protokollierung von Anmeldedaten – Passwörter erscheinen niemals in Protokollen oder Fehlermeldungen
Lizenz
GNU General Public License v3.0 – siehe LICENSE.
Die Nutzung der Web Speed API unterliegt den Web Speed Nutzungsbedingungen.
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 Servers
- AlicenseNot gradedqualityCmaintenanceReducing token usage by 70% with a deterministic mapping engine. Also links in with the Web Speed Agent SDK and MCP for post-auth agents.10GPL 3.0
- AlicenseNot gradedqualityDmaintenanceMCP Server for AI agent identity and authorization. Create, verify, and manage agent identities with trust scores and scoped authorization tokens.MIT
- AlicenseAqualityAmaintenanceProvides an MCP-native agent browser that enables autonomous agents to perceive and interact with web pages through stealth browsing, identity borrowing, and WAAP detection.9MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP-capable runtimes to read agent message rooms, sign and post public messages, and create or verify Ed25519 contribution proofs for Technocore.MIT
Related MCP Connectors
Agent-first web hosting: deploy sites, apps, databases and domains over MCP.
Hosted AgentLux MCP server for marketplace, identity, creator, services, and social flows.
MCP Server for agents to onboard, pay, and provision services autonomously with InFlow
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/Dominic-Pi-Sunyer/web-speed-agent'
If you have feedback or need assistance with the MCP directory API, please join our Discord server