# @dialect: AGENTFABRIC=1.0
Agent Script Reference
After you configure the assets and other elements of your agent network project, you build the rest of the workflow using Agent Script. Agent Script enables you to build predictable, context-aware agent workflows that don’t rely solely on interpretation by an LLM.
Agent Script Structure
The following sections explain settings and configurations specific to MuleSoft agent network projects. To learn more about Agent Script, see the Agent Script documentation.
Dialect Referencing and Versioning
Agent Script files contain a header specifying the dialect and a version binding. SEMVER major and minor are used for fixing to a specific dialect version.
The dialect header specifies that the script is strictly bound to a specific version or later of the AGENTFABRIC dialect. Deploying an agent to a runtime that doesn’t support this version results in an error.
-
Using major.minor (for example,
AGENTFABRIC=1.1) binds to version 1.1 or later -
Using major only (for example,
AGENTFABRIC=1) references the latest version within that major version
Example
System Section
This section defines the instructions attribute, which acts as a default system prompt used whenever an agentic node doesn’t define its own system.instructions.
Example
system:
instructions: "You are the onboarding agent"
The system section has these parameters.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
Default system prompt used when an agentic node doesn’t define its own |
String |
Yes |
Agent Config Section
The config section is the standard Agent Script config section, with the addition of the optional default_llm field. This section defines metadata and default settings for the agent.
Example
config:
agent_name: "employee-onboarding"
label: "Employee Onboarding Agent"
description: "An Agent that performs employee onboarding"
The config section has these parameters.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
The name identifier for the agent. |
String |
- |
|
A human-readable display name for the agent. |
String |
- |
|
A description of what the agent does. |
String |
- |
|
Specifies a default LLM to be used on all agentic nodes that don’t specify otherwise. |
@llm reference See LLM |
No |
LLM Section
The llm element is where you define the LLMs to use for reasoning and generation. Each target must use the llm:// URI scheme so the runtime binds to the correct governed connection.
Example
llm:
open-api-llm:
target: "llm://open_ai_connection"
kind: "OpenAI"
model: "gpt5-mini"
reasoning_effort: "LOW"
gemini-llm:
target: "llm://gemini_connection"
kind: "Gemini"
model: "gemini-3-flash-preview"
thinking_level: "HIGH"
top_p: 0.3
LLM Configuration: OpenAI
The OpenAI configuration has these properties.
The OpenAI default URL is https://api.openai.com/v1.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
Governed LLM connection as a URI; must use the |
URI ( |
Yes |
|
Discriminator for the LLM provider; selects which provider-specific attributes apply |
String, |
Yes |
|
The name of the model to use |
String |
Yes |
|
Constrains effort on reasoning for reasoning models. gpt-5.1 defaults to |
enum['NONE', 'MINIMAL', 'LOW', 'MEDIUM', 'HIGH'] |
No |
|
Controls randomness in the output |
number |
No |
|
Nucleus sampling parameter |
number |
No |
|
Number of most likely tokens to return at each position |
integer |
No |
|
Maximum number of tokens to generate |
integer |
No |
LLM Configuration: Gemini
The Gemini configuration has these properties.
The default Gemini URL is https://generativelanguage.googleapis.com.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
Governed LLM connection as a URI; must use the |
URI ( |
Yes |
|
Discriminator for the LLM provider; selects which provider-specific attributes apply |
String, |
Yes |
|
The name of the model to use |
String |
Yes |
|
The level of thoughts tokens that the model should generate |
Enum['LOW', 'HIGH'] |
No |
|
Indicates the thinking budget in tokens. 0 is DISABLED. -1 is AUTOMATIC. The default values and allowed ranges are model dependent |
Number |
No |
|
Controls the degree of randomness in token selection. Lower temperatures are good for prompts that require a less open-ended or creative response, while higher temperatures can lead to more diverse or creative results |
Number |
No |
|
Tokens are selected from the most to least probable until the sum of their probabilities equals this value. Use a lower value for less random responses and a higher value for more random responses |
Number |
No |
|
Whether to return the log probabilities of the tokens that were chosen by the model at each step |
Boolean |
No |
|
Maximum number of tokens that can be generated in the response |
Integer |
No |
Action Definitions
You define A2A and MCP actions in Agent Script under the top-level actions block. Each action target uses a URI whose scheme is the underlying protocol (for example a2a:// or mcp://), so the runtime can route the connection correctly.
A2A Actions
A2A actions execute the message/send A2A method and do not specify inputs or outputs.
Example
actions:
hr_agent:
target: "a2a://hr_agent_connection"
kind: "a2a:send_message"
A2A actions have these properties.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
Governed A2A connection as a URI; must use the |
URI ( |
Yes |
|
Indicates that this executes the message/send A2A method. |
"a2a:send_message" |
Yes |
MCP Actions
MCP actions invoke Model Context Protocol actions with optional input binding.
Example
actions:
send_slack_message:
target: "mcp://slack_mcp_connection"
kind: "mcp:tool"
tool_name: "send-message"
inputs:
channel: string = "my-default-channel"
message: string
MCP actions have these properties.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
Governed MCP connection as a URI; must use the |
URI ( |
Yes |
|
Constant indicating that this invokes an MCP tool |
"mcp:tool" |
Yes |
|
The name of the tool to call |
String |
Yes |
|
Define bindable arguments. Input arguments provided are not exhaustive. The tool will auto-discover additional arguments and consider them in slot filling mode. |
Object |
No |
A2A Trigger
Triggers reference one of the interfaces defined for a broker in the agent network. Each broker must have one—and only one—trigger per each interface declared in its agent network.
The A2A trigger reacts to send/message methods and automatically manages the task history, context ID and task IDs. The trigger also responds to various A2A protocol methods.
| Agent network only supports triggers using JSON-RPC or HTTP JSON transport. |
Example
trigger employeeOnboardingTrigger:
kind: "a2a"
target: "brokers://employee-onboarding/a2a"
on_message: -> transition to @orchestrator.hrSystemOnboard
The A2A trigger has these properties.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
Value that indicates this is an A2A trigger. |
|
Yes |
|
Broker interface entry point. Must use the |
URI ( |
Yes |
|
Procedure that executes when the A2A interface receives a new |
Procedure |
Yes |
Node Types
Agent network and Agent Script support these node types.
Subagent Node
This node defines a generic agent loop node, made of a prompt and a set of actions. Because it can use actions and supports human-in-the-loop flows, this node is ideal for implementing patterns like classification, semantic routing, or LLM reasoning.
Example
- subagent profile-extractor:
description: "Extracts structured user profile data from text"
reasoning:
instructions: -> Extract the following information from the user's message: {!@request.payload.message.parts[0].text}
outputs:
properties:
name:
type: "string"
description: "Full name of the person"
minLength: 1
email:
type: "string"
description: "Email address"
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
age:
type: "integer"
description: "Person's age"
minimum: 0
maximum: 150
preferences:
type: "object"
description: "User preferences"
properties:
newsletter:
type: "boolean"
description: "Whether user wants newsletter"
default: "false"
category:
type: "string"
description: "Preferred category"
enum:
- "tech"
- "business"
- "sports"
tags:
type: "array"
description: "Interest tags"
items:
type: "string"
minItems: 1
maxItems: 10
max_number_of_loops: 5
max_consecutive_errors: 5
task_timeout_secs: 30
on_exit: -> transition to @orchestrator.process_profile
The subagent node has these properties.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
The node identifier, defined next to the node type. |
String |
Yes |
|
An optional short, human-readable display name for the node. |
String |
No |
|
A CommonMark string providing a description of the node. |
String |
No |
|
A procedure that executes when the node execution finishes. If |
Procedure, but only |
No |
|
Overrides the default LLM setting |
@llm reference See LLM Section |
No |
|
Overrides the global |
String |
No |
|
Session-specific query or instructions for this particular node, typically containing user provided or user related context |
String |
Yes |
|
The available actions |
Array[actions] |
No |
|
Schema definition describing the expected structure of the agent’s output |
Outputs See Node Outputs |
No |
|
The maximum number of loops an execution can take. Useful for keeping the execution from running too long and consuming too many tokens. Default: 25 |
Integer |
No |
|
The maximum number of consecutive errors allowed during execution. Useful for keeping the node from running too long and consuming too many tokens. |
Integer |
No |
|
A timeout (in seconds) for the total node execution. |
Integer |
No |
|
A schema definition for the agentic output. |
Object See Node Outputs |
No |
Orchestrator Node
The orchestrator node is a specialization of the subagent node used for orchestrating multiple agents and MCP servers to achieve a specified goal. It is optimized for multi-agent orchestration. Use this node type for workflows that need to call multiple external agents or actions to achieve a goal.
Example
orchestrator flight-booking-agent:
description: books flights by looking for the best offer across approved partners
system:
instructions: "You are a flight booking agent. The process for flight booking is: 1. Ask the user for a destination and travel dates and present them with matching alternatives using available actions. 2. Allow the user to change or refine the search. 3. Once the user selects a flight, book it using the concur agent tool."
reasoning:
instructions: -> @request.payload.message.parts[0].text
actions:
search-flight: @actions.search-flight with companyId = @variables.companyId
get-flight-info: @actions.get-flight-info
concur: @actions.concur-agent with http_headers = {"Authorization": @request.headers["Authorization"]}
max_number_of_loops: 10
max_consecutive_errors: 10
task_timeout_secs: 60
outputs:
properties:
flightNumber:
type: "string"
description: "The flight identification number"
airline:
type: "string"
description: "The airline name"
on_exit: -> transition to @executor.send_summary
The orchestrator node has these properties.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
The node identifier, defined next to the node type. |
String |
Yes |
|
An optional short, human-readable display name for the node. |
String |
No |
|
A CommonMark string providing a description of the node. |
String |
No |
|
A procedure that executes when the node execution finishes. If |
Procedure, but only |
No |
|
Overrides the default LLM setting |
@llm reference See LLM Section |
No |
|
Overrides the global |
String |
No |
|
Session-specific query or instructions for this particular node, typically containing user provided or user related context |
String |
Yes |
|
The available actions |
Array[actions] |
No |
|
Schema definition describing the expected structure of the agent’s output |
Outputs See Node Outputs |
No |
|
The maximum number of loops an execution can take. Useful for keeping the execution from running too long and consuming too many tokens. Default: 25 |
Integer |
No |
|
The maximum number of consecutive errors allowed during execution. Useful for keeping the node from running too long and consuming too many tokens. |
Integer |
No |
|
A timeout (in seconds) for the total node execution. |
Integer |
No |
|
A schema definition for the agentic output. |
Object See Node Outputs |
No |
Generator Node
The generator node calls an LLM to generate text. It is not an agent loop, and it does not support human-in-the-loop learning or other actions. It performs exactly one LLM call. Use this node for summarization, formatting, or templated text generation.
Example
generator summarize-report:
description: "Generate a one-paragraph summary of the report."
prompt: "Summarize the following in one paragraph: {!@variables.report}"
on_exit: -> transition to ...
The generator node has these properties.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
The node identifier, defined next to the node type. |
String |
Yes |
|
An optional short, human-readable display name for the node. |
String |
No |
|
A CommonMark string providing a description of the node. |
String |
No |
|
A procedure that executes when the node execution finishes. If |
Procedure, but only |
No |
|
A reference to the LLM connection. |
@llm reference See LLM Section |
No |
|
Overrides the global |
String |
No |
|
Session-specific query or instructions for this particular node, typically containing user provided or user related context. |
String |
Yes |
|
A schema definition for the agentic output. |
Object See Node Outputs |
No |
Executor Node
The executor node is used to execute a set of Agent Script statements, primarily for setting variables or deterministic tool invocations. Use this node to set variables or call actions with known or fixed arguments.
Example
executor sendHrSlackUpdate:
do: -> run @actions.send_slack_message with text=@generator.generate-hr-slack-update-message.output with channel_id="my-onboarding-channel-id"
on_exit: -> transition to @router.countrySwitch
The executor node has these properties.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
The node identifier, defined next to the node type. |
String |
Yes |
|
An optional short, human-readable display name for the node. |
String |
No |
|
A CommonMark string providing a description of the node. |
String |
No |
|
A procedure that executes when the node execution finishes. If |
Procedure, but only |
No |
|
Agent Script statements to execute |
procedure |
Yes |
Router Node
The router node performs dynamic transitions based on deterministic conditions. This node doesn’t support transition to in its on_exit attribute. Use this node for branching based on structured output from a previous node.
Example
router countryRouter:
routes:
- target: @orchestrator.argentinaOnboard
when: @orchestrator.hrSystemOnboard.output.country == "ARG"
label: "Argentina"
- target: @orchestrator.usOnboard
when: @orchestrator.hrSystemOnboard.output.country == "USA"
label: "USA"
otherwise:
target: @echo.invalidCountryResponse
The router node has these properties.
| Parameter | Description | Type | Required |
|---|---|---|---|
|
The node identifier, defined next to the node type. |
String |
Yes |
|
An optional short, human-readable display name for the node. |
String |
No |
|
A CommonMark string providing a description of the node. |
String |
No |
|
An array of condition and target pairs, plus an optional label field for UI. Must define at least one route. Each route contains: |
Array |
Yes |
|
Defines a default transition when no route condition matches. Contains: |
Object |
Yes with |
Echo Node
The echo node sends a response back to the client. The number of responses depends on the trigger interface and its configuration. Use this node for the end of a workflow, or anytime you want to emit a response.
Example
echo addArtifact:
kind: "a2a:artifact_update_event"
artifact: a2a.artifact({
artifactId: uuid(),
name: "myArtifact",
description: "this is optional",
parts: [
a2a.textPart("You have been onboarded! Your employee ID is " + @orchestrator.hrSystemOnboard.output.employeeId)
],
metadata: {},
}),
append: false
lastChunk: false
echo setStatus:
kind: "a2a:status_update_event"
state: "TASK_STATE_COMPLETED",
message: a2a.message({
messageId: uuid(),
parts: [
a2a.textPart("You have been onboarded! Your employee ID is " + @orchestrator.hrSystemOnboard.output.employeeId)
]
})
| Parameter | Description | Type | Required |
|---|---|---|---|
|
The node identifier, defined next to the node type. |
String |
Yes |
|
An optional short, human-readable display name for the node. |
String |
No |
|
A CommonMark string providing a description of the node. |
String |
No |
|
A procedure that executes when the node execution finishes. If |
Procedure, but only |
No |
|
Discriminator for the event type. Valid values: |
String |
Yes |
|
The task state. Used with |
String |
Yes (for |
|
A message object created via |
Message object |
Yes (for |
|
An artifact object created via |
Artifact object |
Yes (for |
|
Whether to append to an existing artifact. Used with |
Boolean |
No |
|
Whether this is the last chunk of the artifact. Used with |
Boolean |
No |
|
Optional metadata dictionary. |
dict |
No |
The following table summarizes echo node parameters organized by kind.
| Kind | Required Parameters | Optional Parameters |
|---|---|---|
|
|
|
|
|
|
Echo Node Behavior
The following table describes echo node behavior based on the A2A operation used by the client.
| Operation / Condition | Echo Behavior |
|---|---|
|
Each echo invocation updates the stored task. Each echo invocation emits a push notification payload for all created push notifications. A consolidated response is emitted when the graph ends or is suspended. |
|
An immediate response is sent before graph execution is triggered. The response includes the task and context ID. A stored task entry with the response already exists before graph execution begins. All echo invocations update the stored task atomically (including consolidated and individual events). Each echo invocation emits a push notification payload for all created push notifications. |
|
All echo invocations update the stored task atomically (including consolidated and individual events). All individual events are sent through the event stream. Each echo invocation emits a push notification payload for all created push notifications. |
|
This condition works on top of the scenarios above. Any task in a non-terminal state can be subscribed to. Whenever echo is executed, events are pushed to all subscribed clients. |
A2A Namespace Functions
The a2a namespace provides a set of functions that support A2A Task object creation. Do not prefix these functions with @ as it’s reserved for references such as @variables, @actions, @request, and @orchestrator.<nodeId>.
| Function | Description | Input Arguments | Output | Example |
|---|---|---|---|---|
|
Builds an A2A Message object |
|
|
|
|
Builds a TextPart object (kind: "text") |
|
|
|
|
Builds a DataPart object (kind: "data") |
|
|
|
|
Builds a FilePart object (kind: "file") |
|
|
|
|
Builds an A2A Artifact object |
|
|
|
Usage notes:
-
Functions are designed to be composed:
a2a.messageanda2a.artifactacceptpartscreated bya2a.textPart/a2a.dataPart/a2a.filePart. -
a2a.filePartrequires eitheruriORbytes(base64-encoded), but not both. -
a2a.artifactauto-generatesartifactIdif it’s not provided. -
All
metadataparameters are optional and accept arbitrary dictionaries. -
For tasks, it’s not necessary to define the
id,contextIdandhistoryattributes, those are automatically populated by the trigger.
Built-in Functions
Use these functions in expressions alongside references and interpolations. They include time and ID helpers (now, uuid), string utilities (strip, startswith, and endswith), JSON parsing (parse_json), and common numeric helpers (abs, round, and sum) for deterministic math-style logic without calling external tools.
| Function | Description | Input arguments | Output | Example |
|---|---|---|---|---|
|
Current UTC time in ISO 8601 format |
None |
String (ISO 8601) |
|
|
Random UUID v4 |
None |
String (UUID) |
|
|
Removes leading/trailing characters from a string |
String, optional chars (default: whitespace) |
String |
|
|
Whether a string starts with a prefix |
String, prefix |
Boolean |
|
|
Whether a string ends with a suffix |
String, suffix |
Boolean |
|
|
Absolute value |
Number |
Number |
|
|
Round to optional digit count |
Number, optional |
Number |
|
|
Sum of a numeric list |
List |
Number |
|
|
Parse a JSON string |
String (valid JSON) |
Object or array |
|
Node Outputs
Use the outputs field to define the expected shape of the agent’s response using a schema notation similar to a JSON schema. When provided, the agent produces output matching the defined structure for downstream parsing and processing.
Each property maps to a field in the agent’s output. These types are supported.
Note: Advanced JSON schema features are not supported, so do not copy patterns from generic JSON Schema tutorials unless they match what is documented here.
| Type | Description |
|---|---|
String |
Text values with optional constraints like |
Number / Integer |
Numeric values with optional constraints like |
Boolean |
|
Array |
Lists of items, where |
Object |
Nested structures with their own |
Each property definition can include:
-
type: The data type (required). -
description: A human-readable explanation of the property’s purpose. -
default: A default value if the property is omitted.
The outputs definition doesn’t support:
-
additionalPropertiesor similar JSON Schema extensibility flags -
Combinators such as
anyOf,oneOf, orallOf -
References or shared definitions (
$ref,$defs) -
Composition beyond nested
object/arraystructures as described above
Node Expressions and References
Nodes access data from other parts of the workflow using expressions.
These references are used.
| Prefix | Reference | Example |
|---|---|---|
|
LLM definitions |
|
|
action definitions |
|
|
Trigger request data |
|
|
HTTP headers (case-insensitive) |
|
|
Workflow variables |
|
|
Node references |
|
Accessing Node Output and Input
Every node has .output (the value it produced) and .input (the output of whichever node transitioned into it).
Example
@orchestrator.hrSystemOnboard.output.employeeId # returns the `employeeId` property of the object returned by the `hrSystemOnboard` node @generator.writeEmailContent.output # returns the string generated by the `writeEmailContent` node
-
Use
.outputwhen you know exactly which upstream node you’re referencing. -
Use
.inputwhen multiple nodes transition into the current one and you want to decouple it from the specific path taken.
In this example, @generator.generate_email.input returns whichever of node_a, node_b, or node_c actually transitioned into it.
node_a ──┐ node_b ──┼──► generate_email ──► send_email node_c ──┘
Setting Action Headers
Any actions that connect to an external system often need to set custom headers. Use cases range from propagating authorization headers (for example, in OBO authentication) to adding custom correlation information.
For this, both the MCP and A2A actions automatically get an implicit optional http_headers parameter object type that can be used to set those:
actions:
my_hr_agent: @actions.hr_agent with http_headers = {"Authorization": @request.headers["Authorization"], "X-CorrelationId": @variables.conversationId}
String Interpolation
Use {!expression} to embed values inside strings.
Example
prompt: "The employee's country is {!@orchestrator.hrOnboard.output.country}"
Slot Filling
Use slot filling (…) to tell an LLM to figure out a value.
Example
actions:
send_message: @actions.send_slack_message with message = ...
# LLM decides the message content
Tool Binding at the Node Level
When you reference a tool inside a node, you can fix, default, or slot-fill its arguments using with.
Example
actions:
# All arguments via slot filling (LLM decides everything)
sendToDefault: @actions.send_slack
# Fix the channel, LLM fills the message
sendToFixed: @actions.send_slack with channel = "agent-fabric"
# Fix everything -- fully deterministic
fullyDeterministic: @actions.send_slack with message = @variables.calculatedMessage with channel = @variables.channelId



