# Agents

> MCP tools for the Agents module. See the [Agents module docs](/docs/modules/agents) for permissions and data model.

# Agents

MCP tools for the Agents module. See the [Agents module docs](/docs/modules/agents) for permissions and data model.

### `create-agent`

Create an agent

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `project_id` | `string` | no | Public ID of the project |
| `ai_provider_id` | `string` | no | Public ID of the AI provider to pin. Mutually exclusive with `model_route_id`. |
| `model_route_id` | `string` | no | Public ID of a model route in the same project. The agent's completion model is then resolved through the route's ordered targets with failover. Mutually exclusive with `ai_provider_id` and `model`. |
| `name` | `string` | no | — |
| `instructions` | `string` | no | — |
| `model` | `string` | no | — |
| `tool_bindings` | `array<object>` | no | Tools to attach, one binding object per tool — the only attachment field. An entry is either a reference (`{ "tool_id": … }`) or an inline definition (`{ "tool": … }`). See [Tool Bindings](/docs/modules/agents#tool-bindings). |
| `max_steps` | `number` | no | — |
| `tool_choice` | `any` | no | Tool choice strategy. Accepts a string (`"auto"`, `"required"`) or an object (`{ "type": "tool", "tool_name": "my_tool" }`). A forcing value (`"required"` or the object form) forbids a final assistant message on every step of every turn, including a resumed or continued one, so it requires a `has_tool_call` entry in `stop_conditions` — otherwise the write is refused with `FORCED_TOOL_CHOICE_CANNOT_STOP`. |
| `stop_conditions` | `array<object>` | no | Conditions that end the agent's work early, on top of `max_steps`. Two scopes: `{"type": "has_tool_call", "tool_name": "<resolved tool name>"}` ends the **turn** after the step that calls the named tool. It narrows when the loop ends — it never lets it run past `max_steps`. `{"type": "max_chain_generations", "max_generations": <n>}` bounds the **continuation chain** instead: once the chain has spawned that many generations, further resumptions stop with `chain_limit` rather than extending it. It never shortens a turn. The effective ceiling is the smaller of this and the deployment's `MAX_CONTINUATION_CHAIN_GENERATIONS`, so an agent can be stricter than the platform but never looser. An unknown `type`, a `has_tool_call` without a `tool_name`, a `max_chain_generations` whose `max_generations` is not a positive integer, or a non-object entry is rejected with 400. |
| `active_tool_ids` | `array<string>` | no | — |
| `guardrail_ids` | `array<string> \| null` | no | Guardrails attached at the agent scope. |
| `step_rules` | `array<object>` | no | — |
| `boundary_policy` | `object` | no | — |
| `temperature` | `number` | no | — |
| `knowledge_config` | `object` | no | — |
| `output_schema` | `object \| null` | no | JSON Schema describing the structured object the model must return. When set, non-streaming generations constrain output to this schema and the parsed value is returned as `output.object`. The schema is enforced on the way back, not just sent to the model: an object that violates it fails the generation with 502 `OUTPUT_SCHEMA_VALIDATION_FAILED`, naming the violated field. Constraints beyond `required`/`type` (`minLength`, `enum`, `pattern`, `minItems`) are honored and are what reject a structurally valid but degenerate answer. See the Structured Output section in the Agents module docs. |
| `max_context_messages` | `number` | no | Maximum number of recent messages included in the context window. Null means no limit. |
| `single_session_per_actor` | `boolean` | no | When true, only one open session per actor_id is allowed for this agent. |
| `trace_content_mode` | `string \| null` | no | Zero-retention opt-in for this agent. `null` inherits the project's setting; `none` means trace and generation content is never written. Setting `full` under a project whose own mode is `none` is refused with 400 — the project is a floor an agent may only tighten. |
| `on_approval_expiry` | `string \| null` | no | What happens when one of this agent's held tool calls expires un-approved. `null` (the default) and `terminate` end the chain there — the expired approval, its `approvals.expired` event and the auto-filed `approval_expired` exception are the whole record. `react` spawns a continuation that reports the staleness to the agent, for an agent that acts on it. |
| `version_label` | `string \| null` | no | Optional tag for the config version this write archives (e.g. `initial`). Annotates the version only — it is not stored on the agent and is not part of the config, so labelling a change is never itself a change. |

### `list-agents`

List agents

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `project_id` | `string` | no | Project public ID to filter by |
| `limit` | `number` | no | Maximum number of results to return |
| `offset` | `number` | no | Number of results to skip |

### `get-agent`

Get an agent

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |

### `update-agent`

Update an agent

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |
| `ai_provider_id` | `string \| null` | no | — |
| `model_route_id` | `string \| null` | no | Model route in the same project. Mutually exclusive with `ai_provider_id` and `model`; set to null to clear. |
| `name` | `string \| null` | no | — |
| `instructions` | `string \| null` | no | — |
| `model` | `string \| null` | no | — |
| `tool_bindings` | `array<object> \| null` | no | Tools attached to the agent — the only attachment field. Replaces the whole binding list; set to `null` to clear. See [Tool Bindings](/docs/modules/agents#tool-bindings). |
| `max_steps` | `number \| null` | no | — |
| `tool_choice` | `any \| null` | no | Tool choice strategy. Accepts a string (`"auto"`, `"required"`) or an object (`{ "type": "tool", "tool_name": "my_tool" }`). A forcing value (`"required"` or the object form) forbids a final assistant message on every step of every turn, including a resumed or continued one, so it requires a `has_tool_call` entry in `stop_conditions` — otherwise the write is refused with `FORCED_TOOL_CHOICE_CANNOT_STOP`. |
| `stop_conditions` | `array<object> \| null` | no | Conditions that end the agent's work early, on top of `max_steps`. Two scopes: `{"type": "has_tool_call", "tool_name": "<resolved tool name>"}` ends the **turn** after the step that calls the named tool. It narrows when the loop ends — it never lets it run past `max_steps`. `{"type": "max_chain_generations", "max_generations": <n>}` bounds the **continuation chain** instead: once the chain has spawned that many generations, further resumptions stop with `chain_limit` rather than extending it. It never shortens a turn. The effective ceiling is the smaller of this and the deployment's `MAX_CONTINUATION_CHAIN_GENERATIONS`, so an agent can be stricter than the platform but never looser. An unknown `type`, a `has_tool_call` without a `tool_name`, a `max_chain_generations` whose `max_generations` is not a positive integer, or a non-object entry is rejected with 400. |
| `active_tool_ids` | `array<string> \| null` | no | — |
| `guardrail_ids` | `array<string> \| null` | no | Guardrails attached at the agent scope. |
| `step_rules` | `array<object> \| null` | no | — |
| `boundary_policy` | `object \| null` | no | — |
| `temperature` | `number \| null` | no | — |
| `knowledge_config` | `object \| null` | no | — |
| `output_schema` | `object \| null` | no | JSON Schema describing the structured object the model must return. When set, non-streaming generations constrain output to this schema and the parsed value is returned as `output.object`. The schema is enforced on the way back, not just sent to the model: an object that violates it fails the generation with 502 `OUTPUT_SCHEMA_VALIDATION_FAILED`, naming the violated field. Constraints beyond `required`/`type` (`minLength`, `enum`, `pattern`, `minItems`) are honored and are what reject a structurally valid but degenerate answer. See the Structured Output section in the Agents module docs. |
| `max_context_messages` | `number \| null` | no | Maximum number of recent messages included in the context window. Null means no limit. |
| `single_session_per_actor` | `boolean \| null` | no | When true, only one open session per actor_id is allowed for this agent. |
| `trace_content_mode` | `string \| null` | no | Zero-retention opt-in for this agent. `null` inherits the project's setting; `none` means trace and generation content is never written. Setting `full` under a project whose own mode is `none` is refused with 400. |
| `on_approval_expiry` | `string \| null` | no | What happens when one of this agent's held tool calls expires un-approved. `null` (the default) and `terminate` end the chain there — the expired approval, its `approvals.expired` event and the auto-filed `approval_expired` exception are the whole record. `react` spawns a continuation that reports the staleness to the agent, for an agent that acts on it. |
| `version_label` | `string \| null` | no | Optional tag for the config version this write archives (e.g. `pre-tone-change`). Annotates the version only — it is not stored on the agent and is not part of the config, so labelling a change is never itself a change. Ignored when the write changes nothing, since no version is created. |

### `patch-agent`

Partially update an agent

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |
| `ai_provider_id` | `string \| null` | no | — |
| `model_route_id` | `string \| null` | no | Model route in the same project. Mutually exclusive with `ai_provider_id` and `model`; set to null to clear. |
| `name` | `string \| null` | no | — |
| `instructions` | `string \| null` | no | — |
| `model` | `string \| null` | no | — |
| `tool_bindings` | `array<object> \| null` | no | Tools attached to the agent — the only attachment field. Replaces the whole binding list; set to `null` to clear. See [Tool Bindings](/docs/modules/agents#tool-bindings). |
| `max_steps` | `number \| null` | no | — |
| `tool_choice` | `any \| null` | no | Tool choice strategy. Accepts a string (`"auto"`, `"required"`) or an object (`{ "type": "tool", "tool_name": "my_tool" }`). A forcing value (`"required"` or the object form) forbids a final assistant message on every step of every turn, including a resumed or continued one, so it requires a `has_tool_call` entry in `stop_conditions` — otherwise the write is refused with `FORCED_TOOL_CHOICE_CANNOT_STOP`. |
| `stop_conditions` | `array<object> \| null` | no | Conditions that end the agent's work early, on top of `max_steps`. Two scopes: `{"type": "has_tool_call", "tool_name": "<resolved tool name>"}` ends the **turn** after the step that calls the named tool. It narrows when the loop ends — it never lets it run past `max_steps`. `{"type": "max_chain_generations", "max_generations": <n>}` bounds the **continuation chain** instead: once the chain has spawned that many generations, further resumptions stop with `chain_limit` rather than extending it. It never shortens a turn. The effective ceiling is the smaller of this and the deployment's `MAX_CONTINUATION_CHAIN_GENERATIONS`, so an agent can be stricter than the platform but never looser. An unknown `type`, a `has_tool_call` without a `tool_name`, a `max_chain_generations` whose `max_generations` is not a positive integer, or a non-object entry is rejected with 400. |
| `active_tool_ids` | `array<string> \| null` | no | — |
| `guardrail_ids` | `array<string> \| null` | no | Guardrails attached at the agent scope. |
| `step_rules` | `array<object> \| null` | no | — |
| `boundary_policy` | `object \| null` | no | — |
| `temperature` | `number \| null` | no | — |
| `knowledge_config` | `object \| null` | no | — |
| `output_schema` | `object \| null` | no | JSON Schema describing the structured object the model must return. When set, non-streaming generations constrain output to this schema and the parsed value is returned as `output.object`. The schema is enforced on the way back, not just sent to the model: an object that violates it fails the generation with 502 `OUTPUT_SCHEMA_VALIDATION_FAILED`, naming the violated field. Constraints beyond `required`/`type` (`minLength`, `enum`, `pattern`, `minItems`) are honored and are what reject a structurally valid but degenerate answer. See the Structured Output section in the Agents module docs. |
| `max_context_messages` | `number \| null` | no | Maximum number of recent messages included in the context window. Null means no limit. |
| `single_session_per_actor` | `boolean \| null` | no | When true, only one open session per actor_id is allowed for this agent. |
| `trace_content_mode` | `string \| null` | no | Zero-retention opt-in for this agent. `null` inherits the project's setting; `none` means trace and generation content is never written. Setting `full` under a project whose own mode is `none` is refused with 400. |
| `on_approval_expiry` | `string \| null` | no | What happens when one of this agent's held tool calls expires un-approved. `null` (the default) and `terminate` end the chain there — the expired approval, its `approvals.expired` event and the auto-filed `approval_expired` exception are the whole record. `react` spawns a continuation that reports the staleness to the agent, for an agent that acts on it. |
| `version_label` | `string \| null` | no | Optional tag for the config version this write archives (e.g. `pre-tone-change`). Annotates the version only — it is not stored on the agent and is not part of the config, so labelling a change is never itself a change. Ignored when the write changes nothing, since no version is created. |

### `delete-agent`

Delete an agent

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |
| `force` | `boolean` | no | When `true`, deletes the agent's dependent generations and traces instead of returning `409 AGENT_HAS_DEPENDENTS`. |

### `create-agent-generation`

Run an agent generation

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |
| `wait` | `boolean` | no | When omitted or `false` (default), the generation runs in the background and `202 Accepted` is returned immediately with a `generation_id` to poll. Pass `true` to block until the generation settles and receive the result. Mutually exclusive with `stream: true`. A `builtin` tool call always waits. |
| `messages` | `array<object>` | yes | — |
| `stream` | `boolean` | no | When true the response is an SSE stream |
| `tool_context` | `object \| null` | no | Key-value pairs forwarded as `X-Soat-Context-<key>` headers on every `http`, `mcp` and `builtin` tool call in this generation. The header name is the deployment's configured context prefix (`X-Soat-Context-` by default) plus the key verbatim — no character is re-cased. Keys are never case-converted — they round-trip exactly as sent. An invalid or colliding key is rejected with `400 INVALID_TOOL_CONTEXT_KEY`. |
| `action_id` | `string` | no | Logical action label recorded on the generation's usage meter, so spend can be rolled up per action (e.g. an A/B/C/D operating action). |
| `guardrail_context` | `object \| null` | no | Caller-supplied guardrail context (the `context.*` namespace guard and class expressions read at tool-dispatch time). Free-form and never interpreted by the platform; a guardrail may combine it with a `context_tool` per its `context_mode`. See the guardrails module. |
| `metadata` | `object \| null` | no | Caller-supplied key/value metadata attached to the generation record for per-run audit attribution (e.g. the knowledge-corpus version that produced this action). Round-trips verbatim when the generation is fetched via the generations API. The bag is caller-owned and no key is reserved: server-owned state (usage attribution, the served agent version, the model route's record, the extraction summary) lives in its own top-level generation fields and cannot be written from here. Use the request's own `action_id` field to set the usage-attribution label. |
| `extract` | `boolean` | no | Per-turn override of the agent's `knowledge_config.extraction` default. Omit to follow the agent's stored config. Set `false` to suppress automatic memory extraction for this turn (e.g. an operational or tool-listing turn that would only add noise to a curated memory). Set `true` to force extraction on for this turn even when the agent does not enable it by default, provided the agent has a `write_memory_id`. Has no effect on streaming or `requires_action` turns, which never extract. |
| `knowledge_config` | `object \| null` | no | Per-generation knowledge retrieval override. Array filters (memory_ids, memory_tags, document_ids, document_paths) are unioned with the agent's stored knowledge_config; scalar fields (min_score, limit) use the per-generation value when present. |

### `submit-agent-tool-outputs`

Submit tool outputs for a paused generation

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |
| `generation_id` | `string` | yes | — |
| `tool_outputs` | `array<object>` | yes | — |

### `list-agent-versions`

List an agent's config versions

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |
| `limit` | `number` | no | Maximum number of results to return |
| `offset` | `number` | no | Number of results to skip |

### `get-agent-version`

Get an archived agent config version

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |
| `version` | `number` | yes | — |

### `restore-agent-version`

Restore an archived config as a new version

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |
| `version` | `number` | yes | — |
| `label` | `string` | no | Tag for the version this restore creates. Defaults to `restored from v{version}`. |

### `set-agent-release`

Set or replace a staged rollout

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |
| `stable_version` | `number` | yes | An existing version to serve as the baseline |
| `canary_version` | `number` | yes | An existing version to trial. Must differ from `stable_version`. |
| `canary_percent` | `number` | yes | Percentage of traffic to assign to `canary_version` |
| `promotion_gate` | `string \| null` | no | Eval to gate promotion on. It must belong to this project and evaluate this agent; anything else is a `400`. Omit it, or send null, for a rollout that can be promoted at will. |

### `promote-agent-release`

Promote the canary and end the rollout

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |

### `abort-agent-release`

Abort the rollout and roll back to stable

#### Arguments

| Argument | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `agent_id` | `string` | yes | — |
