Все рецепты

Построй свой MCP-сервер: дай Claude доступ к любому API

MCP (Model Context Protocol) — это USB-интерфейс для AI: стандартный разъём, через который Claude подключается к любому инструменту. Разбираем, как спроектировать и запустить собственный MCP-сервер — от выбора инструментов до первого вызова из Claude Desktop.

СреднийMCP30 минTypeScript, MCP SDK, Claude Desktop
1

Когда MCP, а когда обычный код?

Вы хотите дать Claude доступ к CRM. Без MCP есть три пути: данные в промпт (ограничен контекстом), промежуточный сервис (поддерживать навсегда), или API-вызовы прямо в приложении (жёсткая привязка). MCP решает иначе — универсальный протокол, как USB-C: один разъём для всех устройств. Простое правило: Claude сам решает, какой инструмент вызвать — MCP. Фиксированная цепочка вызовов — обычный код или n8n. Главная ценность — переиспользование: написал сервер для Jira, и к нему подключается Claude Desktop, Cursor, любой MCP-клиент.

Когда MCP, а когда нет?

Claude сам выбирает инструмент и порядок вызовов
Нужно переиспользовать доступ к API в разных клиентах
Линейный пайплайн с фиксированной последовательностью
Одноразовый скрипт для конкретной задачи
MCP — не замена Function Calling. Function Calling — вы контролируете логику в коде. MCP — Claude сам решает, что вызвать. Разные уровни автономии.
2

Узкие инструменты побеждают широкие — всегда

Инструмент `manage_database(action, params)` — это кнопка «сделать хорошо». Claude не понимает, что произойдёт, и вызывает её непредсказуемо. А `query_users`, `update_order`, `get_product` — три понятных кнопки, которые Claude комбинирует сам. Ответьте на три вопроса до кода: что Claude должен уметь, что ему не нужно, и где граница безопасного. Начинайте только с read-инструментов — Claude будет экспериментировать, и пусть эксперименты не стоят вам строк в базе.

❌ Широкий инструмент

  • manage_database(action, params)
  • Claude не знает что именно произойдёт
  • Ошибки сложно отлаживать

✅ Узкие инструменты

  • query_users, update_order, get_product
  • Claude комбинирует сам
  • Каждый тестируется отдельно
Напишите описание инструмента до кода. Если не можете объяснить в двух предложениях, когда Claude должен его вызывать — граница инструмента ещё нечёткая.
3

Три слоя сервера — и только один ваш

MCP-сервер — не веб-сервер в привычном смысле. Это процесс-переводчик: с одной стороны Claude со своими запросами, с другой — ваш API или база данных. Переводчик принимает запрос, делает нужный вызов, возвращает результат в понятном Claude формате. Транспорт (stdio или HTTP+SSE) — для начала всегда stdio: нет сетевых проблем, нет auth, проще отлаживать. Протокол (JSON-RPC 2.0) — SDK полностью скрывает эту деталь. Ваша бизнес-логика — единственный слой, где вы принимаете решения. Остальное — шаблон, который SDK генерирует за вас.
Ваша бизнес-логика
Что именно делает инструмент
Протокол (JSON-RPC 2.0)
SDK обрабатывает автоматически
Транспорт (stdio / HTTP+SSE)
Начинайте с stdio — проще
MCP-сервер = три слоя:
  Бизнес-логика: ваш код (единственное, что вы пишете)
  Протокол: JSON-RPC 2.0 (SDK обрабатывает)
  Транспорт: stdio (локально) или HTTP+SSE (удалённо)

Инструмент = имя + схема входа + обработчик
  get_order({ orderId }) → данные заказа из БД
  Начинайте с stdio — проще отлаживать
4

Описание инструмента — это промпт. Пишите его как промпт

