Function calling или MCP: в чём разница и что выбрать для агента
Это не два конкурирующих способа, а два уровня одной задачи. Разбираем, кто описывает инструмент, кто его запускает и когда нужен MCP.
5 мин · · агенты · сравнение
Function calling vs MCP: частый вопрос тех, кто делает агента и видит в документации обе технологии. Ответ в том, что они решают разные части одной задачи. Function calling отвечает на вопрос «как модель сообщает, что хочет вызвать функцию», а MCP на вопрос «как приложение находит и запускает инструменты, которые написали другие». Ниже разберём, кто что делает, как это выглядит в запросе к API и когда достаточно простого списка tools.
Function calling: инструменты внутри запроса
При вызове функций вы передаёте модели в запросе список инструментов: имя, описание и JSON Schema аргументов. Модель не выполняет код. Вместо текстового ответа она может вернуть структурированный запрос «вызови get_order_status с такими аргументами». Дальше работает ваше приложение:
- отправляет запрос с описанием инструментов;
- получает от модели вызов функции;
- выполняет функцию у себя;
- отправляет результат обратно в следующем запросе;
- получает итоговый текстовый ответ.
Код инструмента живёт в вашем приложении, а описание передаётся в каждом запросе. Через шлюз Zukko это работает в обоих форматах. В OpenAI-формате (/v1/chat/completions) описание лежит в tools, а ответ приходит в tool_calls:
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.zukko.pro/v1", api_key=os.environ["ZUKKO_API_KEY"])
tools = [{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Возвращает статус заказа по номеру",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},В Anthropic-формате (/v1/messages) поля называются иначе: инструмент описывается через input_schema, вызов приходит блоком tool_use, а результат возвращается блоком tool_result. Базовый адрес для официального Anthropic SDK без /v1:
import os
import anthropic
client = anthropic.Anthropic(base_url="https://api.zukko.pro", api_key=os.environ["ZUKKO_API_KEY"])
resp = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=1024,
tools=[{
"name": "get_order_status",
"description": "Возвращает статус заказа по номеру",
"input_schema": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
},
}],
messages=[{"role": "user", "content": "Где мой заказ A-1042?"}],
)
for block in resp.content:
if block.type == "tool_use":
print(block.id, block.name, block.input)Структуру запросов смотрите в справочниках Chat Completions и Messages; подробный разбор на примере Claude есть в заметке про tool use.
MCP: протокол для подключаемых инструментов
Model Context Protocol вводит стандарт общения между приложением с моделью (хостом) и программами, которые предоставляют контекст (серверами). Хост создаёт MCP-клиента, тот подключается к серверу и запрашивает список инструментов (tools/list), а затем вызывает нужный (tools/call). Протокол построен на JSON-RPC 2.0, а транспортов два: stdio для локальных серверов и Streamable HTTP для удалённых. Кроме инструментов сервер может отдавать ресурсы и промпты.
Ключевое отличие в том, где живёт код и кто его написал. MCP-сервер это отдельная программа. Хост не знает заранее, какие у неё функции: он спрашивает. Поэтому один и тот же сервер подключается к Claude Code, к редактору и к вашему приложению без доработок. Общее описание сервера есть в заметке что такое MCP-сервер; в Claude Code такие серверы подключаются командой claude mcp add.
Они не конкуренты
Самое частое заблуждение: MCP заменяет function calling. На практике хост берёт список инструментов с MCP-сервера, превращает его в обычный список tools для запроса к модели, а когда модель вызывает инструмент, пересылает вызов серверу. То есть function calling остаётся механизмом «модель просит вызов», а MCP определяет, откуда берутся инструменты и как они выполняются. Для шлюза разницы нет: он видит обычный запрос к модели с tools внутри.
Сравнение
| Вопрос | Function calling | MCP |
|---|---|---|
| Кто описывает инструмент | Ваше приложение в каждом запросе | MCP-сервер, хост запрашивает список |
| Где выполняется код | В вашем приложении | В отдельном процессе или сервисе |
| Повторное использование | Копируете описание между проектами | Один сервер подключается к разным хостам |
| Чужие готовые инструменты | Нужно интегрировать самому | Подключаются командой или URL |
| Сложность старта | Минимальная | Нужен сервер и транспорт |
| Контроль | Полный, всё в вашем коде | Зависит от доверия к серверу |
MCP-сервер и обычный API
Отдельный вопрос: чем MCP-сервер отличается от API. Обычный API рассчитан на программиста, который читает документацию и пишет вызовы. MCP-сервер рассчитан на модель: инструменты описаны схемами и текстом, чтобы хост мог показать их модели без ручной интеграции. Нередко MCP-сервер просто оборачивает существующий API. Если у вас уже есть REST-сервис и один потребитель, отдельный MCP-слой может не понадобиться.
Когда что выбирать
Хватит tools в запросе, если:
- приложение одно, функций немного, и они тесно связаны с вашей логикой;
- нужен полный контроль над выполнением и правами;
- вы не хотите держать отдельный процесс.
Стоит делать MCP-сервер, если:
- инструменты нужны нескольким хостам: Claude Code, редактору, своему боту;
- вы хотите подключать готовые серверы других авторов;
- инструменты пишет другая команда или на другом языке;
- нужно выставить возможности продукта «наружу» для агентов.
Что с расходом
Описание каждого инструмента входит в запрос и тарифицируется как вход, независимо от того, написан он вручную или получен из MCP. Допустим (условно), что хост подключил 30 инструментов по 120 токенов описания, а сессия делает 100 запросов: 3 600 × 100 = 360 000 токенов входа. Для claude-sonnet-5-5 (вход 0.4, чтение кэша 0.05 за 1M токенов на 18 октября 2026):
- по цене входа: 360 000 × 0.4 / 1 000 000 = $0.144;
- при чтении из кэша: 360 000 × 0.05 / 1 000 000 = $0.018.
Для Claude скидка за кэш видна шлюзу только в Anthropic-формате (/v1/messages); в OpenAI-формате весь вход идёт по цене входа. Поэтому длинные списки инструментов лучше держать в Anthropic-формате, а лишние отключать. Текущие цены смотрите в GET https://api.zukko.pro/v1/models.
Частые вопросы
Можно ли использовать MCP без function calling?
Модель должна уметь вызывать инструменты, чтобы MCP был полезен. Как именно модели справляются с вызовами, зависит от модели, поэтому проверяйте выбранную на своих сценариях.
Нужен ли MCP, если у меня один бот?
Скорее нет. Простой список tools и функции в коде проще и надёжнее. MCP окупается, когда инструменты нужно переиспользовать.
Безопасен ли чужой MCP-сервер?
Это программа, которая запускается у вас и может выполнять действия. Подключайте только доверенные серверы, проверяйте права и не давайте доступ к лишнему.
Работает ли это из России?
Доступ из России идёт через шлюз, оплата СБП, картой MasterCard или криптой. Оба подхода одинаково работают через Zukko.
Создайте ключ в кабинете и запустите пример с get_order_status, чтобы увидеть цикл вызова своими глазами.
zukko
Платите в 25×
меньше
за Claude Code & ChatGPT
Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.
Похожие статьи
- RAG или MCP: в чём разница и что выбрать для доступа модели к даннымRAG кладёт найденные куски в промпт, MCP даёт модели инструменты, которые она вызывает сама. Разбираем, чем они отличаются, сколько стоит каждый и как их сочетать.
- Claude Desktop или Claude Code: в чём разница и что выбратьДесктопное приложение и консольный агент делят один движок, но входят в систему по-разному. Сравниваем сценарии, доступ к моделям и стоимость.
- opencode или Codex CLI: какой консольный агент выбратьОба агента открыты, оба читают AGENTS.md и работают со своим API. Различия в провайдерах, режимах и в том, как считается кэш. Сравниваем и считаем сессию.
- Claude Code локально: что реально работает с локальной модельюClaude Code можно запустить на модели, которая работает на вашем компьютере. Разбираем, как это настроить, чем это отличается от облачных моделей и когда считать деньги, а не железо.