Продолжая разговор про архитектуру и принципы устройства MCP-сервера, в этой статье я покажу пример создания собственного сервиса для автоматизации работы с OpenAPI-спецификациями: как спроектировать, реализовать и что настроить при развертывании, проблемы и их решения
Постановка задачи на реализацию своего MCP-сервера
Чтобы наглядно продемонстрировать принципы работы и внутреннюю архитектуру MCP-сервера, а также автоматизировать процессы работы со спецификациями OpenAPI, я решила реализовать собственную разработку в виде отдельного микросервиса. MCP-сервер предназначен для генерации, валидации и публикации OpenAPI-спецификации в Postman. Такой ограниченный перечень функций, охватывающий не все задачи SDLC-цикла REST API обусловлен тем, что разработку тестов и тестирование мок-сервера для коллекции HTTP-запросов на основе импортированной в Postman спецификации, можно сделать встроенными средствами этой платформы. Для этого даже на Free-тарифе доступен внутренний ИИ-агент самого Postman, который может выполнить следующие действия:
- добавить примеры успешных и неуспешных ответов к каждому запросу по всей коллекции;
- написать тесты к каждому запросу для контрактного (функционального) тестирования;
- добавить к коллекции подробное описание;
- опубликовать документацию;
- создать мок-сервер, имитирующий реализованный API для тестирования;
- запустить автоматизированное тестирование коллекции запросов к созданному мок-серверу, используя инструмент Runner.

Таким образом, для моего MCP-сервера достаточно всего 3 функции:
- по пользовательским требованиям генерация OpenAPI-спецификации согласно лучшим практикам проектирования REST API, заданным правилам и соглашениям об именованиях;
- ее валидация;
- публикация в Postman при отсутствии критических ошибок.
Для выполнения первой функции MCP-сервер будет сам обращаться к LLM, сообщая ей о пользовательских требованиях в пользовательском промпте и ссылаясь в системном промпте на доступные ресурсы с описанием правил генерации нужного документа. Задача валидации решается локальным линтером, который анализирует полученную спецификацию, сгенерированную LLM или написанную человеком, проверяя на наличие синтаксических ошибок и соответствие заданным правилам. А публикация в Postman с автоматическим созданием коллекции запросов на основе спецификации – всего лишь вызов к API этой платформы.
Перед проектированием самого MCP-сервера, надо сперва определить контекст его использования и внедрения. Для моего примера это приведено в следующей таблице.
| Характеристика | Значение для MCP-сервера | Влияние на архитектуру и реализацию |
| Назначение | Наглядно продемонстрировать принципы работы и внутреннюю архитектуру MCP-сервера, а также автоматизировать процессы работы со спецификациями OpenAPI, используя LLM и инструмент тестирования веб-приложений Postman | Явная передача данных в аргументах вызовов к MCP-серверу для максимальной наглядности |
| Пользователи | Студенты курсов BABOK-SCHOOL: аналитики, разработчики и менеджеры ИТ-проектов, которые проектируют и тестируют REST API, разрабатывают и валидируют OpenAPI-спецификации, в т.ч. с помощью LLM и ИИ-инструментов | Необходимо ограничить доступ к MCP-серверу внешним клиентам, кроме студентов курсов BABOK-SCHOOL и их ИИ-клиентам. Нужен механизм аутентификации, проверяющий наличие зарегистрированного пользователя на платформе https://apps.babok-school.ru/, и возможность его обращения к MCP-серверу |
| Ландшафт внедрения | Микросервисная система «Платформа изучения БД и API: Демо-стенд по базам данных, архитектуре и интеграциям ИС» https://apps.babok-school.ru/, доступ к которой студенты получают по личному API-ключу | Проверка возможности обращения к MCP-серверу по API-ключу пользователя платформы https://apps.babok-school.ru/ (передавать в Bearer Token). Из-за обращения к API основного сервиса платформы для аутентификации и LLM-провайдерам для генерации OpenAPI, производительность и время отклика MCP-сервера будет зависеть от этих внешних систем. |
| Область применения | Индивидуальная практика по работе с MCP-серверами, по генерации и проверке OpenAPI-спецификаций, тестированию REST API в рамках обучения на курсах BABOK-SCHOOL | Генерируемые и передаваемые OpenAPI-спецификации – это примеры для обучения, а не конфиденциальные данные для промышленного использования. Чтобы снижения рисков утечки ключей к API LLM-провайдеров и Postman (из-за открытой передачи в теле запроса) можно создать в этих сервисах ключи с ограниченным сроком действия и использовать их в обращениях к MCP-серверу |
Проектирование MCP-сервера: определение возможностей и схемы JSON-RPC сообщений
После фиксации контекста использования и внедрения, далее следует распределить функции проектируемого MCP-сервера по возможностям (capabilities) в соответствии с MCP-протоколом, классифицировав каждую функцию как базовый блок (примитив):
- инструмент (tool) – исполняемый код, который ИИ-клиент может вызывать, функция с четким описанием. У инструментов есть 2 метода:
- tools/list – запрос списка всех доступных на сервере инструментов с описанием их аргументов по JSON-схеме, возвращает массив;
- tools/call – выполнение конкретного инструмента с переданными аргументами? возвращает контент (текст, изображения и пр.);
- ресурс (resource) – данные, которые MCP-сервер предоставляет ИИ-клиенту в режиме только для чтения. В отличие от инструментов, ресурсы имеют свой URI и могут динамически обновляться. У ресурсов есть 5 методов:
- resources/list – получение списка конкретных статичных ресурсов, известных серверу;
- resources/templates/list – получение списка динамических шаблонов URI, по которым клиент может запрашивать данные;
- resources/read – чтение содержимого конкретного ресурса по его URI;
- resources/subscribe – подписка клиента на обновления конкретного ресурса;
- resources/unsubscribe – отмена подписки.
- промпт (prompt) – инструкции для ИИ, которые позволяют LLM лучше понять контекст, не выполняя операции и тратя на это токены. Методы промптов:
- prompts/list – запрос списка промптов MCP-сервера, возвращает набор шаблонов подсказок для LLM;
- prompts/get – запрос конкретного промпта, возвращает ее текст, включая заданные аргументы.
Взаимодействие ИИ-клиента с удаленным MCP-сервером идет через 2 канала:
- клиент отправляет серверу POST-запросы по HTTP-протоколу, передавая JSON-RPC сообщение в теле;
- сервер общается с клиентом через SSE (Server-Sent Events)– технологию HTML5, позволяющую отправлять данные клиенту в реальном времени по HTTP-протоколу без постоянных запросов с клиентской стороны.
Согласно MCP-протоколу, типовое сообщение JSON-RPC выглядит так:
{
"jsonrpc": "2.0",
"id": "ID запроса",
"method": "примитив/метод",
"params": {
"name": "название инструмента или промпта",
"arguments": {
"argument_1": "значение_1",
"argument_2": "значение_2"
}
}
}

