Salesforce Agentforce A2A Wrapper
41by mvrzan
An example implementation of a financial AI Agent built with Agentforce and made accessible through the A2A protocol. The Heroku backend provides A2A protocol support, and the agent uses Heroku AppLink to perform API invocations.
Getting Started
README
Agentforce A2A Wrapper
Connect Salesforce Agentforce to the world through the Agent-to-Agent (A2A) Protocol with intelligent orchestration powered by Heroku Managed Inference and Agents.
Note: This is a custom A2A protocol implementation that wraps Agentforce agents. Salesforce's native A2A support is currently in pilot and not used in this project.
Table of Contents
What does it do?
This application demonstrates how to expose Salesforce Agentforce agents through the A2A (Agent-to-Agent) Protocol while adding an intelligent orchestration layer powered by Heroku Managed Inference and Agents (MIA).
The demo showcases two operational modes:
Orchestrator Mode - True agent-to-agent communication where:
- User queries first reach Heroku MIA (Claude 4.5 Sonnet)
- MIA intelligently decides when to delegate to the Agentforce financial agent
- Agentforce performs specialized financial tasks (stock prices, company data)
- MIA synthesizes the information into conversational responses
- Creates a seamless multi-agent collaboration experience
Direct Mode - Pure A2A protocol implementation:
- Direct client-to-Agentforce communication following A2A specifications
- Demonstrates standard agent discovery and streaming capabilities
- Shows session caching for performance optimization (30-minute TTL)
- Reduces latency from ~5s to <1s on subsequent requests
Key capabilities:
- A2A Protocol Compliance: Full implementation of agent card discovery and JSON-RPC messaging
- Real-time Streaming: Server-Sent Events (SSE) for immediate response delivery
- Heroku Managed Inference and Agents: Easily add LLM capabilities to your application
- Heroku AppLink Integration: Secure Salesforce authentication and API invocations
- Function Calling: Tool-based architecture allowing MIA to delegate specialized tasks
- Dual Architecture: Toggle between orchestrated and direct agent communication
How does it work?
Orchestrator Mode Flow:
- Initial Request: User sends a message through the chat interface
- MIA Routing: Request reaches Heroku Managed Inference and Agents (Claude 4.5 Sonnet)
- Decision Making: MIA analyzes the query and decides if it requires financial agent assistance
- Tool Invocation: For financial queries, MIA calls the
query_agentforcefunction - A2A Communication: Server acts as A2A client to communicate with Agentforce via the A2A protocol
- Agent Execution: Agentforce processes the request
- Data Retrieval: Agent fetches stock prices, company profiles, or earnings data using Heroku AppLink for API calls
- Response Synthesis: MIA receives the tool result and generates a conversational response
- Streaming Display: Response streams back to user via SSE in real-time
Direct A2A Mode Flow:
- Agent Discovery: Client fetches agent card from
/.well-known/a2a/agent-card.json - Session Creation: First message creates a new Agentforce session
- Message Streaming: User message sent via A2A JSON-RPC protocol
- Agent Processing: FinancialAgentExecutor handles the request with session reuse
- Salesforce Integration: Heroku AppLink provides authorized access to Salesforce APIs
- Real-time Streaming: Artifact-update events push response chunks immediately
- Client Rendering: React frontend displays streaming responses with markdown formatting
Demo
Architecture Diagram - Orchestrator Mode

Architecture Diagram - Direct Mode

Orchestrator Mode Demo

