Skip to main content

Tools Commands

See Tools module docs for permissions and data model.

soat create-tool​

Create a tool

  • Method: POST
  • Path: /api/v1/tools

Usage​

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, body_mode and response_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). response_mode is json (default: the body parsed as JSON, else returned as text) or base64, which returns a 2xx body as \{ content_type, filename, data_base64 \} — the same file shape multipart accepts, so a pipeline step can relay a downloaded file. filename comes from Content-Disposition and is omitted when the target names none; a body over TOOL_RESPONSE_MAX_BYTES is 502 TOOL_RESPONSE_TOO_LARGE. 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. A credential slot takes a reference, never a literal: a literal secret_access_key, session_token or credentials under auth, a literal credential-named headers value (Authorization, Cookie, or a name containing api-key/token/secret/password), or a url carrying a password or a literal credential-named query parameter (those names, plus key and sig/signature) is refused with 400 LITERAL_CREDENTIAL, meta.paths naming each one. A stored literal reads back as \{"no_echo": true\} (a url holding one is masked whole), an object rather than a string so a read-edit-write round trip fails the schema check instead of writing the placeholder in as the credential. A value carrying a \{\{secret:...\}\} reference is the wiring, not the credential, and stays readable. 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. A literal credential in headers or url is refused, exactly as in execute.

  • 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. 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. On an mcp tool a preset reaches each action whose input schema declares it; an action whose schema declares no properties receives every one. 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​

soat list-tools

Options​

--project-id​

Project public ID to filter by

  • Source: query
  • Required: no
  • Type: string

soat get-tool​

Get a tool

  • Method: GET
  • Path: /api/v1/tools/{tool_id}

Usage​

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​

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, body_mode and response_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). response_mode is json (default: the body parsed as JSON, else returned as text) or base64, which returns a 2xx body as \{ content_type, filename, data_base64 \} — the same file shape multipart accepts, so a pipeline step can relay a downloaded file. filename comes from Content-Disposition and is omitted when the target names none; a body over TOOL_RESPONSE_MAX_BYTES is 502 TOOL_RESPONSE_TOO_LARGE. 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. A credential slot takes a reference, never a literal: a literal secret_access_key, session_token or credentials under auth, a literal credential-named headers value (Authorization, Cookie, or a name containing api-key/token/secret/password), or a url carrying a password or a literal credential-named query parameter (those names, plus key and sig/signature) is refused with 400 LITERAL_CREDENTIAL, meta.paths naming each one. A stored literal reads back as \{"no_echo": true\} (a url holding one is masked whole), an object rather than a string so a read-edit-write round trip fails the schema check instead of writing the placeholder in as the credential. A value carrying a \{\{secret:...\}\} reference is the wiring, not the credential, and stays readable. 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. A literal credential in headers or url is refused, exactly as in execute.

  • 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. 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. On an mcp tool a preset reaches each action whose input schema declares it; an action whose schema declares no properties receives every one. 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​

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

Options​

--tool-id​

—

  • Source: path
  • Required: yes
  • Type: string
--force​

Delete the tool even when another project has accepted a share of it, revoking those shares, or an ingestion rule converts with it. A decider backend still refuses.

  • Source: query
  • Required: no
  • Type: boolean
  • Default: false

soat call-tool​

Call a tool

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

Usage​

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"\}