Runtime expressions

Runtime expressions let you dynamically reference values during workflow execution: inputs from the caller, responses from previous steps, secrets, and more. They are used in both Flower and Arazzo workflow definitions.

Expressions start with a $ prefix and are resolved at runtime.

Expression variables #

Flow inputs ($inputs) #

Access values passed by the caller when invoking a flow.

query:
  q: $inputs.city

Nested access and array indexing are supported (see Accessing data for all syntaxes):

Expression Description
$inputs.city Top-level input
$inputs.address.zipcode Nested object property
$inputs.items.0.name Array element (dot notation)
$inputs.items[0].name Array element (JMESPath)

Current step response ($response) #

Reference the HTTP response of the current step.

outputs:
  lat: $response.body.0.lat
  lon: $response.body.0.lon
  status: $response.status
Path Description
$response.body Parsed response body (JSON)
$response.body.<path> Deep access into the body
$response.status HTTP status code
$response.headers Response headers
$statusCode Shortcut for $response.status
$status Shortcut for $response.status

Current step request ($request) #

Reference the request sent for the current step.

Path Description
$request.method HTTP method (GET, POST, etc.)
$request.url Full URL including query string
$request.query Query parameters
$request.headers Request headers
$request.body Request body
$method Shortcut for $request.method
$url Shortcut for $request.url

Current step outputs ($outputs) #

Reference resolved outputs of the current step. Useful when an output depends on another output’s value.

outputs:
  lat: $response.body.0.lat
  coordinates: "$outputs.lat, $response.body.0.lon"

Previous step results ($steps) #

Access the request, response, or outputs of a previously executed step.

steps:
  - id: get_lat_lon
    request:
      method: GET
      url: https://nominatim.openstreetmap.org/search
      query:
        q: $inputs.city
        format: jsonv2
    outputs:
      lat: $response.body.0.lat

  - id: get_weather
    request:
      method: GET
      url: https://api.open-meteo.com/v1/forecast
      query:
        latitude: $steps.get_lat_lon.outputs.lat

The pattern is $steps.<step_id>.<property>.<path> where <property> is one of:

Pattern Description
$steps.<id>.outputs.<key> A resolved output value
$steps.<id>.response.body.<path> Response body access
$steps.<id>.response.status Response status code
$steps.<id>.request.url Request URL

Server secrets ($secrets) #

Reference secrets stored on the server. Secret values are never included in workflow outputs.

headers:
  Authorization: "Bearer $secrets.API_KEY"

Secret names must start with a letter, followed by letters, digits, or underscores (e.g. API_KEY, myToken2).

See Secrets for how to configure secrets on your MCP server.

Current user token ($current_user.token) #

Returns the OAuth token of the currently authenticated user. Only available on private MCP servers. Useful for forwarding the user’s identity to external APIs.

headers:
  Authorization: "Bearer $current_user.token"

Accessing data #

Two syntaxes are available:

Both work with any expression variable ($response, $inputs, $steps, etc.).

Dot notation #

$response.body.current.temperature_2m     # object property
$response.body.0.lat                      # array element (0-based)
$response.body.users.0.address.city       # combined

JMESPath #

JMESPath support is a Bump.sh extension. It is not part of the Arazzo specification.

When dot notation is not enough, Bump.sh supports JMESPath, a query language for JSON. An expression is automatically treated as JMESPath when it contains bracket syntax ([*], [0], [?...], [0:3]) or a function call (avg(...), length(...), etc.).

Projections ([*]) #

Extract a property from every element of an array:

# Given response body: {"users": [{"name": "Alice"}, {"name": "Bob"}]}
outputs:
  names: $response.body.users[*].name
  # -> ["Alice", "Bob"]

Indexing ([n]) #

outputs:
  first_user: $response.body.users[0].name
  # -> "Alice"

Slicing ([start:end]) #

outputs:
  first_three: $response.body.items[0:3]

Filtering ([?condition]) #

Select array elements matching a condition:

