# Tools Commands

> See [Tools module docs](../../modules/tools) for permissions and data model.

# Tools Commands

See [Tools module docs](../../modules/tools) for permissions and data model.

### `soat create-tool`

Create a tool

- Method: `POST`
- Path: `/api/v1/tools`

#### Usage

```bash
soat create-tool --name <string>
```

#### Options

##### `--project-id`

Public ID of the project

- Source: `body`
- Required: no
- Type: `string`

##### `--name`

Tool name

- Source: `body`
- Required: yes
- Type: `string`

##### `--type`

Tool type (default http)

- Source: `body`
- Required: no
- Type: `enum("http", "client", "mcp", "builtin", "pipeline")`

##### `--description`

What the tool does

- Source: `body`
- Required: no
- Type: `string`

##### `--parameters`

JSON Schema for tool input

- Source: `body`
- Required: no
- Type: `object`

##### `--execute`

Execution config for http tools. Supported fields: `url` (required), `method` (default `POST`), `headers`, and `body_mode`. The `url` may contain `\{paramName\}` placeholders (e.g. `/users/\{userId\}`) that are replaced at call time with the corresponding tool argument value (URL-encoded). Arguments consumed as path parameters are excluded from the query string and request body. `body_mode` is `json` (default) or `multipart`. In `multipart` mode the merged tool arguments are sent as a `multipart/form-data` body: scalar fields become plain form fields and a field shaped like `\{ content_type, filename, data_base64 \}` is decoded from base64 and attached as a file part (the hardcoded `Content-Type: application/json` is dropped so `fetch` sets the multipart boundary itself).  `auth` adds a computed request credential, for targets whose `Authorization` value cannot be expressed as a static header. Supported `auth.type` values:  - `aws_sigv4` — signs the request with AWS Signature Version 4. Requires `region`, `service`, `access_key_id` and `secret_access_key`; `session_token` is optional (temporary credentials). Incompatible with `body_mode: multipart`, whose body bytes are not known at signing time. - `gcp_service_account` — mints a Google OAuth 2.0 access token from a signed service account assertion and sends it as a bearer token. Requires `credentials` (the service account key file JSON, as a string) and `scopes` (a non-empty array). Tokens are cached per service account and scope set until shortly before they expire.  Credential fields accept `\{\{secret:...\}\}` references and should use them — a tool is readable by anyone who can `GET /tools`, and the stored reference is what is echoed back, never the resolved value.  `headers` values additionally accept `\{\{context:<key>\}\}` references, resolved per call from the caller's `tool_context`, so a per-user credential can be placed in the real header the target expects (`Authorization: Bearer \{\{context:ocaToken\}\}`) instead of only in an `X-Soat-Context-<key>` header. Valid **only** inside `headers` — a context value is caller-supplied, so it may not steer the `url` — and a key missing from the `tool_context` at call time fails the tool call with `MISSING_TOOL_CONTEXT_KEY` rather than sending an empty credential. See the Tool Context reference. 

- Source: `body`
- Required: no
- Type: `object`

##### `--mcp`

MCP server config (`url`, `headers`). `headers` values accept `\{\{secret:...\}\}` and `\{\{context:<key>\}\}` references, resolved right before the outbound MCP request; `url` accepts `\{\{secret:...\}\}` only.

- Source: `body`
- Required: no
- Type: `object`

##### `--actions`

Allowlist of actions. For `builtin` tools: SOAT platform action names (required). For `mcp` tools: an optional allowlist of MCP tool names to scope the server surface — omit or set `null` to expose every tool the MCP server offers. Ignored for other tool types.

- Source: `body`
- Required: no
- Type: `array<string>`

##### `--denied-actions`

For `mcp` tools: an optional denylist of MCP tool names to hide. Applied after `actions` and taking precedence over it. Use it to scope a read+write MCP server read-only by denying just the write tools. Omit or set `null` to deny nothing. Ignored for other tool types.

- Source: `body`
- Required: no
- Type: `array<string>`

