Skip to main content
Glama
ZephyraRR

mcp-web-tools-server

by ZephyraRR

mcp-web-tools-server

Пользовательский сервер Model Context Protocol (MCP), который предоставляет агенту ИИ реальные, работающие инструменты для загрузки веб-страниц и извлечения из них содержимого: чистый читаемый текст статьи, структурированные данные по CSS-селектору и проверку разрешений через robots.txt.

Что такое MCP?

MCP — это открытый протокол, первоначально опубликованный Anthropic, который стандартизирует способ подключения ИИ-приложений (например, Claude Desktop или Claude Code) к внешним инструментам и источникам данных. Вместо того чтобы каждое ИИ-приложение изобретало свой собственный формат плагинов, сервер MCP предоставляет фиксированный набор инструментов (и, опционально, ресурсов и промптов) через простой интерфейс JSON-RPC, и любой совместимый с MCP клиент может обнаруживать и вызывать их одинаковым способом. Этот репозиторий является одним из таких серверов: он запускается как небольшой локальный процесс и общается по MCP через stdio, поэтому любой MCP-клиент может перечислить его инструменты и вызвать их, не зная ничего о httpx, selectolax или trafilatura под капотом.

Related MCP server: better-fetch

Почему это полезно

Из коробки LLM не может загрузить живую веб-страницу. Этот сервер закрывает этот пробел небольшим, протестированным и хорошо очерченным набором инструментов: агент может извлечь читаемый текст статьи, получить конкретные поля со страницы по CSS-селектору (цена, заголовок, теги — что угодно, в зависимости от структуры страницы) и проверить, разрешает ли robots.txt сайта запрос перед его выполнением. Он намеренно узкий, а не универсальный фреймворк для скрапинга, исходя из того, что несколько инструментов, которые работают корректно и предсказуемо ошибаются, более полезны для агента, чем большая поверхность, которая иногда не работает.

Инструменты

fetch_and_extract(url: str) -> str

Загружает URL и возвращает чистый, читаемый текст основного содержимого: скрипты, стили, навигация, реклама и подвалы удалены. Использует trafilatura для извлечения статей, с эвристикой плотности абзацев (на основе selectolax) в качестве запасного варианта для страниц, с которыми trafilatura не уверенно справляется.

extract_structured(url: str, css_selectors: dict) -> dict

Загружает URL и извлекает поля по CSS-селектору, например:

{"title": "h1", "price": ".price", "tags": ".tag-list a"}

возвращает:

{"title": "Trail Blazer 29 Mountain Bike", "price": "$1,249.00", "tags": ["mountain", "hardtail", "29er"]}

Селектор, соответствующий одному элементу, возвращает его текст, соответствующий нескольким — возвращает список их текстов, не соответствующий ни одному — возвращает null. Разбор выполняется с помощью selectolax.

check_robots_txt(url: str) -> dict

Загружает robots.txt целевого сайта и сообщает, разрешено ли пользовательскому агенту этого сервера запрашивать указанный URL, используя стандартный urllib.robotparser из Python. Если robots.txt не найден, он сообщает об этом явно (robots_txt_found: false), а не молча предполагает, что разрешение фактически было получено.

Это существует, потому что этикет скрапинга должен быть первостепенной заботой, а не запоздалой мыслью: агент (или управляющий им человек) должен иметь возможность проверить разрешение перед загрузкой, а не только когда что-то пошло не так.

Принципы проектирования

  • Честная идентификация. Запросы используют реальную строку User-Agent, идентифицирующую этот инструмент и ссылающуюся на этот репозиторий, а не поддельный браузерный UA.

  • Ограниченные запросы. Каждая загрузка имеет фиксированный тайм-аут (10 секунд по умолчанию), чтобы медленный или зависший сервер не мог заблокировать весь сеанс.

  • robots.txt — это инструмент, а не молча принудительное правило. check_robots_txt предоставляется, чтобы агент (или управляющий им человек) мог проверить разрешение перед скрапингом, но в настоящее время он не блокирует fetch_and_extract или extract_structured автоматически. См. Ограничения ниже.

  • Отсутствие сбоев при некорректном вводе. Сетевые ошибки, тайм-ауты и неверные URL перехватываются и возвращаются как чистый текст ошибки или словарь {"error": ...}, а не как необработанное исключение, убивающее процесс сервера.

Структура проекта

mcp_web_tools/
  server.py        MCP server definition and the three tool entry points
  extractors.py     Pure HTML-parsing logic (no network), used for readable-text and CSS-selector extraction
  robots.py         robots.txt fetching and permission checking
  http_client.py    Shared httpx fetch helper: user agent, timeout, error handling
