Skip to main content
Glama
usama-dtc
by usama-dtc

salesforce_upload_report_xml

Upload XML files to Salesforce to create or update reports using defined metadata formats. Specify report details like name, folder ID, and XML content for seamless report generation or modification.

Instructions

Upload XML to generate or update reports in Salesforce.

Examples:

  1. Create a new report:

    • reportName: "Monthly Sales Summary"

    • folderId: "00l5e000000XXXXX" (optional - uploads to user's private reports by default)

    • xmlContent: "<Report xmlns=..."

    • isDeveloperName: false

  2. Update existing report:

    • reportId: "00O5e000000XXXXX"

    • xmlContent: "<Report xmlns=..."

Note: XML must follow Salesforce report metadata format. For custom report types, ensure the report type exists in your org before uploading.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
folderIdNoFolder ID where the report should be saved (optional)
isDeveloperNameNoIf true, reportName is treated as the API name instead of the display name
reportIdNoReport ID to update an existing report
reportNameNoName for the new report (required for new reports)
xmlContentYesXML content for the report in Salesforce report metadata format

Implementation Reference

  • Main handler function that implements the core logic for uploading XML to create or update Salesforce reports using the Metadata API, including validation, creation, update, and error handling.
    export async function handleUploadReportXml(conn: any, args: UploadReportXmlArgs) { const { reportName, reportId, folderId, xmlContent, isDeveloperName = false } = args; try { // Validate input parameters if (!reportId && !reportName) { return { content: [{ type: "text", text: "Either reportName (for new reports) or reportId (for updates) must be provided" }], isError: true, }; } // Validate XML content const xmlValidation = validateReportXml(xmlContent); if (!xmlValidation.isValid) { return { content: [{ type: "text", text: xmlValidation.error! }], isError: true, }; } // For updating existing reports if (reportId) { // First verify the report exists try { await conn.sobject('Report').retrieve(reportId); } catch (error) { return { content: [{ type: "text", text: `Report with ID ${reportId} not found or you don't have access to it` }], isError: true, }; } // Use Salesforce Metadata API to update the report const result = await conn.metadata.update('Report', { fullName: reportId, content: Buffer.from(xmlContent).toString('base64') }); if (result.success) { return { content: [{ type: "text", text: `Report successfully updated with ID: ${reportId}` }], isError: false, }; } else { return { content: [{ type: "text", text: `Failed to update report: ${result.errors?.join(', ') || 'Unknown error'}` }], isError: true, }; } } // For creating new reports else { // Generate API name from display name if needed const developerName = isDeveloperName ? reportName : reportName!.replace(/[^a-zA-Z0-9]/g, '_'); // Prepare report metadata const reportMetadata = { fullName: developerName, content: Buffer.from(xmlContent).toString('base64') }; // Specify folder if provided if (folderId) { // @ts-ignore - JSForce types don't include this property but it's supported reportMetadata.folderId = folderId; } // Use Metadata API to create the report const result = await conn.metadata.create('Report', reportMetadata); if (result.success) { return { content: [{ type: "text", text: `Report "${reportName}" successfully created with ID: ${result.id}` }], isError: false, }; } else { return { content: [{ type: "text", text: `Failed to create report: ${result.errors?.join(', ') || 'Unknown error'}` }], isError: true, }; } } } catch (error) { // Enhanced error handling const errorMessage = error instanceof Error ? error.message : String(error); let enhancedError = errorMessage; // Customize error messages for common issues if (errorMessage.includes('INVALID_CROSS_REFERENCE_KEY')) { enhancedError = `Invalid folder ID or report folder access issue. Please check that the folder exists and you have proper permissions.`; } else if (errorMessage.includes('INSUFFICIENT_ACCESS')) { enhancedError = `Insufficient permissions to create or modify reports. Please check your Salesforce user permissions.`; } else if (errorMessage.includes('INVALID_TYPE')) { enhancedError = `Invalid report type in XML. Ensure the report type specified in the XML exists in your Salesforce org.`; } return { content: [{ type: "text", text: `Error uploading report XML: ${enhancedError}` }], isError: true, }; } }
  • Tool schema definition including name, description, and input schema for validating arguments like reportName, reportId, folderId, xmlContent, and isDeveloperName.
    export const UPLOAD_REPORT_XML: Tool = { name: "salesforce_upload_report_xml", description: `Upload XML to generate or update reports in Salesforce. Examples: 1. Create a new report: - reportName: "Monthly Sales Summary" - folderId: "00l5e000000XXXXX" (optional - uploads to user's private reports by default) - xmlContent: "<Report xmlns=..." - isDeveloperName: false 2. Update existing report: - reportId: "00O5e000000XXXXX" - xmlContent: "<Report xmlns=..." Note: XML must follow Salesforce report metadata format. For custom report types, ensure the report type exists in your org before uploading.`, inputSchema: { type: "object", properties: { reportName: { type: "string", description: "Name for the new report (required for new reports)", optional: true }, reportId: { type: "string", description: "Report ID to update an existing report", optional: true }, folderId: { type: "string", description: "Folder ID where the report should be saved (optional)", optional: true }, xmlContent: { type: "string", description: "XML content for the report in Salesforce report metadata format" }, isDeveloperName: { type: "boolean", description: "If true, reportName is treated as the API name instead of the display name", optional: true } }, required: ["xmlContent"] } };
  • src/index.ts:177-193 (registration)
    Registration in the main tool dispatch switch statement that validates arguments and calls the handleUploadReportXml handler.
    case "salesforce_upload_report_xml": { const reportArgs = args as Record<string, unknown>; if (!reportArgs.xmlContent) { throw new Error('xmlContent is required for report XML upload'); } // Type check and conversion const validatedArgs: UploadReportXmlArgs = { reportName: reportArgs.reportName as string | undefined, reportId: reportArgs.reportId as string | undefined, folderId: reportArgs.folderId as string | undefined, xmlContent: reportArgs.xmlContent as string, isDeveloperName: reportArgs.isDeveloperName as boolean | undefined }; return await handleUploadReportXml(conn, validatedArgs); }
  • src/index.ts:36-46 (registration)
    Registration of the tool in the ListToolsRequestHandler, including UPLOAD_REPORT_XML in the list of available tools.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ SEARCH_OBJECTS, DESCRIBE_OBJECT, QUERY_RECORDS, DML_RECORDS, MANAGE_OBJECT, MANAGE_FIELD, SEARCH_ALL, UPLOAD_REPORT_XML // Add new tool to the list ],
  • Helper function to validate the XML content before uploading, checking format and Salesforce report structure.
    function validateReportXml(xmlContent: string): { isValid: boolean; error?: string } { try { // Check if content is valid XML if (!xmlContent.trim().startsWith('<')) { return { isValid: false, error: "Invalid XML format: Content must be XML starting with '<'" }; } // Check if it's a Salesforce report XML if (!xmlContent.includes('<Report xmlns') && !xmlContent.includes('<report>')) { return { isValid: false, error: "XML content doesn't appear to be a valid Salesforce report definition" }; } return { isValid: true }; } catch (error) { return { isValid: false, error: `XML validation error: ${error instanceof Error ? error.message : String(error)}` }; } }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/usama-dtc/salesforce_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server