Are you looking at all the new AI tools and wondering how you can connect them to your powerful, battle-tested APIs? You’re in the right place!
In this walkthrough, we’ll enhance an existing Salesforce System API by implementing the Dual-Exposure Pattern. This is a fancy way of saying we’ll make your API “AI-ready” by adding a new, smart entry point for AI agents without breaking your existing RESTful interface.
We will expose three core operations—create a case, get case details, and update a case—as discoverable AI tools, all from the comfort of Anypoint Code Builder.
🎥 See It in Action!
Want to watch the process? Check out the full video walkthrough right here:
The “Why”: The Dual-Exposure Pattern 🚪🚪
Our main goal is to use the Dual-Exposure Pattern.
Think of it this way: your API is a secure building. Right now, it has one “front door” for traditional applications (the REST API). We’re going to add a second “front door” (an MCP Server) specifically for AI agents.
The best part? Both doors lead to the same underlying business logic. This means you ensure consistency, save a ton of development time, and don’t have to manage two different codebases!
✅ What You’ll Need
- An existing MuleSoft API project (We’ll use a
salesforce-system-api). - Anypoint Code Builder (VS Code).
Ready? Let’s get building!
Step 1: Get Your Project Ready
First, we need to add the MuleSoft MCP Connector to our project.
- Open your
pom.xmlfile. - Add this dependency inside your
<dependencies>section. This gives you the MCP components you’ll need.
<dependency>
<groupId>com.mulesoft.connectors</groupId>
<artifactId>mule-mcp-connector</artifactId>
<version>1.2.0</version>
<classifier>mule-plugin</classifier>
</dependency>
Next, let’s create a new, separate config file to keep our MCP flows nice and organized.
- In the Explorer, right-click the
src/main/muledirectory. - Select Mule: Create Configuration File.
- Name it
salesforce-system-mcp.xml.
Step 2: The Secret Sauce – Refactor for Reusability 💡
This is the most important step for making your logic reusable.
Our original API flow for “get case” probably uses data that only comes from an HTTP listener, like attributes.uriParams.caseNumber. An AI tool won’t send a URI parameter!
We need to “decouple” our logic from the HTTP trigger. We’ll use a flow variable as the common, shared piece of data.
- Open your original
salesforce-system-api.xmlfile. - In the
get:\cases\(caseNumber):api-configflow, add a Transform Message component right at the beginning. - Use this DataWeave expression. It cleverly checks for the HTTP parameter first, but if it’s not there, it uses a variable we’ll set later (
vars.caseNumber).
%dw 2.0
output application/java
vars.caseNumber default attributes.uriParams.caseNumber
- Now, find the next transform in that same flow (e.g.,
Mock IncidentDetails Response) and update it to use our new variable:vars.caseNumber(instead ofattributes.uriParams.caseNumber). - Repeat this process for your
patch:\cases\(caseNumber):api-configflow, too.
Awesome! Our core logic is now independent and can be called from anywhere—HTTP or AI!
Step 3: Build Your AI ‘Front Door’ with MCP Tools
Let’s switch to our new salesforce-system-mcp.xml file and build our AI tools.
🔧 Tool 1: Get Case Details (get_case_details)
- Drag an MCP Tool Listener onto the canvas to start a new flow.
- Click the + icon to create a new MCP Server Configuration:
- Name:
mule-mcp-server - Connection: Select Streamable HTTP Server.
- Listener config: Select your existing
http-listener-config. (This is the magic that makes the Dual-Exposure pattern work! ✨) - Server Name:
mule-mcp-server - Server Version:
1.0.0
- Name:
- Back in the Tool Listener properties, define what the AI agent will see:
- Name:
get_case_details - Description:
Retrieves the details of a specific Salesforce case. - Parameters Schema: This JSON tells the AI what inputs it needs.
{ "$schema": "[http://json-schema.org/draft-07/schema#](http://json-schema.org/draft-07/schema#)", "type": "object", "properties": { "caseNumber": { "type": "string" } }, "required": ["caseNumber"] }
- Name:
- Inside the flow, add a Transform Message to create the
caseNumbervariable that our refactored flow expects. - Add a Flow Reference component and set its Flow name to
get:\cases\(caseNumber):api-config.
🔧 Tool 2: Create a New Case (create_case)
- Drag another Tool Listener onto the canvas.
- Configure it:
- Configuration: Select your existing
mule-mcp-server. - Name:
create_case - Description:
Creates a new case in Salesforce. - Parameters Schema:
{ "$schema": "[http://json-schema.org/draft-07/schema#](http://json-schema.org/draft-07/schema#)", "type": "object", "properties": { "subject": { "type": "string" }, "description": { "type": "string" } }, "required": ["subject", "description"] }
- Configuration: Select your existing
- Add a Flow Reference and point it to
post:\cases:api-config. (This one is simple; the original flow already expects the right payload!)
🔧 Tool 3: Update an Existing Case (update_case)
- Drag one final Tool Listener onto the canvas.
- Configure it:
- Configuration: Select
mule-mcp-server. - Name:
update_case - Description:
Updates an existing Salesforce case. - Parameters Schema:
{ "$schema": "[http://json-schema.org/draft-07/schema#](http://json-schema.org/draft-07/schema#)", "type": "object", "properties": { "caseNumber": { "type": "string" }, "newStatus": { "type": "string" } }, "required": ["caseNumber", "newStatus"] }
- Configuration: Select
- Add a Transform Message to set the
caseNumbervariable (frompayload.caseNumber) and also set thepayloadfor thenewStatus. - Add a Flow Reference and point it to
patch:\cases\(caseNumber):api-config.
Step 4: The Grand Finale – Run and Test! 🚀
You’ve done all the hard work. Time for the payoff!
- Run the Application: Hit “Run and Debug” in Anypoint Code Builder.
- Configure the MCP Client:
- Follow the steps to Add an MCP Server in VS Code.
- Paste this JSON into your
mcp.jsonfile. This tells the VS Code chat agent where to find your local server.{ "servers": { "salesforce-system-mcp": { "url": "http://localhost:8081/mcp", "type": "http" } }, "inputs": [] }
- Verify Discovery: Save the
mcp.jsonfile. Look at the status bar at the bottom of VS Code. You should see the MCP status update to “start | 3 tools”. This confirms it found your three new AI tools! 🥳 - Test in the Chat:
- Open the Chat view in VS Code.
- At the top of the chat input, click the dropdown and select Agent.
- Now, talk to your API using natural language!
create a new case with subject "Printer Offline" and description "The main office printer is not responding"get details for case INC1C23456update case INC123456 to status "Resolved"
The chat agent will understand your request, find the right tool, and ask for your permission to run it. You’ll see the response from your Mule app right in the chat.
Congratulations! You now have a true dual-exposure API, ready for both traditional and AI-driven integration! 🎉