tests/
  test_extractors.py    Unit tests against local HTML fixtures, no network
  test_robots.py        Unit tests with the network call mocked out
  test_http_client.py   Unit tests for URL validation
  test_integration.py   Integration tests against live public sites, marked and run separately
  fixtures/              Static HTML used by the unit tests
scripts/
  test_client.py    Standalone script that launches the server and talks real MCP protocol to it

Запуск сервера

python -m venv venv
# Windows
venv\Scripts\activate
# macOS/Linux
source venv/bin/activate

pip install -r requirements.txt
python -m mcp_web_tools.server

Сервер общается через stdio по протоколу MCP; запуск напрямую из терминала просто оставит его ожидающим подключения клиента. Используйте его через MCP-клиент (см. ниже) или прилагаемый скрипт тестового клиента.

Настройка в качестве MCP-сервера в Claude Desktop или Claude Code

Добавьте запись в конфигурацию сервера вашего MCP-клиента, указав command на интерпретатор Python в виртуальном окружении и args на модуль. Для Claude Desktop это помещается в claude_desktop_config.json:

{
  "mcpServers": {
    "web-tools": {
      "command": "C:\\path\\to\\mcp-web-tools-server\\venv\\Scripts\\python.exe",
      "args": ["-m", "mcp_web_tools.server"],
      "cwd": "C:\\path\\to\\mcp-web-tools-server"
    }
  }
}

На macOS/Linux command будет /path/to/mcp-web-tools-server/venv/bin/python.

Для Claude Code выполните:

claude mcp add web-tools -- /path/to/mcp-web-tools-server/venv/bin/python -m mcp_web_tools.server

(подставьте путь к виртуальному окружению Windows, если применимо), или добавьте эквивалентную запись в .mcp.json вашего проекта.

Запуск тестов

Модульные тесты запускаются с локальными HTML-фикстурами и не обращаются к сети:

pytest

Интеграционные тесты обращаются к реальным стабильным публичным тестовым сайтам (example.com и books.toscrape.com, стандартные публичные цели для тестирования/демонстрации скрапинга) и исключены из запуска по умолчанию. Запускайте их явно, когда есть доступ к сети:

pytest -m integration

Также есть отдельный скрипт, который запускает сервер как реальный подпроцесс и управляет им через реальный протокол клиент/сервер MCP, а не вызывает функции Python напрямую:

python scripts/test_client.py

Ограничения и что бы я добавил следующим

  • Нет рендеринга JavaScript. Этот сервер загружает сырой HTML с помощью httpx. Страницы, которые отображают контент на стороне клиента (тяжелые React/Vue SPA), вернут мало или ничего полезного. Четвертый инструмент, оборачивающий Playwright для загрузки через headless-браузер, был бы естественным следующим дополнением, ценой гораздо большей требовательности к ресурсам.

  • Нет ограничения скорости. Каждый вызов инструмента выполняет один запрос при вызове. Нет встроенного регулирования по домену или очереди запросов, если агент вызывает инструменты в плотном цикле на один и тот же хост. check_robots_txt показывает crawl_delay_seconds, когда сайт публикует его, но в настоящее время ничто не принуждает к его соблюдению.

  • robots.txt носит рекомендательный характер, а не обязательный. fetch_and_extract и extract_structured не обращаются к check_robots_txt автоматически перед загрузкой. Это намеренное решение по объему для этой версии (агент должен сначала сам вызвать check_robots_txt), но более строгий режим, который автоматически отказывает в запрещённых запросах, был бы разумным дополнением.

  • Эвристика читаемости базовая. Запасной вариант с selectolax, используемый, когда trafilatura не даёт уверенного результата, представляет собой простой оценщик плотности абзацев. Он достаточно хорош для типичных макетов статей и блогов, но будет хуже работать на необычных структурах страниц, чем специализированная библиотека для читаемости.

  • Нет кэширования. Каждый вызов повторно загружает URL, даже для одного и того же URL с интервалом в несколько секунд. Подходит для демо/портфолио сервера, не идеально для более интенсивного использования.

  • Один транспорт на практике. Сервер настроен на stdio, который используется Claude Desktop и Claude Code. SDK mcp также поддерживает транспорты SSE и потокового HTTP; подключение одного из них потребуется для запуска этого сервера как хостинг-сервиса, а не локального подпроцесса.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    An MCP server that enables AI assistants to fetch web content in multiple formats (HTML, JSON, text, Markdown) with intelligent content extraction, chunk management, and browser automation support.
    5
    96 npm
    15
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that gives AI tools a reliable way to fetch content from the web, handling anti-bot protection and JavaScript-rendered pages.
    895 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that gives AI agents web tools to read, crawl, map, extract, classify, enrich, screenshot, and pull images from live websites using the Synoppy API.
    9 npm
    1
    MIT