Как протестировать MCP-сервер на утечку контекста: практический чеклист для разработчиков

MCP-серверы дают AI-агентам доступ к базам данных, файлам и API, но вместе с данными может утекать контекст — промпты, схемы, учётные данные. Разбираем, как проверить MCP-сервер на утечку контекста до подключения к агенту: чеклист с примерами на Python и curl.

Схема взаимодействия MCP-клиента, AI-агента и MCP-сервера с выделенным слоем безопасности контекста
Схема взаимодействия MCP-клиента, AI-агента и MCP-сервера с выделенным слоем безопасности контекста
Zeekr007.jpg | by L1Ucgen | wikimedia_commons | CC BY 4.0

Когда AI-агент подключается к MCP-серверу, он получает не только данные — он передаёт контекст. Если сервер не проверяет, что именно и кому он отдаёт, вместе с результатом запроса могут уйти системный промпт, схема базы данных, токены аутентификации или фрагменты предыдущих диалогов.

Проблема не гипотетическая: в августе 2026 года исследователи PortSwigger показали, как через инструмент LLM можно извлечь системный промпт модели, если сервер не экранирует возвращаемые значения. А в марте 2026 года Anthropic в обновлении MCP SDK добавила предупреждение о необходимости валидации контекста на стороне сервера.

Эта статья — не общий обзор безопасности MCP, а конкретный чеклист для разработчика: какие тесты прогнать, чтобы убедиться, что MCP-сервер не утекает контекст.

Что такое утечка контекста в MCP и почему это опасно

MCP (Model Context Protocol) — это открытый протокол, который позволяет AI-агентам вызывать инструменты, получать данные и обращаться к ресурсам через стандартизированный интерфейс. Сервер может предоставлять доступ к PostgreSQL, файловой системе, Slack, Jira или внутреннему API компании.

Утечка контекста происходит, когда сервер в ответе на запрос инструмента возвращает данные, которые не должны покидать изолированное окружение агента. Типичные сценарии:

  • Извлечение системного промпта — агент передаёт на сервер инструкцию, а сервер возвращает её как часть результата.
  • Эксфильтрация схемы — сервер в ответ на запрос данных возвращает структуру таблиц или имена колонок, которые не были явно запрошены.
  • Утечка учётных данных — токен доступа или API-ключ попадает в лог или ответ сервера.
  • Межсессионное смешивание — данные одного пользователя становятся доступны другому из-за некорректной изоляции контекста.

Каждый из этих сценариев — не просто нарушение безопасности, а прямая угроза для compliance: GDPR, HIPAA или SOC 2 требуют контроля над тем, какие данные покидают систему.

Чеклист: 5 тестов на утечку контекста

Ниже — пять проверок, которые можно выполнить до подключения MCP-сервера к продакшен-агенту. Каждый тест снабжён примером запроса и ожидаемым результатом.

Тест на отражение системного промпта

Самый простой и самый частый сценарий: агент передаёт на сервер системный промпт, а сервер возвращает его обратно как часть ответа.

Как проверить

Используйте curl или Python SDK (mcp) для отправки запроса к инструменту, который принимает текстовый ввод. Включите в запрос маркер, который явно не должен появляться в ответе, если сервер работает корректно.

bash
curl -X POST http://localhost:8000/tools/call \
-H «Content-Type: application/json» \
-d ‘{
«name»: «search_documents»,
«arguments»: {
«query»: «IGNORE_THIS_MARKER_abc123»
}
}’

Ожидаемый результат: маркер `IGNORE_THIS_MARKER_abc123` не появляется ни в одном поле ответа.

Что делать, если нашёлся: сервер, вероятно, подставляет ввод пользователя в ответ без экранирования. Нужно добавить фильтрацию: либо на стороне сервера (экранировать спецсимволы), либо на стороне клиента (не передавать конфиденциальные данные в запросы к внешним инструментам).

Тест на инъекцию в описание инструмента

MCP-сервер публикует список инструментов с описаниями. Если описание содержит поле, которое рендерится без экранирования, злоумышленник может внедрить туда код или инструкцию для агента.

Как проверить

Создайте MCP-сервер с инструментом, у которого в описании есть пользовательский ввод. Вызовите `tools/list` и проверьте, не интерпретируется ли описание как команда.

python
from mcp.server import FastMCP

server = FastMCP(«test-server»)

@server.tool()
def echo(user_input: str) -> str:
«»»Echo the input: {user_input}»»»
return user_input

Ожидаемый результат: при вызове `tools/list` описание инструмента должно быть статической строкой, а не подстановкой `user_input`.

Что делать, если нашёлся: никогда не включайте пользовательский ввод в описание инструмента. Если нужно передать контекст, используйте отдельное поле `inputSchema` и валидируйте его на сервере.

Тест на эксфильтрацию схемы данных

