Мы уже разобрались что такое MCP, из чего он состоит и как написать свой сервер. Но часто совершают серьезную ошибку при работе с MCP.
Этой ошибкой является дать агенту все доступные тулы и отправить работать. Агент не понимает контекст так, как понимаете его вы. Он выбирает тулы на основе описаний и текущего промпта. И может вызвать тул, который не предусматривался.
Но почему это так критично?
1. Безопасность
Каждый тул расширяет поверхность некорректного выполнения.
Представьте агент для аналитики продаж. Вы подключили ему MCP-сервер с тулами:
get_sales_data, send_email, delete_records, update_user.Агент хочет отправить отчёт вызывает функцию
send_email. Но в промпте была неоднозначность, и он решает "помочь" почистить старые данные через delete_records.Никакого злого умысла. Просто был доступ, и он решил что так правильно.
2. Надёжность
Чем больше тулов, тем выше шанс что агент выберет не тот. Модели путаются при большом выборе, особенно если описания тулов похожи между собой. Результат: непредсказуемое поведение, которое сложно дебажить.
3. Скорость и стоимость
Это часто забывают. Каждый тул это дополнительные токены в контексте. Описание, параметры, схема всё это обрабатывается при каждом запросе.
Чем больше тулов, тем:
- дольше обрабатывается запрос
- дороже каждый вызов (токены описаний входят в input tokens)
- ниже точность выбора нужного тула
При 5 тулах модель выбирает правильный почти всегда. При 50 точность заметно падает.
Принцип минимальных привилегий
Тот же принцип, что и в безопасности обычных систем: давай доступ только к тому, что нужно для конкретной задачи.
Агент для чтения аналитики? Только read тулы.
Агент для отправки отчётов? Только на отправку.
Один агент = один набор тулов под его задачу.
Как это на практике
Регистрируем тулы динамически только нужные для конкретного агента:
// ❌ так лучше не делать
server.tool("delete_records", ...);
server.tool("send_email", ...);
server.tool("update_user", ...);
// ✅ только то, что нужно агенту
const allowedTools = getToolsForAgent(agentRole); // ["get_sales_data"]
allowedTools.forEach(toolName => {
server.tool(toolName, toolDefinitions[toolName]);
});
В реальности можно описывать доступные функции агенту в зависимости от его роли.
Что ещё можно сделать
Логировать каждый вызов тула. Если агент что-то сломал, вы должны знать что именно и когда.
Перед delete или update добавить еще проверку доп проверку.
Ну и обязательно тестировать агента в изолированной среде перед боевым запуском.