
Когда разработчики подключают MCP-сервер к Claude Desktop или другому AI-клиенту, они обычно проверяют, что инструменты работают: файлы читаются, базы данных опрашиваются, API вызываются. Но есть сценарий, который почти никогда не проверяют заранее: что произойдёт, если две разные сессии обратятся к одному MCP-серверу одновременно? Сохранит ли сервер состояние между запросами? Утечёт ли контекст одной сессии в другую?
Model Context Protocol (MCP) не накладывает строгих требований на изоляцию сессий — спецификация 2025-03-26 описывает транспорт, типы ресурсов и инструментов, но оставляет реализацию сервера на усмотрение разработчика. Это означает, что два последовательных или параллельных подключения к одному серверу могут разделять память, файловые дескрипторы или кэш. Для агентов, работающих с разными проектами или пользовательскими данными, такая утечка — прямая угроза безопасности.
В этой статье — практический чеклист проверок, которые стоит выполнить до того, как MCP-сервер попадёт в продакшен. Никакой теории: конкретные тесты, команды и ожидаемые результаты.
Почему MCP-серверы уязвимы к утечке контекста
MCP определяет протокол, а не рантайм. Сервер может быть реализован как:
— однопоточный процесс, обрабатывающий запросы последовательно;
— пул воркеров с общей памятью;
— асинхронный сервер с разделяемым состоянием.
Проблема возникает, когда сервер хранит состояние между вызовами инструментов. Например, инструмент `read_file` может запомнить последний открытый файл и при следующем вызове без аргумента вернуть его содержимое. Если между вызовами сессия сменилась — это утечка.
Спецификация MCP рекомендует, но не требует изоляции. Раздел Transport описывает JSON-RPC поверх stdin/stdout или SSE, но не определяет, как сервер должен управлять контекстом разных клиентов. В официальных примерах SDK (Python, TypeScript) состояние инструментов часто хранится в глобальных переменных модуля.
Чеклист: 6 проверок на утечку контекста
Изоляция файловой системы между сессиями
Самый частый сценарий: MCP-сервер предоставляет доступ к файловой системе. Если сервер использует единый рабочий каталог или кэширует пути, вторая сессия может получить доступ к файлам, открытым первой.
Как проверить
Запустите MCP-сервер.
2. Подключитесь из первого клиента, откройте файл `/project-a/secret.txt`.
3. Не закрывая соединение, подключитесь из второго клиента.
4. Вызовите инструмент без указания пути (если сервер поддерживает состояние) или попробуйте прочитать файл из `/project-b/`.
5. Проверьте, не отображаются ли в ответе данные из первой сессии.
Ожидаемый результат: Каждая сессия должна работать в своей изолированной области. Если сервер не поддерживает явное указание корневого каталога для каждой сессии, это потенциальная утечка.
Состояние инструментов между вызовами
Некоторые инструменты сохраняют промежуточное состояние: курсор в базе данных, последний запрос, пагинацию. Если это состояние не сбрасывается между сессиями, возможна утечка.
Как проверить
Подключитесь к серверу, выполните инструмент с параметром `page=1`.
2. В той же сессии выполните без параметра — сервер должен вернуть ошибку или использовать значение по умолчанию.
3. Отключитесь, подключитесь заново.
4. Выполните тот же инструмент без параметра.
Ожидаемый результат: После переподключения состояние должно быть сброшено. Если сервер помнит `page=1` из предыдущей сессии — это утечка контекста.
Переменные окружения и конфигурация
MCP-серверы часто читают конфигурацию из переменных окружения. Если сервер кэширует эти значения или не перечитывает их при новом подключении, клиент может получить настройки, предназначенные для другой сессии.
Как проверить
Установите `MCP_CONFIG_PATH=/project-a/config.json`.
2. Запустите сервер, подключитесь, проверьте, что инструмент использует правильную конфигурацию.
3. Остановите сервер, установите `MCP_CONFIG_PATH=/project-b/config.json`.
4. Запустите сервер снова и проверьте, что конфигурация обновилась.
Ожидаемый результат: Каждый запуск сервера должен перечитывать окружение. Если сервер использует глобальный кэш, который не сбрасывается при перезапуске — это утечка.
Персистентные данные в shared storage
Некоторые MCP-серверы сохраняют данные на диск: кэш запросов, логи, временные файлы. Если эти данные не изолированы по сессиям, одна сессия может прочитать результаты работы другой.
Как проверить
Выполните инструмент, который создаёт временный файл или кэш.
2. Проверьте, где сохранён файл.
3. Из другой сессии (или другого клиента) попробуйте прочитать этот файл.
Ожидаемый результат: Временные файлы должны быть уникальными для каждой сессии или использовать случайные имена. Общий кэш без привязки к сессии — утечка.
Инспекция глобальных переменных сервера
Если у вас есть доступ к исходному коду сервера, проверьте, какие переменные объявлены на уровне модуля. Любая глобальная переменная, которая изменяется в процессе обработки запроса, — кандидат на утечку.
Как проверить (Python SDK example)
python
# Потенциальная утечка
last_opened_file = None
@mcp.tool()
def open_file(path: str) -> str:
global last_opened_file
last_opened_file = path
return read_file(path)
@mcp.tool()
def get_last_file() -> str:
return last_opened_file # Если вызвать из другой сессии — утечка
Ожидаемый результат: Каждый инструмент должен быть stateless или использовать локальное состояние сессии. Если сервер использует глобальные переменные для хранения состояния между вызовами — это проблема.
Тест параллельных подключений
Самый надёжный тест — одновременная работа двух клиентов с одним сервером.
Как проверить
Запустите MCP-сервер.
2. Напишите скрипт, который открывает два параллельных соединения.
3. Из первого соединения выполните инструмент, который записывает данные (например, `write_file` с уникальным содержимым).
4. Из второго соединения выполните инструмент, который читает те же данные.
5. Проверьте, что второй клиент не видит данные первого.
Ожидаемый результат: Данные одной сессии не должны быть доступны другой. Если сервер использует общую файловую систему без изоляции по сессиям — утечка.
Что делать, если утечка найдена
Универсального решения нет — всё зависит от реализации сервера. Но есть общие принципы:
- Используйте идентификатор сессии. Каждое подключение должно получать уникальный ID, и все операции должны быть привязаны к нему.
- Избегайте глобального состояния. Храните состояние в контексте запроса, а не в глобальных переменных.
- Изолируйте файловую систему. Если сервер работает с файлами, используйте временные каталоги с уникальными именами для каждой сессии.
- Сбрасывайте кэш при новом подключении. Если сервер использует кэш, убедитесь, что он не переносится между сессиями.
- Документируйте модель изоляции. В README сервера должно быть явно указано, как обрабатываются параллельные подключения.
Ограничения и что ещё стоит проверить
Предложенный чеклист покрывает типовые сценарии, но не является исчерпывающим. Утечка контекста может происходить и на уровне транспорта (например, если SSE-соединения не изолированы), и на уровне внешних сервисов, к которым обращается сервер.
Если вы используете MCP-сервер, написанный не вами, проверьте:
— есть ли в документации раздел о безопасности и изоляции;
— как сервер обрабатывает ошибки — не возвращает ли он дамп памяти или стек вызовов с чувствительными данными;
— какие права доступа имеет сервер в файловой системе — не может ли он читать файлы других пользователей.
Для серверов из официального репозитория modelcontextprotocol/servers ситуация разная: SQLite-сервер, например, открывает базу при старте и не изолирует запросы между сессиями — это означает, что два клиента, подключённые к одному серверу, работают с одной базой данных. Если этого требует архитектура, хорошо, но если нет — это потенциальная утечка.
Что дальше
Перед подключением любого MCP-сервера к рабочему окружению выполните хотя бы первые три проверки из чеклиста. Если сервер не проходит тест на изоляцию, используйте отдельные экземпляры для разных проектов — запускайте сервер с разными параметрами для каждой сессии.
Спецификация MCP продолжает развиваться, и, возможно, в будущих версиях появятся встроенные механизмы изоляции. Пока их нет, ответственность за безопасность лежит на разработчике сервера. Проверка на утечку контекста — минимальный набор тестов, который стоит включить в CI/CD любого MCP-сервера, предназначенного для работы с несколькими клиентами.