Skip to content

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://<tool-id>

<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):

agents:
  - id: helper
    type: react
    tools:
      - tool://search
      - tool://translate

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 Input map. This is what makes tool:// the recommended primitive for agentic work.
  • Validation runs before the pipeline — required-field checks, type checks (string, number/integer, boolean, object, array), and enum membership. The first violation is returned as a Go error wrapping tool %q input validation failed.
  • Type lenience — integer and number both accept float64 (JSON's only numeric type) and int. Unknown declared types pass silently so workspace authors can use date, 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 receives payload = "SELECT 1". See feedback_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.