Skip to main content
Permission policies control what happens when an Agent wants to call a tool. Built-in and MCP tool calls are evaluated as allow, ask, or deny; client-side custom tools always pause so your application can execute them and return the result.

Runtime behavior

When a tool call is projected into the event stream:
EventMeaningKey fields
agent.tool_useBuilt-in tool callid, name, input, evaluated_permission
agent.mcp_tool_useMCP tool callid, name, input, mcp_server_name, evaluated_permission
agent.custom_tool_useClient-side custom tool requestid, name, input
evaluated_permission can be:
ValueBehavior
allowThe platform executes the tool directly
askThe turn pauses and waits for user.tool_confirmation
denyThe platform returns a denied tool result to the Agent
Custom tools do not support permission_policy; they are executed by your client and resolved with user.custom_tool_result.

Configure policies on an agent

Configure built-in and MCP tool permissions inside the Agent tools array:
{
  "tools": [
    {
      "type": "agent_toolset_20260401",
      "enabled_tools": ["Bash", "Read", "Write"],
      "configs": [
        {"name": "Read", "permission_policy": {"type": "always_allow"}},
        {"name": "Write", "permission_policy": {"type": "always_ask"}},
        {"name": "Bash", "permission_policy": {"type": "always_deny"}}
      ]
    },
    {
      "type": "mcp_toolset",
      "mcp_server_name": "weather-service",
      "configs": [
        {"name": "get_forecast", "permission_policy": {"type": "always_ask"}}
      ]
    }
  ]
}
LocationApplies toDescription
tools[].configs[].permission_policyOne named toolPer-tool override. For built-in tools, name is a built-in tool name such as Read; for MCP tools, name is the raw tool name exposed by that MCP server
tools[].configs[].enabledOne named toolSet to false to disable and deny that tool. When using enabled_tools, keep disabled tools out of that allowlist
permission_policy.type values:
ValueRuntime result
always_allowevaluated_permission: "allow"
always_askevaluated_permission: "ask" and the turn waits for user.tool_confirmation
always_denyevaluated_permission: "deny"

Pending action flow

When a tool call needs human or client input:
  1. The stream emits agent.tool_use or agent.custom_tool_use.
  2. The stream emits session.status_idle with stop_reason.type: "requires_action".
  3. stop_reason.event_ids lists the event IDs that need a response.
  4. Your client sends a response event to POST /api/v1/cloud/sessions/{session_id}/events.
  5. The Agent continues the same turn.
{
  "type": "session.status_idle",
  "status": "idle",
  "stop_reason": {
    "type": "requires_action",
    "event_ids": ["evt_01JZ6Q3FB6SG8F7J1M2N"]
  }
}
Pending actions do not automatically time out. They remain pending until your client resolves them or the session/turn is cancelled.

Confirm a tool call

Use the id of the agent.tool_use event as tool_use_id. This is an evt_... event ID, not the model provider’s internal tool-use ID.
curl -X POST https://api.qoder.com/api/v1/cloud/sessions/sess_abc123/events \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "type": "user.tool_confirmation",
        "tool_use_id": "evt_01JZ6Q3FB6SG8F7J1M2N",
        "result": "allow"
      }
    ]
  }'

Complete a custom tool

Custom tools are configured on the Agent with type: "custom"; see Agent Tools. When the Agent requests one, execute it in your application and respond with the agent.custom_tool_use event ID:
curl -X POST https://api.qoder.com/api/v1/cloud/sessions/sess_abc123/events \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "type": "user.custom_tool_result",
        "custom_tool_use_id": "evt_01JZ6R1V9Z8K2M3N4P5Q",
        "content": [{"type": "text", "text": "Order status: shipped"}]
      }
    ]
  }'
The content value can be a string, one text block, or an array of text blocks. The returned event is stored with content-block shape.

FAQ

Q: Can one turn require multiple responses? A: Yes. stop_reason.event_ids may contain multiple event IDs; respond to each pending tool request. Q: Do pending actions time out? A: No. They stay pending until resolved or until the session/turn is cancelled. Q: Can custom tools use permission_policy? A: No. Custom tools are client-side, so the client is responsible for executing or refusing them.

Next steps

Tools

Equip your agent with built-in, MCP, and custom tools.

Session event stream

Stream agent thinking, messages, and tool calls over SSE.

Start a session

Run an agent against an environment.

Agent setup

Review Agent configuration.