Некоторые MCP-серверы для баз данных при выполнении запроса возвращают не только строки, но и метаданные: имена таблиц, типы колонок, ограничения. Если агент не фильтрует ответ, эти данные могут уйти в лог или на внешний сервер.

Как проверить

Выполните запрос к инструменту, который работает с базой данных, и проверьте, не возвращает ли сервер структуру таблицы без явного запроса.

bash
curl -X POST http://localhost:8000/tools/call \
-H «Content-Type: application/json» \
-d ‘{
«name»: «query_database»,
«arguments»: {
«sql»: «SELECT id, name FROM users LIMIT 1»
}
}’

Ожидаемый результат: ответ содержит только запрошенные данные (`id`, `name`), без дополнительных полей вроде `column_type`, `table_schema` или `constraints`.

Что делать, если нашёлся: настройте MCP-сервер так, чтобы он возвращал только те поля, которые явно запрошены. Метаданные должны быть доступны только через отдельный инструмент (например, `get_schema`), и только после аутентификации.

Тест на утечку через логирование

MCP-серверы часто логируют запросы и ответы. Если в лог попадает конфиденциальный контекст (токены, промпты, персональные данные), это утечка, даже если сам ответ корректен.

Как проверить

Запустите MCP-сервер с включённым логированием (уровень DEBUG или INFO). Выполните несколько запросов, затем проверьте файлы логов.

bash
tail -f /var/log/mcp-server.log | grep -E «(token|api_key|password|secret)»

Ожидаемый результат: в логах нет строк, содержащих учётные данные, системные промпты или персональные данные пользователей.

Что делать, если нашёлся: настройте маскировку полей в логах. В Python SDK можно использовать фильтры логирования:

python
import logging

class SensitiveDataFilter(logging.Filter):
def filter(self, record):
record.msg = record.msg.replace(record.args.get(‘token’, »), ‘*’)
return True

logger = logging.getLogger(‘mcp’)
logger.addFilter(SensitiveDataFilter())

Тест на межсессионное смешивание

Если MCP-сервер кеширует контекст между запросами разных пользователей, данные одной сессии могут стать доступны другой. Это особенно опасно для серверов, работающих с базами данных или файловыми системами.

Как проверить

Отправьте два параллельных запроса от разных клиентов (или с разными идентификаторами сессии) и проверьте, не пересекаются ли их контексты.

python
import asyncio
import httpx

async def test_session_isolation():
async with httpx.AsyncClient() as client:
# Session A
resp_a = await client.post(«http://localhost:8000/tools/call», json={
«name»: «store_data»,
«arguments»: {«key»: «session_a», «value»: «secret_a»}
})
# Session B
resp_b = await client.post(«http://localhost:8000/tools/call», json={
«name»: «get_data»,
«arguments»: {«key»: «session_a»}
})
# Если session_b может прочитать session_a — утечка
print(resp_b.json())

asyncio.run(test_session_isolation())

Ожидаемый результат: данные, записанные в сессии A, недоступны в сессии B.

Что делать, если нашёлся: добавьте в MCP-сервер механизм изоляции контекста: либо по идентификатору сессии (session_id), либо по токену аутентификации. Никогда не используйте глобальное состояние для хранения пользовательских данных.

Что делать, если тесты не пройдены

Если хотя бы один из пяти тестов выявил проблему, не подключайте сервер к продакшен-агенту. Дальнейшие шаги зависят от типа утечки:

  • Отражение промпта — добавьте экранирование на стороне сервера или фильтрацию на стороне клиента.
  • Инъекция в описание — перепишите описание инструмента как статическую строку.
  • Эксфильтрация схемы — настройте возврат только запрошенных полей.
  • Утечка в логах — внедрите маскировку конфиденциальных данных.
  • Смешивание сессий — добавьте изоляцию контекста по идентификатору сессии.

После исправлений повторите все пять тестов. Только после полного прохождения чеклиста можно подключать сервер к агенту, который работает с реальными пользовательскими данными.

Ограничения и следующие шаги

Чеклист покрывает базовые сценарии утечки контекста, но не заменяет полноценный аудит безопасности. Если MCP-сервер работает с особо чувствительными данными (медицина, финансы, госсектор), стоит добавить:

  • Тест на race condition при параллельных запросах.
  • Тест на утечку через timing side-channel.
  • Аудит зависимостей MCP-сервера на известные уязвимости.

Полную спецификацию MCP можно найти на сайте протокола. Исходные коды референсных серверов — в репозитории на GitHub. Python SDK для создания собственных серверов доступен в отдельном репозитории Anthropic.

Перед подключением нового MCP-сервера к агенту, который обрабатывает запросы пользователей, прогнать эти пять тестов — минимальная гигиена, которая предотвращает утечки, способные стоить компании репутации и штрафов.

Источники