Классифицируем функции проектируемого MCP-сервера по примитивам и напишем примеры JSON-RPC сообщений, скрыв служебные поля «jsonrpc» и «id», что делают большинство ИИ-клиентов.
| Функция MCP-сервера | Вид возможности и метод MCP-сервера | Что учесть при проектировании схемы JSON-RPC сообщения | Пример JSON-RPC сообщение в теле POST-запроса HTTP к MCP-серверу |
| Генерация OpenAPI-спецификацию по требованиям пользователя с помощью внешней LLM по заданным правилам (корпоративным стандартам) |
|
Генерация делается через обращение к внешнему LLM-провайдеру. В параметры функции вызова инструмента MCP-сервера надо передавать название/URL LLM-сервиса, название LLM-модели и аутентификационные данные для внешнего LLM-сервиса (Bearer-токены, ключи API). |
{
"method": "tools/call",
"params": {
"name": "generate_openapi",
"arguments": {
"requirements": "сервис бронирования мест в ресторанах",
"llm_api_key": "…",
"provider": "openrouter",
"model": "openai/gpt-oss-120b:free"
}
}
}
|
| Валидация OpenAPI-спецификации на соответствие корпоративным стандартам |
|
Локальный инструмент без обращения к внешним сервисам, проверка на соответствие делается обычным линтером. В параметры функции вызова инструмента MCP-сервера надо передавать YAML-документ спецификации OpenAPI, который будет проверяться на соответствие правилам в корпоративных стандартах |
{
"method": "tools/call",
"params": {
"name": "validate_openapi",
"arguments": {
"spec_yaml": "openapi: 3.0.0
…
"
}
}
}
|
| Публикация валидной OpenAPI-спецификации в Postman |
|
Вызов к API Postman с передачей YAML-документа спецификации OpenAPI и указанием названия коллекции, куда Postman сохранит созданные по спецификации HTTP-запросы к указанным ресурсам |
{
"method": "tools/call",
"params": {
"name": "publish_to_postman",
"arguments": {
"spec_yaml": "openapi: 3.0.0
…
"postman_api_key": "…",
"collection_name": "рестораны"
}
}
}
|
| Просмотр правил оформления OpenAPI-спецификации (корпоративных стандартов) |
|
Правила оформления спецификации будут в виде файла лежать локально на самом MCP-сервере в текстовом виде (YAML-файл). Чтобы скрыть от ИИ-клиента физическое расположение файла и дать доступ к актуальной версии стандартов без привязки к конкретному пути, в параметрах вызова MCP-сервера нужно передавать универсальный URI, например, standards://latest, резолвинг которого делать в коде MCP-сервера. |
{
"method": "resources/read",
"params": {
"uri": "standards://latest"
}
}
|
| Просмотр промптов |
|
Промпты (prompts) – инструкции для ИИ, которые позволяют LLM лучше понять контекст, не выполняя операции с тратой токенов. Будет всего 3 промпта: для генерации спецификации, валидации и просмотра системного промпта (базовой скрытой инструкции, задающей нейросети ее характер, роль, правила поведения, стиль общения и ограничения) |
{
"method": "prompts/get",
"params": {
"name": "generate_openapi_spec",
"arguments": {
"requirements": "Сервис регистрации на рейс"
}
}
}
|
Реализация и развертывание
Закончив с проектированием, можно переходить к реализации. Как обычно, в качестве языка разработки я использую Python. Основным фреймворком для создания веб-приложения выбираю FastAPI, более производительный по сравнению с Flask благодаря асинхронному характеру. Он нужен для подключения ИИ-клиентов к MCP-серверу и отправке ответов по SSE (Server-Sent Events). Функции обработки JSON-RPC сообщений согласно протоколу MCP реализованы с помощью библиотеки mcp. В отличие от фреймворка Fast MCP, она более низкоуровневая и позволяет проще контролировать логику работы сервера. Для отправки запросов внешним системам, а также работы с JSON-схемами, YAML-документами и OpenAPI-спецификациями нужны соответствующие библиотеки: httpx, jsonschema, PyYAML, prance, openapi-spec-validator, openapi-schema-validator и deepdiff для поиска различий между сложными иерархическими структурами данных (словари, списки, строки и объекты).
Визуально архитектура основных компонентов MCP-сервера и схема его взаимодействия с внешними сервисами представлена на следующей диаграмме.

