- BrainTools - https://www.braintools.ru -

API для LLM: разбираем по пунктам, как устроен и как работает протокол MCP

API для LLM: разбираем по пунктам, как устроен и как работает протокол MCP - 1

Привет! Меня зовут Миша Васильев, я разработчик в команде AI Битрикс24.

В последнее время мы часто говорим про МСР и вот, наконец, решили рассказать простыми словами о том, что это такое, как работает, как мы это используем и планируем использовать. Если коротко, то MCP — это АРІ для LLM.

Что такое MCP, как было до него и как это работает сейчас

МСР — открытый протокол, представленный компанией Anthropic в 2024 году. По мерками AI-технологий это было уже давно. Цель протокола — стандартизировать предоставление контекста приложениям с большими языковыми моделями (БЯМ).

Очень важно понимать, что из всего того, что происходит вокруг приложений с БЯМ, МСР — самая не-ИИшная часть. Это четко детерминированная система, в которой нет места галлюцинациям и другим вещам, связанным с вероятностной природой моделей. Суть MCP наиболее близка к тому, что мы называем API.

Посмотрим, как было раньше

В самом начале, если вы общались с какой-то LLM-моделью, то даже если она знала, как вам помочь, она не могла это сделать сама. Она могла только рассказать, что вам нужно сделать, чтобы получить нужный результат.

API для LLM: разбираем по пунктам, как устроен и как работает протокол MCP - 2

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

API для LLM: разбираем по пунктам, как устроен и как работает протокол MCP - 3

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

Но появление МСР позволило улучшить такие сценарии. Теперь списки инструментов и в целом контекст запроса можно отделить от самого приложения и сделать их динамическим.

В нашем примере мы добавили два МСР-сервера. Первый предоставил нам ресурс — это список членов команды, а второй — инструмент, то есть возможность создать событие в календаре. Где-то за кадром, остался еще МСР-сервер мессенджера, но судя по диалогу он не понадобился).

API для LLM: разбираем по пунктам, как устроен и как работает протокол MCP - 4

Какие ключевые выгоды мы получаем, используя MCP

Масштабируемость: легко подключать новые сервисы, не нужно в коде программы, самого AI-агента что-то менять.

Гибкость: инструменты не зашиты в код агента

Разделение ответственности: агент думает — МСР исполняет

Безопасность: контроль доступа к вызовам инструментов и изоляция выполнения

Повторное использование: один и тот же МСР-сервис доступен разным агентам

Как работает MCP

Разберемся с ключевыми определениями протокола, их три: хост, клиент и сервер

API для LLM: разбираем по пунктам, как устроен и как работает протокол MCP - 5

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

Если вам нужны внешние данные, например список задач на портале или макеты из Figma, то это будет, скорее всего, удаленный сервер.

Как общаются друг с другом клиент и сервер 

Общение между ними происходит через протокол, основанный на JSON-RPC

API для LLM: разбираем по пунктам, как устроен и как работает протокол MCP - 6

Транспортно возможны два варианта:

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

  • для подключения к удаленному серверу используется Streamable HTTP. В протоколе есть поддержка как stateful так и stateless соединений, в том числе через стриминг ответов от сервера к клиенту через протокол SSE. 

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

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

Теперь перейдем к тем фишкам и возможностям, которые предоставляют нам клиент и сервер. 

Сервер

Сервер предоставляет нам инструменты, ресурсы и промпты. Рассмотрим каждый элемент более подробно. 

Инструменты

Инструменты позволяют нам изолированно выполнять каких-либо функции. Мы можем получить список инструментов, можем выполнить один или несколько. В инструментах содержится описание их самих и параметров, которые мы передаем туда через JSON Schema. 

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

В стандарте прописано, что описание инструмента должно быть четким, но немногословным. Также стандарт предлагает делать инструменты специализированными — модели проще понимают, когда инструмент делает что-то одно и делает это хорошо. 

Ресурсы

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

