salesforce_dml_records
Perform data manipulation operations on Salesforce records: insert new records, update existing ones, delete records, or upsert based on external IDs.
Instructions
Perform data manipulation operations on Salesforce records:
insert: Create new records
update: Modify existing records (requires Id)
delete: Remove records (requires Id)
upsert: Insert or update based on external ID field Examples: Insert new Accounts, Update Case status, Delete old records, Upsert based on custom external ID
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| operation | Yes | Type of DML operation to perform | |
| objectName | Yes | API name of the object | |
| records | Yes | Array of records to process | |
| externalIdField | No | External ID field name for upsert operations |
Implementation Reference
- src/tools/dml.ts:46-121 (handler)The main handler function that executes the DML operations (insert, update, delete, upsert) on Salesforce records using the JSForce connection, formats results, and returns MCP response.export async function handleDMLRecords(conn: any, args: DMLArgs) { const { operation, objectName, records, externalIdField } = args; let result: DMLResult | DMLResult[]; switch (operation) { case 'insert': result = await conn.sobject(objectName).create(records); break; case 'update': result = await conn.sobject(objectName).update(records); break; case 'delete': result = await conn.sobject(objectName).destroy(records.map(r => r.Id)); break; case 'upsert': if (!externalIdField) { throw new Error('externalIdField is required for upsert operations'); } result = await conn.sobject(objectName).upsert(records, externalIdField); break; default: throw new Error(`Unsupported operation: ${operation}`); } // Format DML results const results = Array.isArray(result) ? result : [result]; const successCount = results.filter(r => r.success).length; const failureCount = results.length - successCount; let responseText = `${operation.toUpperCase()} operation completed.\n`; responseText += `Processed ${results.length} records:\n`; responseText += `- Successful: ${successCount}\n`; responseText += `- Failed: ${failureCount}\n\n`; if (failureCount > 0) { responseText += 'Errors:\n'; results.forEach((r: DMLResult, idx: number) => { if (!r.success && r.errors) { responseText += `Record ${idx + 1}:\n`; if (Array.isArray(r.errors)) { r.errors.forEach((error) => { responseText += ` - ${error.message}`; if (error.statusCode) { responseText += ` [${error.statusCode}]`; } if (error.fields && error.fields.length > 0) { responseText += `\n Fields: ${error.fields.join(', ')}`; } responseText += '\n'; }); } else { // Single error object const error = r.errors; responseText += ` - ${error.message}`; if (error.statusCode) { responseText += ` [${error.statusCode}]`; } if (error.fields) { const fields = Array.isArray(error.fields) ? error.fields.join(', ') : error.fields; responseText += `\n Fields: ${fields}`; } responseText += '\n'; } } }); } return { content: [{ type: "text", text: responseText }], isError: false, }; }
- src/tools/dml.ts:4-37 (schema)The MCP Tool definition object for 'salesforce_dml_records', including name, description, and inputSchema for validation.export const DML_RECORDS: Tool = { name: "salesforce_dml_records", description: `Perform data manipulation operations on Salesforce records: - insert: Create new records - update: Modify existing records (requires Id) - delete: Remove records (requires Id) - upsert: Insert or update based on external ID field Examples: Insert new Accounts, Update Case status, Delete old records, Upsert based on custom external ID`, inputSchema: { type: "object", properties: { operation: { type: "string", enum: ["insert", "update", "delete", "upsert"], description: "Type of DML operation to perform" }, objectName: { type: "string", description: "API name of the object" }, records: { type: "array", items: { type: "object" }, description: "Array of records to process" }, externalIdField: { type: "string", description: "External ID field name for upsert operations", optional: true } }, required: ["operation", "objectName", "records"] } };
- src/index.ts:119-131 (registration)Registration in the CallToolRequestHandler switch statement: validates input arguments and calls the handleDMLRecords handler.case "salesforce_dml_records": { const dmlArgs = args as Record<string, unknown>; if (!dmlArgs.operation || !dmlArgs.objectName || !Array.isArray(dmlArgs.records)) { throw new Error('operation, objectName, and records array are required for DML'); } const validatedArgs: DMLArgs = { operation: dmlArgs.operation as 'insert' | 'update' | 'delete' | 'upsert', objectName: dmlArgs.objectName as string, records: dmlArgs.records as Record<string, any>[], externalIdField: dmlArgs.externalIdField as string | undefined }; return await handleDMLRecords(conn, validatedArgs); }
- src/index.ts:45-63 (registration)Registration of the DML_RECORDS tool schema in the ListToolsRequestHandler.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ SEARCH_OBJECTS, DESCRIBE_OBJECT, QUERY_RECORDS, AGGREGATE_QUERY, DML_RECORDS, MANAGE_OBJECT, MANAGE_FIELD, MANAGE_FIELD_PERMISSIONS, SEARCH_ALL, READ_APEX, WRITE_APEX, READ_APEX_TRIGGER, WRITE_APEX_TRIGGER, EXECUTE_ANONYMOUS, MANAGE_DEBUG_LOGS ], }));
- src/tools/dml.ts:39-44 (schema)TypeScript interface defining the input arguments for the DML handler, used for validation.export interface DMLArgs { operation: 'insert' | 'update' | 'delete' | 'upsert'; objectName: string; records: Record<string, any>[]; externalIdField?: string; }