web-speed-oss
Web Speed
Web Speedは、AIエージェントにおける信号対雑音比(Signal-to-Noise)の問題を解決します。現代のWebは人間の目向けに最適化されていますが(乱雑なHTML、複雑なレイアウト、JSを多用したインターフェース)、Web Speedはその混沌を、高スループットのエージェント群向けに設計された、決定論的でトークン効率の高い構造マップに変換します。
AIは含まれていません。 anthropicもopenaiも、LLMへの依存も一切ありません。すべての解釈は呼び出し側のエージェント内で行われます。
なぜ存在するのか
問題 | Web Speedの解決策 |
生のHTMLは15万文字以上のスクリプト、スタイル、SVGのノイズを含む | 構造以外のすべてを削除 → 最大97%のトークン削減 |
LLMは生のDOMで要素IDを幻覚したり、インタラクションポイントを見逃したりする | 固定された構造マップを返す — そこにあるものはそこにあり、捏造は一切なし |
カスタムスクレーパーはサイトごとに壊れる | 決定論的プロトコル — Web上のすべてのサイトで同じJSON形式 |
エージェントがページを1往復ずつ再発見しなければならない |
|
Related MCP server: Delta-MCP
ツール
ツール | 説明 |
| 完全な構造マップ:見出し、ナビゲーション、コンテンツリンク、フォーム、テーブル、テキスト、メタデータ |
| フォームを送信(GETまたはPOST)し、結果ページのマップを取得 |
| ルートURLからクロールし、全ページの結合マップを返す |
| CSSセレクタに一致するノードの詳細な構造データ |
| 即時のページ分類 — |
| キャッシュされたマップを破棄し、次回の呼び出しで最新を取得 |
インストール
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.txt実行
MCPインスペクターを使用したローカル開発の場合:
mcp dev server.pystdio経由で直接実行する場合(MCPクライアントが起動する方法):
python server.pyClaude / Coworkへの登録
~/Library/Application Support/Claude/claude_desktop_config.json(Mac)またはWindows上の同等のファイルに追加します:
{
"mcpServers": {
"web-speed": {
"command": "/absolute/path/to/web-interpreter/venv/bin/python",
"args": ["/absolute/path/to/web-interpreter/server.py"]
}
}
}その後、Claude Desktop / Coworkを終了して再起動します。6つのツールがweb-speed MCPサーバーの下に表示されます。
出力スキーマ
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": "" }
}
}主要フィールド:
navigation— セマンティックなnav/header/footer要素内のリンク(サイトのクローム、メニュー)。最大60件。content_links— ページ本文内のリンク(記事、検索結果、リスト)。60件で切り捨てられた場合でも実際の数を知るために常にtotalが含まれます。forms— すべてのフィールドを含むすべてのフォーム。CSRFトークンは非表示フィールドのvalueにそのまま保持されます。page_type— 構造から推論:パスワードフィールド →login、多数のアイテム/リンク →listing、段落を含む<article>→article、フォーム →form、リンクが主 →navigation。
page_type
軽量 — 分類のみを返します。ページがキャッシュされている場合は即時です。
{
"url": "https://example.com/login",
"fetched_at": "2025-01-01T12:00:00Z",
"page_type": "login",
"title": "Sign In"
}submit_form
interpret_pageと同じ出力形式で、送信後にサーバーが到達したページのマップを返します。
{
"url": "https://example.com/login",
"method": "POST",
"fields": {
"email": "user@example.com",
"password": "hunter2",
"_csrf": "abc123"
}
}CSRFトークンはfieldsにそのまま入ります。前回のinterpret_page呼び出しのforms配列内の非表示フィールドから取得してください。
inspect_element
CSSセレクタに一致するノードの詳細な構造データ。最大25要素。
{
"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" }
]
}
]
}セレクタの例: #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 }エラー
ツールは例外を発生させません。失敗時:
{
"error": true,
"code": "FETCH_FAILED | PARSE_FAILED | TIMEOUT | NOT_HTML",
"message": "human-readable explanation",
"url": "https://example.com/broken"
}エージェントによる出力の利用方法
サイトのナビゲート:
サイトのクローム(メニュー、ヘッダー、フッター)にはnavigationを、ページ本文のリンクにはcontent_linksを読み取ります。content_links.totalはリストが切り捨てられていても存在する数を示します。目的に一致するリンクを選択し、interpret_pageを呼び出します。
フォームの送信:
formsを読み取ります。各フィールドにはname(送信するもの)、type(期待されるデータ型)、label/placeholder(用途)、required、valueがあります。非表示フィールド(type: "hidden")はCSRFトークンを保持しているため、そのvalueをそのまま渡します。フラットなname → value辞書を作成し、submit_formを呼び出します。
実行前の分類:
ロジックを分岐させる必要がある場合(例:ログインページかダッシュボードか?)、フルでinterpret_pageを呼び出すコストをかけずに、まずpage_typeを呼び出します。
コンポーネントの詳細確認:
マップ内にテーブルを見つけたが個別の行が必要な場合や、商品リストがあるが各カードのリンクと価格が必要な場合は、CSSセレクタを指定してinspect_elementを呼び出し、ページ全体を再読み込みせずに特定のノードの詳細構造を取得します。
マルチステップワークフローの事前計画:
開始前にsite_mapを呼び出します。全ページのタイトル、タイプ、階層、発リンク、およびサイト全体の全フォームを取得できるため、ワークフロー全体(ログインフォームの場所、データ入力ページの場所、送信エンドポイントの場所)を1往復もせずに計画できます。
page_typeはシグナルであり、保証ではない:
分類はヒューリスティックです。JavaScriptでレンダリングされるSPAで空のHTMLシェルを返すものは、多くの場合otherになります。パスワードフィールドはJavaScriptが実行されるまでHTML内に存在しないためです。page_typeは高速なフィルターとして扱い、実際のformsやheadingsで検証してください。
共有レジストリの同期
デフォルトでは、OSSサーバーが構築するすべての新しいページマップは、api.getwebspeed.ioのWeb Speed共有レジストリに非同期で提供されます。これはクラウドソーシングによるフライホイールです。URLを取得したすべてのエージェントがそれをグローバルキャッシュに追加するため、他の場所の次のエージェントは即座に応答を得られます。
これはオプトアウト方式です。 貢献者が増えるほど全員のエージェントが高速に動作するため、デフォルトでオンになっています。
共有されるもの
構造的なページデータのみ:
ページタイプ、タイトル、説明
見出し、ナビゲーションリンク、コンテンツリンク
フォームフィールド名、型、ラベル(値は含まれません)
テーブル、テキストブロック
Open Graphメタデータ
共有されないもの: クッキー、セッション・トークン、フォームの値、JSレンダリングされたマップ(セッション固有のログイン状態が含まれる可能性があるため)。
同期の無効化
サーバー起動前に環境変数を設定します:
WEB_SPEED_REGISTRY_SYNC=false python server.pyまたはMCPクライアント設定で:
{
"mcpServers": {
"web-speed": {
"command": "/path/to/venv/bin/python",
"args": ["/path/to/server.py"],
"env": {
"WEB_SPEED_REGISTRY_SYNC": "false"
}
}
}
}セルフホスト型レジストリへの指定
独自のホストインスタンスを実行している場合は、同期先をそこに指定します:
WEB_SPEED_REGISTRY_URL=https://your-instance.example.com python server.py同期の動作
ファイア・アンド・フォーゲット:貢献はバックグラウンドで送信されます。エージェントのリクエストは、pingの成功に関係なくフルスピードで完了します。
キャッシュミス時のみ:ローカルの24時間ディスクキャッシュに既にあるマップは再送信されません。
失敗はサイレント:ネットワークエラー、タイムアウト、サーバー拒否はDEBUGレベルでのみログ記録され、エージェントには表示されません。
アーキテクチャ
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)AIなし。解釈なし。エージェントが脳です。
既知の制限
JSレンダリングされるSPA: JavaScript(React、Vue、Angular)を介してコンテンツを読み込むページは、プリレンダリングされたHTMLシェルのみを返します。JSによって注入されるパスワードフィールド、検索結果、ナビゲーションは欠落します。表示されているものに対して
inspect_elementを使用し、SPAを多用するターゲットにはブラウザ自動化ツールと組み合わせてください。page_typeのヒューリスティクス: 分類は構造的で高速ですが、完璧ではありません。内部リンクが多いマーケティングページはlistingと判定される可能性があり、メールフィールドはあるがパスワードフィールドがないページはloginとは判定されません。キャッシュはローカルディスク:
./cache/ディレクトリはローカルです。マルチプロセスや分散デプロイメントでは、キャッシュエントリはインスタンス間で共有されません。共有キャッシュが必要な場合は、cache.pyをRedisやMemcachedバックエンドに置き換えてください。レート制限は未実装: Web Speedはアウトバウンドリクエストをスロットリングしません。大量のエージェント群を運用する場合は、サーバーの前にレート制限プロキシ(Cloudflare、nginxなど)を配置してください。
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