Загрузка 0
ПОДЕЛИТЬСЯ

Мой блог

Листай вниз

Как я создал собственный MCP-сервер: разработка, код и реальные грабли

Как я создал собственный MCP-сервер: разработка, код и реальные грабли

Подробности изложены в материале первоисточника. Создание собственного MCP-сервера может показаться быстрой задачей на один вечер, особенно если основную работу по написанию кода выполняет искусственный интеллект. Однако на практике львиная доля времени уходит вовсе не на программирование, а на проектирование структуры инструментов, настройку прав доступа и решение задач, которые невозможно было предусмотреть заранее. Успех подобных проектов во многом зависит от внешних факторов, ограничений каталогов и нюансов взаимодействия с клиентским ПО.

Агент справился с созданием эндпоинта за считанные часы. Протокол Model Context Protocol поверх streamable HTTP представляет собой JSON-RPC-запросы внутри тела POST. Клиент отправляет запрос на знакомство с сервером, запрашивает перечень доступных инструментов, а затем поочередно вызывает их. Входные и выходные данные передаются в виде обычных словарей. Для реализации такого подхода мне не потребовались громоздкие фреймворки или специализированные SDK. Я просто добавил один единственный маршрут поверх уже существующего бэкенда, избежав добавления лишних программных зависимостей.

архитектурная схема взаимодействия с MCP-сервером
Общая схема работы протокола Model Context Protocol поверх HTTP
статистика подключений и вызовов инструментов
Графики посещений и активности ботов каталогов в сравнении с реальными вызовами

Проектирование функционала и ограничений

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

Реклама

Вторым важным аспектом стали правила разграничения доступа. Некоторые данные на сервере могут быть доступны абсолютно любому пользователю, тогда как другие требуют обязательной авторизации и проверки персональных прав на конкретный ресурс. Не менее ответственным этапом оказалось наименование методов. Современные каталоги поощряют древовидную структуру имен, например, точечные пути вроде stories.search. Мой проект набрал 98 баллов из 100 в каталоге smithery.ai именно благодаря соблюдению этого стандарта. Однако при интеграции в экосистему ChatGPT такой подход может вызвать проблемы, так как там действуют строгие ограничения, а точки могут отбрасываться.

Реклама

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

Организация аутентификации и доступов

Процесс настройки аутентификации стал, пожалуй, наиболее трудоемким этапом всей разработки. Первой задачей было научить сервер точно идентифицировать пользователя. Поскольку такие клиенты, как Claude или ChatGPT, подключаются к удаленным серверам самостоятельно, у пользователя нет возможности вручную прописать секретный ключ в настройках. Серверу необходима полноценная система авторизации по стандарту OAuth, когда пользователь нажимает кнопку подключения, проходит стандартный экран подтверждения прав и возвращается в сессию. Поддержание безопасности такого узла целиком ложится на плечи разработчика.

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

Инфраструктурные затраты и поддержка

С технической точки зрения MCP-сервер представляет собой легковесный микросервис с крайне редкой и неравномерной нагрузкой. Большую часть времени он простаивает и активируется только в моменты обращения пользовательского агента. Вычислительные затраты стремятся к нулю и с запасом укладываются в бесплатные лимиты облачных провайдеров. Публикация в официальных реестрах и подача заявок в магазины приложений также производятся бесплатно. Единственной постоянной статьей расходов для меня стала подписка на командный тариф Claude для работы с коннекторами.

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

Реклама

Непредвиденные сложности после релиза

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

Другой неожиданностью стали проблемы с документацией во время модерации. Магазин приложений отклонил заявку из-за того, что политика конфиденциальности описывала устаревшую архитектуру четырех read-only инструментов без авторизации, хотя к моменту проверки проект вырос до шести эндпоинтов за OAuth с правами на запись. Проверяющие сверяют текст документации с реальным поведением эндпоинта, и поддерживать эти описания в актуальном состоянии приходится вручную.

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

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

Анализ реального трафика и выводы

Главный вопрос успешности проекта кроется вовсе не в инженерных метриках, а в том, пользовался ли кто-то вашим решением помимо самого автора. Статистика моего сервера зафиксировала более 3700 подключений, причем со временем суточный трафик вырос с нескольких десятков до тысячи запросов. Однако детальный анализ показал, что подавляющее большинство этого трафика генерируют автоматические боты каталогов, поисковые сканеры и системы мониторинга, которые лишь проверяют доступность хоста и запрашивают список инструментов, но никогда их не вызывают. Реальными пользователями на начальном этапе остаются лишь разработчики и тестировщики.

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

  • Фиксировать имена инструментов в отдельной проектной документации еще до написания исходного кода.
  • Включать подробное логирование входящих запросов с первого же деплоя на продакшн.
  • Четко разграничивать публичные данные и закрытые ресурсы, не блокируя без необходимости базовое описание возможностей сервера.
  • Настраивать мок базы данных на основе реальных драйверов с автоматическим приведением типов, а не полагаться на ручные заглушки.
  • Внедрить строгую проверку версии, блокирующую деплой при изменении состава инструментов без обновления метаданных в реестре.

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

01.