<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="9fd53f88-b7c5-4175-9480-db313b27f9fd" >
<http:listener-connection host="0.0.0.0" port="${http.port}" />
</http:listener-config>
<a2a:server-config name="A2A_Server" doc:name="A2A Server" doc:id="3e1c7c42-133d-4853-87f0-90617c8ad700" >
<a2a:connection listenerConfig="HTTP_Listener_config" agentPath="/financial-summary-agent" /> #(1)
<a2a:card name="financial-summary-agent" url="http://localhost:8081/financial-summary-agent/" version="1.0.0" > #(2)
<a2a:description ><![CDATA[An agent that can return financial statements based on the stock ticker]]></a2a:description>
<a2a:skills >
<a2a:agent-skill id="1" name="financial-report" >
<a2a:description ><![CDATA[Returns company financial reports]]></a2a:description>
</a2a:agent-skill>
</a2a:skills>
</a2a:card>
</a2a:server-config>
xml
A2A Connector 0.1.0-BETA - Examples
The HTTP Listener uses the values in the A2A server configuration to populate the Agent Card. Client A2A agents use the information in the Agent Card to determine:
-
When to use the agent (based on description and skills)
-
Where to contact the agent (based on the url property)
Configure an A2A Server
This is an example A2A server configuration:
1 | a2a:connection specifies the path to use to listen for requests. |
2 | a2a:card has the information that populates the Agent Card. A2A Connector automatically returns this data in the Agent Card format when the client requests it at the ./well-known/agent.json path. |
Write a Listener That Receives the A2A Request
This example shows how a listener is created. The user prompt that’s sent from the client agent is extracted to a variable user_prompt
:
<flow name="a2sfinancialagent" doc:id="fcd9c8be-94c2-4543-9eff-7f3e2b2f58fb" >
<a2a:task-listener doc:name="Task Listener" doc:id="c86ea98a-ae50-43be-a7ae-7bb60df17f8e" config-ref="A2A_Server">
</a2a:task-listener>
<set-variable value="#[payload.message.parts[0].text]" doc:name="Set task user prompt" doc:id="0f017d97-1761-4fc7-8b6b-13f3557a4b28" variableName="user_prompt"/>
</flow>
xml
Example Response
The response is formatted as an A2A task, which is then returned to the client:
<ee:transform doc:name="Transform Message" doc:id="32fd4cee-9380-4f0a-839d-880a7f25ea7f">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{
"id": vars.task_id,
"sessionId": vars.session_id,
"status": {
"state": "completed",
"message": {
"role": "agent",
"parts": [
{
"type": "text",
"text": payload.response
}
]
},
"timestamp": (now() >> 'UTC') as String {format: "yyyy-MM-dd'T'HH:mm:ss'Z'"}
},
"artifacts": [
{
"name": "Answer",
"index": 0,
"parts": [
{
"type": "text",
"text": payload.response
}
]
}
]
}]]></ee:set-payload>
</ee:message>
</ee:transform>
xml
Mule App Example
This example shows how a financial A2A agent Mule app that can answer queries related to US companies and their financial standings listens to A2A requests and passes the user prompt to an LLM using the open source MuleSoft Inference connector.
You can paste this code into the Studio XML editor to quickly load the flow for this example into your Mule app:
<flow name="sranana2aconnectorFlow" doc:id="fcd9c8be-94c2-4543-9eff-7f3e2b2f58fb" >
<a2a:task-listener doc:name="Task Listener" doc:id="c86ea98a-ae50-43be-a7ae-7bb60df17f8e" config-ref="A2A_Server">
</a2a:task-listener> #(1)
<logger level="INFO" doc:name="Logger" doc:id="08d7c476-ed04-4775-be88-ed2c143851e6" message="Triggering MCP Tools"/> #(2)
<set-variable value="#[payload.id]" doc:name="Set Task Id" doc:id="3b1702ea-88c1-4c06-a4ef-971ef8138504" variableName="task_id"/> #(3)
<set-variable value='#[(payload.sessionId) default ""]' doc:name="Set Session Id" doc:id="d0790291-fb71-4a10-a953-1b68fa8bbb47" variableName="session_id"/> #(4)
<set-variable value="#[payload.message.parts[0].text]" doc:name="Set task user prompt" doc:id="0f017d97-1761-4fc7-8b6b-13f3557a4b28" variableName="user_prompt"/> #(5)
<mac-inference:mcp-tools-native-template doc:name="[MCP] Tooling" doc:id="55e0960a-5795-4223-adf4-dfb23365dc3e" config-ref="MuleSoft_Inference_Text_generation_config">
<mac-inference:template ><![CDATA[You are a specialized assistant that performs financial analysis based on stock market data using stock market symbols]]></mac-inference:template> #(6)
<mac-inference:instructions ><![CDATA[Your sole purpose is to use the tools “get_company_symbol” and “get_company_financials" to answer financial questions about US based companies. If the user asks about anything other than stock market or financial aspects of public US companies, politely state that you cannot help with that topic and can only assist with companies financial data. Do not attempt to answer unrelated questions or use tools for other purposes.
Response Format: should be a JSON with 3 properties message, status (consist of "input_required", "completed", “error”) and sentiment with values (“Buy”, “Sell” or “Hold”) and reasoning (indicating in 2-3 sentences as to how the sentiment was decided)
Example queries: “Should I buy CRM stock?”, “Should I sell MSFT?”, “How is AAPL doing?”]]></mac-inference:instructions>
<mac-inference:data ><![CDATA[#[payload.message.parts[0].text]]]></mac-inference:data>
</mac-inference:mcp-tools-native-template>
<set-variable value="#[payload.response]" doc:name="MCP Tooling Response" doc:id="60810200-5643-477c-8a45-76f1e0dcc9e0" variableName="mcp_tooling_results"/> #(7)
<mac-inference:agent-define-prompt-template doc:name="Finance Agent" doc:id="b25e375b-f3be-45c1-a545-4f93690f98ce" config-ref="MuleSoft_Inference_Text_generation_config"> #(8)
<mac-inference:template ><![CDATA[#["You are a specialized assistant for performing financial analysis based on stock market data using stock market symbols.
Use the following context to answer
Context: $(vars.mcp_tooling_results)"]]]></mac-inference:template>
<mac-inference:instructions ><![CDATA[Your sole purpose is to answer questions about the financial information of US based companies. If the user asks anything other than stock market or financial aspects of public companies, politely state that you cannot help with that topic and can only assist with companies financial data. Do not attempt to answer unrelated questions or use tools for other purposes.
Response Format: Should be JSON with 3 properties, including message, status ("input_required", "completed", “error”), and sentiment with values (“Buy”, “Sell” or “Hold”) and reasoning (tell in 2-3 sentences how the sentiment was decided)
Example queries: “Should I buy CRM stock?”, “Should I sell MSFT?”, “How is AAPL doing?”]]></mac-inference:instructions>
<mac-inference:data ><![CDATA[#[vars.user_prompt]]]></mac-inference:data>
</mac-inference:agent-define-prompt-template>
<ee:transform doc:name="Transform Message" doc:id="32fd4cee-9380-4f0a-839d-880a7f25ea7f"> #(9)
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{
"id": vars.task_id,
"sessionId": vars.session_id,
"status": {
"state": "completed",
"message": {
"role": "agent",
"parts": [
{
"type": "text",
"text": payload.response
}
]
},
"timestamp": (now() >> 'UTC') as String {format: "yyyy-MM-dd'T'HH:mm:ss'Z'"}
},
"artifacts": [
{
"name": "Answer",
"index": 0,
"parts": [
{
"type": "text",
"text": payload.response
}
]
}
]
}]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
xml
1 | The a2a:task-listener component acts as the entry point, waiting to receive a task from an A2A server. This task contains a user’s query about stock market data. |
2 | The logger component outputs an informational message Triggering MCP Tools to the MuleSoft logs. |
3 | The set-variable component extracts the ID from the incoming payload (the task received in step 1) and stores it in a flow variable named task_id . |
4 | Another set-variable component extracts the sessionId from the payload. If sessionId isn’t present, it defaults to an empty string. This value is stored in a flow variable named session_id . |
5 | This set-variable extracts the actual user query from the payload. Specifically, it takes the text from the first part of the message within the payload and stores it in a flow variable named user_prompt . |
6 | The mac-inference:mcp-tools-native-template configures an LLM to act as a specialized financial analysis assistant. |
7 | This set-variable component takes the response generated by the mac-inference:mcp-tools-native-template (from step 6) and stores it in a flow variable named mcp_tooling_results . |
8 | The mac-inference:agent-define-prompt-template component processes the results from the previous AI interaction to generate a user-friendly response. |
9 | The ee:transform (DataWeave transformation) component takes the payload.response from the previous AI interaction and transforms it into a structured JSON output. |
Configure the A2A Client to Call Other A2A Agents
<flow name="sranana2aconnectorFlow1" doc:id="973b8e26-66e6-449e-809d-9ae42125c693" >
<a2a:task-listener doc:name="Task Listener" doc:id="974a49ae-98a7-4f1c-a216-1b66f0a77b71" config-ref="A2A_Server"/>
<a2a:send-task doc:name="Send Prompt to A2A Agent" doc:id="1814db20-45b7-43e2-81e0-68211f1ae9af" config-ref="A2A_Client">
<a2a:task ><![CDATA[#[payload.prompt]]]></a2a:task>
</a2a:send-task>
</flow>
xml