Блог • AI / Agent
Новые возможности Claude Managed Agents 2026: как AI Agent сам решает, разрешён ли Tool Call? Permission policy JSON и MCP Security
10 сентября 2026 года Anthropic добавил новый тип в permission policy Claude Managed Agents: auto. В тот же день события agent.tool_use и agent.mcp_tool_use начали нести поле evaluation рядом с прежним evaluated_permission.
То, что модель предложила Tool Call, ещё не значит, что вызов исполнят. Решает оценка стратегии на сервере: она читает JSON policy из конфигурации Agent и по имени инструмента, input и содержимому сессии этого вызова ставит allow, deny или ask.
В этой статье:
- На каком слое останавливается каждая из трёх permission policy
auto: что смотрит повызовная оценка и какой JSON оставляют три исхода- Почему MCP toolset по умолчанию
always_askи как его сложить с auto - После остановки сессии на
requires_action, как писатьuser.tool_confirmation. - Как в JSONNote разделить стратегию, события и запросы на одобрение
Запомните это: auto — не «всё открыто» и не ручное одобрение. Если сервер считает вызов безопасным, он уже отработал до того, как вы его увидели; если высоким риском — у клиента даже нет шанса отменить deny. Ниже: три стратегии → оценка по вызову → JSON события → MCP → поток одобрения.
Три стратегии: always_allow, always_ask, auto
permission policy касается только инструментов, которые исполняет сервер: встроенный agent_toolset_20260401 и MCP toolset, которые вы подключаете. Пользовательские инструменты исполняет ваше приложение, эта стратегия их не берёт. В запросе нужен beta-заголовок managed-agents-2026-04-01. Официальное описание:
Claude Managed Agents Permission policies.
Стратегия решает «когда этому вызову бежать», а не «есть ли инструмент в каталоге». Убрать инструмент у Agent — через disable. Не ждите, что стратегия его спрячет.
| Стратегия | Что делает сервер | Что ещё делать клиенту |
|---|---|---|
always_allow |
Сразу исполняет, никого не ждёт | Достаточно читать события, шага подтверждения нет |
always_ask |
Останавливается после события tool_use | На каждое заблокированное событие отправить user.tool_confirmation |
auto |
Оценивает этот вызов: бежать, отказать или остановиться и спросить вас | Обрабатывать только события со статусом ask; deny не отменить |
Значения по умолчанию с двух сторон разные. У Agent toolset по умолчанию always_allow. У MCP toolset по умолчанию always_ask. Ни один toolset сам не включает auto — это нужно записать в JSON.
Уже идущая session продолжает жить с тем toolset, с которым её создали. После правки Agent новую стратегию получат только новые session. Примечания к выпуску:
Claude Platform release notes (2026-09-10).
Что auto смотрит на самом деле
Раньше было только «этот инструмент всегда можно» или «этот инструмент всегда спрашивать». auto переносит решение с уровня инструмента на уровень вызова.
В документации конкретно: оценка смотрит сам инструмент, input этого вызова и содержимое сессии до этого момента. Поэтому один и тот же bash с двумя разными command может дать один allow и один deny.
-
1
Вызов разрешён
Сервер считает этот вызов безопасным: инструмент исполняется как при
always_allow. Паузы нет, человеческого окна нет. -
2
Вызов отклонён
Сервер оценил его как высокий риск: инструмент не бежит. Agent получает ошибочный tool result:
Permission to use {tool_name} has been denied., иis_error: true. Сессия продолжается. Ваш клиент этот deny не изменит. -
3
Вызов остановился и ждёт вас
Сервер не даёт однозначного вывода: сессия встаёт на паузу как при
always_ask. Дальше вы разрешаете или отклоняете событием подтверждения.
Намерение читается только из тех user.message, которые отправляете вы. Результаты инструментов, скачанные страницы, ответы MCP Server, сообщения между тредами: сервер оценивает содержимое, но не считает их инструкциями. Некоторые вызовы оцениваются как высокий риск, кто бы ни просил.
Если недоверенный текст конечного пользователя вы кладёте как есть в user.message, сервер примет это за ваше намерение и может разрешить вызов. Таким входным инструментам отдельно ставьте always_ask.
В каком JSON пишется стратегия
Стратегия появляется в двух местах: default_config.permission_policy у toolset и перекрытие одного инструмента в configs. Конфиг ниже ставит Agent toolset и GitHub MCP в auto, а bash отдельно закрепляет как always_ask.
{
"name": "Ops Agent",
"model": "claude-opus-5",
"mcp_servers": [
{
"type": "url",
"name": "github",
"url": "https://mcp.example.com/github"
}
],
"tools": [
{
"type": "agent_toolset_20260401",
"default_config": {
"permission_policy": { "type": "auto" }
},
"configs": [
{
"name": "bash",
"permission_policy": { "type": "always_ask" }
}
]
},
{
"type": "mcp_toolset",
"mcp_server_name": "github",
"default_config": {
"permission_policy": { "type": "auto" }
}
}
]
}
mcp_server_name должен совпасть с записью в mcp_servers, у которой name тот же. Когда на стороне MCP перекрывают по имени инструмента, name — имя, которое сообщил Server, не ваш собственный псевдоним.
Если опустить default_config, Agent toolset включится как always_allow. Это удобное значение по умолчанию, не безопасное.
evaluation, которую оставляет каждый вызов
Какая бы ни была стратегия, agent.tool_use и agent.mcp_tool_use несут поле верхнего уровня evaluated_permission со значением allow, ask или deny. У большинства событий есть ещё объект evaluation, в котором type показывает, какая стратегия вынесла решение.
При auto в объекте ещё пишется решение сервера; если исход ask или deny, добавляется reason_code. Официальный пример: bash идёт через auto, высокорисковый вызов отклонён.
{
"type": "agent.tool_use",
"id": "sevt_01pqr...",
"name": "bash",
"input": {
"command": "rm -rf /workspace/reports"
},
"evaluated_permission": "deny",
"evaluation": {
"type": "auto",
"evaluated_permission": {
"type": "deny",
"reason_code": "high_risk"
}
},
"processed_at": "2026-03-25T14:05:12Z"
}
| evaluation | Результат верхнего уровня | Смысл |
|---|---|---|
{"type":"always_allow"} |
allow | Разрешённая стратегия — always_allow, вызов уже исполнен |
{"type":"always_ask"} |
ask | Разрешённая стратегия — always_ask, сессия вас ждёт |
{"type":"auto","evaluated_permission":{"type":"allow"}} |
allow | auto счёл этот вызов безопасным, уже отработал |
{"type":"auto","evaluated_permission":{"type":"ask","reason_code":"indeterminate"}} |
ask | auto не дал вывода, остановился спросить вас |
{"type":"auto","evaluated_permission":{"type":"deny","reason_code":"high_risk"}} |
deny | auto оценил как высокий риск, уже отказал |
reason_code нужен клиенту для ветвления и журнала аудита, это не текст для человека. Сейчас в документации названы indeterminate и high_risk. Клиент должен пережить будущие новые type или reason_code.
В двух случаях нет evaluation. Agent вызвал инструмент, который в сессии не включён: в событии только evaluated_permission: "deny". Старых событий, записанных до появления поля, тоже нет: тогда allow читали как always_allow, ask — как always_ask.
Это тот же слой, что «JSON — граница безопасности», но разрез другой. Там arguments модели сначала надо проверить; здесь платформа сама пишет результат оценки, и его не перевернуть. Предыдущая статья:
AI Agent и граница безопасности JSON.
MCP Tool Call и always_ask по умолчанию
MCP уносит каталог инструментов из вашего репозитория на внешний Server. Server отдаёт tool по JSON-RPC, у каждого tool есть inputSchema. Host кормит каталог модели и превращает её вызов в tools/call. Спецификация:
У Managed Agents к этому отношение по умолчанию осторожное: MCP toolset стоит always_ask. Новый инструмент, добавленный на уже подключённый Server, тихо в вашем приложении не исполнится. Это первая дверь MCP Security на стороне платформы — надёжнее, чем «верить description самого Server».
Менять всё равно можно. Доверяете GitHub MCP и хотите меньше прерываний — смените у этого toolset default_config.permission_policy на always_allow или auto. Меняется «когда исполнять», не «нужно ли ещё проверять Schema».
| Слой | На что отвечает | На что не отвечает |
|---|---|---|
| JSON Schema | Верны ли поля, типы, обязательные ключи и перечисления параметров | Должен ли этот вызов случиться |
| Tool Calling | Какой инструмент выбрала модель и какие arguments заполнила | Исполнит ли Host |
| permission policy | allow / ask / deny для этого вызова | Совпадает ли payload со schema, увела ли description модель |
Три слоя вместе похожи на дверь. Включить только auto, а Schema оставить {"sql":{"type":"string"}} — вход для оценщика слишком широк, чтобы судить, больше вызовов падают в indeterminate, то есть ask. Сжать schema — помочь auto вынести вывод, который можно записать в лог. Кто за какой слой отвечает:
Безопасность MCP: почему Schema, Tool Calling и права не заменяют друг друга.
JSON-поток одобрения после ask
Вызов со статусом ask может прийти только из always_ask или из auto со статусом indeterminate. Дальше порядок событий фиксирован.
-
1
Сначала событие tool_use
Сессия отдаёт
agent.tool_useилиagent.mcp_tool_use, внутри уже естьevaluated_permission: "ask". -
2
Затем idle
Сессия на паузе: у
session.status_idleполеstop_reason.typeравноrequires_action. id заблокированных событий — вstop_reason.event_ids. Она будет ждать. -
3
Вы отвечаете событием подтверждения
На каждый заблокированный id отправьте
user.tool_confirmation: вtool_use_id— id того события, вresult—allowилиdeny. При отказеdeny_messageможет объяснить. В одном запросе может быть несколько подтверждений. -
4
Сессия снова running
Когда все блокировки сняты, разрешённые инструменты исполняются; отклонённые не бегут, Agent получает tool result с вашим
deny_message.
{
"events": [
{
"type": "user.tool_confirmation",
"tool_use_id": "sevt_01ask...",
"result": "allow"
},
{
"type": "user.tool_confirmation",
"tool_use_id": "sevt_01mcp...",
"result": "deny",
"deny_message": "Do not push to main from this session."
}
]
}
Если evaluated_permission события не ask, повторное подтверждение даст 400. Сюда входят вызовы, которые auto уже пометил deny: у клиента нет канала на пересмотр. Интерактивно можно через ant beta:sessions connect: в терминале видны ожидающие вызовы, их можно разрешить или отклонить.
Свою очередь одобрения, запись deny обратно в Agent и воспроизводимую стратегию в Host оставим статье про реализацию. Здесь только тот JSON, который платформа уже оценила за вас.
auto — не контрольная точка
В документации есть фраза, которую нельзя пропускать: auto — не человеческая контрольная точка. Если сервер считает вызов безопасным, он исполнится до того, как кто-то его увидит; эффект может быть необратим. Инструменту, который должен видеть человек, ставьте always_ask.
Пользовательские инструменты тоже не в этих воротах. У agent.custom_tool_use нет ни evaluated_permission, ни evaluation. Ваше приложение получает событие, само решает исполнить или отказать и отвечает user.custom_tool_result. Платформа этот прыжок за вас не оценит.
Поэтому фраза «как AI Agent сам решает, разрешён ли Tool Call» узкая: только инструменты Agent и MCP, которые исполняет сервер, и только после того, как вы явно записали policy как auto. Остальное либо всегда можно, либо всегда спрашивать, либо платформе вообще не принадлежит.
Сверить стратегию и события в JSONNote
JSON стратегии, событие tool_use и запрос подтверждения внешне похожи, поля — с разных слоёв. При отладке не сканируйте глазами.
-
1
Сначала отформатировать стратегию
Конфиг
toolsу Agent бросьте в форматтер JSON и убедитесь, чтоdefault_configиconfigsнесутpermission_policy.typeбез опечатки и не съеденный перекрытием. -
2
Затем проверить форму события
Через JSON Schema напишите минимальную schema для
evaluation:typeперечисляетalways_allow/always_ask/auto; при auto требуйте вложенныйevaluated_permission. Неизвестныйreason_codeсовместите черезadditionalProperties, не отсекайте сразу. -
3
Сравнить два вызова
Когда один инструмент один раз разрешили, другой раз отказали, через JSON Diff выровняйте два
inputи дваevaluation. Разница почти всегда в command, path или только что случившемся шаге сессии, не в имени инструмента. -
4
Оставить разбор, которым можно поделиться
Стратегию и замаскированные события коллеге можно передать через Hash-шаринг: данные не идут на сервер. Ключи и промышленные token туда не кладите.
FAQ
Пропустит ли auto все Tool Call?
Нет. auto оценивает каждый вызов: два вызова одного инструмента с разным input и сессией могут разойтись. high_risk даёт прямой deny; клиент не отменит его через user.tool_confirmation.
Законный JSON Schema уже значит «можно исполнять»?
Нет. Schema отвечает только, верна ли форма параметров. permission policy отвечает, можно ли этому вызову бежать. Законная по форме команда bash под auto всё равно может выйти deny.
Какая стратегия у MCP Tool Call по умолчанию?
У MCP toolset по умолчанию always_ask. Новый инструмент, добавленный на Server, сам в вашем приложении не исполнится. Когда Server уже доверен, смените default_config.permission_policy на always_allow или auto.
Попадают ли пользовательские инструменты под permission policy?
Нет. Custom tools исполняет ваше приложение. Событие — agent.custom_tool_use, без evaluated_permission и evaluation. Вы сами решаете, бежать или нет, затем отвечаете user.custom_tool_result.
Может ли auto заменить ручное одобрение?
Нет. В документации прямо: auto — не человеческая контрольная точка. Если сервер считает вызов безопасным, он исполнится до того, как кто-то его увидит; побочные эффекты могут быть необратимы. Инструмент, который должен видеть человек, отдельно ставьте в always_ask.
Итог
Добавленный 10 сентября auto сменил «можно ли пользоваться этим инструментом» на «можно ли бежать этому вызову». Опора — JSON policy, которую вы записали в Agent, плюс инструмент, input и сессия этого вызова; результат возвращается в evaluated_permission и evaluation события.
Модель предлагает вызов. Движок стратегии разрешает, отказывает или останавливается спросить человека. MCP по умолчанию сначала спрашивает. Пользовательские инструменты — ваши. Клиент не отменяет deny.
Читайте JSON стратегии и JSON события как два договора. Законный Schema — ещё не разрешение. Инструменты, которые должен смотреть человек, оставляйте в always_ask; тем, кому нужно меньше прерываний и при этом поля аудита, открывайте auto.
Разобрать стратегию и события tool_use