Skip to main content
External tools are custom tools that your application runs. The agent can call the tool during a session, but Dari does not execute handler code for it. Instead, Dari emits a tool request and waits for your application to submit the result. Use an external tool when the handler needs to run in your own infrastructure, call private services, or use credentials that should not be available in the session sandbox. Declare the external tool in dari.yml, then put its schemas in a tool directory:
# dari.yml
custom_tools:
  - name: repo_search
    path: tools/repo_search
    kind: external
    timeout_seconds: 60
# tools/repo_search/tool.yml
name: repo_search
description: Search the checked-out repository for matching content.
input_schema: input.schema.json
output_schema: output.schema.json
// tools/repo_search/input.schema.json
{
  "type": "object",
  "properties": {
    "query": { "type": "string" }
  },
  "required": ["query"]
}
The path must point under tools/ and exist in the bundle. For an external tool with no local code, create the directory and commit tool.yml plus the referenced schema files. When the model calls the tool, Dari emits tool.call_requested and waits for your app to submit tool.result_submitted. You can receive requests by streaming session events or by configuring an agent webhook.
{
  "type": "tool.result_submitted",
  "message_id": "msg_123",
  "tool_call_id": "call_abc",
  "is_error": false,
  "result": { "matches": ["docs/manifest.mdx"] }
}
Submit the result to:
POST /v1/sessions/{session_id}/events
Notes:
  • result is raw JSON. Dari wraps it for the model.
  • Successful results are validated against the output_schema from tool.yml when present.
  • Error results use is_error: true and skip output-schema validation.
  • While waiting, the message status is waiting_for_tool.
  • If timeout_seconds expires, Dari returns a timeout error to the model.