Когда Claude выбирает инструмент, он читает три вещи: имя, описание, схему параметров. Это и есть промпт — только в формате JSON Schema. От качества этих трёх элементов зависит, будет ли Claude вызывать инструмент правильно, слишком часто, слишком редко или с неправильными параметрами. Имя — глагол + объект: `get_customer_orders`, `search_knowledge_base`. Не `tool1`, не `handleRequest`. Claude использует имя как первую подсказку при выборе инструмента, и оно должно быть самоочевидным. Описание — мини-инструкция для Claude. Включите: что делает инструмент, когда вызывать, что возвращает. Отдельно: когда НЕ вызывать. Кажется излишним, но именно негативные инструкции предотвращают ложные вызовы. Схема параметров — добавляйте описания к каждому полю. `customerId` без описания — загадка. `customerId` с «UUID из CRM, не email и не имя» — конкретная инструкция. Claude будет передавать именно то, что вы ожидаете. Принцип: если стажёр поймёт инструмент, прочитав только схему — она хорошая.
Инструмент: search_orders
Описание: "Поиск заказов по статусу или клиенту.
  Вызывать: когда спрашивают о заказах, доставке.
  НЕ вызывать: для создания/изменения заказов."
Параметры:
  customerId — "UUID из CRM, не email и не имя"
  status — pending | shipped | delivered
  limit — макс 20, по умолчанию 10
Включите в описание инструмента когда его НЕ вызывать. Звучит странно, но отрицательные инструкции снижают количество ложных вызовов в разы.
5

Ошибки — это промпты для Claude, а не логи для вас

Представьте: Claude — курьер, которому вы дали адрес. GPS говорит «улица не найдена» — одна ситуация (уточнить). «Дорога закрыта» — другая (объехать). «GPS недоступен» — третья (подождать). Ваша задача — давать Claude именно такие сигналы, а не просто «что-то пошло не так». В обычном API ошибка летит разработчику как HTTP 500. В MCP — ошибка летит Claude, и он должен с ней что-то сделать: повторить, объяснить пользователю, выбрать другой инструмент. Два типа: исключение процесса (сервер упал — Claude бессилен) и ошибка в контенте (`isError: true` с описанием — Claude читает и реагирует). Для бизнес-ошибок всегда второй вариант. Никогда не бросайте исключения из обработчика — это убивает весь MCP-сервер, а не один вызов. Что писать в ошибке? Три элемента: что произошло, почему, что попробовать дальше. Не «Internal error», а «Order not found. The orderId may be from another system. Try search_orders by customer name.» Claude буквально прочитает это и скорректирует следующий шаг.
Тестируйте ошибки первыми. Вызовите инструмент с несуществующим ID, пустой строкой, невалидными параметрами — и проверьте, что Claude получает полезные подсказки, а не стектрейсы.
6

Подключил — теперь итерируй описания, а не код

Claude Desktop — идеальная среда для проверки MCP-сервера, потому что это рентген: видны не только результаты, но и как Claude рассуждал, какой инструмент выбрал, с какими параметрами. Добавить сервер — файл конфига с путём к скомпилированному JS, перезапуск приложения, инструменты появились. Но важнее настройки — методика тестирования. Попросите Claude выполнить задачу с цепочкой вызовов: «Найди заказы клиента Иванов за последнюю неделю и скажи, какой из них на доставке». Это проверит и отдельные инструменты, и их комбинацию — именно для этого вы и строили MCP-сервер. Итерация — самая ценная часть процесса. После первого теста вы обнаружите: Claude вызывает с неправильными параметрами (проблема описания), вызывает когда не нужно (описание слишком широкое), не вызывает когда нужно (название неочевидное). Каждый из этих сигналов — это правка в описании инструмента, а не в логике. Итерация описаний даёт больше, чем рефакторинг кода.
Используйте MCP Inspector (`npx @modelcontextprotocol/inspector`) до Claude Desktop — он показывает инструменты и позволяет вызывать вручную, как Postman для MCP. Экономит 80% времени на отладку.

Результат

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