Skip to content

Ikanos — Schema — Steps

Steps enable multi-step orchestration — calling multiple consumed operations in sequence and combining their results. Use steps anywhere call: is allowed: on MCP tools, on REST operations, and on aggregate flows.

Simple mode (single call:) is preferred when one operation is enough. Orchestrated mode (steps:) is for multi-source composition and lookups.


Modes

Mode Looks like Use when
Simple call: + with: The tool delegates to a single consumed operation
Orchestrated steps: + mappings: The tool combines multiple operations or joins data

Exactly one mode is used per tool / operation / flow.


Anatomy of an orchestrated block

steps:                                  # keyed map; key IS the step name
  step1:
    type: call
    call: github.list-users
  step2:
    type: call
    call: github.get-user
    with:
      username: "$.step1.users[0].login"

mappings:
  - { target: output_field, value: "$.step2.userId" }
  • steps: is a keyed map keyed by step name. Iteration order is preserved and defines execution order.
  • Each step is referenced downstream by its map key.
  • mappings: glues the final step outputs to the exposed operation's output parameters.

Step types

type: call

Executes a consumed operation.

fetch-user:
  type: call
  call: github.get-user
  with:
    username: "{{github_username}}"

type: lookup

Searches through a previous step's output for a matching record. Useful for in-memory joins.

find-user-by-email:
  type: lookup
  index: list-all-users          # name of an earlier `call` step
  match: email                   # field in that step's output
  lookupValue: "{{email_to_find}}"
  outputParameters: ["fullName", "department"]

Variable references

Inside with: and mappings:, two reference styles are supported:

Syntax Resolves to
"{{paramName}}" A Mustache template against tool input parameters and binds
"$.stepName.fieldPath" The output of a previous step, addressed by JSONPath

Examples:

with:
  username: "{{github_username}}"             # from tool input
  organization: "$.fetch-user.organization"   # from previous step
  role: "ADMIN"                               # literal

Mappings

Mappings connect step outputs to the exposed operation's output parameters.

mappings:
  - { target: database_name, value: "$.fetch-db.dbName" }
  - { target: row_count,     value: "$.query-db.totalRows" }
  - { target: rows,          value: "$.query-db.results" }
  • target: is the name of an outputParameter declared on the exposed operation.
  • value: is a JSONPath into any previous step's output.

Putting it together

get-user-by-email:                       # operation key under a REST resource
  method: GET
  path: "/users/by-email"
  inputParameters:
    email: { in: query, required: true }
  steps:
    list-all-users:
      type: call
      call: hr.list-employees
    find-user:
      type: lookup
      index: list-all-users
      match: email
      lookupValue: shipyard-api.email
      outputParameters: ["fullName", "department"]
  mappings:
    - { target: name,       value: "$.find-user.fullName" }
    - { target: department, value: "$.find-user.department" }
  outputParameters:
    - { name: name,       type: string }
    - { name: department, type: string }

When to refactor into an aggregate

If the same steps: block is used by more than one tool or operation, move it into an aggregate flow and reference it via ref:. See Aggregates for the full pattern.