Перейти к содержанию
Публикация AiManual

Свой MCP-сервер: вечер на код и месяц на OAuth, имена и публикацию

Практический кейс создания MCP-сервера для продукта: код занял один вечер, а недели ушли на инструменты, OAuth и публикацию. Разбор подводных камней реестров и

Коротко

Что будет в материале

  1. 01

    Что такое MCP-сервер и зачем он вашему продукту

  2. 02

    Вечер на код: как AI-агент написал MCP-сервер

  3. 03

    Сколько инструментов делать и как их называть

  4. 04

    Почему имена инструментов нельзя менять после публикации

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

Реальную стоимость лучше всего показывает статистика первых двух недель: больше 3700 подключений к серверу и всего 147 реальных вызовов инструментов. Все 147 пришли от самого автора или ревьюера, настоящих пользователей среди них не было.

Ниже разобрано, что именно AI-агент не может решить за разработчика и где спрятаны главные расходы времени.

Что такое MCP-сервер и зачем он вашему продукту

MCP (Model Context Protocol) даёт AI-клиентам вроде Claude и ChatGPT стандартный способ вызывать функции вашего продукта. Клиент получает список инструментов, которые вы описали, и вызывает их напрямую, без парсинга документации и без отдельного кода под ваш API для каждой модели. Подробнее о протоколе и его экосистеме - в материале о том, как MCP подключает ИИ-агентов к внешним инструментам.

Пример из кейса: сервер для публикации историй. Он отдаёт инструменты для поиска, создания черновика и публикации, и AI-клиент выполняет эти действия по просьбе пользователя прямо из чата.

Технически MCP поверх streamable HTTP - это JSON-RPC в теле POST. Клиент просит сервер представиться, запрашивает список инструментов, затем вызывает их по одному. Фреймворк и SDK не нужны: поверх существующего бэкенда добавляется один маршрут, и новых зависимостей не появляется.

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

Вечер на код: как AI-агент написал MCP-сервер

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

Схематично обмен с клиентом выглядит так:

POST /mcp
{"jsonrpc": "2.0", "id": 1, "method": "initialize"}
{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}
{"jsonrpc": "2.0", "id": 3, "method": "tools/call",
 "params": {"name": "stories.search", "arguments": {"query": "mcp"}}}

Три шага: представление, список инструментов, вызов. Всё остальное - обработка аргументов и логика вашего продукта.

Простота кода не означает простоту проекта. Один маршрут - это только транспорт. Всё, что делает сервер полезным и безопасным, лежит вне кода.

Сколько инструментов делать и как их называть

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

Верхней границы как таковой нет, но у неё есть цена. Linux MCP daemon отдаёт агенту состояние системы через 38 инструментов, и это осознанный компромисс: широкий охват против простоты выбора.

Имена лучше делать читаемыми деревом, точечным путём вроде stories.search. Скоринг в каталогах поощряет такие имена: листинг автора набрал 98 из 100 в smithery.ai как раз из-за этого правила, отмечает источник.

Правила каталогов при этом конфликтуют. Библиотека серверов ChatGPT не примет листинг с точкой: допустимый шаблон имени ^[a-zA-Z0-9_-]{1,64}$, точка отбрасывается.

Вывод: имена выбирайте с оглядкой на все реестры, куда планируете попасть. Если целевой реестр один, конфликт не важен. Если реестров несколько, точку придётся либо не использовать, либо мириться с тем, что один из каталогов ваше имя не примет.

Почему имена инструментов нельзя менять после публикации

Как только реестр просканировал сервер, заявка принята, и каждое опубликованное имя становится именем, которое придётся хранить. Его несут листинги, заявки и чужие сохранённые конфигурации. Это уже не рефакторинг, а миграция по системам, которыми вы не управляете.

Пример: переименование stories.search в search_stories ломает всех, у кого в конфигурации прописан старый вызов. Правка на вашей стороне ничего не исправит, потому что строку хранит чужая конфигурация.

Поэтому имена продумывают до публикации. Час на схему имен дешевле, чем поддерживать оба варианта или объяснять пользователям, почему инструмент перестал работать.

Правила доступа: что открывать анонимно, а что только авторизованным

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

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

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

Обратный пример - публичный MCP-сервер movahedi-privacy с данными о канадском законодательстве о приватности: подключение по Streamable HTTP без регистрации, ключей и OAuth. Там отдаются открытые данные, и авторизация просто не нужна. Что выбирать, зависит от того, что именно возвращают инструменты.

OAuth: самая дорогая часть проекта

Обычный API-ключ для MCP-клиентов вроде Claude или ChatGPT не подходит. Клиент подключается к серверу сам, и вставить ключ некуда: пользователь не редактирует конфиг, он нажимает «подключить».

Значит, придётся поднять собственный сервер авторизации по стандарту OAuth. В кейсе это названо самой дорогой частью проекта, и ответственность за безопасность этой части целиком ложится на разработчика.

Причина в том, что серверу нужно понимать, от чьего имени его зовут. Публиковать и править истории можно только свои, приватную историю читает только её автор. Без корректной авторизации этим проверкам не на чем стоять.

OAuth требует времени на настройку, тестирование и поддержку безопасности. Задача не разовая: токены выдаются, истекают и отзываются, а ошибка в этой части стоит дороже всего остального.

Публикация в реестрах: подводные камни, которые всплыли

Кейс выявил три проблемы на этапе публикации. Первая: устаревшая политика конфиденциальности. Её нужно обновить так, чтобы она отвечала текущим требованиям реестра, и сделать это до подачи заявки. Вторая: отставшая версия сервера. Реестр сканирует то, что развёрнуто, поэтому публиковать имеет смысл актуальную сборку, а не ту, что осталась на стенде. Третья: токен с правом read:org для организации в GitHub. Без него часть проверок не пройдёт.

Чек-лист перед подачей заявки:

  • политика конфиденциальности актуальна и отвечает требованиям реестра;
  • версия сервера на боевом адресе совпадает с той, которую вы заявляете;
  • для организации в GitHub подготовлен токен с правом read:org;
  • имена инструментов зафиксированы и не будут меняться после сканирования.

Список короткий, но каждый пункт способен отложить публикацию на дни, если обнаружится в момент подачи.

Статистика: 3700+ подключений и 147 вызовов

За две недели сервер получил больше 3700 подключений, но лишь 147 реальных вызовов инструментов, и все они пришли от автора или ревьюера. Об этом говорится в разборе кейса.

Подключение и вызов - разные вещи. Подключения бывают автоматическими или тестовыми и сами по себе не означают использования. Реальную ценность показывают вызовы инструментов, а не счётчик сессий.

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

Стоит ли делать свой MCP-сервер: выводы

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

  • Начинайте с 4-8 инструментов и добавляйте новые только по реальной потребности.
  • Продумывайте имена до публикации: переименование после сканирования превращается в миграцию чужих конфигураций.
  • Разделяйте инструменты по правам и не закрывайте список возможностей от анонимных клиентов, если хотите, чтобы они понимали, зачем подключаться.
  • Закладывайте время на OAuth как на отдельный проект, а не как на подпункт в задаче.
  • Проверяйте политику конфиденциальности и версию сервера до подачи заявки.

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

Подписаться на канал