Skip to main content
Glama
nam090320251

Dynamic Excel MCP Server

by nam090320251

generate_excel

Create Excel files from JSON schemas with custom layouts, multiple sheets, formulas, charts, and advanced formatting for reports, dashboards, and data exports.

Instructions

Generate an Excel file from a structured JSON schema.

Use this tool when the user wants to:

  • Create an Excel file

  • Export data to Excel

  • Generate a report/spreadsheet

  • Download data as .xlsx file

The tool accepts a JSON schema describing the structure, data, and formatting of the Excel file.

Supported features:

  • Multiple sheets

  • Custom column widths and formats

  • Cell styling (fonts, colors, borders, alignment)

  • Data validation

  • Conditional formatting

  • Formulas and totals

  • Charts and images

  • Page setup and printing options

  • Freeze panes, auto-filter

  • Merged cells

  • Grouped rows/columns

  • Sheet protection

Layout types:

  • table: Simple data table (default)

  • report: Formatted report with headers and styling

  • form: Form-style layout

  • dashboard: Dashboard with charts

  • calendar: Calendar view

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
file_nameNoName of the Excel file (e.g., "report.xlsx")
sheetsYesArray of sheet configurations
metadataNoWorkbook metadata
optionsNoOutput options

Implementation Reference

  • Main handler for the 'generate_excel' tool: validates input schema, selects generator (Basic or Report), generates Excel file buffer, uploads to storage (S3 or local), generates presigned URL, returns structured response with download link.
    server.setRequestHandler(CallToolRequestSchema, async (request) => {
      if (request.params.name !== 'generate_excel') {
        throw new McpError(
          ErrorCode.MethodNotFound,
          `Unknown tool: ${request.params.name}`
        );
      }
    
      try {
        logger.info('Received generate_excel request');
    
        // Validate schema
        const validation = SchemaValidator.validate(request.params.arguments);
    
        if (!validation.success) {
          throw new McpError(
            ErrorCode.InvalidParams,
            `Schema validation failed: ${validation.errors.join(', ')}`
          );
        }
    
        const config: ExcelConfig = validation.data;
    
        // Select appropriate generator
        const generator = selectGenerator(config);
    
        // Generate Excel file
        logger.info(`Generating Excel file: ${config.file_name}`);
        const buffer = await generator.generate(config);
    
        logger.info(`Excel file generated, size: ${buffer.length} bytes`);
    
        // Upload to storage
        const fileName = config.file_name || `report_${Date.now()}.xlsx`;
        const key = await storage.upload(buffer, fileName);
    
        // Get download URL
        let downloadUrl: string;
        if (storage instanceof S3Storage) {
          const expiresIn = parseInt(process.env.PRESIGNED_URL_EXPIRY || '3600');
          downloadUrl = await storage.getPresignedUrl(key, expiresIn);
        } else {
          downloadUrl = await (storage as LocalStorage).getFileUrl(key);
        }
    
        logger.info('Excel file ready for download');
    
        // Return result
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify({
                success: true,
                download_url: downloadUrl,
                file_name: fileName,
                file_size: buffer.length,
                sheets_count: config.sheets.length,
                message: 'Excel file generated successfully',
                expires_in: storageType === 's3' ? parseInt(process.env.PRESIGNED_URL_EXPIRY || '3600') : null,
              }, null, 2),
            },
          ],
        };
      } catch (error) {
        logger.error('Error generating Excel:', error);
    
        if (error instanceof McpError) {
          throw error;
        }
    
        throw new McpError(
          ErrorCode.InternalError,
          `Failed to generate Excel file: ${error instanceof Error ? error.message : 'Unknown error'}`
        );
      }
    });
  • src/index.ts:57-148 (registration)
    Registers the 'generate_excel' tool in the MCP server with detailed description and comprehensive input schema for Excel generation configuration.
      server.setRequestHandler(ListToolsRequestSchema, async () => {
        return {
          tools: [
            {
              name: 'generate_excel',
              description: `Generate an Excel file from a structured JSON schema.
    
    Use this tool when the user wants to:
    - Create an Excel file
    - Export data to Excel
    - Generate a report/spreadsheet
    - Download data as .xlsx file
    
    The tool accepts a JSON schema describing the structure, data, and formatting of the Excel file.
    
    Supported features:
    - Multiple sheets
    - Custom column widths and formats
    - Cell styling (fonts, colors, borders, alignment)
    - Data validation
    - Conditional formatting
    - Formulas and totals
    - Charts and images
    - Page setup and printing options
    - Freeze panes, auto-filter
    - Merged cells
    - Grouped rows/columns
    - Sheet protection
    
    Layout types:
    - table: Simple data table (default)
    - report: Formatted report with headers and styling
    - form: Form-style layout
    - dashboard: Dashboard with charts
    - calendar: Calendar view`,
              inputSchema: {
                type: 'object',
                properties: {
                  file_name: {
                    type: 'string',
                    description: 'Name of the Excel file (e.g., "report.xlsx")',
                  },
                  sheets: {
                    type: 'array',
                    description: 'Array of sheet configurations',
                    items: {
                      type: 'object',
                      properties: {
                        name: {
                          type: 'string',
                          description: 'Sheet name',
                        },
                        layout: {
                          type: 'string',
                          enum: ['table', 'report', 'form', 'dashboard', 'calendar'],
                          description: 'Layout type for the sheet',
                        },
                        columns: {
                          type: 'array',
                          description: 'Column definitions',
                        },
                        data: {
                          type: 'array',
                          description: 'Array of data rows',
                        },
                        formatting: {
                          type: 'object',
                          description: 'Formatting options',
                        },
                        charts: {
                          type: 'array',
                          description: 'Charts to add to the sheet',
                        },
                      },
                      required: ['name', 'columns', 'data'],
                    },
                  },
                  metadata: {
                    type: 'object',
                    description: 'Workbook metadata',
                  },
                  options: {
                    type: 'object',
                    description: 'Output options',
                  },
                },
                required: ['sheets'],
              },
            },
          ],
        };
      });
  • Zod schema definition for ExcelConfig used for input validation, defining structure for workbook, sheets, columns, data, formatting, charts, etc.
    export const ExcelSchema = z.object({
      file_name: z.string().describe('Name of the Excel file'),
    
      sheets: z.array(SheetSchema).min(1),
    
      // Workbook metadata
      metadata: z.object({
        title: z.string().optional(),
        subject: z.string().optional(),
        author: z.string().optional().default('AI Assistant'),
        description: z.string().optional(),
        company: z.string().optional(),
        category: z.string().optional(),
        keywords: z.array(z.string()).optional(),
      }).optional(),
    
      // Output options
      options: z.object({
        storage: z.enum(['s3', 'local']).optional(),
        compress: z.boolean().optional(),
        password: z.string().optional(),
      }).optional(),
    });
    
    // Export types
    export type ColumnConfig = z.infer<typeof ColumnSchema>;
    export type ConditionalFormatting = z.infer<typeof ConditionalFormattingSchema>;
    export type ChartConfig = z.infer<typeof ChartSchema>;
    export type FormattingConfig = z.infer<typeof FormattingSchema>;
    export type SheetConfig = z.infer<typeof SheetSchema>;
    export type ExcelConfig = z.infer<typeof ExcelSchema>;
  • Core method in BaseGenerator that creates an Excel worksheet: sets columns, applies header styles, adds data rows with formatting/validation, applies sheet-level formatting (freeze panes, filters, etc.), adds charts.
    protected async createSheet(sheetConfig: SheetConfig): Promise<ExcelJS.Worksheet> {
      const worksheet = this.workbook.addWorksheet(sheetConfig.name);
    
      // Setup columns
      worksheet.columns = sheetConfig.columns.map(col => ({
        header: col.header,
        key: col.key,
        width: col.width || 15,
      }));
    
      // Apply header styling
      this.applyHeaderStyle(worksheet, sheetConfig.columns);
    
      // Add data rows
      await this.addDataRows(worksheet, sheetConfig);
    
      // Apply formatting
      if (sheetConfig.formatting) {
        await this.applyFormatting(worksheet, sheetConfig);
      }
    
      // Add charts
      if (sheetConfig.charts) {
        await this.addCharts(worksheet, sheetConfig.charts);
      }
    
      return worksheet;
    }
  • Generates the final Excel file buffer from the workbook using ExcelJS writeBuffer.
    protected async generateBuffer(): Promise<Buffer> {
      const buffer = await this.workbook.xlsx.writeBuffer();
      return Buffer.from(buffer);
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It lists supported features and layout types, which adds some context about capabilities, but it does not disclose critical behavioral traits such as whether the tool creates a file locally or returns a download link, error handling, performance considerations, or any limitations (e.g., file size constraints). For a tool with no annotations and complex functionality, this is a significant gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and appropriately sized, starting with a clear purpose and usage guidelines, followed by supported features and layout types. However, it includes a lengthy list of features that could be condensed or prioritized, and some sentences (e.g., the bullet points under usage) are repetitive. Overall, it is efficient but could be more streamlined.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of the tool (4 parameters, nested objects, no output schema, and no annotations), the description is moderately complete. It covers purpose, usage, features, and layouts, but lacks details on output behavior, error handling, and practical constraints. Without an output schema, it should ideally explain what is returned (e.g., file data or a link), but it does not, leaving gaps for an AI agent to understand full usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, so the schema already documents all parameters thoroughly. The description adds minimal value beyond the schema by mentioning that the tool 'accepts a JSON schema describing the structure, data, and formatting of the Excel file,' but it does not provide additional syntax, examples, or constraints. With high schema coverage, the baseline is 3, as the description does not compensate with extra param details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Generate an Excel file from a structured JSON schema.' It specifies the verb ('Generate'), resource ('Excel file'), and input type ('structured JSON schema'), making it distinct and unambiguous. With no sibling tools, differentiation is not needed, but the purpose is specific and complete.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage scenarios: 'Use this tool when the user wants to: - Create an Excel file - Export data to Excel - Generate a report/spreadsheet - Download data as .xlsx file.' This gives clear context for when to use the tool. However, with no sibling tools, there are no alternatives to compare against, so it lacks guidance on when not to use it or what other tools might be available, preventing a perfect score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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/nam090320251/dynamic-excel-mcp-server'

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