Быстрый взгляд
Если веб-запросы вашего агента продолжают блокироваться или вместо настоящего контента возвращается JavaScript-оболочка, Nstdata Crawl рендерит страницу в реальном браузере и перенаправляет её через прокси-сеть Nstdata, прежде чем передать вашему MCP-серверу чистый Markdown.
Предварительные условия
Вам нужен Python 3.10 или новее — официальный пакет mcp требует этого — совместимый с MCP хост, такой как Claude Desktop или Claude Code, и аккаунт Nstdata с токеном API Crawl, доступным на странице продукта Nstdata Crawl после регистрации. Полная документация по конечным точкам и параметрам для основного API доступна в документации Nstdata Crawl, что полезно, если вы хотите добавить опции, такие как скриншоты или вывод в PDF, помимо того, что использует этот пример. Вам не нужен отдельный ключ API поисковой системы для этой сборки: инструмент web_search ниже получает собственную страницу результатов поисковой системы через Nstdata Crawl, а не вызывает выделенный поисковый API.
Установка
Создайте виртуальную среду и установите два пакета, которые нужны этому серверу: официальный MCP Python SDK с его CLI дополнениями и SDK Crawl от Nstdata.
python3 -m venv .venv
source .venv/bin/activate
pip install "mcp[cli]" nstdata-ai-crawl
Запуск этого во время написания данной статьи установил mcp 1.27.0 и nstdata-ai-crawl 0.1.1, текущие версии каждого пакета на момент написания; pip install всегда разрешает на самое новое, когда вы его запускаете. Другие зависимости не требуются — SDK Crawl поставляется с собственным HTTP-клиентом внутри.
Настройка
Сохраните следующее как mcp_server.py. Он определяет два инструмента: web_search, который получает страницу результатов поисковой системы и возвращает ссылки на ней, и read_page, который получает любой URL и возвращает его очищенноеMarkdown-содержимое.
import os
from mcp.server.fastmcp import FastMCP
from nstdata_ai_crawl import Format, NstDataClient, ScrapeRequestDto
NSTDATA_API_TOKEN = os.environ["NSTDATA_API_TOKEN"]
client = NstDataClient(NSTDATA_API_TOKEN)
mcp = FastMCP("nstdata-web-search"
Попробуйте Nstdata бесплатно →
`NstDataClient.submit_scrape_task_sync` блокирует выполнение до завершения операции извлечения, именно поэтому обе функции утилит определены как обычные `def`, а не `async def` -- FastMCP поддерживает оба варианта. `Format.LINKS` и `Format.MARKDOWN` указывают Nstdata Crawl, какие представления страницы вернуть; запрос только того, что нужно каждой утилите, позволяет уменьшить размер ответа и снизить стоимость этапа разрешения хранения ссылок.
Реальный Хэндшейк
Прежде чем подключать это к работающему хосту, убедитесь, что сервер действительно корректно поддерживает MCP, следуя той же схеме, что и в официальном руководстве по построению серверов MCP. Официальный клиент SDK может общаться с сервером через тот же транспорт stdio, который использует хост, так что вы можете протестировать хэндшейк без Claude Desktop или Claude Code в процессе:
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
server_params = StdioServerParameters(
command="python3",
args=[
Запуск этого к серверу приведет к следующему выводу:
=== Живой stdio обратный вызов: tools.list ===
- web_search: required=['query']
- read_page: required=['url']
Этот вывод представляет собой реальный круговорот клиент-сервер: клиент запустил сервер как подпроцесс, завершил хэндшейк MCP initialize и получил обратно сгенерированные схемы обеих утилит через tools/list -- для этого шага не потребовался вызов API Nstdata, поскольку перечисление утилит не затрагивает сеть.
Присоединение возможностей
Claude Desktop считывает определения серверов из claude_desktop_config.json (~/Library/Application Support/Claude/claude_desktop_config.json на macOS, %AppData%\Claude\claude_desktop_config.json на Windows). Добавьте сервер в mcpServers:
{
"mcpServers": {
"nstdata-web-search": {
"command": "python3",
"args": ["/absolute/path/to/mcp_server.py"],
"env": {
"NSTDATA_API_TOKEN": "your-nstdata-crawl-token"
Claude Code, более подробно затронутый в сравнении Claude Code и Codex, регистрирует тот же сервер stdio из командной строки вместо JSON-файла -- смотрите официальную справку Claude Code по MCP для полного набора опций claude mcp add:
claude mcp add --env NSTDATA_API_TOKEN=your-nstdata-crawl-token --transport stdio nstdata-web-search -- python3 /absolute/path/to/mcp_server.py
Запуск этой команды в процессе написания этой статьи, а затем проверка claude mcp list вернула:
nstdata-web-search-test: python3 /path/to/mcp_server.py - ✔ Подключено
Статус ✔ Подключено означает, что Claude Code успешно запустил процесс сервера и завершил хэндшейк MCP с ним -- это не подтверждает, что токен Nstdata Crawl действителен, поскольку этот вызов происходит только тогда, когда утилита фактически вызывается. Если вызов утилиты позже завершится с ошибкой аутентификации, первым делом стоит проверить токен, а не подключение MCP.
Пример работы
Как только сервер подключен, запрос, например "что изменилось в спецификации MCP недавно, и суммируйте верхний результат", выполняется следующим образом: Claude вызывает web_search с запросом о изменениях в спецификации MCP, получает несколько кандидатских URL-адресов, выбирает один, который выглядит авторитетным, и вызывает read_page, чтобы собрать фактическое содержимое страницы в разговор до ответа. Иллюстративная форма значения возврата этого второго вызова выглядит так:
{
"content": [
{
"type": "text",
"text": "# Журнал изменений Model Context Protocol\n\n## 2026-07-28\n\n- ..."
}
]
}
Затем Claude читает этотMarkdown-текст так же, как и любой другой текст в разговоре, и может указать исходный URL, откуда он пришел, поскольку этот URL был аргументом для read_page с самого начала.
Ограничения
web_search здесь извлекает страницу результатов одного поискового движка и возвращает необработанные ссылки; он не ранжирует результаты, не понимает намерение запроса и не разбивает результаты на страницы так, как это сделает специализированное поисковое API. Фильтр "duckduckgo.com" not in link является наивной эвристикой для исключения собственных навигационных ссылок поискового движка, а не надежным парсером результатов — версия для продакшна должна фильтровать более точно или переключаться на поискового провайдера, предназначенного для программного использования, если качество ранжирования имеет значение. Биллинг следует модели "за извлечение" Nstdata Crawl: каждый вызов web_search и каждый вызов read_page являются отдельными оплачиваемыми запросами, так что один вопрос пользователя, который инициирует один поиск и три чтения страниц, стоит четыре извлечения, и приведенный выше код не кеширует повторные запросы. Nstdata Crawl также ограничивает каждый запрос таймаутом в 60 секунд и возвращает HTTP 429 с заголовком Retry-After, когда вызывающая сторона превышает свой лимит запросов; этот минимальный пример не реализует повторные попытки или откат, так что версия для продакшна должна добавлять оба. Наконец, рассматривайте это как инструмент для агента, выполняющего ограниченные, по запросу, извлечения, а не для массового скрапинга — уважайте условия обслуживания целевых сайтов и robots.txt, и поддерживайте объем запросов пропорциональным реальному вопросу пользователя, а не выполняйте непрерывные обходы с одними и теми же учетными данными.
Заключение
Работающий сервер веб-поиска MCP сводится к двум инструментам — одному, который находит кандидатные URL, и одному, который извлекает чистый контент с конкретного URL — соединенным с уровнем извлечения, который может действительно обойти то, что современные веб-сайты делают, чтобы блокировать простой HTTP-скрапинг. JavaScript-рендеринг и прокси-доступ Nstdata Crawl покрывают этот уровень извлечения, официальный MCP Python SDK обрабатывает протокольную инфраструктуру, и тот же сервер подключается как к Claude Desktop, так и к Claude Code через один и тот же стандартный ввод-вывод. Проверьте установление соединения с реальным клиентом перед подключением к хосту, следите за моделью биллинга за извлечение, если ваш агент выполняет поиск и читает на каждый вопрос, и рассматривайте наивную фильтрацию ссылок в этом примере как отправную точку, а не как готовый бэкенд для поиска.
Попробуйте Nstdata бесплатно →
ЧЗВ
В: Что такое сервер MCP, в одном предложении?
Сервер MCP — это программа, которая предоставляет вызываемые инструменты, данные или шаблоны запросов AI-приложению через Протокол Контекста Модели, чтобы ИИ мог вызывать реальные функции вместо того, чтобы только генерировать текст.
В: Нужно ли мне использовать именно Nstdata Crawl, или я могу извлекать страницы сам по простым HTTP-запросам?
Вы можете извлекать страницы с любым HTTP-клиентом, но простые запросы обычно не срабатывают на страницах с рендерингом JavaScript и блокируются сайтами с детекцией ботов; Nstdata Crawl обрабатывает и то, и другое, рендеря страницы в реальном браузере и направляя запросы через свою прокси-сеть.
В: Позволяет ли это Claude искать в интернете, как поисковик?
Нет. Инструмент web_search в этом примере извлекает страницу результатов одного поискового движка и возвращает ссылки на ней; он не индексирует сам интернет и не ранжирует результаты так, как это делает специализированный поисковик.
В: Сколько стоит это запускать?
Стоимость зависит от текущей цены за извлечение Nstdata Crawl, опубликованной на странице продукта Crawl, умноженной на количество поисков и чтений страниц, которые на самом деле выполняет ваш агент — каждое из которых является отдельным оплачиваемым извлечением.
В: Могу ли я использовать этот сервер и с Claude Code, и с Claude Desktop?
Да. Оба подключаются к одному и тому же серверу stdin; Claude Desktop читает определение сервера из claude_desktop_config.json, а Claude Code регистрирует его с помощью claude mcp add.
В: Подвергнут ли мой токен Nstdata API риску раскрытия перед LLM?
Нет. Токен живет в переменных окружения процесса сервера и используется только внутри mcp_server.py для аутентификации с Nstdata Crawl; LLM видит только возвращаемые значения инструмента, никогда сам токен.
В: Что произойдет, если целевой поисковик заблокирует или ограничит запрос?
Nstdata Crawl возвращает результат, не являющийся успешным, с кодом ошибки, который функция web_search отображает как сообщение об ошибке в простом тексте; этот минимальный пример не выполняет автоматические повторные попытки, так что версия для продакшна должна добавить откат и стратегию запасного запроса.
В: Нужно ли мне развертывать этот сервер где-то, или он может работать локально?
Он может работать полностью на вашем собственном компьютере как локальный подпроцесс, который Claude Desktop или Claude Code запускает через стандартный ввод-вывод; вам нужно только публичное развертывание, если вы exposing сервер удаленному хосту через HTTP.