This document explores integration patterns between Salesforce Agentforce and Azure AI Foundry Agent Service using the Microsoft Agent Framework and Agent-to-Agent (A2A) protocol.
Research Date: November 2025
Key Technologies:
- Microsoft Agent Framework (Released October 2025)
- Azure AI Foundry Agent Service (GA May 2025)
- Salesforce Agentforce Platform (2025)
- A2A (Agent-to-Agent) Protocol
While both platforms provide robust agent capabilities, Salesforce Agentforce does not currently support the A2A protocol natively. There are four viable integration approaches, but understanding the distinction between Azure AI Foundry's managed service and Microsoft Agent Framework SDK is critical:
Azure AI Foundry Connected Agents (Managed Service):
- ✅ Multi-agent orchestration within Azure AI Foundry only
- ✅ Natural language routing between Azure agents
- ❌ NOT A2A protocol compatible
- ❌ Cannot connect to external agents (like Salesforce)
Microsoft Agent Framework (Separate SDK):
- ✅ Open-source SDK (C#, Python, TypeScript)
- ✅ A2A protocol support for external agents
- ✅ Can connect to remote agents via A2A
⚠️ Separate from Azure AI Foundry Agent Service⚠️ Requires custom development and orchestration code
For Salesforce A2A integration, you MUST use Microsoft Agent Framework SDK, not Azure AI Foundry's Connected Agents feature.
The Microsoft Agent Framework provides a unified approach to building multi-agent systems with:
- A2A Protocol Support: Connect to remote agents using open standards
- Unified
AIAgentInterface: Common abstraction for all agent types - Multi-Agent Orchestration: Built-in patterns for agent collaboration
- Language Support: C#, Python, TypeScript
A2A Protocol Features:
- Standard discovery via
/.well-known/agent-card.json - Agent Cards describing capabilities and endpoints
- Remote agent proxy pattern
- OAuth 2.0, Service Principal authentication
Documentation: Microsoft Agent Framework
Connected Agents (GA May 2025):
- Native multi-agent coordination
- Primary agent delegates to specialized sub-agents
- No custom orchestrator required
- Natural language routing
Agent Framework Integration:
- Works with Microsoft Agent Framework
- Can connect to remote A2A agents
- Full thread visibility for agent-to-agent messages
Documentation: Connected Agents
Core Components:
- Atlas Reasoning Engine: Autonomous decision-making
- Agent Builder: Low-code/no-code configuration
- Agent Script: Hybrid reasoning (deterministic + LLM)
- Data Cloud Integration: Customer 360 data access
- Multi-Channel Deployment: Voice, Web, Mobile
Integration Capabilities:
- REST APIs for programmatic access
- OAuth 2.0 authentication
- Apex and Flow Builder for business logic
- AgentExchange marketplace
- MCP (Model Context Protocol) partners
Documentation: Salesforce Agentforce
Description: Azure AI Foundry agent directly calls Salesforce REST APIs using the OpenAPI tool.
graph LR
A[Azure AI Foundry Agent] -->|OpenAPI Tool| B[Salesforce REST API]
B --> C[Salesforce Data Cloud]
B --> D[Agentforce Actions]
E[Microsoft Entra ID] -->|OAuth 2.0| B
style A fill:#0078D4,color:#fff
style B fill:#00A1E0,color:#fff
style C fill:#00A1E0,color:#fff
style D fill:#00A1E0,color:#fff
Implementation Steps:
-
Create OpenAPI 3.0 Specification
openapi: 3.0.0 info: title: Salesforce CRM API version: v60.0 servers: - url: https://your-instance.salesforce.com/services/data/v60.0 paths: /sobjects/Account/{id}: get: summary: Get Account Details parameters: - name: id in: path required: true schema: type: string
-
Configure Azure AI Foundry Agent
using Azure; using Azure.AI.Agents.Persistent; using Azure.Identity; var credential = new DefaultAzureCredential(); var client = new PersistentAgentsClient( "https://YOUR-RESOURCE.services.ai.azure.com/api/projects/YOUR-PROJECT", credential ); // Load OpenAPI specification BinaryData spec = BinaryData.FromBytes(File.ReadAllBytes("salesforce-api-spec.json")); // Configure authentication (using managed identity - recommended) OpenApiManagedAuthDetails managedAuth = new() { Audience = "https://your-instance.salesforce.com" }; // OR use anonymous auth for development // OpenApiAnonymousAuthDetails anonAuth = new(); // Create OpenAPI tool definition OpenApiToolDefinition openApiTool = new( name: "salesforce_api", description: "Access Salesforce CRM data via REST API", spec: spec, openApiAuthentication: managedAuth ); // Create agent with OpenAPI tool PersistentAgent agent = client.Administration.CreateAgent( model: "gpt-4o", name: "SalesforceIntegrationAgent", instructions: "You help users access and analyze Salesforce CRM data using the Salesforce API.", tools: [openApiTool] ); Console.WriteLine($"Created agent: {agent.Id}");
Pros:
- ✅ Real-time data access
- ✅ No data duplication
- ✅ Straightforward implementation
- ✅ Uses existing Salesforce APIs
Cons:
- ❌ API rate limits
- ❌ Latency for each API call
- ❌ No A2A protocol benefits
- ❌ Agentforce reasoning not leveraged
Best For: Simple CRUD operations, data queries, triggering Salesforce actions
Description: Build specialized Azure AI Foundry agents for different Salesforce operations, orchestrated by a main agent using Azure's native Connected Agents feature. Important: Connected Agents only coordinates between Azure agents within the same Azure AI Foundry project - it does NOT support A2A protocol or external agent communication.
graph TD
A[Main Azure Agent<br/>Orchestrator] -->|Connected Agent<br/>Azure-Internal Only| B[Salesforce Data Agent<br/>Azure]
A -->|Connected Agent<br/>Azure-Internal Only| C[Salesforce Analytics Agent<br/>Azure]
A -->|Connected Agent<br/>Azure-Internal Only| D[CRM Update Agent<br/>Azure]
B -->|Azure Functions Tool| E[Salesforce Query APIs]
C -->|Azure Functions Tool| F[Salesforce Reports API]
D -->|Azure Functions Tool| G[Salesforce Update APIs]
E --> H[Salesforce Data Cloud]
F --> H
G --> H
I[User Request] --> A
A --> J[Unified Response]
style A fill:#0078D4,color:#fff
style B fill:#50E6FF,color:#000
style C fill:#50E6FF,color:#000
style D fill:#50E6FF,color:#000
style H fill:#00A1E0,color:#fff
Implementation Steps:
-
Create Specialized Sub-Agents
using Azure; using Azure.AI.Agents.Persistent; using Azure.Identity; var credential = new DefaultAzureCredential(); var client = new PersistentAgentsClient( "https://YOUR-RESOURCE.services.ai.azure.com/api/projects/YOUR-PROJECT", credential ); // Assume azureFunctionsTool is already defined (Azure Functions tool definition) // Create Salesforce Data Agent PersistentAgent dataAgent = client.Administration.CreateAgent( model: "gpt-4o-mini", name: "SalesforceDataAgent", instructions: @"You retrieve customer data from Salesforce. Query accounts, contacts, opportunities, and cases. Use the Azure Functions tool to call Salesforce APIs.", tools: [azureFunctionsTool] ); // Create Salesforce Analytics Agent PersistentAgent analyticsAgent = client.Administration.CreateAgent( model: "gpt-4o-mini", name: "SalesforceAnalyticsAgent", instructions: @"You analyze Salesforce data and generate insights. Run reports, calculate metrics, identify trends.", tools: [azureFunctionsTool] ); // Create CRM Update Agent PersistentAgent updateAgent = client.Administration.CreateAgent( model: "gpt-4o-mini", name: "CRMUpdateAgent", instructions: @"You update Salesforce records safely. Validate data before updates. Log all changes.", tools: [azureFunctionsTool] );
-
Configure Main Orchestrator Agent
// Create connected agent tool definitions ConnectedAgentToolDefinition dataAgentTool = new( new ConnectedAgentDetails( dataAgent.Id, "SalesforceDataAgent", "Retrieves customer data from Salesforce CRM" ) ); ConnectedAgentToolDefinition analyticsAgentTool = new( new ConnectedAgentDetails( analyticsAgent.Id, "SalesforceAnalyticsAgent", "Analyzes Salesforce data and generates insights" ) ); ConnectedAgentToolDefinition updateAgentTool = new( new ConnectedAgentDetails( updateAgent.Id, "CRMUpdateAgent", "Updates Salesforce CRM records safely" ) ); // Create main orchestrator with connected agents PersistentAgent mainAgent = client.Administration.CreateAgent( model: "gpt-4o", name: "SalesforceOrchestrator", instructions: @"You help users with Salesforce CRM operations. Delegate data retrieval to SalesforceDataAgent. Delegate analysis to SalesforceAnalyticsAgent. Delegate updates to CRMUpdateAgent. Coordinate responses from multiple agents.", tools: [dataAgentTool, analyticsAgentTool, updateAgentTool] ); Console.WriteLine($"Created main agent: {mainAgent.Id}");
-
Create Azure Function for Salesforce API Calls
[FunctionName("SalesforceQuery")] public async Task<IActionResult> QuerySalesforce( [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req) { // Parse request var requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var query = JsonSerializer.Deserialize<SalesforceQueryRequest>(requestBody); // Call Salesforce API var salesforceClient = new SalesforceClient( instanceUrl: Environment.GetEnvironmentVariable("SALESFORCE_INSTANCE_URL"), accessToken: await GetSalesforceToken() ); var result = await salesforceClient.QueryAsync(query.SoqlQuery); return new OkObjectResult(result); }
Pros:
- ✅ Built-in orchestration (no custom code)
- ✅ Specialized agents for different tasks
- ✅ Full Azure observability and tracing
- ✅ Scalable architecture
- ✅ Easy to extend with new agents
- ✅ Native Azure AI Foundry managed service
Cons:
- ❌ All agents must be Azure AI Foundry agents (no external agents)
- ❌ NOT A2A protocol compatible
- ❌ Cannot connect to external Salesforce agents
- ❌ Agentforce reasoning capabilities not directly used
- ❌ More complex setup than Option 1
Best For: Complex workflows with multiple specialized Azure agents, when all logic stays within Azure AI Foundry ecosystem
Description: Use Microsoft Agent Framework (separate SDK, not Azure AI Foundry's Connected Agents) to build an A2A-compliant wrapper around Salesforce APIs. This enables true Agent-to-Agent communication using the A2A protocol. Note: This requires using Microsoft Agent Framework SDK, which is separate from Azure AI Foundry Agent Service.
graph LR
A[Your Agent<br/>Microsoft Agent Framework SDK] -->|A2A Protocol| B[Custom A2A Wrapper<br/>Azure Container Instance]
B -->|/.well-known/<br/>agent-card.json| A
B -->|Salesforce REST API| C[Salesforce Platform]
C --> D[Agentforce]
C --> E[Data Cloud]
C --> F[Einstein AI]
G[Microsoft Agent<br/>Framework SDK<br/>NOT Azure Foundry] -.->|Required for A2A| A
H[OAuth 2.0] -->|Authenticate| B
style A fill:#0078D4,color:#fff
style B fill:#FFA500,color:#fff
style C fill:#00A1E0,color:#fff
style D fill:#00A1E0,color:#fff
style E fill:#00A1E0,color:#fff
style F fill:#00A1E0,color:#fff
style G fill:#FFA500,color:#fff
A2A Protocol Flow:
sequenceDiagram
participant Azure as Azure AI Foundry Agent
participant Framework as Microsoft Agent Framework
participant Wrapper as A2A Wrapper
participant SF as Salesforce API
Azure->>Framework: Discover Salesforce agent
Framework->>Wrapper: GET /.well-known/agent-card.json
Wrapper-->>Framework: Agent Card (capabilities)
Framework-->>Azure: Salesforce agent available
Azure->>Framework: Send task to Salesforce agent
Framework->>Wrapper: POST /a2a/task<br/>(A2A message)
Wrapper->>SF: Translate to Salesforce API call
SF-->>Wrapper: API response
Wrapper-->>Framework: A2A response
Framework-->>Azure: Task result
Implementation Steps:
-
Create Agent Card for Salesforce Capabilities
{ "name": "Salesforce Agentforce", "description": "Access Salesforce CRM data and Agentforce capabilities", "version": "1.0.0", "capabilities": [ { "name": "query_accounts", "description": "Query Salesforce accounts", "input_schema": { "type": "object", "properties": { "filters": { "type": "object" }, "fields": { "type": "array" } } } }, { "name": "create_opportunity", "description": "Create a sales opportunity", "input_schema": { "type": "object", "properties": { "account_id": { "type": "string" }, "amount": { "type": "number" }, "close_date": { "type": "string" } } } }, { "name": "agentforce_analyze", "description": "Use Agentforce to analyze customer data", "input_schema": { "type": "object", "properties": { "query": { "type": "string" }, "context": { "type": "object" } } } } ], "endpoints": { "task": "https://your-wrapper.azurewebsites.net/a2a/task" }, "authentication": { "type": "oauth2", "authorization_url": "https://login.salesforce.com/services/oauth2/authorize", "token_url": "https://login.salesforce.com/services/oauth2/token" } } -
Build A2A Wrapper Server (C#)
using Microsoft.AspNetCore.Mvc; using A2A; [ApiController] [Route("a2a")] public class SalesforceA2AController : ControllerBase { private readonly ISalesforceClient _salesforceClient; // Expose agent card at well-known location [HttpGet(".well-known/agent-card.json")] public IActionResult GetAgentCard() { var agentCard = LoadAgentCardFromConfig(); return Ok(agentCard); } // Handle A2A task requests [HttpPost("task")] public async Task<IActionResult> HandleTask([FromBody] A2ATaskRequest request) { try { // Translate A2A message to Salesforce API call var salesforceResult = request.Capability switch { "query_accounts" => await _salesforceClient.QueryAccountsAsync( request.Input["filters"], request.Input["fields"] ), "create_opportunity" => await _salesforceClient.CreateOpportunityAsync( request.Input ), "agentforce_analyze" => await _salesforceClient.InvokeAgentforceAsync( request.Input["query"], request.Input["context"] ), _ => throw new NotSupportedException($"Capability {request.Capability} not supported") }; // Return A2A response return Ok(new A2ATaskResponse { Status = "completed", Result = salesforceResult }); } catch (Exception ex) { return Ok(new A2ATaskResponse { Status = "failed", Error = ex.Message }); } } }
-
Connect Using Microsoft Agent Framework with A2A
Important: This uses Microsoft Agent Framework SDK (separate from Azure AI Foundry), not Azure AI Foundry's Connected Agents feature. The Agent Framework returns
AIAgentinterface which is NOT compatible with Azure AI Foundry'sPersistentAgent.using System; using A2A; using Microsoft.Agents.AI; using Microsoft.Agents.AI.A2A; // Option 1: Well-known discovery (recommended for production) A2ACardResolver agentCardResolver = new(new Uri("https://your-wrapper.azurewebsites.net")); // Discover Salesforce agent via A2A protocol (looks for /.well-known/agent-card.json) AIAgent salesforceAgent = await agentCardResolver.GetAIAgentAsync(); // Option 2: Direct configuration (for development/private discovery) // A2AClient a2aClient = new(new Uri("https://your-wrapper.azurewebsites.net/salesforce")); // AIAgent salesforceAgent = a2aClient.GetAIAgent(); // Now you can interact with the salesforceAgent using standard AIAgent operations // Note: This is Microsoft Agent Framework, NOT Azure AI Foundry // You would need to use Agent Framework's orchestration patterns // See: https://learn.microsoft.com/agent-framework/tutorials/overview // Example interaction (Agent Framework pattern): var thread = salesforceAgent.GetNewThread(); await foreach (var message in salesforceAgent.InvokeAsync("Get account details for Contoso", thread)) { Console.WriteLine(message.Content); }
Note: Microsoft Agent Framework A2A agents return
AIAgentinterface and use Agent Framework orchestration. This is fundamentally different from Azure AI Foundry'sPersistentAgentsClientwhich returnsPersistentAgent. You cannot mix the two SDKs.
Pros:
- ✅ True A2A protocol compliance
- ✅ Future-proof if Salesforce adds native A2A
- ✅ Extensible architecture
- ✅ Can expose Agentforce reasoning capabilities
- ✅ Standard discovery and capability negotiation
- ✅ Works with Microsoft Agent Framework SDK
Cons:
- ❌ Requires Microsoft Agent Framework SDK (separate from Azure AI Foundry)
- ❌ Custom development and maintenance for wrapper
- ❌ Additional infrastructure (wrapper service hosting)
- ❌ Salesforce doesn't natively support A2A
- ❌ More complex than direct API integration
- ❌ Cannot use Azure AI Foundry's Connected Agents (different architecture)
- ❌ Custom orchestration code required
Best For: Organizations using Microsoft Agent Framework for multi-platform agent orchestration, future-proofing for A2A ecosystem
Microsoft.Agents.AI.A2A NuGet package. Azure AI Foundry Connected Agents does NOT support A2A or external agents.
Description: Extract Salesforce knowledge into Azure AI Search for semantic search capabilities, while maintaining bidirectional communication for actions.
graph TD
A[Salesforce Data Cloud] -->|ETL Pipeline<br/>Nightly Sync| B[Azure Data Factory]
B --> C[Azure AI Search<br/>Vector Index]
D[Azure AI Foundry Agent] -->|Azure AI Search Tool| C
D -->|Query Embeddings| C
C -->|Semantic Results| D
E[Agentforce] -->|Webhook Events| F[Azure Functions]
F -->|Trigger| D
D -->|REST API<br/>Update Actions| G[Salesforce APIs]
G --> A
H[User Query] --> D
D --> I[AI Response with<br/>Salesforce Context]
style A fill:#00A1E0,color:#fff
style B fill:#0078D4,color:#fff
style C fill:#0078D4,color:#fff
style D fill:#0078D4,color:#fff
style E fill:#00A1E0,color:#fff
Data Flow:
sequenceDiagram
participant SF as Salesforce
participant ADF as Azure Data Factory
participant Search as Azure AI Search
participant Agent as Azure AI Foundry Agent
participant User as User
Note over SF,Search: Nightly Knowledge Sync
SF->>ADF: Extract data (Accounts, Contacts, Cases)
ADF->>ADF: Transform to JSON + Generate embeddings
ADF->>Search: Index documents with vectors
Note over Agent,User: User Query
User->>Agent: "Find high-value customers in tech sector"
Agent->>Search: Semantic search query
Search-->>Agent: Ranked results with context
Agent->>Agent: Reason about results
Agent-->>User: "Here are 5 enterprise tech customers..."
Note over SF,Agent: Real-time Action
SF->>Azure Functions: Webhook: New high-value opportunity
Azure Functions->>Agent: Trigger analysis
Agent->>SF: Update opportunity score via API
Implementation Steps:
-
Set Up ETL Pipeline (Azure Data Factory)
{ "name": "Salesforce-to-AzureSearch-Pipeline", "properties": { "activities": [ { "name": "ExtractSalesforceData", "type": "Copy", "source": { "type": "SalesforceSource", "query": "SELECT Id, Name, Industry, AnnualRevenue, Description FROM Account WHERE IsDeleted = false" }, "sink": { "type": "JsonSink" } }, { "name": "GenerateEmbeddings", "type": "AzureFunction", "functionName": "GenerateEmbeddings" }, { "name": "IndexToAzureSearch", "type": "Copy", "source": { "type": "JsonSource" }, "sink": { "type": "AzureSearchIndexSink" } } ], "triggers": [ { "name": "NightlySync", "type": "ScheduleTrigger", "recurrence": { "frequency": "Day", "interval": 1, "startTime": "2025-01-01T02:00:00Z" } } ] } } -
Create Azure AI Search Index with Vector Fields
using Azure.Search.Documents.Indexes; using Azure.Search.Documents.Indexes.Models; var indexDefinition = new SearchIndex("salesforce-knowledge") { Fields = new[] { new SearchField("id", SearchFieldDataType.String) { IsKey = true }, new SearchField("name", SearchFieldDataType.String) { IsSearchable = true }, new SearchField("industry", SearchFieldDataType.String) { IsFacetable = true }, new SearchField("description", SearchFieldDataType.String) { IsSearchable = true }, new SearchField("annualRevenue", SearchFieldDataType.Double) { IsSortable = true }, new SearchField("descriptionVector", SearchFieldDataType.Collection(SearchFieldDataType.Single)) { VectorSearchDimensions = 1536, VectorSearchProfileName = "vector-profile" } }, VectorSearch = new VectorSearch { Profiles = { new VectorSearchProfile("vector-profile", "vector-config") }, Algorithms = { new HnswAlgorithmConfiguration("vector-config") } } }; await searchIndexClient.CreateIndexAsync(indexDefinition);
-
Configure Azure Agent with AI Search Tool
// Create Azure AI Search tool var azureSearchTool = new AzureAISearchToolDefinition( searchResourceName: "your-search-service", indexName: "salesforce-knowledge", authentication: new AzureAISearchAuthConfig { Type = AzureAISearchAuthType.ManagedIdentity } ); // Create agent with AI Search tool var agent = await client.Administration.CreateAgentAsync( model: "gpt-4o", name: "SalesforceKnowledgeAgent", instructions: @"You help users find and analyze Salesforce customer data. Use Azure AI Search to find relevant customers, accounts, and opportunities. Provide insights based on semantic similarity and business context. When users request updates, use the OpenAPI tool to call Salesforce APIs.", tools: new ToolDefinition[] { azureSearchTool, salesforceOpenApiTool } );
-
Set Up Salesforce Webhooks for Real-Time Events
// Salesforce Apex Trigger trigger OpportunityWebhook on Opportunity (after insert, after update) { if (Trigger.isAfter) { for (Opportunity opp : Trigger.new) { if (opp.Amount > 100000 && opp.StageName == 'Prospecting') { // Send webhook to Azure Functions HttpRequest req = new HttpRequest(); req.setEndpoint('https://your-function-app.azurewebsites.net/api/opportunity-event'); req.setMethod('POST'); req.setHeader('Content-Type', 'application/json'); req.setBody(JSON.serialize(opp)); Http http = new Http(); HttpResponse res = http.send(req); } } } }
Pros:
- ✅ Semantic search capabilities
- ✅ Vector similarity for finding relevant data
- ✅ Hybrid search (keyword + vector)
- ✅ Fast query performance
- ✅ Bidirectional integration (read + write)
Cons:
- ❌ Data duplication
- ❌ Eventual consistency (sync lag)
- ❌ ETL pipeline complexity
- ❌ Storage costs for indexed data
Best For: Knowledge-intensive scenarios, semantic search requirements, large-scale data analysis
| Feature | Option 1: Direct API |
Option 2: Connected Agents |
Option 3: A2A Wrapper |
Option 4: AI Search |
|---|---|---|---|---|
| Complexity | Low | Medium | High | High |
| Real-time Data | ✅ Yes | ✅ Yes | ✅ Yes | ❌ Eventual |
| Semantic Search | ❌ No | ❌ No | ❌ No | ✅ Yes |
| A2A Protocol | ❌ No | ❌ No | ✅ Yes | ❌ No |
| Azure Managed | ✅ Yes | ✅ Yes | ❌ No | ✅ Yes |
| External Agents | ❌ No | ❌ No | ✅ Yes | ❌ No |
| Requires Custom SDK | ❌ No | ❌ No | ✅ Agent Framework | ❌ No |
| Agentforce Reasoning | ✅ Possible | ❌ No | ||
| Setup Time | 1-2 days | 3-5 days | 2-3 weeks | 1-2 weeks |
| Maintenance | Low | Low | Medium-High | Medium |
| Scalability | Medium | High | High | Very High |
| Cost | Low | Medium | Medium-High | Medium-High |
| Future-Proof | Medium | Medium | Very High | High |
For an educational research repository, document all four options in this sequence:
Start with Option 1 - Direct API Integration
- Simple to understand and implement
- Teaches basic agent-to-external-system patterns
- Quick wins for students
- Code Example: OpenAPI tool configuration
Progress to Option 2 - Connected Agents
- Shows Azure's native multi-agent capabilities
- Teaches enterprise orchestration patterns
- Prepares for complex scenarios
- Code Example: Multi-agent coordination
Explore Option 3 - A2A Wrapper
- Advanced topic for protocol implementation
- Future-proofs knowledge base
- Teaches standards-based integration
- Code Example: Custom A2A server
Implement Option 4 - Azure AI Search
- Shows RAG patterns with external systems
- Teaches vector search and embeddings
- Best for knowledge-heavy scenarios
- Code Example: ETL pipeline + semantic search
using Azure;
using Azure.AI.Agents.Persistent;
using Azure.Identity;
var credential = new DefaultAzureCredential();
var client = new PersistentAgentsClient(
"https://YOUR-RESOURCE.services.ai.azure.com/api/projects/YOUR-PROJECT",
credential
);
// Load OpenAPI spec from file
BinaryData spec = BinaryData.FromBytes(File.ReadAllBytes("salesforce-api-spec.json"));
// Configure authentication - using managed identity (recommended)
OpenApiManagedAuthDetails managedAuth = new()
{
Audience = "https://your-instance.salesforce.com"
};
// Create OpenAPI tool definition
OpenApiToolDefinition openApiTool = new(
name: "salesforce",
description: "Access Salesforce CRM data via REST API",
spec: spec,
openApiAuthentication: managedAuth
);
// Create agent with tool
PersistentAgent agent = client.Administration.CreateAgent(
model: "gpt-4o",
name: "SalesforceAgent",
instructions: "You are a helpful assistant that provides Salesforce CRM data access.",
tools: [openApiTool]
);
Console.WriteLine($"Created agent: {agent.Id}");using Azure;
using Azure.AI.Agents.Persistent;
using Azure.Identity;
var credential = new DefaultAzureCredential();
var client = new PersistentAgentsClient(
"https://YOUR-RESOURCE.services.ai.azure.com/api/projects/YOUR-PROJECT",
credential
);
// Create specialized agents (assume tools are defined)
PersistentAgent dataAgent = client.Administration.CreateAgent(
model: "gpt-4o-mini",
name: "DataAgent",
instructions: "You retrieve Salesforce data using Azure Functions.",
tools: [azureFunctionsTool]
);
PersistentAgent analyticsAgent = client.Administration.CreateAgent(
model: "gpt-4o-mini",
name: "AnalyticsAgent",
instructions: "You analyze data and provide insights.",
tools: [azureFunctionsTool]
);
// Create connected agent tool definitions
ConnectedAgentToolDefinition dataAgentTool = new(
new ConnectedAgentDetails(dataAgent.Id, "DataAgent", "Retrieves data")
);
ConnectedAgentToolDefinition analyticsAgentTool = new(
new ConnectedAgentDetails(analyticsAgent.Id, "AnalyticsAgent", "Analyzes data")
);
// Create main orchestrator
PersistentAgent mainAgent = client.Administration.CreateAgent(
model: "gpt-4o",
name: "Orchestrator",
instructions: "Coordinate between data retrieval and analysis agents.",
tools: [dataAgentTool, analyticsAgentTool]
);
// Create thread and send message
PersistentAgentThread thread = client.Threads.CreateThread();
client.Messages.CreateMessage(
thread.Id,
MessageRole.User,
"Find the top 10 accounts by revenue and analyze trends"
);
ThreadRun run = client.Runs.CreateRun(thread.Id, mainAgent.Id);Important: This example uses Microsoft Agent Framework SDK, NOT Azure AI Foundry SDK.
using System;
using A2A;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.A2A;
// Discover Salesforce agent via A2A protocol
A2ACardResolver resolver = new(new Uri("https://salesforce-a2a-wrapper.azurewebsites.net"));
// Get agent from well-known location (/.well-known/agent-card.json)
AIAgent salesforceAgent = await resolver.GetAIAgentAsync();
Console.WriteLine($"Connected to A2A agent: {salesforceAgent.Name}");
// Use the agent (Microsoft Agent Framework patterns)
var thread = salesforceAgent.GetNewThread();
await foreach (var message in salesforceAgent.InvokeAsync(
"Get account details for Contoso Corporation",
thread))
{
Console.WriteLine($"Response: {message.Content}");
}Note: AIAgent from Agent Framework is NOT compatible with Azure AI Foundry's PersistentAgent. These are two separate SDK architectures.
// Configure Salesforce connected app in Entra ID
var authConfig = new OpenApiAuthConfig
{
Type = OpenApiAuthType.OAuth,
ClientId = "YOUR_ENTRA_APP_ID",
ClientSecret = "YOUR_ENTRA_APP_SECRET",
AuthorizationUrl = "https://login.microsoftonline.com/YOUR_TENANT/oauth2/v2.0/authorize",
TokenUrl = "https://login.microsoftonline.com/YOUR_TENANT/oauth2/v2.0/token",
Scopes = new[] { "https://your-instance.salesforce.com/.default" }
};using Azure.Identity;
// Use Managed Identity for authentication
var credential = new DefaultAzureCredential();
// Azure automatically handles token acquisition and refresh
var client = new PersistentAgentsClient(endpoint, credential);- Never hardcode credentials - Use Azure Key Vault or environment variables
- Implement least privilege - Grant only necessary Salesforce API permissions
- Use managed identities - Leverage Azure Managed Identity when possible
- Audit all actions - Log agent-to-Salesforce communications
- Implement rate limiting - Respect Salesforce API limits
- Cache frequently accessed data - Reduce API calls
- Use batch operations - Combine multiple Salesforce operations
- Implement connection pooling - Reuse HTTP connections
- Monitor latency - Track response times for optimization
- Use async/await - Non-blocking operations for better throughput
- Implement retry logic - Handle transient failures
- Use circuit breakers - Prevent cascading failures
- Monitor API quotas - Track Salesforce API usage
- Implement fallback strategies - Graceful degradation
- Test error scenarios - Validate error handling
When Salesforce potentially adds native A2A protocol support:
- Option 3 becomes preferred - Direct A2A connection without wrapper
- Simplified architecture - Remove custom wrapper layer
- Agentforce reasoning - Direct access to Agentforce capabilities
- Standard discovery - Use Salesforce's official agent card
As the agent ecosystem evolves:
- Multiple A2A agents - Connect to various SaaS platforms
- Agent marketplaces - Discover and integrate pre-built agents
- Standard protocols - Industry-wide agent communication standards
- Enterprise agent networks - Internal agent collaboration
A: No. Azure AI Foundry's Connected Agents feature is for coordinating agents within the same Azure AI Foundry project only. It does NOT support:
- A2A (Agent-to-Agent) protocol
- External agent connections
- Remote agent proxies
- Salesforce or any non-Azure agents
Connected Agents uses natural language routing between Azure-managed agents in your project. It's a managed service feature, not an A2A client.
A: Microsoft Agent Framework SDK (separate open-source project). This SDK provides:
Microsoft.Agents.AI.A2ANuGet packageA2ACardResolverandA2AClientclasses- A2A protocol implementation
- Remote agent proxy capabilities
You would need to:
- Use Microsoft Agent Framework SDK (NOT Azure AI Foundry Agent Service)
- Build a custom A2A wrapper around Salesforce APIs
- Write custom orchestration code
- Host your own infrastructure
A: No. Based on official Microsoft documentation (as of November 2025):
- Semantic Kernel is actively maintained
- Agent orchestration features are marked "experimental" but under active development
- Microsoft Agent Framework is described as a "progression" of Semantic Kernel + AutoGen
- Both SDKs coexist; Agent Framework combines patterns from both
Clarification: Microsoft Agent Framework represents the evolution of multi-agent orchestration, combining best practices from Semantic Kernel and AutoGen into a unified SDK. Semantic Kernel continues as an enterprise AI SDK.
A: It's separate. They serve different purposes:
Azure AI Foundry Agent Service (Managed PaaS):
- Managed agent runtime
- Built-in tools (Azure AI Search, Bing, Functions, etc.)
- Thread management, observability, content filters
- Enterprise features (RBAC, VNet, BYOS)
- Connected Agents for internal multi-agent
Microsoft Agent Framework (SDK):
- Open-source development kit
- Custom orchestration patterns
- A2A protocol support
- Requires custom hosting and infrastructure
- Flexibility for multi-platform agent systems
You could potentially use Agent Framework SDK to build agents that call Azure AI Foundry agents via APIs, but they are architecturally distinct approaches.
Decision Tree:
-
Simple API calls to Salesforce → Option 1 (OpenAPI Tool)
- Real-time data access
- Easiest to implement
- No custom orchestration
-
Complex workflows within Azure only → Option 2 (Connected Agents)
- Multiple specialized Azure agents
- Natural language routing
- Fully managed by Azure
-
True A2A protocol with external agents → Option 3 (Agent Framework + A2A Wrapper)
- Requires Microsoft Agent Framework SDK
- Custom development
- Future-proof for A2A ecosystem
- Most complex
-
Knowledge-intensive scenarios → Option 4 (Azure AI Search)
- Semantic search capabilities
- Vector similarity
- Eventual consistency acceptable
- Microsoft Agent Framework
- A2A Protocol Specification
- Azure AI Foundry Connected Agents
- Azure AI Foundry Agent Service
While Salesforce Agentforce and Azure AI Foundry Agent Service don't currently support direct A2A protocol integration, there are four viable approaches for enabling agent collaboration. However, it's critical to understand the architectural distinctions:
-
Azure AI Foundry Connected Agents ≠ A2A Protocol
- Connected Agents is for internal Azure agent coordination only
- Does NOT connect to external agents
- Does NOT support A2A protocol
- Managed service with natural language routing
-
For True A2A Integration: Use Microsoft Agent Framework
- Separate open-source SDK (not Azure AI Foundry managed service)
- Provides A2A protocol support
- Requires custom development and hosting
- Can connect to remote agents via A2A
-
Semantic Kernel Status
- NOT deprecated - actively maintained
- Agent orchestration features are experimental
- Microsoft Agent Framework is a progression (combining SK + AutoGen)
- Both SDKs coexist for different use cases
- Direct API Integration (Option 1) - Simplest approach using OpenAPI tools, no A2A
- Connected Agents (Option 2) - Azure's native multi-agent for internal agents only
- Agent Framework + A2A Wrapper (Option 3) - True A2A protocol (requires separate SDK)
- Knowledge Integration (Option 4) - Semantic search with Azure AI Search
Each approach has trade-offs in complexity, capabilities, and maintenance requirements. For educational purposes, documenting all four patterns provides comprehensive coverage of modern agent integration techniques.
Recommendation:
- Start with Option 1 for quick wins and learning basic patterns
- Progress to Option 2 to understand Azure's managed multi-agent capabilities
- Explore Option 3 only if you need true A2A protocol and are willing to use Agent Framework SDK
- Implement Option 4 for knowledge-intensive scenarios with semantic search
Document Version: 1.1 (Corrected)
Last Updated: November 6, 2025
Corrections: Clarified distinction between Azure AI Foundry Connected Agents (managed, Azure-only) and Microsoft Agent Framework (SDK, A2A support). Corrected Semantic Kernel deprecation status (NOT deprecated).
Authors: Azure AI Foundry Agent Service Research Team