Закулисный взгляд на основные компоненты серверов MCP — от обработки запросов и управления сессиями до кеширования и хранилищ контекста.

Современные ассистенты на базе искусственного интеллекта (ИИ) столь же эффективны, насколько богатыми данными и инструментами они располагают.

КДПВ, но в тему
КДПВ, но в тему

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

Вместо создания уникальных интеграций для каждой базы данных, API или корпоративной системы разработчики могут полагаться на единый интерфейс MCP, словно на универсальное “AI-USB”, подключая ИИ к любому источнику данных.

В этой статье мы познакомимся с архитектурой сервера MCP, пояснив ключевые компоненты и их роль в соединении ИИ с важным контекстом.

Общий обзор архитектуры MCP

Верхнеуровнево, MCP функционирует через три роли: хост, клиент и сервер:

  • Хост — это приложение с поддержкой ИИ (например, чат-ассистент или IDE улучшенное средствами ИИ), с которым взаимодействует конечный пользователь.

  • Внутри хоста существует клиент, который управляет протоколом MCP со стороны приложения и поддерживает постоянное соединение с сервером.

  • Сервер — это отдельная программа или сервис, предоставляющая определенные возможности (доступ к базе данных, веб-поисковый инструмент, файловую систему и т.д.) через стандартизированный интерфейс MCP.

Так взаимодействуют эти три роли на практике:

  1. Хост интерпретирует пользовательские запросы и определяет, какая возможность сервера требуется. Например, если пользователь спрашивает: «Сколько клиентов зарегистрировались сегодня?», клиент хоста может перенаправить запрос на аналитический сервер MCP.

  2. Клиент передает запрос посредством JSON-RPC соответствующему серверу.

  3. Сервер выполняет действие и возвращает результаты клиенту. Например, он запрашивает базу данных и возвращает количество.

  4. Клиент передает ответ хосту, который использует его для формирования окончательного ответа для пользователя.

Это разделение труда позволяет модели ИИ сосредоточиться на анализе и работе с языком, а серверу MCP — на действиях и получении данных.

Это четкое разделение: хост+клиент обрабатывают взаимодействие с пользователем и рассуждения ИИ, а сервер обеспечивает выполнение инструментов и доступ к данным.

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

  • Коммуникационный слой

  • Обработчики запросов

  • Хранилища контекста

  • Оркестраторы сессий

  • Слои кеширования

Далее мы рассмотрим каждый компонент и его роль в работе MCP.

Коммуникационный слой

В основе каждого сервера MCP лежит коммуникационный слой, который "использует" протокол MCP для обмена данными. Внутри самого MCP в качестве формата сообщений для всех обменов используется JSON-RPC 2.0.

JSON-RPC — легковесный и не зависящий от состояния протокол удаленных вызовов процедур (RPC), использующий JSON для кодирования сообщений. Он облегчает связь между клиентом и сервером, позволяя клиенту выполнять методы на сервере, как если бы они были локальными функциями.

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

Серверы MCP поддерживают сохраняющее состояние соединение с клиентом на протяжении сессии. Независимо от того, является ли транспорт локальной трубой (STDIO), HTTP-потоком или WebSocket, соединение остается открытым, позволяя выполнять ряд взаимодействий в рамках единого контекста. Это позволяет серверу сохранять/поддерживать контекст от одного запроса к следующему.

Например, если сервер только что вернул первую страницу большого документа, следующий запрос на вторую страницу будет понят в контексте предыдущего. Внутри сервер может использовать разные транспортные методы — STDIO для локальных инструментов или Server-Sent Events/HTTP для удаленных серверов. Но все транспорты в итоге передают сообщения JSON-RPC в обоих направлениях. Коммуникационный компонент сервера абстрагирует эти детали, чтобы остальная часть логики сервера могла обрабатывать запросы на высоком уровне и не беспокоиться об их доставке — через трубу или сетевой сокет.

Таким образом, компонент обработки протокола выступает своеобразным коммуникационным шлюзом: он принимает входящие JSON-RPC вызовы, переводит их в внутренние вызовы функций и отправляет обратно JSON-RPC ответы. Он соблюдает спецификацию MCP (например, правильно форматирует сообщения, управляет идентификаторами для пар запрос-ответ, обрабатывает ошибки), чтобы сервер и клиент оставались синхронизированными.

Обработчики запросов

Сервер MCP становится полезным только тогда, когда он начинает действовать в ответ на запросы. Здесь в работу вступают обработчики запросов. Это функции или методы, выполняемые на сервере для конкретных действий при получении соответствующего запроса MCP. Каждую возможность сервера реализует соответствующий обработчик запросов.