API Specification
A2A Protocol Endpoints
GET /.well-known/a2a/agent-card.json
- Returns the A2A agent card for agent discovery
- No authentication required
- Response includes agent capabilities, identity, and service configuration
POST /a2a/jsonrpc
- JSON-RPC 2.0 endpoint for A2A protocol messages
- Handles
agent.sendMessage,agent.startTask, and streaming task execution - Uses A2A SDK
jsonRpcHandlerfor protocol compliance - Returns streaming task updates via artifact-update events
POST /a2a/rest
- RESTful alternative to JSON-RPC endpoint
- Same functionality as JSON-RPC but with REST semantics
- Uses A2A SDK
restHandlerfor protocol compliance
Orchestrator Endpoint
POST /api/orchestrator/chat
- Intelligent agent orchestration powered by Heroku MIA
- Headers:
Content-Type: application/json - Body:
{ messages: Array<{ role: "user" | "assistant" | "system", content: string }> } - Returns: Server-Sent Events stream with content and tool results
- Event Types:
{ type: "content", content: string }- Streaming response chunks{ type: "tool_result", tool: "agentforce", content: string }- Agentforce responsesdata: [DONE]- Stream completion marker
Authentication:
Bearer token authentication using INFERENCE_KEY environment variable
Technologies Used
Client
- React - 19.2.0 - UI framework
- TypeScript - Type-safe JavaScript
- Vite - Build tool and dev server
- Tailwind CSS - 4.1.18 - Utility-first CSS framework
- react-markdown - Markdown rendering for chat messages
- A2A SDK - 0.3.9 - Agent-to-Agent Protocol JavaScript SDK
Server
- Node.js - JavaScript runtime
- TypeScript - Type-safe JavaScript
- Express - 5.2.1 - Web framework
- A2A SDK - 0.3.9 - A2A Protocol server implementation
- Heroku AppLink - Salesforce authentication and API access
- Salesforce Agentforce API v1 - AI agent integration
- Heroku Managed Inference and Agents - Claude 4.5 Sonnet orchestration
- HMAC-SHA256 - Request signature validation
For a more detailed overview of the development & production dependencies, please check server package.json or client package.json.
Configuration
Requirements
To run this application locally, you will need the following:
- Node.js version 20 or later installed (type
node -vin your terminal to check). Follow instructions if you don't have node installed - npm version 10.0.0 or later installed (type
npm -vin your terminal to check). Node.js includesnpm - git installed. Follow the instructions to install git
- A Salesforce account enabled with Agentforce
- Heroku account with access to Managed Inference and Agents
- Heroku AppLink setup in your Salesforce org (see setup instructions below)
- (Optional) Finnhub API key if you want to use external financial data API
Setup
Local Environment Configuration
-
Clone the repository
git clone https://github.com/mvrzan/salesforce-agentforce-a2a-wrapper.git cd salesforce-agentforce-a2a-wrapper -
Configure Heroku AppLink
Important: This application uses Heroku AppLink to authenticate with Salesforce. You need to configure AppLink in your Salesforce org first.
Follow the Heroku AppLink documentation to:
- Create a Connected App in Salesforce
- Configure OAuth scopes (api, refresh_token, offline_access)
- Add your Heroku app to the AppLink configuration
-
Configure Server Environment Variables
Copy the example file and fill in your credentials:
cd server/src cp .env.example .envEdit
server/src/.envwith your values:# Salesforce Agentforce Configuration AGENTFORCE_AGENT_ID=your_agentforce_agent_id # Heroku AppLink Configuration APP_LINK_CONNECTION_NAME=your_applink_connection_name # Heroku Managed Inference and Agents (Claude 4.5 Sonnet) INFERENCE_URL=your_heroku_inference_url INFERENCE_KEY=your_heroku_inference_api_key INFERENCE_MODEL_ID=your_selected_llm_model # API Security, example: 81144c5228d0 API_SECRET=your_generated_secret_key # Server Configuration APP_URL=http://localhost:3000 APP_PORT=3000 # External APIs (Optional) FINHUB_API_KEY=your_finhub_api_keyGenerate a secure API secret:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"⚠️ Note: The client does not require environment variables. It automatically detects whether it's running on localhost or in production and adjusts API URLs accordingly.
-
Install Dependencies
Install server dependencies:
cd ../server npm installInstall client dependencies:
cd ../client npm install -
Start the Application
Start the server (from the
serverdirectory):npm run devIn a new terminal, start the client (from the
clientdirectory):npm run dev -
Access the Application
Open your browser and navigate to
http://localhost:5173
Salesforce configuration
Agent creation
First step is to create an Agentforce Agent by following official instructions.
Agent Data Library
Ensure you have the Agent Data Library configured with the latest Salesforce earnings report.
Heroku AppLink with Agentforce
Once your Agent is successfully configured, it is time to set up the Heroku AppLink connection.
Topics
The agent needs the following Topics:
Classification Description:
Fetch and provide formatted information from various earnings reports using the Agenforce Data Library.
Scope:
My job is only to retrieve relevant information from the Agenforce Data Library based on user queries about earnings reports and provide the information in a formatted manner. I will not handle unrelated queries or perform tasks outside of fetching and formatting earnings report data.
Instruction 1:
Use the Agenforce Data Library to search for relevant earnings report data based on the user's query.
Instruction 2:
Ensure the information retrieved is accurate and corresponds to the user's request.
Instruction 3:
Format the retrieved data clearly and concisely before presenting it to the user.
Instruction 4:
If the requested information is unavailable, inform the user and provide alternative options if applicable.
Instruction 5:
Ask clarifying questions to better understand the user's specific needs regarding the earnings reports.
Action: Use Answer Questions with Knowledge and select your Agentforce Data Library.
Classification Description:
Handles requests to retrieve stock prices and company information based on a provided stock symbol.
Scope:
Your job is only to retrieve either the stock price or company information based on the stock symbol provided by the user, using external APIs.
Instruction 1:
Use the Agenforce Data Library to search for relevant earnings report data based on the user's query.
Instruction 2:
If a user provides a stock symbol, call the external API to retrieve the stock price.
Instruction 3:
Ask the user for clarification if the request is ambiguous or if the stock symbol is missing.
Instruction 4:
Provide the retrieved information clearly and concisely to the user.
Action 1: Select the Get_Stock_Price action from your Heroku AppLink connection.
Action 2: Select the Get_Company_Profile action from your Heroku AppLink connection.
Once you are done, make sure to Publish your Agent.
Heroku AppLink with JWT
In order to allow Agentforce API invocation from the Heroku server, ensure Heroku AppLink integration with JWT is configured.
Deployment
Heroku Deployment
Once you are happy with your application, you can deploy it to Heroku!
Prerequisites:
- Heroku CLI installed
- Heroku account created
- Heroku AppLink configured in your Salesforce org
Deployment Steps:
-
Create a Heroku App
heroku create your-app-name -
Set Environment Variables
Configure all required environment variables in Heroku:
heroku config:set AGENTFORCE_AGENT_ID=your_agentforce_agent_id heroku config:set APP_LINK_CONNECTION_NAME=your_applink_connection_name heroku config:set INFERENCE_URL=https://us.inference.heroku.com heroku config:set INFERENCE_KEY=your_heroku_inference_api_key heroku config:set INFERENCE_MODEL_ID=claude-4-5-sonnet heroku config:set API_SECRET=your_generated_secret_key heroku config:set FINHUB_API_KEY=your_finhub_api_key heroku config:set VITE_API_SECRET=your_finhub_api_key heroku config:set VITE_API_URL=your_finhub_api_key -
Configure AppLink Addon
Add and configure the Heroku AppLink addon.
-
Configure MIA Addon
Add and configure the Heroku MIA addon.
-
Deploy to Heroku
git push heroku main -
Open Your App
heroku open
For more detailed deployment instructions, please follow the official Heroku documentation.
License
Disclaimer
This software is to be considered "sample code", a Type B Deliverable, and is delivered "as-is" to the user. Salesforce bears no responsibility to support the use or implementation of this software.