##### `--context-keys`

Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Soat-Context-<key>` by default). When `null` or omitted, every key in the caller's `tool_context` is forwarded — the behavior of every tool created before this field existed. When set, only the listed keys are, so a per-user credential in `tool_context` can be confined to the tools that need it; `[]` forwards none. The server-pinned identity keys (`session_id`, `actor_id`, `actor_external_id`) are always forwarded. A key consumed by a `\{\{context:<key>\}\}` token in this tool's own headers is substituted regardless of this list — the tool declared that header itself.

- Source: `body`
- Required: no
- Type: `array<string>`

##### `--preset-parameters`

Fixed parameters pinned on every call this tool makes, whatever its type. Keys matching fields in the input schema are removed from the schema shown to the model, and a pinned value wins over one the model or a direct caller supplies for the same key.  Values accept `\{\{context:<key>\}\}` references, resolved per call from the caller's `tool_context`, so a pin can be the run's own value — the one account this run may act on — rather than one fixed when the tool was created. A resolved value is retyped to the parameter's declared schema type; a key missing from the call's `tool_context` fails the call with `MISSING_TOOL_CONTEXT_KEY` rather than sending the literal placeholder. `\{\{secret:...\}\}` is not resolved here. See the Tool Context reference.

- Source: `body`
- Required: no
- Type: `object`

##### `--pipeline`

Pipeline definition for `pipeline` tools. See the `pipeline` field on the Tool schema for the full structure.

- Source: `body`
- Required: no
- Type: `object`

##### `--output-mapping`

Universal JSON Logic mapping applied to the tool's raw result. See the `output_mapping` field on the Tool schema for details.

- Source: `body`
- Required: no
- Type: `object`

##### `--guardrail-ids`

Guardrails attached at the tool scope.

- Source: `body`
- Required: no
- Type: `array<string>`

### `soat list-tools`

List tools

- Method: `GET`
- Path: `/api/v1/tools`

#### Usage

```bash
soat list-tools
```

#### Options

##### `--project-id`

Project public ID to filter by

- Source: `query`
- Required: no
- Type: `string`

##### `--limit`

Maximum number of results to return

- Source: `query`
- Required: no
- Type: `integer`
- Default: `50`

##### `--offset`

Number of results to skip

- Source: `query`
- Required: no
- Type: `integer`
- Default: `0`

### `soat get-tool`

Get a tool

- Method: `GET`
- Path: `/api/v1/tools/{tool_id}`

#### Usage

```bash
soat get-tool --tool-id <string>
```

#### Options

##### `--tool-id`

—

- Source: `path`
- Required: yes
- Type: `string`

### `soat update-tool`

Update a tool

- Method: `PATCH`
- Path: `/api/v1/tools/{tool_id}`

#### Usage

```bash
soat update-tool --tool-id <string>
```

#### Options

##### `--tool-id`

—

- Source: `path`
- Required: yes
- Type: `string`

##### `--name`

—

- Source: `body`
- Required: no
- Type: `string`

##### `--type`

—

- Source: `body`
- Required: no
- Type: `enum("http", "client", "mcp", "builtin", "pipeline")`

##### `--description`

—

- Source: `body`
- Required: no
- Type: `string \| null`

##### `--parameters`

—

- Source: `body`
- Required: no
- Type: `object`

##### `--execute`

Execution config for http tools. Supported fields: `url` (required), `method` (default `POST`), `headers`, and `body_mode`. The `url` may contain `\{paramName\}` placeholders (e.g. `/users/\{userId\}`) that are replaced at call time with the corresponding tool argument value (URL-encoded). Arguments consumed as path parameters are excluded from the query string and request body. `body_mode` is `json` (default) or `multipart`. In `multipart` mode the merged tool arguments are sent as a `multipart/form-data` body: scalar fields become plain form fields and a field shaped like `\{ content_type, filename, data_base64 \}` is decoded from base64 and attached as a file part (the hardcoded `Content-Type: application/json` is dropped so `fetch` sets the multipart boundary itself).  `auth` adds a computed request credential, for targets whose `Authorization` value cannot be expressed as a static header. Supported `auth.type` values:  - `aws_sigv4` — signs the request with AWS Signature Version 4. Requires `region`, `service`, `access_key_id` and `secret_access_key`; `session_token` is optional (temporary credentials). Incompatible with `body_mode: multipart`, whose body bytes are not known at signing time. - `gcp_service_account` — mints a Google OAuth 2.0 access token from a signed service account assertion and sends it as a bearer token. Requires `credentials` (the service account key file JSON, as a string) and `scopes` (a non-empty array). Tokens are cached per service account and scope set until shortly before they expire.  Credential fields accept `\{\{secret:...\}\}` references and should use them — a tool is readable by anyone who can `GET /tools`, and the stored reference is what is echoed back, never the resolved value.  `headers` values additionally accept `\{\{context:<key>\}\}` references, resolved per call from the caller's `tool_context`, so a per-user credential can be placed in the real header the target expects (`Authorization: Bearer \{\{context:ocaToken\}\}`) instead of only in an `X-Soat-Context-<key>` header. Valid **only** inside `headers` — a context value is caller-supplied, so it may not steer the `url` — and a key missing from the `tool_context` at call time fails the tool call with `MISSING_TOOL_CONTEXT_KEY` rather than sending an empty credential. See the Tool Context reference. 

- Source: `body`
- Required: no
- Type: `object`

##### `--mcp`

MCP server config (`url`, `headers`). `headers` values accept `\{\{secret:...\}\}` and `\{\{context:<key>\}\}` references, resolved right before the outbound MCP request; `url` accepts `\{\{secret:...\}\}` only.

- Source: `body`
- Required: no
- Type: `object`

##### `--actions`

Allowlist of actions. For `builtin` tools: SOAT platform action names. For `mcp` tools: an optional allowlist of MCP tool names to scope the server surface (`null` exposes every tool). Ignored for other tool types.

- Source: `body`
- Required: no
- Type: `array<string>`

##### `--denied-actions`

For `mcp` tools: an optional denylist of MCP tool names to hide. Applied after `actions` and taking precedence over it. Use it to scope a read+write MCP server read-only by denying just the write tools. `null` denies nothing. Ignored for other tool types.

- Source: `body`
- Required: no
- Type: `array<string>`

##### `--context-keys`

Optional allowlist of `tool_context` keys that may be forwarded to this tool as prefixed context headers (`X-Soat-Context-<key>` by default). When `null` or omitted, every key in the caller's `tool_context` is forwarded — the behavior of every tool created before this field existed. When set, only the listed keys are, so a per-user credential in `tool_context` can be confined to the tools that need it; `[]` forwards none. The server-pinned identity keys (`session_id`, `actor_id`, `actor_external_id`) are always forwarded. A key consumed by a `\{\{context:<key>\}\}` token in this tool's own headers is substituted regardless of this list — the tool declared that header itself.

- Source: `body`
- Required: no
- Type: `array<string>`

##### `--preset-parameters`

Fixed parameters pinned on every call this tool makes, whatever its type. Keys matching fields in the input schema are removed from the schema shown to the model, and a pinned value wins over one the model or a direct caller supplies for the same key.  Values accept `\{\{context:<key>\}\}` references, resolved per call from the caller's `tool_context`, so a pin can be the run's own value — the one account this run may act on — rather than one fixed when the tool was created. A resolved value is retyped to the parameter's declared schema type; a key missing from the call's `tool_context` fails the call with `MISSING_TOOL_CONTEXT_KEY` rather than sending the literal placeholder. `\{\{secret:...\}\}` is not resolved here. See the Tool Context reference.

- Source: `body`
- Required: no
- Type: `object`

##### `--pipeline`

Pipeline definition for `pipeline` tools. See the `pipeline` field on the Tool schema for the full structure.

- Source: `body`
- Required: no
- Type: `object`

##### `--output-mapping`

Universal JSON Logic mapping applied to the tool's raw result. See the `output_mapping` field on the Tool schema for details.

- Source: `body`
- Required: no
- Type: `object`

##### `--guardrail-ids`

Guardrails attached at the tool scope.

- Source: `body`
- Required: no
- Type: `array<string>`

### `soat delete-tool`

Delete a tool

- Method: `DELETE`
- Path: `/api/v1/tools/{tool_id}`

#### Usage

```bash
soat delete-tool --tool-id <string>
```

#### Options

##### `--tool-id`

—

- Source: `path`
- Required: yes
- Type: `string`

### `soat call-tool`

Call a tool

- Method: `POST`
- Path: `/api/v1/tools/{tool_id}/call`

#### Usage

```bash
soat call-tool --tool-id <string>
```

#### Options

##### `--tool-id`

—

- Source: `path`
- Required: yes
- Type: `string`

##### `--action`

For `builtin` tools: the action name (must be in the tool's `actions` list). For `mcp` tools: the MCP tool name to invoke (must be in the tool's `actions` allowlist when one is set, and must not be in its `denied_actions` denylist). Ignored for `http` tools. 

- Source: `body`
- Required: no
- Type: `string`

##### `--input`

Input parameters for the tool call. These are merged with the tool's `preset_parameters` before execution; a preset value wins over the same key sent here. 

- Source: `body`
- Required: no
- Type: `object<string, unknown>`

##### `--tool-context`

Key/value context for this call, forwarded to the tool as `X-Soat-Context-<key>` request headers and resolving any `\{\{context:<key>\}\}` token in the tool's `execute.headers`, `mcp.headers` or `preset_parameters`. Narrowed by the tool's `context_keys` allowlist when it sets one. This route has no session, so it stamps no server-derived identity: the reserved keys `session_id`, `actor_id` and `actor_external_id` are dropped from this bag (in any casing) rather than forwarded, so a downstream tool can still trust that a context header naming one is server-derived. Every other key becomes an HTTP header name and must match that grammar, or the call fails with `INVALID_TOOL_CONTEXT_KEY`. 

- Source: `body`
- Required: no
- Type: `object<string, string>`
- Example: `\{"tenantId":"acme","userToken":"tok_abc123"\}`