Доступ к ресурсам дается только на чтение. Если что-то нужно изменить, то следует использовать инструмент. Например, получить данные о встрече в календаре — это ресурс, поставить встречу в календарь — инструмент. 

В качестве ресурса может выступать практически все, что угодно, даже погода. Например, погода на конкретный день в конкретном городе может быть представлена в виде ресурсе со схемой weather в древовидном представлении:
weather://forecast/kgd/2025-09-12

Все это определяется шаблоном, чтобы модель могла понять, как ей создать уникальный идентификатор ресурса и запросить его:

{
  "uriTemplate": "weather://forecast/{city-code}/{date}",
  "name": "weather-forecast",
  "title": "Weather Forecast",
  "description": "Get weather forecast for any city and date",
  "mimeType": "application/json"
}

Промпты

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

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

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

Клиент

Разберемся с тем, что сервер может попросить сделать на клиенте. 

Это семплинг, корневые директории и элицитация

Сэмплинг

Сервер может попросить клиента выполнить ИИ-запрос.

У нас есть хост — приложение, которое уже утилизирует какое-то соединение с языковой моделью. И если серверу для выполнения каких-то заданий нужно сделать запрос в ИИ-модель, он может не делать этого сам, а «попросить» клиента сделать это. 

Но протокол накладывает на эту возможность ряд важных ограничений:

  • Действие должно быть подтверждено пользователем, так как эти действия не бесплатны.

  • Важно, чтобы все данные прозрачно передавались в языковую модель. Сервер не может «сейчас сходить в ИИ-модель, чтобы кое-что спросить». Он должен подтвердить у человека, у пользователя, весь запрос целиком. 

  • Сервер может попросить передать в запросе к ИИ-модели контекст беседы с пользователем, но пользователь должен иметь возможность этот контекст изолировать. 

Корневые директории

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

Пример:

{
  "uri": "file:///Users/agent/travel-planning",
  "name": "Travel Planning Workspace”
}

Элицитация

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

Как мы все это используем

На самом деле используем не все, а пока только определенную часть всех возможностей MCP-протокола.

Наш ИИ-помощник Марта AI использует MCP, чтобы помогать клиентам в рабочих сценариях.

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

Битрикс24 скоро сможет выступать в роли MCP-сервера, чтобы сторонние ИИ-агенты могли работать с порталом. Например, при работе из сторонних ИИ-агентов можно будет добавлять и контроллировать задачи, добавлять сделки в CRM. Доступно будет уже скоро.


Пример: готовый сценарий работы по MCP-протоколу

Разберем сценарий, на который я ссылался в самом начале статьи: “Создать встречу с командой завтра, в 15:00”.

1. Инициализация (Lifecycle Management)

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

Клиент → Сервер:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "elicitation": {},
      "sampling": {},
      "roots": {}
    },
    "clientInfo": {
      "name": "calendar-ai-client",
      "version": "1.0.0"
    }
  }
}

Сервер → Клиент:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "serverInfo": {
      "name": "calendar-mcp-server",
      "version": "1.2.3"
    },
    "capabilities": {
      "tools": { "listChanged": true },
      "resources": { "listChanged": true, "subscribe": true },
      "prompts": { "listChanged": true }
    }
  }
}

Клиент → Сервер (уведомление):

{
  "jsonrpc": "2.0",
  "method": "notifications/initialized"
}

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

2. Обнаружение инструментов (Tools Discovery)

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

Клиент → Сервер:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list"
}

Сервер → Клиент:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "create_calendar_event",
        "title": "Создать календарное событие",
        "description": "Создает событие в календаре пользователя с заданными параметрами",
        "inputSchema": {
          "type": "object",
          "properties": {
            "title": { "type": "string" },
            "startTime": { "type": "string", "format": "date-time" },
            "endTime": { "type": "string", "format": "date-time" },
            "attendees": { "type": "array", "items": { "type": "string" } },
            "description": { "type": "string" }
          },
          "required": ["title", "startTime", "endTime"]
        }
      }
    ],
    "nextCursor": null
  }
}

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

