sf-agent-framework
Version:
AI Agent Orchestration Framework for Salesforce Development - Two-phase architecture with 70% context reduction
504 lines (391 loc) • 11.4 kB
Markdown
# MCP Integration Patterns for Salesforce
## Overview
This document provides proven patterns and best practices for implementing Model
Context Protocol (MCP) integrations with Salesforce, based on industry standards
and emerging practices.
## Core Integration Patterns
### 1. Direct API Pattern
**Use Case**: Simple, direct access to Salesforce data for AI agents
```javascript
// Pattern: Direct MCP-to-Salesforce API
class DirectAPIPattern {
constructor(connection) {
this.connection = connection;
}
async query(soql) {
// Direct pass-through with validation
const validated = this.validateSOQL(soql);
return await this.connection.query(validated);
}
}
```
**Benefits**:
- Simple implementation
- Low latency
- Direct data access
**Considerations**:
- API limits apply directly
- Less control over data transformation
- Security validation required
### 2. Gateway Pattern
**Use Case**: Enterprise environments requiring centralized control
```yaml
Architecture: AI_Agents -> MCP_Gateway -> MCP_Servers -> Salesforce
Components:
gateway:
- Authentication proxy
- Rate limiting
- Request routing
- Audit logging
benefits:
- Centralized security
- Unified monitoring
- Policy enforcement
- Multi-system support
```
### 3. Cache-Aside Pattern
**Use Case**: High-volume read operations with acceptable staleness
```javascript
class CacheAsidePattern {
constructor(mcpServer, cache) {
this.server = mcpServer;
this.cache = cache;
}
async query(soql) {
const cacheKey = this.generateKey(soql);
// Check cache first
const cached = await this.cache.get(cacheKey);
if (cached) return cached;
// Fetch from Salesforce
const result = await this.server.query(soql);
// Cache for future requests
await this.cache.set(cacheKey, result, this.ttl);
return result;
}
}
```
### 4. Event-Driven Pattern
**Use Case**: Real-time AI responses to Salesforce changes
```javascript
// Pattern: Salesforce Platform Events to MCP
class EventDrivenPattern {
constructor() {
this.eventSubscriptions = new Map();
}
subscribeToPlatformEvent(eventName, handler) {
// Subscribe to Salesforce Platform Event
this.connection.streaming.topic(`/event/${eventName}`).subscribe(async (message) => {
// Transform event for MCP
const mcpEvent = this.transformEvent(message);
// Notify AI agents
await this.notifyAgents(mcpEvent);
// Execute handler
await handler(mcpEvent);
});
}
}
```
### 5. Bulk Operation Pattern
**Use Case**: Large-scale data operations initiated by AI
```javascript
class BulkOperationPattern {
constructor(connection) {
this.connection = connection;
this.bulkThreshold = 200; // Records
}
async createRecords(objectType, records) {
if (records.length < this.bulkThreshold) {
// Use standard API
return await this.connection.sobject(objectType).create(records);
}
// Use Bulk API 2.0
const job = this.connection.bulk2.createJob({
object: objectType,
operation: 'insert',
});
const batch = await job.open();
await batch.execute(records);
await batch.close();
return await this.waitForCompletion(job);
}
}
```
## Security Patterns
### 1. OAuth 2.0 with JWT Bearer
**Use Case**: Server-to-server authentication without user interaction
```javascript
class JWTBearerAuth {
async getAccessToken() {
const jwt = this.createJWT({
iss: this.clientId,
sub: this.username,
aud: this.loginUrl,
exp: Math.floor(Date.now() / 1000) + 300,
});
const response = await fetch(`${this.loginUrl}/services/oauth2/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: jwt,
}),
});
return response.json();
}
}
```
### 2. Field-Level Security Enforcement
**Use Case**: Ensuring AI respects Salesforce security model
```javascript
class FieldSecurityPattern {
async query(soql, userContext) {
// Get user's field permissions
const permissions = await this.getUserFieldPermissions(userContext);
// Parse and validate SOQL
const parsed = this.parseSOQL(soql);
const allowedFields = this.filterAllowedFields(parsed.fields, permissions);
// Rebuild query with allowed fields only
const secureSOQL = this.rebuildSOQL(parsed, allowedFields);
return await this.connection.query(secureSOQL);
}
}
```
### 3. Data Masking Pattern
**Use Case**: Protecting sensitive data in AI interactions
```javascript
class DataMaskingPattern {
constructor(maskingRules) {
this.rules = maskingRules;
}
async query(soql) {
const results = await this.connection.query(soql);
// Apply masking rules
return results.records.map((record) => {
const masked = { ...record };
for (const [field, rule] of Object.entries(this.rules)) {
if (masked[field]) {
masked[field] = this.applyMask(masked[field], rule);
}
}
return masked;
});
}
applyMask(value, rule) {
switch (rule.type) {
case 'partial':
return value.substring(0, 4) + '****';
case 'hash':
return this.hash(value);
case 'remove':
return '[REDACTED]';
default:
return value;
}
}
}
```
## Performance Patterns
### 1. Query Optimization Pattern
**Use Case**: Ensuring efficient SOQL generation by AI
```javascript
class QueryOptimizationPattern {
optimizeSOQL(soql) {
let optimized = soql;
// Add selective filters
if (!soql.includes('LIMIT')) {
optimized += ' LIMIT 200';
}
// Use indexed fields in WHERE
optimized = this.ensureIndexedFields(optimized);
// Avoid SELECT *
optimized = this.specifyFields(optimized);
// Add query hints
optimized = this.addQueryHints(optimized);
return optimized;
}
}
```
### 2. Connection Pooling Pattern
**Use Case**: Managing multiple concurrent AI agent requests
```javascript
class ConnectionPoolPattern {
constructor(poolSize = 10) {
this.pool = [];
this.available = [];
this.waiting = [];
// Initialize pool
for (let i = 0; i < poolSize; i++) {
this.createConnection();
}
}
async getConnection() {
if (this.available.length > 0) {
return this.available.pop();
}
// Wait for available connection
return new Promise((resolve) => {
this.waiting.push(resolve);
});
}
releaseConnection(conn) {
if (this.waiting.length > 0) {
const resolve = this.waiting.shift();
resolve(conn);
} else {
this.available.push(conn);
}
}
}
```
### 3. Adaptive Rate Limiting
**Use Case**: Dynamically adjusting to Salesforce API limits
```javascript
class AdaptiveRateLimiter {
constructor() {
this.window = 3600000; // 1 hour
this.maxRequests = 15000; // Default
this.currentRate = 1.0;
}
async executeWithRateLimit(operation) {
await this.waitIfNeeded();
try {
const result = await operation();
this.adjustRate(true);
return result;
} catch (error) {
if (error.code === 'REQUEST_LIMIT_EXCEEDED') {
this.adjustRate(false);
// Retry with backoff
await this.backoff();
return this.executeWithRateLimit(operation);
}
throw error;
}
}
adjustRate(success) {
if (success) {
this.currentRate = Math.min(1.0, this.currentRate * 1.1);
} else {
this.currentRate = Math.max(0.1, this.currentRate * 0.5);
}
}
}
```
## Multi-Agent Patterns
### 1. Agent Orchestration Pattern
**Use Case**: Coordinating multiple AI agents accessing Salesforce
```yaml
orchestration_pattern:
coordinator:
- Manages agent registry
- Routes requests
- Handles dependencies
- Aggregates results
example_workflow:
- Agent A: Analyzes customer data
- Agent B: Generates recommendations
- Agent C: Creates follow-up tasks
- Coordinator: Ensures sequential execution
```
### 2. Federated Query Pattern
**Use Case**: AI agents querying multiple Salesforce orgs
```javascript
class FederatedQueryPattern {
constructor(orgs) {
this.orgs = orgs; // Map of org connections
}
async federatedQuery(query) {
const promises = Array.from(this.orgs.entries()).map(async ([orgName, connection]) => {
try {
const results = await connection.query(query);
return { orgName, results, success: true };
} catch (error) {
return { orgName, error, success: false };
}
});
const results = await Promise.all(promises);
return this.aggregateResults(results);
}
}
```
## Agentforce 3 Preparation Patterns
### 1. Registry-Ready Pattern
**Use Case**: Preparing MCP servers for Agentforce 3 registry
```json
{
"metadata": {
"name": "salesforce-crm-mcp",
"version": "1.0.0",
"compatibility": {
"mcp": "1.0",
"agentforce": "3.0"
}
},
"capabilities": {
"tools": ["query", "create", "update", "delete"],
"resources": ["accounts", "contacts", "opportunities"],
"events": ["record.created", "record.updated"]
},
"security": {
"authentication": ["oauth2", "jwt"],
"encryption": ["tls1.3"],
"compliance": ["soc2", "gdpr"]
}
}
```
### 2. Migration Pattern
**Use Case**: Migrating from custom integrations to MCP
```javascript
class MCPMigrationPattern {
async migrateEndpoint(legacyEndpoint) {
// 1. Analyze legacy endpoint
const analysis = await this.analyzeLegacy(legacyEndpoint);
// 2. Generate MCP tool definition
const toolDef = this.generateToolDefinition(analysis);
// 3. Create compatibility wrapper
const wrapper = this.createWrapper(legacyEndpoint, toolDef);
// 4. Register with MCP server
await this.mcpServer.registerTool(toolDef, wrapper);
// 5. Validate functionality
await this.validateMigration(legacyEndpoint, toolDef);
return { toolDef, wrapper };
}
}
```
## Best Practices Summary
### Do's
- ✅ Implement comprehensive error handling
- ✅ Use connection pooling for scalability
- ✅ Cache frequently accessed data
- ✅ Respect Salesforce security model
- ✅ Monitor and adapt to API limits
- ✅ Version your MCP servers
- ✅ Document all tools thoroughly
- ✅ Test with production-like data volumes
### Don'ts
- ❌ Bypass Salesforce security
- ❌ Ignore API limits
- ❌ Cache sensitive data without encryption
- ❌ Allow unrestricted SOQL execution
- ❌ Skip audit logging
- ❌ Hardcode credentials
- ❌ Ignore error scenarios
- ❌ Deploy without monitoring
## Pattern Selection Guide
Choose patterns based on:
1. **Scale Requirements**
- Small: Direct API Pattern
- Medium: Cache-Aside Pattern
- Large: Gateway + Bulk Patterns
2. **Security Requirements**
- Standard: OAuth 2.0
- High: JWT Bearer + Field Security
- Critical: Full Gateway Pattern
3. **Performance Requirements**
- Low latency: Direct API + Caching
- High throughput: Bulk + Pool Patterns
- Mixed: Adaptive patterns
4. **Integration Complexity**
- Simple: Direct patterns
- Complex: Gateway + Orchestration
- Multi-system: Federated patterns