MCP определяет три типа возможностей сервера:

  • Ресурсы: Это конечные точки для извлечения информации. Обработчик ресурсов может вернуть данные из базы данных, загрузить документ или перечислить элементы в облачном хранилище. Важно, что ресурсы являются только для чтения или пассивными — они предоставляют данные, но обычно не вызывают побочных эффектов. Например, сервер MCP для базы знаний может иметь ресурс, называемый searchArticles, который принимает запрос и возвращает соответствующие статьи из корпуса. Обработчик запросов для этого ресурса выполняет поиск и форматирует результаты для отправки обратно. Ресурсы часто обрабатывают большие объемы данных (файлы, результаты крупных запросов), поэтому их обработчики могут поддерживать потоковую передачу фрагментов или пагинацию для повышения эффективности.

  • Инструменты: Это активные операции, которые могут выполнять побочные эффекты или выполнять вычисления. Обработчик инструмента может создавать новую запись в базе данных, отправлять электронное письмо, вызывать внешний API или даже управлять чем-то вроде веб-браузера. Инструменты позволяют ИИ влиять на реальный мир (в разумных пределах). Например, сервер MCP может предоставить инструмент sendSlackMessage, который, получив канал и сообщение, отправляет их в Slack. Обработчик запросов для этого инструмента содержит логику вызова API Slack и возвращения результата о успехе/ошибке. Поскольку инструменты могут иметь эффекты, их обработчики, как правило, включают проверки и проверки безопасности. Они также четко определяют входные параметры и схему выхода, чтобы ИИ (и клиент) знали, как их использовать.

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

Каждый обработчик привязан к определенному имени метода (например, "tool.sendSlackMessage"). Когда приходит запрос, протокольный слой сервера направляет его к правильному обработчику. Этот обработчик выполняется, возвращает результат (или ошибку), и сервер отправляет это обратно клиенту.

Серверы MCP часто включают встроенный обработчик для запроса обнаружения возможностей — способа для клиента выяснить, “что ты можешь сделать?”. Это может быть этап инициализации, когда сервер возвращает список всех доступных инструментов, ресурсов и подсказок (иногда включая схемы или примеры).

Обработчики запросов реализованы на языке, на котором написан сервер (Python, JS и т.п.), с использованием SDK или фреймворков, предоставляемых MCP для упрощения этого сопоставления.

Пример: Менеджер закладок

Рассмотрим пример сервера MCP, который управляет простым менеджером закладок. Он демонстрирует, как создавать и извлекать закладки, а также предлагает подсказку для осмысленного сохранения ссылок.

from mcp.server.fastmcp import FastMCP
from mcp.server.stdio import stdio_server
from mcp.server import InitializationOptions, NotificationOptions
from pathlib import Path
import json
import asyncio

BOOKMARKS_FILE = Path("bookmarks.json")
if not BOOKMARKS_FILE.exists():
    BOOKMARKS_FILE.write_text("[]", encoding="utf-8")

app = FastMCP("MCP Bookmarks Server")

# Утилита для загрузки/сохранения закладок
def load_bookmarks():
    return json.loads(BOOKMARKS_FILE.read_text(encoding="utf-8"))

def save_bookmarks(data):
    BOOKMARKS_FILE.write_text(json.dumps(data, indent=2), encoding="utf-8")

#### ИНСТРУМЕНТЫ ####
@app.tool()
def add_bookmark(title: str, url: str, tags: list[str] = []) -> str:
    bookmarks = load_bookmarks()
    bookmarks.append("title": title.strip(), "url": url.strip(), "tags": tags)
    save_bookmarks(bookmarks)
    return f"Закладка 'title' сохранена."

#### РЕСУРСЫ ####
@app.resource("bookmark://index")
def get_bookmark(index: int) -> dict:
    bookmarks = load_bookmarks()
    if 0 <= index < len(bookmarks):
        return bookmarks[index]
    return "error": "Закладка не найдена."

#### ПОДСКАЗКИ ####
@app.prompt()
def suggest_bookmark_title(topic: str) -> str:
    return f"Предложите ясное и привлекательное название для закладки о: topic"

# —————————–
# ТОЧКА ВХОДА (Явный транспорт)
# —————————–
async def main():
    async with stdio_server() as (read_stream, write_stream):
        await app.run(
            read_stream,
            write_stream,
            InitializationOptions(
                server_name="mcp-bookmarks-server",
                server_version="0.1.0",
                capabilities=app.get_capabilities(
                    notification_options=NotificationOptions(),
                    experimental_capabilities=,
                ),
            ),
        )

if __name__ == "__main__":
    asyncio.run(main())
  • Инструмент: add_bookmark позволяет сохранить новую закладку с дополнительными тегами.

  • Ресурс: get_bookmark извлекает закладку по индексу.

  • Подсказка: suggest_bookmark_title помогает ИИ создать подходящие названия.

Хранилища контекста

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

