Scavenge
Scavenge — детерминированные веб-доказательства для людей и кодинг-агентов
Scavenge проверяет одно поле на одной веб-странице и сообщает каждое место, где это поле появляется, что говорит каждое представление и откуда именно взялось каждое значение.
Он собирает наблюдения полей с точным происхождением. Он не определяет, какое наблюдение семантически верно. Для этого суждения нужно знать, что означает страница, и движок намеренно на это неспособен — см. Почему он останавливается.
Что он делает
$ scavenge inspect https://example.com/product/123 --field price
FIELD: price
RAW_DOM 99.00 USD [raw_dom:0]
raw: '$99.00'
source: div.product-price
STRUCTURED_DATA 99.00 USD [structured_data:0]
raw: '99.00'
source: script[0]/offers/price
EMBEDDED_STATE not observed
RENDERED_DOM 79.00 USD [rendered_dom:0]
raw: '$79.00'
source: div.product-price
NETWORK_JSON 79.00 USD [network_json:0]
raw: '79.00'
source: GET https://example.com/api/products/123 /price
ACQUISITION
HTTP 200 48213 bytes 0.31s
RENDER OK
JSON responses observed: 12Сырой HTML говорит 99.00, отрендеренная страница говорит 79.00, а API-вызов объясняет почему. Вы можете увидеть это за две секунды; движок не утверждает это.
Related MCP server: attest-capture-mcp
Зачем он существует
Страница утверждает один и тот же факт в нескольких местах — видимый HTML, JSON-LD, гидратационный блоб, отрендеренный DOM, XHR-ответ — и они расходятся чаще, чем хотелось бы. Выяснить, какие из них содержат ваше поле — это работа в DevTools, выполняемая вручную, один раз на цель, навсегда. Агент тоже может это сделать, но не воспроизводимо и без точного происхождения.
Почему он останавливается
Изначальная цель была более амбициозной: детерминированно решать, относятся ли значения, найденные в разных представлениях, к одному и тому же реальному объекту, и сообщать, где они согласуются или расходятся.
Реальные магазины нарушили это предположение. Значения, которые выглядели сопоставимыми, принадлежали
каруселям рекомендаций, корзинам, таблицам финансирования, локаторам магазинов, вариантам товаров и
вторым блокам Product на той же странице. Прогон валидации по 12 магазинам показал, что
каждое расхождение, о котором сообщал движок, было именно такого рода — значения и происхождение были
верны, сравнение было неверным.
Правильное исправление превращается в разрешение сущностей. Поэтому Scavenge останавливается на шаг раньше:
собирать доказательства детерминированно и позволить человеку или агенту интерпретировать их. Полный
отчет, включая результаты, которые убили предыдущий дизайн, находится в
docs/research/.
Поддерживаемые поля
price и availability. Два, не "произвольные".
Поддерживаемые каналы
RAW_DOM · STRUCTURED_DATA · EMBEDDED_STATE · RENDERED_DOM · NETWORK_JSON
Они не одинаково валидированы. В 23-страничной валидации по 12 магазинам
STRUCTURED_DATA выдал значения в 28 из 46 прогонов, а EMBEDDED_STATE только в 6.
MCP
Один инструмент, inspect_web_field(url, field), возвращающий структурированные доказательства — не прозу.
{
"mcpServers": {
"scavenge": { "command": "python", "args": ["-m", "scavenge.mcp"] }
}
}Сервер ни о чем не рассуждает, не генерирует код для скрапинга и не вызывает модель.
Структурированный вывод
{
"schema_version": 3,
"target": "https://example.com/product/123",
"field": "price",
"observations": [
{
"id": "raw_dom:0",
"channel": "RAW_DOM",
"normalized_value": {"kind": "money", "amount": "99.00", "currency": "USD"},
"raw": "$99.00",
"provenance": {"selector": "div.product-price"},
"subject": {"scope": "PAGE", "key": "", "reason": ""},
"status": "OK",
"note": ""
}
],
"acquisition": {
"http_status": 200, "http_bytes": 48213, "http_challenge": "",
"render_status": "OK", "json_responses": 12
},
"warnings": []
}Архитектура
MCP ─┐
├─→ evidence engine ─→ HTTP · raw DOM · structured data
CLI ─┘ embedded state · rendered DOM · network JSONОдин движок. Оба интерфейса вызывают его; тест утверждает, что JSON CLI — это JSON движка.
Установка
pip install git+https://github.com/aarohim24/Scavenge.git
python -m playwright install chromium # required for rendered DOM and network channels
scavenge inspect https://example.com/p/1 --field priceПока нет на PyPI — намеренно, пока API не пройдет раунд внешней обратной связи.
--no-render пропускает браузер и сообщает только HTTP-каналы.
Границы безопасности
Только http/https. file://, localhost, loopback, link-local и частные диапазоны
отклоняются до любого запроса — что особенно важно в MCP, где агент предоставляет URL-адреса
без просмотра человеком. Тела ограничены 512 КБ, JSON-ответы ограничены 40, ограниченные
ожидания, ограниченная загрузка robots.txt. robots.txt соблюдается, а таймаут или недоступный
robots.txt никогда не трактуется как разрешение. Ни один захваченный запрос не воспроизводится, ни один
аутентифицированный запрос не повторяется, ничего со страницы не выполняется.
Что он явно не делает
Решать, какое наблюдение верно. v0.1 не публикует никакого сравнения.
Разрешение сущностей. Он не может надежно отличить товар страницы от второго блока Product, плитки апсейла, суммы корзины или строки локатора магазина.
Сканировать, планировать или переходить по ссылкам.
Обходить анти-бот системы. Он обнаруживает очевидный вызов и сообщает об этом; он никогда его не обходит.
Вызывать LLM, в любом режиме.
Известные ограничения
Нет сравнения в v0.1. Более ранняя версия публиковала отношения
EQUAL/DIFFERENT. Валидация на реальных данных показала, что каждоеDIFFERENT, которое она выдавала на живых магазинах, сравнивало две разные сущности, поэтому функция была удалена, а не исправлена. Полный результат вdocs/research/OSS-FINAL-CORRECTNESS.md.Валюта часто
null.$обозначает дюжину валют; без объявленного доказательства сумма сохраняется, а валюта отклоняется. Неизвестность распространена; неверное должно отсутствовать.Мелкие единицы не моделируются — Shopify
2950и отображаемое29.50— это два разных наблюдения.Детерминизм относится к генерации отчета, а не к вебу. Те же байты на входе — тот же отчет на выходе. Тот же URL не всегда даст те же байты.
Блокированный рендер обнаруживается только по именованным сигналам; тонкая безымянная оболочка — нет.
Доступ с уважением к robots.txt исключает многих крупных ритейлеров полностью.
Лицензия
Apache-2.0.
Статус
Экспериментальный v0.1. Опубликован для технической обратной связи, не для продакшена. API может измениться. Он был проверен на 23 страницах в 12 магазинах, плюс детерминированный набор фикстур; это небольшая выборка, и это не бенчмарк.
Запись исследований — включая результаты, которые убили более ранние версии этой идеи —
находится в docs/research/.
This server cannot be deployed
Maintenance
Related MCP Connectors
Give agents eyes on any web page: structured context, and changes explained in plain language.
Deterministic public-web change observation with evidence-bound commercial interpretation.
Measures your site in a real browser and returns verifiable observations, with evidence and limits.
Read-only public website inspection: evidence-backed Machine Presence observations with uncertainty.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceEnables AI agents to query structured data refined from unstructured web sources, including developer breaking changes, B2B pricing matrices, regulatory compliance, semantic search, and on-demand URL refinement.1-
- AlicenseNot gradedqualityCmaintenanceEnables evidence-grade capture of web pages as screenshots, PDFs, or HTML, returning a signed artifact URL, SHA-256 digest, timestamp, and optional public evidence page for attestation.MIT
- FlicenseAqualityBmaintenanceEnables extracting precise data from web pages by parsing the DOM with CSS selectors and returning structured JSON, while also offering tools to inspect page structure, discover candidate selectors, and verify them without loading full pages into context.5-
- FlicenseNot gradedqualityBmaintenanceEnables natural language web data extraction into structured JSON via browser automation, supporting field-based and goal-based modes with optional vision.1-