# Given: [{"name": "Alice", "age": 25}, {"name": "Bob", "age": 35}]
outputs:
  seniors: $response.body.users[?age > `30`].name
  # -> ["Bob"]

Literal numbers in filter conditions must be wrapped in backticks (`30`), as per JMESPath syntax.

Functions #

outputs:
  avg_temp: avg($response.body.hourly.temperature_2m)
  count: length($response.body.items)

Numeric

Function Description Example
abs(val) Absolute value abs($inputs.delta)
avg(arr) Average of a numeric array avg($response.body.temps[*])
ceil(num) Round up ceil($response.body.score)
floor(num) Round down floor($response.body.score)
sum(arr) Sum of a numeric array sum($response.body.prices[*])

Array and object

Function Description Example
length(val) Length of array, object, or string length($response.body.items)
keys(obj) Keys of an object keys($response.body.config)
values(obj) Values of an object values($response.body.config)
sort(arr) Sort an array sort($response.body.scores[*])
sort_by(arr, &expr) Sort by expression sort_by($response.body.users[*], &age)
max(arr) Maximum value max($response.body.scores[*])
max_by(arr, &expr) Max by expression max_by($response.body.users[*], &age)
min(arr) Minimum value min($response.body.scores[*])
min_by(arr, &expr) Min by expression min_by($response.body.users[*], &age)
reverse(arr) Reverse array or string reverse($response.body.items)
flatten(arr) Flatten nested arrays (1 level) flatten($response.body.nested)
to_array(val) Wrap value in an array to_array($inputs.value)

String

Function Description Example
to_string(val) Convert to string to_string($response.body.id)
to_number(val) Convert to number to_number($response.body.count)

Type

Function Description Example
type(val) Returns the JSON type of a value type($response.body.result)

Nested function calls (like length(sort($ref[*]))) are not supported.

String interpolation #

Multiple expressions can coexist in a single string:

outputs:
  summary: "$steps.get_weather.outputs.temperature in $inputs.city"
  # -> "22.5 in Marseille"

String interpolation only works with dot notation expressions. JMESPath expressions (containing [*], [0], functions, etc.) are resolved as a whole and cannot be combined with other expressions in the same string.

Conditions #

Expressions inside when clauses are resolved, then evaluated with standard operators.

actions:
  - when: "$statusCode == 200"
    do: next
  - when: "$statusCode == 202"
    do: retry
    wait: 2
  - when: "$response.body.status == 'pending'"
    do: retry

Supported operators: ==, !=, >, <, >=, <=, AND, OR, !.

Complete example #

flower: "0.1"
id: weather
title: Get the weather for a specific city

flows:
  - id: weather_forecast
    description: Get the weather forecast for a specific city
    inputs:
      properties:
        city:
          type: string
      required:
        - city

    steps:
      - id: get_lat_lon
        request:
          method: GET
          url: https://nominatim.openstreetmap.org/search
          query:
            q: $inputs.city
            format: jsonv2
        outputs:
          lat: $response.body.0.lat
          lon: $response.body.0.lon

      - id: get_weather_forecast
        request:
          method: GET
          url: https://api.open-meteo.com/v1/forecast
          query:
            latitude: $steps.get_lat_lon.outputs.lat
            longitude: $steps.get_lat_lon.outputs.lon
            daily: temperature_2m_min,temperature_2m_max
            hourly: temperature_2m
        outputs:
          temperature_avg: avg($response.body.hourly.temperature_2m)
          temperature_min: $response.body.daily.temperature_2m_min
          temperature_max: $response.body.daily.temperature_2m_max
        actions:
          - when: "$statusCode == 200"
            do: next
          - when: "$statusCode == 429"
            do: retry
            wait: 10

    outputs:
      temperature_avg: $steps.get_weather_forecast.outputs.temperature_avg
      temperature_min: $steps.get_weather_forecast.outputs.temperature_min
      temperature_max: $steps.get_weather_forecast.outputs.temperature_max