Хранилище контекста — это любое внутреннее хранилище, которое сервер использует для хранения состояния или памяти. Это может быть:

  • Память (например, словарь Python) для небольших, быстрых задач — например, хранения списка дел пользователя.

  • Базы данных (например, Postgres или MongoDB) для более сложных и постоянных данных — например, записи клиентов или задачи проекта.

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

  • Внешние сервисы (например, Google Drive или Salesforce), в которых сервер извлекает данные при необходимости и может временно их кэшировать.

Хранилище контекста позволяет серверу отслеживать историю сессий или промежуточные результаты, отвечать быстрее и поддерживать более "умные", осведомленные о контексте инструменты — например, помня предыдущие шаги в разговоре или уже загруженные файлы. Например, сервер автоматизации браузера может хранить куки и открытые вкладки в памяти, обрабатывая многоступенчатый запрос. Или помощник программиста может кэшировать файлы из репозитория, чтобы не загружать их заново для каждого вопроса.

Для прототипов подойдет простое хранение в памяти или на основе файлов. Но для промышленного применения с множеством пользователей или большим объемом данных необходимы масштабируемые системы, такие как Redis, SQL или векторные хранилища. Независимо от бэкэнда, хорошее хранилище контекста использует чистые интерфейсы, чтобы остальная часть сервера могла легко получать доступ или обновлять данные.

Оркестрация сессий

В настройке MCP клиент (часто работающий на вашем компьютере или устройстве) обычно управляет основной логикой сессии. Но сервер также помогает управлять сессиями, особенно когда необходимо отслеживать, что происходит с каждым клиентом.

Каждое подключение к серверу похоже на сессию. Во время этой сессии сервер может запомнить определенные детали о клиенте или задаче. Это управляется специальной частью сервера, называемой Оркестратором сессий.

Но зачем (и когда) серверу MCP требуется оркестрация сессии?

Представьте себе сервер MCP, который автоматизирует просмотр веб-страниц. Клиент поручает ему "найти самый дешевый рейс из X в Y в следующем месяце". Это не простая, одношаговая задача. Возможно, сервер должен:

  1. Открыть браузер

  2. Перейти на сайт путешествий

  3. Заполнить форму

  4. Пролистать несколько страниц результатов

Все эти действия выполняются по порядку, и сервер должен запоминать такие вещи, как открытые страницы или выбранные фильтры. Именно здесь в игру вступает Оркестратор сессий — он управляет всем в ходе этого многоступенчатого процесса.

Даже более простые задачи могут выиграть от управления сессиями. Например:

  • Форма, которая задает вопросы шаг за шагом, может запоминать ваш прогресс.

  • Помощник покупок может отслеживать, какие товары вы добавили в корзину.

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

Оркестратор сессий отвечает за:

  • Поддержание данных сессии: сохранение временной информации, такой как переменные, ввод пользователя или результаты.

  • Связывание запросов: гарантирует, что каждый шаг знает, что произошло на предыдущем.

  • Обработка таймаутов: закрытие сессий и очистка, если клиент отключился или больше неактивен.

  • Управление общими задачами: в редких случаях несколько клиентов могут работать над чем-то вместе (например, на общей доске). Оркестратор также может управлять такими сценариями совместной работы.

Слой кеширования

Серверы MCP часто работают с крупными или медленными источниками данных, такими как большие базы данных или API с ограничением скорости. Чтобы оставаться быстрыми и эффективными, они используют кеширование — способ временного хранения часто используемых или дорогих в извлечении данных.

Некоторые распространенные стратегии кеширования, используемые серверами MCP:

  • Кеширование в памяти: хранение последних результатов в памяти для быстрого повторного использования. Например, цены на акции можно кешировать на несколько секунд, чтобы избежать повторных вызовов API.

  • Постоянное кеширование: использование инструментов, таких как Redis или базы данных, для хранения данных между сессиями или экземплярами сервера — отлично подходит для больших данных или распределенных систем.

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

  • Предварительная загрузка: загрузка данных заранее на основе ожидаемых запросов клиента — например, предзагрузка следующих страниц документа, пока пользователь его читает.

Кеширование может значительно ускорить производительность и сократить затраты, особенно для задач на базе ИИ или API, но требует тщательного продумывания инвалидации — момента обновления или удаления кешированных данных.

С точки зрения разработчика, слой кеширования может быть реализован через существующие библиотеки или сервисы. Например, сервер MCP на Python может использовать словарь в памяти для простого кеширования или functools.lru_cache для мемоизации вызовов функций. Для более сложных нужд он может подключиться к экземпляру Redis или использовать декоратор кеширования, который обрабатывает генерацию ключей на основе параметров запросов.

Заключение

Серверы MCP делают интеграции ИИ более структурированными и разумными. Каждая часть сервера имеет четкую роль: обработчики запросов выполняют действия, хранилище контекста обеспечивает память, управление сессиями поддерживает связь взаимодействий, а кеширование улучшает производительность.

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

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

Комментарии (0)