Skip to main content
Tools are functions the Ekanos assistant (and, where the host allows it, the workflow engine) can call. Each tool declares a name, a description the model reads, an optional parameter schema, and an async run.

Basic tool

Handler behavior

Success

Return a plain JSON-serializable value:

Expected failure (user-facing)

Return { error: '…' }. The model reads this and explains it to the user:

Genuine fault (throw)

Throw for a genuine fault rather than returning { error }:
PublicActionError from @ekanos/sdk/integration belongs to actions (widget-invoked handlers called through useIntegrationAction()), not tools. An action handler’s throw is, by default, collapsed to a generic "Action failed." response under the handler_error code; throwing PublicActionError surfaces its message to the user verbatim instead.

Parameters

Parameters are a narrow slice of JSON Schema — only the wrapper is restricted, not the contents:
Valid at root: type (must be 'object'), properties, required, additionalProperties Invalid at root: title, description, $schema, oneOf, anything other than the four above Inside properties, you are unconstrained — nested objects, arrays, enums, descriptions all pass.

Tool naming

Tool names are ^[a-z][a-z0-9_]*$ — lowercase snake_case:
  • ✅ Valid: list_payments, get_customer, refund_payment
  • ❌ Invalid: ListPayments, list-payments, list payments
The effective name the assistant sees is namespaced by your slug. acme-payments + list_payments becomes acme_payments_list_payments (hyphens → underscores). If you declare acme_payments_list_payments as the raw name, the effective name stays the same (no double prefix). Collisions across two integrations in the same platform are detected and rejected.

Output example

Small, honest examples of what the tool returns. Used by the model as a shape hint:
Keep it short. The model uses it to understand the shape, not to hallucinate realistic data.

Common patterns

Read data

Perform an action

Testing

Use createMockContext() to test tools:

Troubleshooting

Tool not appearing in assistant

Check:
  • Tool name matches ^[a-z][a-z0-9_]*$
  • No duplicate names in your tools array
  • proposes.credentialModel is declared if the tool is for a workflow
  • The integration is activated on the account

defineIntegration() rejects your parameters

Your parameters object has a key other than type, properties, required, or additionalProperties at the root (title, description, $schema, …), or a root type other than 'object'. The root is .strict(), so the error points at tools.<index>.parameters. Remove the key, or move a description into the relevant property schema.

Next steps