3. Промпт (Prompt) — структурированный шаблон

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

Клиент → Сервер:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "prompts/list",
  "params": {}
}

Сервер → Клиент:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "prompts": [
      {
        "name": "schedule_meeting",
        "title": "Запланировать встречу",
        "description": "Шаблон для создания встречи с указанными деталями",
        "arguments": [
          { "name": "title", "description": "Название встречи", "required": true },
          { "name": "startTime", "description": "Время начала (ISO8601)", "required": true },
          { "name": "endTime", "description": "Время окончания (ISO8601)", "required": true },
          { "name": "attendees", "description": "Участники (email)", "required": false }
        ]
      }
    ],
    "nextCursor": null
  }
}

Согласно спецификации клиенты могут получать описания промптов и структуру аргументов.

Если клиент захочет получить конкретный промпт с примерами:

Клиент → Сервер:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "prompts/get",
  "params": {
    "name": "schedule_meeting",
    "arguments": {
      "title": "Встреча с командой",
      "startTime": "2025-09-11T15:00:00Z",
      "endTime": "2025-09-11T16:00:00Z"
    }
  }
}

Сервер → Клиент:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "description": "Создает событие 'Встреча с командой' на указанное время",
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "Пожалуйста, запланируй встречу с командой завтра в 15:00"
        }
      }
    ]
  }
}

4. Элицитация (Elicitation) — уточнение деталей от пользователя

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

Сервер → Клиент (elicitation request):

{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "elicitation/create",
  "params": {
    "message": "Кого вы хотите пригласить на встречу? Укажите email участников.",
    "requestedSchema": {
      "type": "object",
      "properties": {
        "attendees": {
          "type": "array",
          "items": { "type": "string", "format": "email" }
        }
      },
      "required": ["attendees"]
    }
  }
}

Клиент → Сервер (ответ пользователя):

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "action": "accept",
    "content": {
      "attendees": ["alice@example.com", "bob@example.com"]
    }
  }
}

Это строго соответствует формату elicitation в MCP.

5. Вызов инструмента (tools/call) — создание события

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

Клиент → Сервер:

{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "tools/call",
  "params": {
    "name": "create_calendar_event",
    "arguments": {
      "title": "Встреча с командой",
      "startTime": "2025-09-11T15:00:00Z",
      "endTime": "2025-09-11T16:00:00Z",
      "attendees": ["alice@example.com", "bob@example.com"],
      "description": "Обсудить проект и план на неделю"
    }
  }
}

Сервер → Клиент:

{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Событие «Встреча с командой» успешно создано на 2025-09-11 с 15:00 до 16:00."
      }
    ],
    "isError": false
  }
}

Шаблон результата взят из описания tools/call в спецификации.

6. Дополнительные возможности: resources, notifications

Мы можем вернуть не просто текст о том, что встреча создана, а подтверждение или ссылку на событие. В этом случае сервер возвращает ресурс.

Сервер → Клиент (tool возвращает resource_link):

{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "content": [
      {
        "type": "resource_link",
        "uri": "https://calendar.example.com/events/12345",
        "name": "Ссылка на событие",
        "description": "Открыть созданное событие",
        "mimeType": "text/html"
      }
    ],
    "isError": false
  }
}

Поддержка связи с ресурсами описана в разделе tools → resource_link.

Если сервер может изменить доступные ресурсы или инструменты, он может отправить уведомление:

Сервер → Клиент:

{
  "jsonrpc": "2.0",
  "method": "notifications/tools/list_changed"
}

На что клиент может повторно вызвать tools/list для актуализации списка.


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

Автор: vasilyev

Источник [1]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/21994

URLs in this post:

[1] Источник: https://habr.com/ru/companies/bitrix/articles/965410/?utm_source=habrahabr&utm_medium=rss&utm_campaign=965410

www.BrainTools.ru

Rambler's Top100