ブログ • AI / Agent

Claude Managed Agents 2026 の新機能:AI Agent はどう Tool Call の許否を自動判定するのか?JSON 権限ポリシーと MCP Security

2026 年 9 月 10 日、Anthropic は Claude Managed Agents の権限ポリシーに新しい型を足した:auto。同じ日、agent.tool_use と agent.mcp_tool_use イベントは evaluation フィールドを載せ始め、従来の evaluated_permission と並ぶ。

モデルが Tool Call を出すことは、その呼び出しが実行されることではない。本当に決めるのはサーバ上のポリシー評価だ。Agent 設定に書いた JSON policy を読み、この1回のツール名、入力、セッション内容に allow、deny、または ask を出す。

本稿では次を扱う:

まずこれだけ:auto は「全部許可」でも人手の承認でもない。サーバが安全と見なせば、あなたが見る前に走り切る。高リスクと見なせば、クライアントは deny を覆す機会すら無い。以下、「三つのポリシー → 1回ごとの評価 → イベント 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 この1回を評価する:走らせる、拒む、または止まって聞く 結果が 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 は判断をツール単位から呼び出し単位へ移す。

公式の書き方は具体的だ。評価はツールそのもの、この1回の input、これまでのセッションを見る。だから同じ bash でも、二つの違う command なら、一方は allow、一方は deny になりうる。

  1. 1
    呼び出しは通る

    サーバはこの回を安全と見なし、ツールは always_allow と同じように実行する。停止も、人の確認枠も無い。

  2. 2
    呼び出しは拒否される

    サーバは高リスクと評し、ツールは走らない。Agent はエラーの tool result を受ける:Permission to use {tool_name} has been denied.、かつ is_error: true。セッションは続く。クライアントはこの deny を変えられない。

  3. 3
    呼び出しは止まってあなたを待つ

    サーバは確定した結論を出せない。セッションは always_ask と同じように一時停止する。確認イベントで通すか拒む。

意図は、あなたが出した user.message からのみ読む。ツール結果、取得したページ、MCP Server の戻り、スレッド間のメッセージは内容として評価するが、指示にはしない。誰が口を開いても高リスクと評される呼び出しがある。

信頼できない末端ユーザーの原文をそのまま user.message に入れると、サーバはそれをあなたの意図として扱い、呼び出しを通すことがある。その入口のツールには、単独で always_ask を付ける。

ポリシーは JSON のどこに書くか

ポリシーは二箇所に出る。toolset の default_config.permission_policy、および configs 内のあるツールへの上書き。下の設定は Agent toolset と GitHub MCP をどちらも auto にし、bash だけを always_ask に固定する。

Agent 作成時の tools 設定(公式ドキュメントからの抜粋)
{
  "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 を通り、高リスクの1回が拒まれる。

auto に拒否された agent.tool_use イベント
{
  "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 は JSON-RPC で tool を出し、各 tool は inputSchema を持つ。Host は一覧をモデルに渡し、モデルの呼び出しを tools/call に変える。仕様は

MCP Tools。

Managed Agents の既定の態度は保守的だ。MCP toolset の既定は always_ask。すでに接続した Server に新しいツールが足されても、あなたのアプリでは静かに実行されない。これはプラットフォーム側に落とせる MCP Security の第一の門であり、「Server 自身の description を信じる」より硬い。

それでも変えられる。ある 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、権限はなぜ互いに代われないか。

ask のあとの JSON 承認フロー

呼び出しが ask になるのは always_ask、または auto の indeterminate のときだけだ。あとのイベント順は固定されている。

  1. 1
    先に tool_use イベント

    セッションは agent.tool_use または agent.mcp_tool_use を出し、すでに evaluated_permission: "ask" が入っている。

  2. 2
    それから idle

    セッションは一時停止し、session.status_idle の stop_reason.type は requires_action。塞がれたイベント id は stop_reason.event_ids にある。待ち続ける。

  3. 3
    確認イベントを返す

    ブロックされた各 id に user.tool_confirmation を送り、tool_use_id にそのイベント id を、result に allow または deny を入れる。拒否するときは deny_message で説明できる。一つのリクエストに複数の確認を載せられる。

  4. 4
    セッションは running に戻る

    すべてのブロックが解けたあと、許されたツールは実行される。拒まれたものは走らず、Agent はあなたの deny_message を載せた tool result を受ける。

待ち中の呼び出しを許可または拒否する
{
  "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 でなければ、確認を送っても API は 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 ツールだけであり、しかもポリシーを明示的に auto と書いたあとだけだ。残りは常に通すか、常に人に聞くか、そもそもプラットフォームの管轄外だ。

JSONNote でポリシーとイベントを照合する

ポリシー JSON、tool_use イベント、確認リクエストは形が似ている。フィールドは同じ層ではない。目で流してデバッグしない。

  1. 1
    先にポリシーを整形する

    Agent の tools 設定を JSON フォーマット に入れ、default_config と configs 内の permission_policy.type が書き間違っておらず、上書きに食われていないかを確認する。

  2. 2
    それからイベントの形を検証する

    JSON Schema で evaluation の最小 schema を書く。type の列挙は always_allow / always_ask / auto。auto のときは入れ子の evaluated_permission を必須にする。未知の reason_code は additionalProperties で互換し、即座に拒まない。

  3. 3
    二回の呼び出しを比べる

    同じツールが一方で通り一方で拒まれたとき、JSON Diff で二回の input と二回の evaluation を揃える。差はほぼ常に command、path、またはセッションで直前に起きた一歩にあり、ツール名には無い。

  4. 4
    共有できる振り返りを残す

    ポリシーとマスクしたイベントは Hash 共有 で同僚に渡せる。データはサーバを通らない。鍵と本番 token は入れない。

よくある質問

auto はすべての Tool Call を通すのか?

通さない。auto は1回ごとの評価だ。同じツールでも入力とセッションが違えば、結果は違ってよい。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 を付ける。

まとめ

9 月 10 日に足された auto は、「このツールを使ってよいか」を「この1回が走ってよいか」に変えた。判断の根拠は、Agent に書いた JSON policy に、この1回のツール、入力、セッションを足したものだ。判断結果はイベントの evaluated_permission と evaluation に書き戻される。

モデルは呼び出しを出す。ポリシーエンジンは許可し、拒否し、または止まって人に聞く。MCP の既定は先に聞く。カスタムツールは自分で見る。クライアントは deny を覆せない。

ポリシー JSON とイベント JSON を二つの契約として読む。Schema として合法なことを、すでに認可されたことと取り違えない。人が見張るべきツールは always_ask のまま。中断を減らし、監査フィールドも残したいツールに、auto を開ける。

← ブログに戻る