MCP vs API-интеграция: когда что использовать
Архитектурное сравнение MCP, function calling и обычной REST-интеграции. Гайд для CTO и техлидов: где какой паттерн уместен, сколько стоит, как мигрировать.
- architecture
- mcp
- api
- cto
«Зачем мне MCP, если я уже умею делать HTTP-запросы из агента через function calling?» — частый вопрос разработчиков, которые впервые слышат про Model Context Protocol. Короткий ответ: function calling — для одного агента в одной кодовой базе. MCP — для экосистемы. В этой статье разбираем, когда какое решение уместно.
Три способа дать агенту доступ к внешнему миру
1. Прямой API-вызов в коде агента
Самый старый паттерн. В коде агента — прямые HTTP-запросы:
async def check_inn(inn: str) -> dict:
response = await httpx.get(f"https://egrul.nalog.ru/api/?inn={inn}")
return response.json()
# В системном промпте:
# "Если нужно проверить ИНН — вызови tool check_inn(inn=...)"
Плюсы: просто, control полный. Минусы: ничего не переиспользуется, агент должен знать формат запроса.
2. Function calling / tool use
Анонсирован OpenAI в 2023, скопирован Anthropic. Агент сам решает когда вызвать тул, разработчик только описывает сигнатуру:
tools = [
{
"name": "check_inn",
"description": "Проверка ИНН через ФНС",
"parameters": {
"type": "object",
"properties": {"inn": {"type": "string"}}
}
}
]
# Агент сам решает когда позвать
Плюсы: агент умнее. Можно дать 20 тулов и доверить выбор. Минусы: жёстко привязан к конкретной библиотеке (OpenAI SDK / Anthropic SDK). Не переиспользуется в других IDE / агентах.
3. MCP
То же что function calling, но протокол стандартизирован. Один MCP server работает во всех клиентах, которые поддерживают MCP.
Плюсы: ecosystem-effect. Один раз написал — везде работает (Cursor, Claude, Cline, Continue, будущие IDE). Изоляция в отдельный процесс. Минусы: небольшой overhead на запуск процесса (~200мс при cold-start). Нужен runtime для запуска (uv / node).
Когда что выбирать
Прямой API-вызов в коде
Уместно когда:
- У вас один конкретный агент в production — не ecosystem.
- Перформанс критичен (избегаем overhead’а MCP-протокола).
- Очень специфичная логика, которую не стоит выносить в reusable component.
Пример: ML-pipeline в production, который делает 10 000 проверок ИНН/час. Каждая 200мс overhead’а от MCP — это 33 минуты в час впустую. Лучше прямой httpx.
Function calling
Уместно когда:
- Один агент, одна команда разработки.
- Не нужно переиспользовать в других IDE.
- Хотите тонкий control над форматом запроса/ответа.
Пример: внутренний бот в компании, который интегрирован с corporate CRM. Других потребителей этого тула не будет.
MCP
Уместно когда:
- Хотите один раз написать и переиспользовать в Cursor / Claude / Cline.
- Это переиспользуемая интеграция (API ФНС, Slack, GitHub, и т.д.).
- Хотите изоляцию (упал MCP — IDE не пострадает).
- Хотите community-effect (open-source MCP, который кто-то ещё использует).
Пример: интеграция с ФНС / ЕГРЮЛ / ЦБ — это переиспользуемая штука. Десятки людей хотят проверять ИНН через AI. Идеальный кейс для MCP.
Стоимость поддержки
| Аспект | Direct API | Function calling | MCP |
|---|---|---|---|
| Время first-implementation | 1 час | 1 час | 1.5 часа |
| Переиспользование | 0% | ~20% (в одной экосистеме) | ~80% (везде где MCP) |
| Стоимость поддержки 1 года | 100% | 80% | 30% (если open-source с community) |
| Изоляция | Нет | Нет | Да (процесс) |
| Безопасность секретов | Низкая | Средняя | Высокая (env-vars MCP) |
| Cold-start overhead | 0 | 0 | ~200мс (один раз на старте IDE) |
Гибридный подход
В реальной production-системе часто используют все три:
- Прямой API — для high-throughput pipeline’ов (ETL, batch-обработка).
- Function calling — для специфичной логики внутри одного агента (custom-prompts, domain-specific workflows).
- MCP — для переиспользуемых интеграций (DB, документация, API провайдеров).
Atomno Labs — пример: для высоконагруженных production-pipeline’ов клиенты Pro-tier используют наш HTTP API напрямую (function calling). Для интерактивной работы из IDE / при разработке — тот же сервис через MCP. Один backend, два интерфейса.
Миграция: function calling → MCP
Если у вас уже есть function calling, миграция в MCP — несколько часов:
- Извлеките логику тулов в отдельные async-функции (без зависимости от OpenAI/Anthropic SDK).
- Оберните FastMCP:
from fastmcp import FastMCP mcp = FastMCP("my-mcp") @mcp.tool() async def check_inn(inn: str) -> dict: # ваша логика ... if __name__ == "__main__": mcp.run() - Опубликуйте на PyPI (
uv publish). - Старый код function calling — удалите. Вместо него в
mcp.json— ваш новый MCP.
Готово, теперь работает и в Cursor, и в Claude, и где угодно ещё.
Особенно важно для CTO
MCP — это архитектурный паттерн для AI-эпохи. Аналог микросервисов, но для агентских интеграций.
В долгосрочной перспективе:
- Команды, которые пишут MCP вместо direct-API, накопят library of tools.
- Эти tools переиспользуются между проектами/командами.
- Open-source MCP получают community-contributions (мы это видим на наших).
- Стандартизация снижает зависимость от вендора (если завтра Anthropic исчезнет — MCP всё равно работают в Cursor, Cline, Continue, и т.д.).
Стратегически это важнее короткой производительности.
TL;DR (Вкратце)
- Direct API — для high-throughput batch.
- Function calling — для specific custom workflows одного агента.
- MCP — для переиспользуемых интеграций. Long-term — это правильный паттерн для большинства use-cases.
Если выбираете между function calling и MCP для нового проекта — берите MCP. Не потеряете в гибкости, выиграете в переиспользовании.
Что читать дальше
- Что такое MCP — если ещё не читали.
- Безопасность MCP — особенно про изоляцию процессов.
- Каталог 10 готовых MCP — что уже доступно.
Понравилась статья?