Реализованный сервис MCP-сервер доступен студентам нашего образовательного стенда по архитектуре и интеграции ИС.

В заключение покажу несколько скриншотов использования.

Процесс развертывания сервера оказался для меня более трудоемким, чем проектирование и разработка. Поскольку, как и все наши сервисы, MCP-сервер доступен для запросов извне не напрямую, а через Nginx. Это самый популярный обратный прокси-сервер с открытым исходным кодом, поддержкой кеширования и балансировки нагрузки за счет встроенной асинхронной обработки событий. Он обеспечивает базовую защиту, скрывая реальные сокеты, на которых развернуты веб-приложения, защищает от DDoS-атак и перегрузок, а также отвечает за расшифровку HTTPS-трафика и безопасность на уровне HTTP-заголовков. Однако, когда MCP-сервер стоит за Nginx, потоковая передача данных от сервера к клиенту по SSE выдает ошибку, т.к. прокси по умолчанию пытается буферизировать данные или закрывает застывшие сессии. Для SSE-передачи надо, чтобы соединение оставалось открытым в режиме постоянного потока (keep-alive), а тип контента четко соответствовал событийно-ориентированному формату (event-stream). Поэтому в конфигурации Nginx надо принудительно отключать буферизацию, увеличивать таймауты соединения и переключать версию протокола HTTP на 1.1. Вот часть конфигурации прокси-сервера:
location / {
proxy_http_version 1.1; # обязательно для постоянных соединений (keep-alive)
proxy_set_header Connection ""; # запрет закрывать сетевой канал после отправки одного ответа
proxy_set_header Accept "application/json, text/event-stream"; # явный запрос у бэкенда формата JSON или SSE-потока
proxy_set_header X-Accel-Buffering "no"; # полное отключение буферизации для мгновенной доставки сообщений
proxy_pass_header Content-Type; # разрешение FastAPI передавать клиенту заголовок потока (text/event-stream)
proxy_read_timeout 8640s; # тайм-аут удержания связи, пока отвечает внешний сервис
proxy_send_timeout 8640s; # тайм-аут удержания канала открытым во время непрерывной отправки JSON-RPC
proxy_pass http://127.0.0.1:xxxx; # сокет, на котором запущен FastAPI-сервер (адрес локального хоста и порт, закрепленный за приложением)
}
После перезагрузки Nginx с измененной конфигурацией, взаимодействие с MCP-сервером проходит без ошибок.

Поработать с представленным MCP-сервером, а также узнать другие особенности ИИ-систем вы сможете на моих курсах Школы анализа и проектирования информационных систем в нашем лицензированном учебном центре обучения и повышения квалификации системных и бизнес-аналитиков в Москве:


