Сервер MCP
MCP-сервер
Используйте FourA из любого клиента Model Context Protocol (Claude Desktop, Claude Code, Cursor, Windsurf, VS Code) как четыре нативных инструмента и шесть промптов для рабочих процессов. Без кода интеграции и кастомных HTTP-клиентов.
Открытый исходный код на GitHub; в npm как @fouradata/mcp. Текущая версия: 0.5.0.
Быстрый старт: локальный stdio (рекомендуется для Claude Desktop)
Получите ключ на foura.ai/dashboard#api-keys (в один клик, показывается только при создании, формат pk_live_...). Добавьте его в конфигурацию вашего клиента MCP:
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "@fouradata/mcp"],
"env": { "FOURA_API_KEY": "pk_live_..." }
}
}
}
Особенность Claude Desktop: полностью закройте Claude Desktop (
Cmd+Qна macOS) перед редактированием файла конфигурации. Если приложение все еще работает, оно перезапишет ваши правки своей конфигурацией из памяти при выходе.
Команда npx загружает @fouradata/mcp при первом запуске и выполняет его как подпроцесс вашего MCP-клиента. Глобальная установка не требуется.
| Клиент | Где находится конфигурация |
|---|---|
| Claude Desktop (macOS) | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Claude Desktop (Windows) | %APPDATA%\Claude\claude_desktop_config.json |
| Claude Code | claude mcp add foura -- npx -y @fouradata/mcp (сначала установите FOURA_API_KEY в окружении) |
| Cursor | ~/.cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code (расширение MCP) | .vscode/mcp.json |
Перезапустите клиента. Инструменты (foura_auto, foura_single, foura_proxy, foura_browser) и шесть промптов появятся в вашем списке инструментов.
Быстрый старт: hosted (Streamable HTTP)
Для клиентов, поддерживающих транспорт Streamable HTTP (Cursor, Windsurf, VS Code, Claude Code с --transport http), укажите им на hosted endpoint вместо запуска локального подпроцесса:
{
"mcpServers": {
"foura": {
"url": "https://mcp.foura.ai/mcp",
"headers": {
"Authorization": "Bearer pk_live_..."
}
}
}
}
Для Claude Desktop используйте приведенный выше конфиг stdio или пробросьте размещенный endpoint через mcp-remote:
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.foura.ai/mcp", "--header", "Authorization: Bearer pk_live_..."]
}
}
}
Справочник по хост-endpoint'у
| Свойство | Значение |
|---|---|
| URL | https://mcp.foura.ai/mcp |
| Транспорт | Streamable HTTP (POST /mcp, ответы SSE) |
| Аутентификация | Authorization: Bearer pk_live_... на каждый request |
| Версия MCP-протокола | Согласно @modelcontextprotocol/sdk (сейчас 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07) |
| Вызов 401 | WWW-Authenticate: Bearer realm="foura-mcp", resource_metadata="https://foura.ai/docs/mcp/server#auth" |
Хост-сервер работает без сохранения состояния (stateless). Каждый request передает свой ключ, который сервер пересылает в API FourA как X-API-Key. Один ключ открывает доступ ко всем четырем инструментам.
Для защиты от DNS-ребиндинга (CVE-2025-66414) сервер проверяет заголовок Host (должно быть mcp.foura.ai или localhost) и заголовок Origin, если он есть (допустимые значения: mcp.foura.ai, claude.ai, app.cursor.sh, app.cursor.com). Запросы типа сервер-сервер (curl, MCP-клиенты в режиме моста stdio) не передают Origin и проходят без препятствий.
Инструменты
Все четыре инструмента помечены как readOnlyHint: true и openWorldHint: true согласно спецификации MCP от 18.06.2025. Клиенты, которые автоматически подтверждают доверенные инструменты только для чтения, вызывают их без модального окна подтверждения каждого запроса.
foura_auto, это умный инструмент по умолчанию: передайте ему URL, и он вернет контент, самостоятельно выбрав метод загрузки. Остальные три, это низкоуровневые примитивы, которыми он управляет; используйте их, когда вам нужен явный контроль.
foura_auto
Передайте ему URL, когда хотите, чтобы FourA сам выбрал метод запроса. Он совершает ограниченное количество попыток через доступные пути HTTP, proxy и браузера. Передайте validate для защищенных целей, чтобы response обязательно содержал контент, идентифицирующий реальную страницу. Если ни одна из попыток не проходит валидацию, инструмент возвращает ошибку, а не показывает страницу-заглушку с капчей в качестве успешного результата.
Response содержит детали выполнения в meta и, по умолчанию, многоразовую session с proxy, cookies и userAgent. Для обычного последующего запроса вызовите foura_single, передав session.proxy как proxy, сериализуйте cookie в заголовок Cookie и отправьте session.userAgent как заголовок User-Agent. Для рендеринга с помощью JavaScript передайте значения сессии в соответствующие поля foura_browser.
foura_single
Один HTTP request, один response обратно. Полностью дублирует POST /api/single/.
Используйте для статических страниц, JSON API, серверного рендеринга HTML.
Выбор браузера для представления
По умолчанию request представляется как последняя версия Google Chrome. Если цель принимает один браузер и отклоняет другой, задайте browser (Chrome, Edge, Safari, Firefox или Tor), os (Windows, macOS, Android или iOS), или version, либо передайте точный идентификатор profile:
{
"method": "GET",
"url": "https://example.com",
"browser": "Firefox",
"os": "Windows"
}
При совпадении нескольких профилей применяется новейшая версия. Если комбинация не существует, возвращается ошибка со списком доступных вариантов, поэтому request никогда не будет отправлен от имени браузера, который вы не выбирали. Для выбора требуется unblocker, который включен по умолчанию. Каталог опубликован по адресу GET /api/profiles и не требует API-ключа.
Те же четыре поля находятся внутри объекта request в foura_proxy.
foura_proxy
Направляет один HTTP-request через ротируемые proxy с автоматической повторной попыткой. Используйте это, когда foura_single заблокирован или для целевого ресурса требуется определенная страна выхода.
Установите для exitCountries строгий белый список двухбуквенных кодов стран, видимых целевому ресурсу, которые предоставлены пользователем или обусловлены требованиями цели:
{
"maxTries": 5,
"exitCountries": ["CZ", "GB"],
"request": {
"method": "GET",
"url": "https://example.com/pricing",
"browser": "Chrome",
"os": "Windows"
}
}
Значения очищаются от пробелов, переводятся в верхний регистр и дедуплицируются. Прокси с неизвестными узлами выхода исключаются, и запрос никогда не откатывается к незапрошенной стране. При выборе используются последние доступные метаданные страны, видимые целевому узлу, которые обычно обновляются каждые десять минут; это не поиск геолокации в реальном времени во время запроса. Не определяйте обслуживающую страну по адресу хоста прокси.
При успешном выполнении в рамках области видимости возвращается exitCountry и многоразовый идентификатор proxy. Убедитесь, что exitCountry принадлежит запрошенному белому списку. Если в текущем пуле нет совпадений, инструмент возвращает code: "no_eligible_proxy" с нормализованной областью видимости в details.exitCountries. Сохраните эту область видимости и повторите попытку позже. Изменяйте или расширяйте ее только тогда, когда пользователь явно меняет требования.
Если выбранной странице позже потребуется JavaScript, передайте возвращенный идентификатор proxy в foura_browser.proxy, чтобы браузер повторно использовал тот же узел выхода.
foura_browser
Полноценная сессия браузера. JavaScript выполняется, DOM рендерится, возвращаются cookie. Отражает POST /api/browser/.
Используйте для одностраничных приложений, контента с отложенной загрузкой или страниц, защищенных антибот-проверками, для прохождения которых требуется реальный браузер.
Для получения информации о форматах ввода, значениях по умолчанию и правилах валидации каждого инструмента обратитесь к справочнику REST endpoint. Схемы инструментов полностью совпадают с полями REST API, плюс добавлена опция offload_large только для MCP (см. ниже).
Когда целевой узел запускает проверку на ботов
foura_single и foura_proxy возвращают defense, если целевой узел запустил проверку на ботов по пути к телу ответа. defense.solved: true означает, что проверка пройдена, а data является реальной страницей; false означает, что тело ответа может быть страницей с проверкой. Повторите попытку с другим браузером, ОС или версией, либо перейдите к foura_proxy или foura_browser, вместо того чтобы рассматривать страницу проверки как контент.
Типизированные ответы
Каждый ответ инструмента включает как content (текстовая сводка, понятная человеку), так и structuredContent (типизированный JSON, проверенный по outputSchema инструмента). Каждый инструмент имеет свою уникальную структуру:
foura_auto: структура{ status, headers, data }плюсmeta({ rung, solved, attempts, credits }, присутствует всегда, гдеrungявляется одним изcache,probe,proxy,browser,fail) и, по умолчанию,session({ proxy, cookies, userAgent }) для повторного воспроизведения через инструменты более низкого уровня. Безtotal_time.foura_single:{ status, headers, data, total_time, ... }(заголовки представлены в виде массива, по одной записи на каждый прыжок перенаправления)foura_proxy: то же, что и single, плюс{ proxy, total }; успешный результат с областью видимости также включаетexitCountryfoura_browser: отдельная структура{ status, headers: object, body, cookies, userAgent }(примечание:bodyможет быть строкой или объектом в зависимости от content-type)
Клиенты, поддерживающие structuredContent, могут передавать типизированный объект напрямую в LLM, вместо того чтобы требовать от него парсить JSON из обычного текста.
Многозначные заголовки ответа
Заголовки, которые встречаются несколько раз (Set-Cookie, Link, WWW-Authenticate), возвращаются как массивы:
{
"headers": [
{
"result": { "version": "HTTP/2", "code": 200, "reason": "" },
"content-type": "text/html",
"set-cookie": ["a=1; Path=/", "b=2; Path=/"]
}
]
}
Это важно для сайтов, которые устанавливают cookie для сессии, отслеживания и согласия в одном ответе (большинство сайтов электронной коммерции).
Большие ответы: offload_large (по умолчанию: inline)
По умолчанию (начиная с v0.2.0) полные тела ответов возвращаются inline в structuredContent независимо от размера. Это работает в каждом клиенте MCP из коробки.
Если ваш клиент поддерживает MCP resources/read И вы хотите сэкономить токены на больших страницах, передавайте offload_large: true при каждом вызове инструмента. Ответы размером >= 50 КБ затем записываются на диск, возвращаются как resource_link, и ваш клиент скачивает тело только тогда, когда это действительно необходимо. Кэшированные данные истекают через 1 час.
{
"method": "GET",
"url": "https://en.wikipedia.org/wiki/Web_scraping",
"offload_large": true
}
| Клиент | offload_large: true |
|---|---|
| Claude Desktop | пока нет, оставьте по умолчанию false |
| Claude Code, Cursor, Windsurf | поддерживается |
| Расширение VS Code MCP | поддерживается |
Изоляция тенантов: каждый API-ключ получает собственное пространство имен (sha256(apiKey)[:16]). Только ключ, который сохранил payload, может прочитать его обратно. Чтение между тенантами возвращает Payload not found без утечки данных о существовании.
Встроенные промпты
Шесть шаблонов рабочих процессов доступны в разделе /prompts в любом клиенте MCP. Каждый принимает именованные аргументы и возвращает шаблонное сообщение пользователя, управляющее одним или несколькими инструментами.
| Промпт | Аргументы | Что делает |
|---|---|---|
smart_fetch |
url, необязательные must_contain, extract |
Автоматический fetch (выбирает метод, обрабатывает защиту от ботов), затем возвращает или извлекает контент |
scrape_product_page |
url |
Browser fetch, затем извлекает название продукта, цену, изображение, наличие, SKU в виде JSON |
extract_article |
url |
Single с резервным использованием proxy, затем удаляет навигацию/рекламу и возвращает чистую статью в JSON |
monitor_pricing |
url, необязательный target_price |
Proxy fetch, извлекает текущую цену, сравнивает с целевой |
check_endpoint_health |
url, необязательный expected_text |
Single со строгой валидацией, возвращает доступность и время |
bulk_fetch_urls |
urls (через запятую) |
Параллельный single, автоматический переход на proxy для каждого URL, возвращает только метаданные |
Промпты стоят ноль токенов в режиме простоя. Только вызванные промпты попадают в контекст LLM.
Полный текст и ручные резервные промпты: MCP Recipes.
Оболочка ошибки
Каждая ошибка (isError: true) содержит оболочку structuredContent. Минимальные поля для каждой ошибки:
{
"service": "auto | single | proxy | browser",
"code": "rate_limited",
"error": "Rate limit exceeded"
}
При ошибках upstream с HTTP-статусом также присутствует status. При ошибках лимитов частоты и емкости оболочка upstream добавляет retryAfter, current.{concurrency, rpm} и limits.{maxConcurrency, maxRpm}. См. Ошибки API для базовой структуры REST.
Стабильные значения code:
| Code | HTTP | Значение | Безопасен ли повтор? |
|---|---|---|---|
ssrf_blocked |
n/a | Целевой IP в частном или зарезервированном диапазоне (RFC 5735, 6598, зарезервировано IPv6) | Нет, измените URL |
upstream_non_json |
варьируется | Upstream вернул некорректное тело | Возможно, нужно исследовать |
output_validation_failed |
n/a | outputSchema MCP-сервера отклонил ответ upstream (ошибка сервера или неожиданная структура upstream) |
Возможно, сообщите |
bad_request |
400 | Структура ввода отклонена | Нет, исправьте аргументы |
auth_failed |
401 | Ключ отсутствует, недействителен или деактивирован | Нет, исправьте ключ |
forbidden |
403 | Аутентифицирован, но не разрешен | Нет, или переключитесь на foura_proxy |
not_found |
404 | Цель или endpoint отсутствует | Нет |
rate_limited |
429 | Достигнут лимит RPM | Да, ждите retryAfter |
at_capacity |
503 | Достигнут лимит конкурентности | Да, ждите retryAfter |
service_disabled |
503 | Окно обслуживания или ваш план не включает этот инструмент | Обратитесь в поддержку |
service_unavailable |
503 | Общая ошибка 503 | Да, короткая пауза |
upstream_error |
500+ | Ошибка 5xx от upstream | Да, экспоненциальная задержка |
upstream_client_error |
4xx | Другие ошибки 4xx | Обычно нет |
upstream_unknown |
другое | Защитное значение, на практике не должно возникать | Исследовать |
no_eligible_proxy |
n/a | Нет proxy, соответствующих строгой области exitCountries |
Повторите попытку позже; изменяйте область только явно |
LLM-агенты могут читать code напрямую для логики повторных попыток без парсинга текста. Руководство по аутентификации: Аутентификация.
Лимиты
- Встроенное тело по умолчанию. С
offload_large: trueответы >= 50 КБ сохраняются на диск +resource_link(на каждого тенанта, TTL 1 час). - Частные цели отклоняются (RFC 5735, RFC 6598, зарезервированные блоки IPv6) на уровне MCP. Перенаправляются только публичные хосты.
- Ограничение на тело запроса в 256 КБ для входящих запросов
/mcp(реальные полезные нагрузки MCP составляют < 4 КБ). - Ограничения скорости (rate limits) применяются FourA API для каждого сервиса. См. Лимиты скорости.
Селф-хостинг
Полный исходный код сервера доступен публично на GitHub под лицензией @fouradata/mcp. Клонируйте репозиторий, выполните npm install, npm run build и запустите node dist/http.js, чтобы поднять собственный инстанс. Работает без сохранения состояния (stateless) в одном контейнере за любым балансировщиком нагрузки.
Конфигурируемая среда:
| Переменная | По умолчанию | Назначение |
|---|---|---|
PORT |
3076 |
Порт HTTP для прослушивания |
FOURA_API_BASE |
https://api.foura.ai/api |
Базовый URL апстрима FourA REST |
FOURA_MCP_PAYLOADS_DIR |
/data/payloads |
Место кэширования ответов >= 50 КБ на диске (совместно с offload_large: true) |
FOURA_MCP_ALLOWED_HOSTS |
mcp.foura.ai,localhost,127.0.0.1,[::1] |
Список разрешенных хостов для заголовка Host (защита от DNS-rebinding) |
FOURA_MCP_ALLOWED_ORIGINS |
https://mcp.foura.ai,https://claude.ai,https://app.cursor.sh,https://app.cursor.com |
Список разрешенных Origin для вызовов из браузера |
FOURA_MCP_RESOURCE_METADATA_URL |
https://foura.ai/docs/mcp/server#auth |
URL, возвращаемый в WWW-Authenticate при ошибке 401 |
Официальный контейнер запускается от имени uid 1001 (не root). Точка монтирования хоста /data/payloads должна быть доступна для записи этому uid.
Масштабируется горизонтально за любым балансировщиком нагрузки. Клиенты передают свой ключ в каждом запросе, поэтому привязка сессий (sticky session) не требуется.