tool://¶
A self-describing, schema-validated route endpoint. tool:// is Helix's AI-native primitive: every tool declares an input schema, an output schema, and a description. The component validates inbound arguments against the input schema before running the tool's processor pipeline, so an LLM that calls a tool with bad arguments gets a clear error it can correct rather than a runtime crash deep in a transform step.
Use tool:// when you want a route that an agent, an MCP client, or another route can invoke by name, with the same arg-shape guarantees as a typed function.
URI shape¶
<tool-id> is mandatory and must be registered in the component (via YAML tools: or Component.Register). The component takes no URI query params — tool configuration lives in the registered ToolDef.
Both producer and consumer are supported:
- Producer (
to: tool://search) — invoke the tool from another route or step. - Consumer (
from: tool://search) — make the tool startable; the steps below it become its pipeline.
Parameters¶
tool:// itself has no URI parameters. Tools are configured by the ToolDef registered for the ID:
| ToolDef field | Description |
|---|---|
ID |
Tool name. Matches the URI path. |
Description |
Human/LLM-readable purpose. Set on the YAML tools[].description. |
Input |
map[string]FieldDef — argument schema. Every field has type, optional description, required, default, enum, plus nested fields (for object) or items (for array). |
Output |
map[string]FieldDef — declared return shape. Surfaced via OutputJSONSchema() to clients (MCP). |
Pipeline |
The processor pipeline that implements the tool. Built from the route's steps:. |
Validate |
Optional ToolValidation{Schema, Rules} — runtime arg validation (schema checks + Starlang custom rules). |
Headers¶
| Header | Direction | Description |
|---|---|---|
HelixToolID |
Set by producer | The invoked tool's ID. |
HelixToolDescription |
Set by producer | The tool's description string. |
The exchange body must be the tool's arguments. The producer accepts:
map[string]any— used directly.string/[]byte— JSON-decoded into a map; on parse failure wrapped as{"input": <raw>}.
After validation succeeds, the body is set to the validated map for the pipeline.
Examples¶
Define a tool in YAML and call it from another workflow:
tools:
- id: search
description: "Search the knowledge base"
input:
query:
type: string
description: "Search query"
required: true
limit:
type: integer
description: "Max results"
default: 10
output:
results: { type: array, description: "Search results" }
total: { type: integer, description: "Total matches" }
steps:
- transform:
starlang: |
%sl 2.0
output application/json
input payload
---
{ "results": [], "total": 0 }
workflows:
- id: assistant
trigger: { uri: direct://ask }
steps:
- set-body:
starlang: '{ "query": payload, "limit": 5 }'
- target: tool://search
Invoke a tool from an agent (the agent component lists registered tool:// routes as callable tools automatically):
Add custom Starlang validation rules:
tools:
- id: pay
description: "Move money between accounts"
input:
amount: { type: number, required: true }
currency: { type: string, required: true, enum: ["USD","EUR"] }
validate:
schema: true
rules:
- name: positive_amount
expr: 'args["amount"] > 0'
reason: "amount must be positive"
steps:
- target: direct://payments-handler
Behavior notes¶
- Single source of arg-shape truth — the LLM, the MCP server, the A2A server, and the route's transform steps all read the same
Inputmap. This is what makestool://the recommended primitive for agentic work. - Validation runs before the pipeline — required-field checks, type checks (
string,number/integer,boolean,object,array), andenummembership. The first violation is returned as a Go error wrappingtool %q input validation failed. - Type lenience —
integerandnumberboth acceptfloat64(JSON's only numeric type) andint. Unknown declared types pass silently so workspace authors can usedate,email, etc. without breakage. - Outputs are advisory — the component does not validate outbound bodies against
Output. The schema is published to MCP/A2A clients but not enforced at runtime. - Pipeline tools unwrap single-string-field calls — when an agent calls a single-string-arg tool with
{"sql": "SELECT 1"}, the route receivespayload = "SELECT 1". Seefeedback_pipeline_tool_unwrap.md.
Source¶
pkg/component/toolcomp/tool.go, pkg/component/toolcomp/tool_validation_test.go
See also¶
- agent — agents auto-register tool routes and call them by name.
- mcp-server — tool routes are first-class MCP tools (their schemas pass straight through).
- DSL workflow reference — full
tools:shape.