Подтверждение инструментов
Подтверждение инструментов
Инструменты MCP — это возможности агента. Часть из них безопасна по построению и выполняется без запроса; остальные требуют явного согласия пользователя, по каждому серверу инструментов. На этой странице — политика, диалог согласия и где хранятся разрешения (гранты).
Политика
Поле requires_approval записывается для каждого сервера в ~/.levpro-ai/mcp.json:
| Сервер | requires_approval |
Почему |
|---|---|---|
filesystem (всегда включён, управляемый) |
false |
Ограничен активной рабочей папкой и явным allowlist-ом allowed_tools. |
code-sandbox (каталог) |
true |
Выполняет код и устанавливает библиотеки. |
context7 (каталог) |
false |
Манифест помечает его readonly. |
Правила, применяемые при включении записи каталога:
allowed_toolsобязателен и не может содержать*; сервер каталога без явного списка отклоняется.requires_approval = !manifest.readonly. Только записи, чей манифест задаётreadonly: true, пропускают согласие.
Режим планирования полностью убирает code-sandbox, поэтому на ходе планирования нет ничего, что требовало бы подтверждения (см. Режим планирования).
Что видит пользователь
Когда ядро отклоняет вызов инструмента, рендер показывает модальное окно:
- Заголовок: Разрешить выполнение инструмента?
- Показывает Сервер, Инструмент и Аргументы вызова (с превью, если ядро его предоставляет).
- Кнопки: Запретить, Разрешить один раз, Разрешить всегда.
Пока окно открыто, статус показывает Ожидание подтверждения: …. Если на окно так и не ответили, по умолчанию через 120 секунд применяется Запретить — ход не может зависнуть навсегда.
Поток решения
lc.sendChat({ approveExecution: autoApproveExecution() })
└─ Core отклонил вызов инструмента ─► res.approvalDenied {tool, args, preview}
├─ serverId = serverIdFromTool(tool, активные id mcp.json) // mcp_<server>_<tool>
├─ promptToolApproval() ── broadcast ai:approvalRequired ─► модальное окно
│ └─ ответ: deny | once | always (по умолчанию deny после 120 с)
├─ always + serverId ─► config.grantServerApproval(serverId) // сохраняется
├─ deny ─► стоп; ход завершается отказом
└─ once/always ─► syncCoreSessionHistory() затем повтор с approveExecution=true
- Отклонённая попытка усекается из зеркала сессии ядра перед повтором, чтобы модель не видела наполовину продублированный ход.
autoApproveExecution()возвращаетtrue, когда ни один активный сервер не требует подтверждения, или когда у каждого требующего сервера уже есть грант. Иначе ход начинается неподтверждённым, и цикл подтверждения обрабатывает первый заблокированный инструмент.
Гранты
Гранты хранятся в ~/.levpro-ai/app-settings.json:
{ "approvalGrants": { "code-sandbox": true } }
- Записью управляет
electron/config.js:getApprovalGrants(),grantServerApproval(serverId),revokeServerApproval(serverId). ai:getApprovalGrantsотдаёт текущую карту рендеру;ai:approveToolразрешает ожидающий диалог.- «Разрешить всегда» действует на сервер, а не на инструмент — одного разрешения для сервера достаточно, чтобы покрыть все его инструменты на последующих ходах. Отозвать можно, очистив запись в
app-settings.json(встроенного интерфейса отзыва пока нет).
Связанные страницы
- MCP-серверы — каталог, allowlist-ы инструментов и политика подтверждения в контексте.
- Режим выполнения — где происходит цикл подтверждения.
- Режим планирования — почему планированию не нужно подтверждение.