Приёмка интеграции с удалённым MCP-сервером: что подтверждает обнаружение и что ещё нужно проверить
С помощью проверочного запроса без ключа изучите инициализацию, уведомления и каталог инструментов, а затем отдельно проверьте требования каждого из клиентов Claude, ChatGPT и Cursor к сети и аутентификации, чтобы не принимать успешное обнаружение на уровне протокола за полноценное пользовательское тестирование во всех трёх клиентах.
Обновление статуса продукта (проверено 2026-10-09 по пекинскому времени): список из шести инструментов в этой статье — историческое наблюдение от 2026-09-04. everyinfra_chat был отключён вместе с общим текстовым API 2026-09-12 и снова доступен вместе с API для ИИ (бесплатно после пополнения баланса, без стриминга); инструменты очистки данных выведены из эксплуатации. Всегда получайте актуальный список инструментов из ответа MCP-сервера на запрос tools/list.
Если ввести адрес MCP в клиент и увидеть названия инструментов, это полезный шаг, но он ещё не отвечает на вопросы, правильно ли передаются ключи, входят ли реальные вызовы в разрешённые области доступа, распознаёт ли клиент ошибки и соответствуют ли возвращённые данные требованиям задачи.
На примере удалённого эндпоинта EveryInfra этот документ делит приёмку интеграции на четыре уровня: обнаружение по протоколу, согласование аутентификации, работа клиента и бизнес-результаты. Сначала приводится проверочный запрос без ключа, затем объясняется, почему нельзя считать, что для всех трёх клиентов достаточно просто ввести адрес. Это руководство по интеграции с явно указанными границами проведённой проверки, а не заявление об успешном подключении Claude, ChatGPT и Cursor.
Один удалённый адрес и четыре независимых уровня подтверждения
Здесь проверяется точка входа https://api.everyinfra.com/mcp. Обнаружение по протоколу показывает, как сервер описывает себя и какие инструменты предоставляет; согласование аутентификации определяет, как клиент получает и передаёт разрешённые учётные данные; приёмка на уровне клиента проверяет, действительно ли инструменты доступны в текущей сессии; бизнес-приёмка проверяет фактические результаты и ошибки.
Четыре уровня следует фиксировать отдельно. То, что сервер ответил на инициализацию, не означает, что клиент принял последующие уведомления; видимость каталога в клиенте не подтверждает наличие прав на выполнение бизнес-операций; возврат содержимого инструментом не исключает ошибок на уровне бизнес-логики. Не описывайте все эти случаи одним булевым флагом «подключение успешно».
MCP и REST — разные способы интеграции. Примеры REST могут помочь проверить бизнес-семантику, но сами по себе не доказывают, что клиент правильно обрабатывает аутентификацию MCP, блоки контента, ошибки или сценарии подтверждения.
После инициализации также отправляется уведомление
Здесь этот путь обнаружения проверяется по версии MCP 2025-06-18; мы не утверждаем, что это новейшая или единственная версия для всех клиентов. Клиент сначала отправляет initialize и проверяет выбранную сервером версию, затем отправляет notifications/initialized и только после этого переходит к обнаружению инструментов. Последующие HTTP-запросы должны указывать согласованную версию протокола. Жизненный цикл протокола
В ответ на принятое уведомление Streamable HTTP сервер должен вернуть HTTP 202 без тела ответа. Если при инициализации сервер возвращает Mcp-Session-Id, клиент обязан передавать его в последующих запросах; без этого заголовка ответа нельзя самостоятельно создать сессию. Ответы на запросы могут быть в формате JSON или SSE, и реальные клиенты должны поддерживать транспортный формат, предусмотренный протоколом. Спецификация транспорта
Скрипт ниже проверяет только ветку с JSON-ответом, которую использует этот сервер, и не является универсальным MCP-клиентом. При обнаружении SSE, каталога с пагинацией или неподдерживаемой версии он останавливается, оставляя дальнейшую проверку полноценному клиенту; он не делает вид, что разбор одного JSON-объекта охватывает весь протокол.
Диагностический скрипт только для этапа обнаружения
Нужен Node.js 22 или новее со встроенной поддержкой fetch. Скрипт не читает ключи из окружения, не отправляет tools/call, не устанавливает и не изменяет никаких клиентов. В вывод попадают только статус, названия инструментов и проблемы совместимости, без маркетинговых формулировок из описаний сервера.
node --input-type=module <<'JS'
const endpoint = 'https://api.everyinfra.com/mcp';
const supportedVersion = '2025-06-18';
const headers = {
'Content-Type': 'application/json',
Accept: 'application/json, text/event-stream',
};
const issues = [];
async function post(message) {
const response = await fetch(endpoint, {
method: 'POST', headers, redirect: 'error',
body: JSON.stringify(message),
signal: AbortSignal.timeout(20000),
});
return { response, text: await response.text() };
}
function rpcResult(reply, id) {
if (reply.response.status !== 200) {
throw new Error('RPC HTTP ' + reply.response.status);
}
if (!reply.response.headers.get('content-type')?.includes('application/json')) {
throw new Error('This probe only handles JSON; use a full MCP client');
}
const body = JSON.parse(reply.text);
if (body.jsonrpc !== '2.0' || body.id !== id ||
body.error || !body.result || typeof body.result !== 'object') {
throw new Error('Invalid or failed RPC response');
}
return body.result;
}
const initReply = await post({
jsonrpc: '2.0', id: 1, method: 'initialize',
params: {
protocolVersion: supportedVersion, capabilities: {},
clientInfo: { name: 'bip-discovery-only', version: '1.0' },
},
});
const init = rpcResult(initReply, 1);
if (init.protocolVersion !== supportedVersion ||
init.serverInfo?.name !== 'EveryInfra' || !init.capabilities?.tools) {
throw new Error('Unexpected version, server or tool capability');
}
headers['MCP-Protocol-Version'] = init.protocolVersion;
const session = initReply.response.headers.get('mcp-session-id');
if (session) headers['Mcp-Session-Id'] = session;
const notification = await post({
jsonrpc: '2.0', method: 'notifications/initialized',
});
if (notification.response.status !== 202) {
throw new Error('Initialization notification was not accepted');
}
const notificationBytes = Buffer.byteLength(notification.text);
if (notificationBytes !== 0) issues.push('notification_body_not_empty');
// Continue discovery for diagnosis only; never enter a business call.
const listed = rpcResult(await post({
jsonrpc: '2.0', id: 2, method: 'tools/list', params: {},
}), 2);
if (!Array.isArray(listed.tools) || listed.tools.length === 0 ||
listed.tools.some(tool => !tool.name || tool.inputSchema?.type !== 'object') ||
listed.nextCursor) {
throw new Error('Incomplete or unexpected tool list');
}
console.log(JSON.stringify({
observedAt: new Date().toISOString(),
protocolVersion: init.protocolVersion,
sessionHeaderPresent: Boolean(session),
notificationStatus: notification.response.status,
notificationBodyBytes: notificationBytes,
toolNames: listed.tools.map(tool => tool.name),
issues,
businessCallPerformed: false,
hostAcceptanceVerified: false,
}, null, 2));
if (issues.length) process.exitCode = 2;
JSКод выхода 0 означает лишь, что эта ограниченная проверка этапа обнаружения не выявила расхождений, и ни в коем случае не подтверждает готовность к публикации или успешную приёмку в трёх клиентах. Код выхода 2 означает, что каталог получен, но есть расхождения с протоколом; при остальных ошибках выполнение прерывается. Сбои подключения и проблемы совместимости после успешного обнаружения нужно обрабатывать отдельно.
Что удалось проверить на этапе обнаружения и какие проблемы были выявлены
При повторной проверке без аутентификации 2026 9 4 в 20:43 (по китайскому стандартному времени) инициализация вернула HTTP 200 и версию протокола 2025-06-18 без заголовка ответа с ID сессии. Каталог инструментов вернул шесть названий:
everyinfra_list_capabilitieseveryinfra_call_apieveryinfra_chateveryinfra_list_captcha_typeseveryinfra_solve_captchaeveryinfra_search
Однако уведомление о завершении инициализации вернуло HTTP 202 с телом ответа JSON null, а не с пустым телом. Это не соответствует требованиям к ответу на уведомление в указанной версии. Каталог по-прежнему читается, но этого недостаточно, чтобы утверждать, что все клиенты допустят такое расхождение; скрипт должен явно сообщать о нём, а не молча игнорировать.
В этом раунде бизнес-инструменты не вызывались, и не проверялось, приводит ли расхождение к сбоям клиентов. Дальнейшие расхождения в ответах должны исправить специалисты, поддерживающие сервис, после чего результат нужно повторно проверить в реальных клиентах. На данный момент подтверждено только следующее: «на публичном пути обнаружения видны шесть инструментов и расхождение в ответе на уведомление»; писать «полностью совместим с MCP» нельзя.
При повторном запуске того же бесплатного процесса обнаружения 2026-09-08 каталог вернул восемь инструментов, два новых из них — инструменты очистки данных; уведомление о завершении инициализации вернуло HTTP 202 с телом ответа 0 байт, поэтому расхождение в ответе от 4 сентября при этой повторной проверке не повторилось. Это обновление по-прежнему лишь закрывает старые наблюдения на уровне публичного обнаружения и не означает, что Claude, ChatGPT и Cursor прошли аутентификацию или выполнили реальные рабочие вызовы.
Cursor: отдельная проверка поддержки заголовков в конфигурации и реальных прав доступа
Официальная документация Cursor описывает для удалённых серверов параметры url и headers с подстановкой значений из переменных окружения. Ниже показан формат конфигурации, который нужно использовать после авторизации пользователя; в этом раунде он не записывался в пользовательские конфигурации, а реальные вызовы из клиента не проверялись. Документация Cursor по MCP
{
"mcpServers": {
"everyinfra": {
"url": "https://api.everyinfra.com/mcp",
"headers": {
"Authorization": "Bearer ${env:EVERYINFRA_API_KEY}"
}
}
}
}Текущий серверный код проекта обрабатывает заголовки с Bearer-токенами, но наличие этого пути в исходном коде не доказывает, что конкретный ключ работает сегодня. Готовясь к реальной интеграции, убедитесь, что процесс клиента может прочитать указанные переменные окружения, и проверьте права ключа на бизнес-операции; не сохраняйте реальные значения ни в конфигурациях под управлением системы контроля версий, ни на скриншотах, ни в отчётах об ошибках.
Затем обновите каталог в текущей версии Cursor, выбирайте отдельные инструменты и сохраняйте подтверждение пользователя. Не включайте автоматическое выполнение всех инструментов только потому, что каталог виден; ключ с правами на бизнес-операции не следует считать долгосрочным разрешением на любые операции.
Claude: запросы удалённых коннекторов не проходят через локальные сети
В официальной документации Claude по удалённым коннекторам сказано, что запросы идут из облака Anthropic, в том числе для удалённых коннекторов в Claude Desktop. Это другой механизм, чем локальные конфигурации MCP в настройках настольного приложения. Поэтому доступ к адресу из локальной сети подтверждает только его локальную доступность, но не доказывает, что к нему смогут подключиться облачные коннекторы. Инструкции Claude по удалённым коннекторам
При интеграции проверьте точки входа для коннекторов с учётом текущих прав аккаунта и организации, а затем процессы аутентификации, которые поддерживают и сервис, и клиент. Конфигурации OAuth из официальной документации нельзя пересказывать как «можно ввести любой Bearer API-ключ». Если модели аутентификации не совпадают, сначала нужно спроектировать сервисы или контролируемые схемы адаптации и провести их приёмку; нельзя помещать секреты в URL как универсальную замену.
Здесь нет скриншотов пошаговых действий или инструкций «добавьте, и всё заработает», не проверенных на этом аккаунте. Добавление коннекторов, авторизация и итоговое подтверждение меняют состояние аккаунта, поэтому выполнять их нужно после одобрения пользователя; пробные запросы протокола не заменяют таких доказательств.
ChatGPT и OpenAI API: две разные точки входа для интеграции
Официальная документация по аутентификации MCP для плагинов ChatGPT перечисляет OAuth, отсутствие аутентификации и смешанную аутентификацию; при смешанной аутентификации обнаружение проходит без аутентификации, а способ аутентификации выбирается по декларациям безопасности каждого инструмента. То, что для обнаружения ключ не нужен, не значит, что все бизнес-инструменты можно вызывать без аутентификации. Режим разработчика ChatGPT
В этом каталоге инструментов поля securitySchemes и _meta на уровне инструментов не обнаружены. Это наблюдение по конкретному ответу, а не полный аудит реализации аутентификации во всём сервисе; но его достаточно, чтобы понять: по одному лишь успешному обнаружению нельзя утверждать, что требования смешанной аутентификации ChatGPT выполнены.
Конфигурация удалённого MCP для OpenAI Responses API — это ещё один путь с такими параметрами, как server_url, выбор инструментов, аутентификация и одобрение вызовов. Это не инструкции по настройке в интерфейсе ChatGPT; само по себе создание запросов через API не подтверждает, что веб-интерфейсы уже подключены. Руководство OpenAI по MCP и коннекторам
В этом раунде проверялась только документация: бизнес-запросы к OpenAI API не выполнялись, Developer mode для пользователей не включался. Если этот путь будет использоваться в дальнейшем, отдельно проверьте, какие данные уходят в удалённые сервисы, и сохраните шаги одобрения для чувствительных вызовов.
При проектировании аутентификации также отдельно изучите официальное руководство MCP по лучшим практикам безопасности. На этой странице в разделе документации 2025-11-25 объясняется, что токены должны быть предназначены для соответствующих сервисов, и не рекомендуется сквозная передача непроверенных токенов; она не превращает сторонние ключи в универсальные учётные данные MCP и не заменяет приведённые выше проверки обнаружения по версии 2025-06-18.
После HTTP 200 нужно проверить ещё два уровня ответа
Ошибки протокола в MCP могут приходить в поле error верхнего уровня JSON-RPC, а ошибки выполнения инструмента могут выражаться через result.isError. Считать бизнес-операцию успешной только на основании HTTP 200 или наличия текстового блока недостаточно. Спецификация инструментов и ошибок
При выполнении реальных операций также проверяйте структуры данных, которые возвращают инструменты: соответствуют ли выходные данные ожидаемым объектам, не пусты ли они, содержат ли полный результат и нужно ли продолжать опрос асинхронных задач. Если ответ содержит несколько блоков, обрабатывайте их согласно документированному формату ответа каждого инструмента и не предполагайте, что все метаданные находятся в первом текстовом блоке. Данные о списаниях, использовании и балансах нужно проверять по фактическим бизнес-ответам; обнаружение каталогов не подтверждает расчёты по бизнес-вызовам.
Для операций с побочными эффектами, таких как отправка данных, совершение покупок или подача заявок, отображение инструмента в клиенте не означает, что пользователь разрешил его выполнение. Перед вызовом подтвердите цели и параметры; перед повторной попыткой выясните, известен ли результат первой попытки. Пробная проверка без ключа из этого документа намеренно не затрагивает этот уровень.
Запись о приёмке для передачи следующему интегратору
Для каждого клиента отдельно записывайте продукты и их версии, среды запуска, способы передачи данных и аутентификации, доказательства установки и авторизации, фактические названия инструментов, обезличенные входные данные, статусы результатов и ошибки. Фиксируйте время наблюдения и разрешённые рамки вызовов, но не сохраняйте ключи в открытом виде. Успешные примеры, явные сбои и неизвестные результаты документируйте отдельно.
При ведении записей можно опираться на принципы корреляции событий и исключения данных из руководств OWASP по логированию: связывайте события одной операции и не включайте токены, данные сессий или полное содержимое данных клиентов в отладочные материалы. Логи являются лишь частью доказательств приёмки и не заменяют проверку реального поведения клиента.
В этом раунде выполнены публичное обнаружение и проверка расхождений с документацией. Исправление тела ответа на уведомление (оно должно быть пустым), установка и аутентификация в трёх клиентах, авторизованные бизнес-вызовы и приёмка отображения сбоев ещё не завершены. Только когда по каждому из этих пунктов будут получены доказательства, формулировку в руководстве можно будет сменить с «конфигурация ожидает проверки» на «проверено и работает в указанных версиях».
Сначала запустите скрипт обнаружения из этой статьи и убедитесь, что текущие интерфейсы и зафиксированные сведения по-прежнему соответствуют друг другу, а затем переходите к клиентам, выбранным командой. Не вносите изменения сразу в три аккаунта и не копируйте непроверенные конфигурации только ради составления списка совместимости. Документация EveryInfra
Справочник LF-10