convert_excel_to_pdf
Convert Excel files (.xls, .xlsx) to PDF format for sharing, printing, or archiving documents while preserving formatting.
Instructions
Converts Excel files (.xls, .xlsx) to PDF format
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| input_path | Yes | Relative path to the Excel file (.xls, .xlsx) to convert | |
| output_format | No | Output format (currently only PDF is supported) |
Implementation Reference
- src/handlers/convertExcel.ts:52-148 (handler)Core handler function that validates input, checks for LibreOffice, reads Excel file, converts to PDF using libreoffice-convert, saves to temp file, and returns the relative path.
export const handleConvertExcelFunc = async ( args: unknown ): Promise<{ content: { type: string; text: string }[] }> => { // Ensure LibreOffice is installed const libreOfficeInstalled = await checkLibreOfficeInstalled(); if (!libreOfficeInstalled) { throw new McpError( ErrorCode.InvalidRequest, 'LibreOffice is not installed or not found in PATH. Please install LibreOffice to use this tool.' ); } // Parse and validate arguments let parsedArgs: ConvertExcelArgs; try { parsedArgs = ConvertExcelArgsSchema.parse(args); } catch (error) { if (error instanceof z.ZodError) { throw new McpError( ErrorCode.InvalidParams, `Invalid arguments: ${error.errors.map(e => `${e.path.join('.')} (${e.message})`).join(', ')}` ); } const message = error instanceof Error ? error.message : String(error); throw new McpError(ErrorCode.InvalidParams, `Argument validation failed: ${message}`); } try { // Ensure temp directory exists - now await because the function is async const tempDir = await ensureTempDir(); // Resolve input path const inputPath = resolvePath(parsedArgs.input_path); // Check file extension const ext = path.extname(inputPath).toLowerCase(); if (ext !== '.xlsx' && ext !== '.xls') { throw new McpError( ErrorCode.InvalidParams, 'Invalid file format. Only .xlsx and .xls files are supported.' ); } // Read the input file const fileContent = await fs.readFile(inputPath); // Create output path const outputPath = createTempFilePath(path.basename(inputPath)); await fs.mkdir(path.dirname(outputPath), { recursive: true }); // Convert to PDF const pdfBuffer = await libreConvert(fileContent, '.pdf', undefined); // Write the output file await fs.writeFile(outputPath, pdfBuffer); // Create a relative path for the result const relativeOutputPath = path.relative(process.cwd(), outputPath); return { content: [ { type: 'text', text: JSON.stringify({ success: true, output_path: relativeOutputPath, message: 'Excel file successfully converted to PDF', }, null, 2), }, ], }; } catch (error) { console.error('[Excel to PDF MCP] Error in conversion:', error); // Handle specific errors if (error instanceof McpError) { throw error; // Re-throw MCP errors } if (error instanceof Error) { if ('code' in error && error.code === 'ENOENT') { throw new McpError(ErrorCode.InvalidParams, `File not found: ${parsedArgs.input_path}`); } throw new McpError( ErrorCode.InvalidRequest, `Error converting Excel to PDF: ${error.message}` ); } // Generic error throw new McpError( ErrorCode.InvalidRequest, `Unknown error during Excel to PDF conversion` ); } }; - src/handlers/convertExcel.ts:14-17 (schema)Zod schema for tool input parameters: input_path (string) and output_format (pdf).
const ConvertExcelArgsSchema = z.object({ input_path: z.string().min(1).describe('Relative path to the Excel file (.xls, .xlsx) to convert'), output_format: z.enum(['pdf']).default('pdf').describe('Output format (currently only PDF is supported)') }).strict(); - src/handlers/convertExcel.ts:151-156 (registration)ToolDefinition object that registers the tool with name, description, schema, and handler function.
export const convertExcelToolDefinition: ToolDefinition = { name: 'convert_excel_to_pdf', description: 'Converts Excel files (.xls, .xlsx) to PDF format', schema: ConvertExcelArgsSchema, handler: handleConvertExcelFunc, }; - src/handlers/index.ts:18-21 (registration)Aggregation of all tool definitions into an array used by the MCP server.
export const allToolDefinitions: ToolDefinition[] = [ convertExcelToolDefinition, convertNumbersToolDefinition ]; - src/handlers/convertExcel.ts:23-49 (helper)Helper function to verify LibreOffice installation before attempting conversion.
export async function checkLibreOfficeInstalled(): Promise<boolean> { try { const isWindows = process.platform === 'win32'; const command = isWindows ? 'where' : 'which'; const possibleCommands = isWindows ? ['soffice.exe'] : ['libreoffice', 'soffice']; const { exec } = await import('node:child_process'); const execPromise = promisify(exec); // Try with multiple possible command names for (const commandArg of possibleCommands) { try { await execPromise(`${command} ${commandArg}`); console.error(`[Excel to PDF MCP] Found LibreOffice at: ${commandArg}`); return true; } catch { // Continue with next command } } console.error('[Excel to PDF MCP] LibreOffice not found in PATH'); return false; } catch (error) { console.error('[Excel to PDF MCP] Error checking for LibreOffice:', error); return false; } }