Skip to main content
Glama

write_file

Write data to CSV or Excel files with support for multiple sheets, enabling structured data export from the Excel MCP Server.

Instructions

Write data to a new CSV or Excel file (supports multiple sheets for Excel)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
filePathYesPath for the new file (must end with .csv, .xlsx, or .xls)
dataNoArray of arrays representing rows of data (single sheet mode)
headersNoOptional headers for the first row (single sheet mode)
sheetNoSheet name for Excel files (single sheet mode, defaults to "Sheet1")
sheetsNoArray of sheet objects for multi-sheet Excel files

Implementation Reference

  • Core handler function that executes write_file tool: supports writing to CSV/Excel (.xlsx/.xls), single-sheet with data/headers/sheet, multi-sheet with sheets array using ExcelJS.
    async writeFile(args: ToolArgs): Promise<ToolResponse> { const { filePath, data, headers, sheet = 'Sheet1', sheets } = args; const ext = path.extname(filePath).toLowerCase(); const absolutePath = path.resolve(filePath); // Multi-sheet mode for Excel files if (sheets && Array.isArray(sheets)) { if (ext === '.csv') { throw new Error('CSV format does not support multiple sheets. Use .xlsx or .xls for multi-sheet files.'); } if (ext !== '.xlsx' && ext !== '.xls') { throw new Error('Multi-sheet mode only works with Excel files (.xlsx or .xls)'); } const workbook = new ExcelJS.Workbook(); let totalRows = 0; let totalColumns = 0; for (const sheetData of sheets) { if (!sheetData.data || !Array.isArray(sheetData.data)) { throw new Error(`Sheet "${sheetData.name}" must have valid data array`); } const fullData = sheetData.headers ? [sheetData.headers, ...sheetData.data] : sheetData.data; if (fullData.length === 0) { // Add empty row if no data fullData.push([]); } const worksheet = workbook.addWorksheet(sheetData.name); fullData.forEach((row: any[]) => { worksheet.addRow(row); }); totalRows += fullData.length; if (fullData.length > 0 && Array.isArray(fullData[0])) { totalColumns = Math.max(totalColumns, fullData[0].length || 0); } } await workbook.xlsx.writeFile(absolutePath); return { content: [ { type: 'text', text: JSON.stringify({ success: true, filePath: absolutePath, mode: 'multi-sheet', sheetsWritten: sheets.length, sheetNames: sheets.map(s => s.name), totalRowsWritten: totalRows, maxColumnsWritten: totalColumns, }, null, 2), }, ], }; } // Single sheet mode (backward compatible) if (!data || !Array.isArray(data)) { throw new Error('Either "data" (for single sheet) or "sheets" (for multiple sheets) must be provided.'); } const fullData = headers ? [headers, ...data] : data; if (ext === '.csv') { // Write CSV file const csvContent = csvStringify.stringify(fullData); await fs.writeFile(absolutePath, csvContent, 'utf-8'); } else if (ext === '.xlsx' || ext === '.xls') { // Write Excel file const workbook = new ExcelJS.Workbook(); const worksheet = workbook.addWorksheet(sheet); fullData.forEach((row: any[]) => { worksheet.addRow(row); }); await workbook.xlsx.writeFile(absolutePath); } else { throw new Error('Unsupported file format. Please use .csv, .xlsx, or .xls extension.'); } return { content: [ { type: 'text', text: JSON.stringify({ success: true, filePath: absolutePath, mode: 'single-sheet', sheetName: ext === '.csv' ? null : sheet, rowsWritten: fullData.length, columnsWritten: fullData[0]?.length || 0, }, null, 2), }, ], }; }
  • Input schema definition for write_file tool in the MCP tools list, specifying parameters like filePath (required), data, headers, sheet, and optional sheets for multi-sheet Excel files.
    name: 'write_file', description: 'Write data to a new CSV or Excel file (supports multiple sheets for Excel)', inputSchema: { type: 'object', properties: { filePath: { type: 'string', description: 'Path for the new file (must end with .csv, .xlsx, or .xls)', }, data: { type: 'array', description: 'Array of arrays representing rows of data (single sheet mode)', items: { type: 'array', }, }, headers: { type: 'array', description: 'Optional headers for the first row (single sheet mode)', items: { type: 'string', }, }, sheet: { type: 'string', description: 'Sheet name for Excel files (single sheet mode, defaults to "Sheet1")', }, sheets: { type: 'array', description: 'Array of sheet objects for multi-sheet Excel files', items: { type: 'object', properties: { name: { type: 'string', description: 'Sheet name', }, data: { type: 'array', description: 'Array of arrays representing rows of data', items: { type: 'array', }, }, headers: { type: 'array', description: 'Optional headers for the first row', items: { type: 'string', }, }, }, required: ['name', 'data'], }, }, }, required: ['filePath'], },
  • src/index.ts:1242-1255 (registration)
    Tool registration in MCP server: imports FileOperationsHandler, instantiates it (line 55), lists schema in ListToolsRequestHandler (536-593), and dispatches calls to fileOpsHandler.writeFile in CallToolRequestSchema switch.
    // File Operations case 'write_file': return await this.fileOpsHandler.writeFile(toolArgs); case 'add_sheet': return await this.fileOpsHandler.addSheet(toolArgs); case 'write_multi_sheet': return await this.fileOpsHandler.writeMultiSheet(toolArgs); case 'export_analysis': return await this.fileOpsHandler.exportAnalysis(toolArgs); case 'format_cells': return await this.fileOpsHandler.formatCells(toolArgs); case 'auto_fit_columns': return await this.fileOpsHandler.autoFitColumns(toolArgs);

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/ishayoyo/excel-mcp'

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